From ada1b6be7fa46428430e427fd04838065f49273e Mon Sep 17 00:00:00 2001 From: Orklah Date: Sun, 9 Feb 2020 15:31:37 +0100 Subject: [PATCH] bump phpstan to master. Fixed ignored errors --- .github/workflows/push.yml | 4 +-- Makefile | 2 +- phpstan.neon | 4 +-- psalm.xml | 7 ++++ src/DocBlock.php | 2 -- src/DocBlock/DescriptionFactory.php | 3 +- src/DocBlock/ExampleFinder.php | 3 +- src/DocBlock/Serializer.php | 2 ++ src/DocBlock/StandardTagFactory.php | 25 +++++--------- src/DocBlock/TagFactory.php | 7 ++-- src/DocBlock/Tags/Author.php | 2 +- src/DocBlock/Tags/Covers.php | 3 -- src/DocBlock/Tags/Deprecated.php | 1 + src/DocBlock/Tags/Example.php | 3 -- src/DocBlock/Tags/Link.php | 3 -- src/DocBlock/Tags/Method.php | 34 ++++++++++--------- src/DocBlock/Tags/Param.php | 6 ++-- src/DocBlock/Tags/Property.php | 8 ++--- src/DocBlock/Tags/PropertyRead.php | 8 ++--- src/DocBlock/Tags/PropertyWrite.php | 8 ++--- src/DocBlock/Tags/Return_.php | 3 -- src/DocBlock/Tags/See.php | 3 -- src/DocBlock/Tags/Since.php | 1 + src/DocBlock/Tags/Source.php | 3 -- src/DocBlock/Tags/Throws.php | 3 -- src/DocBlock/Tags/Uses.php | 3 -- src/DocBlock/Tags/Var_.php | 10 +++--- src/DocBlockFactory.php | 25 +++++++++----- src/DocBlockFactoryInterface.php | 4 ++- .../unit/DocBlock/StandardTagFactoryTest.php | 6 ---- 30 files changed, 85 insertions(+), 111 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 79968eaf..82bed4dd 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -131,7 +131,7 @@ jobs: all-build-${{ hashFiles('**/composer.lock') }} all-build- - name: Code style check - uses: phpDocumentor/coding-standard@v1.0.0 + uses: phpDocumentor/coding-standard@master with: args: -s @@ -153,7 +153,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - args: analyse src --level max --configuration phpstan.neon + args: analyse src --configuration phpstan.neon psalm: runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index bdeae3d8..f8179dd5 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ phpcbf: .PHONY: phpstan phpstan: - docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpstan-ga:latest analyse src --no-progress --level max --configuration phpstan.neon + docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpstan-ga:latest analyse src --no-progress --configuration phpstan.neon .PHONY: psaml psalm: diff --git a/phpstan.neon b/phpstan.neon index 272dd744..b215c6a9 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,6 +3,6 @@ includes: - /composer/vendor/phpstan/phpstan-webmozart-assert/extension.neon parameters: + level: max ignoreErrors: - # false positive - - '#Method phpDocumentor\Reflection\DocBlock\Tags\Method::filterArguments() should return array but returns array#' + - '#Call to static method Webmozart\\Assert\\Assert::implementsInterface\(\) with class-string#' \ No newline at end of file diff --git a/psalm.xml b/psalm.xml index 9fedb8ab..7b901537 100644 --- a/psalm.xml +++ b/psalm.xml @@ -14,5 +14,12 @@ + + + + + + + diff --git a/src/DocBlock.php b/src/DocBlock.php index a5b9f5ce..75848c6a 100644 --- a/src/DocBlock.php +++ b/src/DocBlock.php @@ -150,7 +150,6 @@ public function getTagsByName(string $name) : array { $result = []; - /** @var Tag $tag */ foreach ($this->getTags() as $tag) { if ($tag->getName() !== $name) { continue; @@ -169,7 +168,6 @@ public function getTagsByName(string $name) : array */ public function hasTag(string $name) : bool { - /** @var Tag $tag */ foreach ($this->getTags() as $tag) { if ($tag->getName() === $name) { return true; diff --git a/src/DocBlock/DescriptionFactory.php b/src/DocBlock/DescriptionFactory.php index 267e5af4..3624a9bb 100644 --- a/src/DocBlock/DescriptionFactory.php +++ b/src/DocBlock/DescriptionFactory.php @@ -15,7 +15,6 @@ use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; -use const PREG_SPLIT_DELIM_CAPTURE; use function count; use function explode; use function implode; @@ -27,6 +26,7 @@ use function strpos; use function substr; use function trim; +use const PREG_SPLIT_DELIM_CAPTURE; /** * Creates a new Description object given a body of text. @@ -128,6 +128,7 @@ private function lex(string $contents) : array PREG_SPLIT_DELIM_CAPTURE ); Assert::isArray($parts); + return $parts; } diff --git a/src/DocBlock/ExampleFinder.php b/src/DocBlock/ExampleFinder.php index db42be71..7249efb0 100644 --- a/src/DocBlock/ExampleFinder.php +++ b/src/DocBlock/ExampleFinder.php @@ -14,7 +14,6 @@ namespace phpDocumentor\Reflection\DocBlock; use phpDocumentor\Reflection\DocBlock\Tags\Example; -use const DIRECTORY_SEPARATOR; use function array_slice; use function file; use function getcwd; @@ -23,6 +22,7 @@ use function rtrim; use function sprintf; use function trim; +use const DIRECTORY_SEPARATOR; /** * Class used to find an example file's location based on a given ExampleDescriptor. @@ -122,6 +122,7 @@ private function getExampleFileContents(string $filename) : ?array } $lines = $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : false; + return $lines !== false ? $lines : null; } diff --git a/src/DocBlock/Serializer.php b/src/DocBlock/Serializer.php index e8a5c647..9db3d526 100644 --- a/src/DocBlock/Serializer.php +++ b/src/DocBlock/Serializer.php @@ -94,6 +94,7 @@ public function getDocComment(DocBlock $docblock) : string } $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment); + return $comment . $indent . ' */'; } @@ -127,6 +128,7 @@ private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, ?int $wra : ''); if ($wrapLength !== null) { $text = wordwrap($text, $wrapLength); + return $text; } diff --git a/src/DocBlock/StandardTagFactory.php b/src/DocBlock/StandardTagFactory.php index 7b348c7f..ef8c6fe7 100644 --- a/src/DocBlock/StandardTagFactory.php +++ b/src/DocBlock/StandardTagFactory.php @@ -71,8 +71,8 @@ final class StandardTagFactory implements TagFactory public const REGEX_TAGNAME = '[\w\-\_\\\\:]+'; /** - * @var string[] An array with a tag as a key, and an - * FQCN to a class that handles it as an array value. + * @var array> An array with a tag as a key, and an + * FQCN to a class that handles it as an array value. */ private $tagHandlerMappings = [ 'author' => Author::class, @@ -97,7 +97,7 @@ final class StandardTagFactory implements TagFactory ]; /** - * @var string[] An array with a anotation s a key, and an + * @var array> An array with a anotation s a key, and an * FQCN to a class that handles it as an array value. */ private $annotationMappings = []; @@ -125,7 +125,7 @@ final class StandardTagFactory implements TagFactory * * @see self::registerTagHandler() to add a new tag handler to the existing default list. * - * @param string[] $tagHandlers + * @param array> $tagHandlers */ public function __construct(FqsenResolver $fqsenResolver, ?array $tagHandlers = null) { @@ -137,9 +137,6 @@ public function __construct(FqsenResolver $fqsenResolver, ?array $tagHandlers = $this->addService($fqsenResolver, FqsenResolver::class); } - /** - * {@inheritDoc} - */ public function create(string $tagLine, ?TypeContext $context = null) : Tag { if (!$context) { @@ -152,29 +149,22 @@ public function create(string $tagLine, ?TypeContext $context = null) : Tag } /** - * {@inheritDoc} + * @param mixed $value */ public function addParameter(string $name, $value) : void { $this->serviceLocator[$name] = $value; } - /** - * {@inheritDoc} - */ public function addService(object $service, ?string $alias = null) : void { $this->serviceLocator[$alias ?: get_class($service)] = $service; } - /** - * {@inheritDoc} - */ public function registerTagHandler(string $tagName, string $handler) : void { Assert::stringNotEmpty($tagName); Assert::classExists($handler); - /** @var object $handler stupid hack to make phpstan happy. */ Assert::implementsInterface($handler, StaticMethod::class); if (strpos($tagName, '\\') && $tagName[0] !== '\\') { @@ -220,9 +210,10 @@ private function createTag(string $body, string $name, TypeContext $context) : T ); try { - /** @var callable $callable */ $callable = [$handlerClassName, 'create']; - $tag = call_user_func_array($callable, $arguments); + Assert::isCallable($callable); + $tag = call_user_func_array($callable, $arguments); + return $tag ?? InvalidTag::create($body, $name); } catch (InvalidArgumentException $e) { return InvalidTag::create($body, $name)->withError($e); diff --git a/src/DocBlock/TagFactory.php b/src/DocBlock/TagFactory.php index 1a2dc893..1602d679 100644 --- a/src/DocBlock/TagFactory.php +++ b/src/DocBlock/TagFactory.php @@ -14,6 +14,7 @@ namespace phpDocumentor\Reflection\DocBlock; use InvalidArgumentException; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod; use phpDocumentor\Reflection\Types\Context as TypeContext; interface TagFactory @@ -69,9 +70,9 @@ public function addService(object $service) : void; * to register the name of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement * the {@see Tag} interface (and thus the create method). * - * @param string $tagName Name of tag to register a handler for. When registering a namespaced tag, - * the full name, along with a prefixing slash MUST be provided. - * @param string $handler FQCN of handler. + * @param string $tagName Name of tag to register a handler for. When registering a namespaced + * tag, the full name, along with a prefixing slash MUST be provided. + * @param class-string $handler FQCN of handler. * * @throws InvalidArgumentException If the tag name is not a string. * @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but diff --git a/src/DocBlock/Tags/Author.php b/src/DocBlock/Tags/Author.php index 4bebe494..0f759c74 100644 --- a/src/DocBlock/Tags/Author.php +++ b/src/DocBlock/Tags/Author.php @@ -14,11 +14,11 @@ namespace phpDocumentor\Reflection\DocBlock\Tags; use InvalidArgumentException; -use const FILTER_VALIDATE_EMAIL; use function filter_var; use function preg_match; use function strlen; use function trim; +use const FILTER_VALIDATE_EMAIL; /** * Reflection class for an {@}author tag in a Docblock. diff --git a/src/DocBlock/Tags/Covers.php b/src/DocBlock/Tags/Covers.php index 5d165f80..77edf4a3 100644 --- a/src/DocBlock/Tags/Covers.php +++ b/src/DocBlock/Tags/Covers.php @@ -41,9 +41,6 @@ public function __construct(Fqsen $refers, ?Description $description = null) $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?DescriptionFactory $descriptionFactory = null, diff --git a/src/DocBlock/Tags/Deprecated.php b/src/DocBlock/Tags/Deprecated.php index 130d8449..09d57d04 100644 --- a/src/DocBlock/Tags/Deprecated.php +++ b/src/DocBlock/Tags/Deprecated.php @@ -75,6 +75,7 @@ public static function create( } Assert::notNull($descriptionFactory); + return new static( $matches[1], $descriptionFactory->create($matches[2] ?? '', $context) diff --git a/src/DocBlock/Tags/Example.php b/src/DocBlock/Tags/Example.php index d27ed477..92668e4b 100644 --- a/src/DocBlock/Tags/Example.php +++ b/src/DocBlock/Tags/Example.php @@ -82,9 +82,6 @@ public function getDescription() : ?string return $this->content; } - /** - * {@inheritdoc} - */ public static function create(string $body) : ?Tag { // File component: File path in quotes or File URI / Source information diff --git a/src/DocBlock/Tags/Link.php b/src/DocBlock/Tags/Link.php index a50c813a..0588f722 100644 --- a/src/DocBlock/Tags/Link.php +++ b/src/DocBlock/Tags/Link.php @@ -39,9 +39,6 @@ public function __construct(string $link, ?Description $description = null) $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?DescriptionFactory $descriptionFactory = null, diff --git a/src/DocBlock/Tags/Method.php b/src/DocBlock/Tags/Method.php index c7a00e4d..92c710d6 100644 --- a/src/DocBlock/Tags/Method.php +++ b/src/DocBlock/Tags/Method.php @@ -44,7 +44,10 @@ final class Method extends BaseTag implements Factory\StaticMethod /** @var string */ private $methodName = ''; - /** @var string[][] */ + /** + * @phpstan-var array + * @var array> + */ private $arguments = []; /** @var bool */ @@ -54,9 +57,9 @@ final class Method extends BaseTag implements Factory\StaticMethod private $returnType; /** - * @param mixed[][] $arguments + * @param array> $arguments * - * @psalm-param array|string> $arguments + * @phpstan-param array $arguments */ public function __construct( string $methodName, @@ -78,9 +81,6 @@ public function __construct( $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, @@ -137,7 +137,7 @@ public static function create( return null; } - [, $static, $returnType, $methodName, $arguments, $description] = $matches; + [, $static, $returnType, $methodName, $argumentLines, $description] = $matches; $static = $static === 'static'; @@ -148,9 +148,11 @@ public static function create( $returnType = $typeResolver->resolve($returnType, $context); $description = $descriptionFactory->create($description, $context); - if ($arguments !== '') { - $arguments = explode(',', $arguments); - foreach ($arguments as &$argument) { + /** @phpstan-var array $arguments */ + $arguments = []; + if ($argumentLines !== '') { + $argumentsExploded = explode(',', $argumentLines); + foreach ($argumentsExploded as $argument) { $argument = explode(' ', self::stripRestArg(trim($argument)), 2); if ($argument[0][0] === '$') { $argumentName = substr($argument[0], 1); @@ -164,10 +166,8 @@ public static function create( } } - $argument = ['name' => $argumentName, 'type' => $argumentType]; + $arguments[] = ['name' => $argumentName, 'type' => $argumentType]; } - } else { - $arguments = []; } return new static($methodName, $arguments, $returnType, $static, $description); @@ -182,7 +182,9 @@ public function getMethodName() : string } /** - * @return string[][] + * @return array> + * + * @phpstan-return array */ public function getArguments() : array { @@ -223,8 +225,8 @@ public function __toString() : string * * @return mixed[][] * - * @psalm-param array|string> $arguments - * @psalm-return array> $arguments + * @phpstan-param array $arguments + * @phpstan-return array */ private function filterArguments(array $arguments = []) : array { diff --git a/src/DocBlock/Tags/Param.php b/src/DocBlock/Tags/Param.php index 658ea973..bd881497 100644 --- a/src/DocBlock/Tags/Param.php +++ b/src/DocBlock/Tags/Param.php @@ -19,7 +19,6 @@ use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; -use const PREG_SPLIT_DELIM_CAPTURE; use function array_shift; use function array_unshift; use function implode; @@ -27,6 +26,7 @@ use function strlen; use function strpos; use function substr; +use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for the {@}param tag in a Docblock. @@ -52,9 +52,6 @@ public function __construct( $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, @@ -69,6 +66,7 @@ public static function create( $type = null; $parts = preg_split('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + Assert::isArray($parts); $variableName = ''; $isVariadic = false; diff --git a/src/DocBlock/Tags/Property.php b/src/DocBlock/Tags/Property.php index 81bff40c..27ce0325 100644 --- a/src/DocBlock/Tags/Property.php +++ b/src/DocBlock/Tags/Property.php @@ -19,7 +19,6 @@ use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; -use const PREG_SPLIT_DELIM_CAPTURE; use function array_shift; use function array_unshift; use function implode; @@ -27,6 +26,7 @@ use function strlen; use function strpos; use function substr; +use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}property tag in a Docblock. @@ -46,9 +46,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, @@ -62,7 +59,8 @@ public static function create( [$firstPart, $body] = self::extractTypeFromBody($body); $type = null; $parts = preg_split('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; + Assert::isArray($parts); + $variableName = ''; // if the first item that is encountered is not a variable; it is a type if ($firstPart && (strlen($firstPart) > 0) && ($firstPart[0] !== '$')) { diff --git a/src/DocBlock/Tags/PropertyRead.php b/src/DocBlock/Tags/PropertyRead.php index a1f8c8a5..135e352d 100644 --- a/src/DocBlock/Tags/PropertyRead.php +++ b/src/DocBlock/Tags/PropertyRead.php @@ -19,7 +19,6 @@ use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; -use const PREG_SPLIT_DELIM_CAPTURE; use function array_shift; use function array_unshift; use function implode; @@ -27,6 +26,7 @@ use function strlen; use function strpos; use function substr; +use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}property-read tag in a Docblock. @@ -46,9 +46,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, @@ -62,7 +59,8 @@ public static function create( [$firstPart, $body] = self::extractTypeFromBody($body); $type = null; $parts = preg_split('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; + Assert::isArray($parts); + $variableName = ''; // if the first item that is encountered is not a variable; it is a type if ($firstPart && (strlen($firstPart) > 0) && ($firstPart[0] !== '$')) { diff --git a/src/DocBlock/Tags/PropertyWrite.php b/src/DocBlock/Tags/PropertyWrite.php index ae57fdc3..ad91267f 100644 --- a/src/DocBlock/Tags/PropertyWrite.php +++ b/src/DocBlock/Tags/PropertyWrite.php @@ -19,7 +19,6 @@ use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; -use const PREG_SPLIT_DELIM_CAPTURE; use function array_shift; use function array_unshift; use function implode; @@ -27,6 +26,7 @@ use function strlen; use function strpos; use function substr; +use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}property-write tag in a Docblock. @@ -46,9 +46,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, @@ -62,7 +59,8 @@ public static function create( [$firstPart, $body] = self::extractTypeFromBody($body); $type = null; $parts = preg_split('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); - $variableName = ''; + Assert::isArray($parts); + $variableName = ''; // if the first item that is encountered is not a variable; it is a type if ($firstPart && (strlen($firstPart) > 0) && ($firstPart[0] !== '$')) { diff --git a/src/DocBlock/Tags/Return_.php b/src/DocBlock/Tags/Return_.php index 96808757..60ba8603 100644 --- a/src/DocBlock/Tags/Return_.php +++ b/src/DocBlock/Tags/Return_.php @@ -32,9 +32,6 @@ public function __construct(Type $type, ?Description $description = null) $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, diff --git a/src/DocBlock/Tags/See.php b/src/DocBlock/Tags/See.php index 21d85910..190973d6 100644 --- a/src/DocBlock/Tags/See.php +++ b/src/DocBlock/Tags/See.php @@ -44,9 +44,6 @@ public function __construct(Reference $refers, ?Description $description = null) $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?FqsenResolver $typeResolver = null, diff --git a/src/DocBlock/Tags/Since.php b/src/DocBlock/Tags/Since.php index 31ce54c9..dcc76963 100644 --- a/src/DocBlock/Tags/Since.php +++ b/src/DocBlock/Tags/Since.php @@ -69,6 +69,7 @@ public static function create( } Assert::notNull($descriptionFactory); + return new static( $matches[1], $descriptionFactory->create($matches[2] ?? '', $context) diff --git a/src/DocBlock/Tags/Source.php b/src/DocBlock/Tags/Source.php index b678806e..2d5387fc 100644 --- a/src/DocBlock/Tags/Source.php +++ b/src/DocBlock/Tags/Source.php @@ -47,9 +47,6 @@ public function __construct($startingLine, $lineCount = null, ?Description $desc $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?DescriptionFactory $descriptionFactory = null, diff --git a/src/DocBlock/Tags/Throws.php b/src/DocBlock/Tags/Throws.php index 549883aa..13f07cec 100644 --- a/src/DocBlock/Tags/Throws.php +++ b/src/DocBlock/Tags/Throws.php @@ -32,9 +32,6 @@ public function __construct(Type $type, ?Description $description = null) $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, diff --git a/src/DocBlock/Tags/Uses.php b/src/DocBlock/Tags/Uses.php index 7a69642d..1be71f66 100644 --- a/src/DocBlock/Tags/Uses.php +++ b/src/DocBlock/Tags/Uses.php @@ -41,9 +41,6 @@ public function __construct(Fqsen $refers, ?Description $description = null) $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?FqsenResolver $resolver = null, diff --git a/src/DocBlock/Tags/Var_.php b/src/DocBlock/Tags/Var_.php index 8f1ae426..12c1e4b0 100644 --- a/src/DocBlock/Tags/Var_.php +++ b/src/DocBlock/Tags/Var_.php @@ -19,7 +19,6 @@ use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; use Webmozart\Assert\Assert; -use const PREG_SPLIT_DELIM_CAPTURE; use function array_shift; use function array_unshift; use function implode; @@ -27,6 +26,7 @@ use function strlen; use function strpos; use function substr; +use const PREG_SPLIT_DELIM_CAPTURE; /** * Reflection class for a {@}var tag in a Docblock. @@ -46,9 +46,6 @@ public function __construct(?string $variableName, ?Type $type = null, ?Descript $this->description = $description; } - /** - * {@inheritdoc} - */ public static function create( string $body, ?TypeResolver $typeResolver = null, @@ -61,7 +58,8 @@ public static function create( [$firstPart, $body] = self::extractTypeFromBody($body); - $parts = preg_split('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + $parts = preg_split('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + Assert::isArray($parts); $type = null; $variableName = ''; @@ -102,7 +100,7 @@ public function getVariableName() : ?string public function __toString() : string { return ($this->type ? $this->type . ' ' : '') - . (empty($this->variableName) ? '' : ('$' . $this->variableName)) + . (empty($this->variableName) ? '' : '$' . $this->variableName) . ($this->description ? ' ' . $this->description : ''); } } diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php index 1e669b5e..cc3be3c9 100644 --- a/src/DocBlockFactory.php +++ b/src/DocBlockFactory.php @@ -18,6 +18,7 @@ use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\StandardTagFactory; use phpDocumentor\Reflection\DocBlock\TagFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod; use Webmozart\Assert\Assert; use function array_shift; use function count; @@ -51,7 +52,7 @@ public function __construct(DescriptionFactory $descriptionFactory, TagFactory $ /** * Factory method for easy instantiation. * - * @param string[] $additionalTags + * @param array> $additionalTags */ public static function createInstance(array $additionalTags = []) : self { @@ -79,6 +80,7 @@ public function create($docblock, ?Types\Context $context = null, ?Location $loc if (is_object($docblock)) { if (!method_exists($docblock, 'getDocComment')) { $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method'; + throw new InvalidArgumentException($exceptionMessage); } @@ -106,6 +108,9 @@ public function create($docblock, ?Types\Context $context = null, ?Location $loc ); } + /** + * @param class-string $handler + */ public function registerTagHandler(string $tagName, string $handler) : void { $this->tagFactory->registerTagHandler($tagName, $handler); @@ -118,8 +123,8 @@ public function registerTagHandler(string $tagName, string $handler) : void */ private function stripDocComment(string $comment) : string { - /** @var string $comment */ $comment = preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]{0,1}(.*)?#u', '$1', $comment); + Assert::string($comment); $comment = trim($comment); // reg ex above is not able to remove */ from a single line docblock @@ -130,7 +135,7 @@ private function stripDocComment(string $comment) : string return str_replace(["\r\n", "\r"], "\n", $comment); } - // phpcs:disable SlevomatCodingStandard.Commenting.ForbiddenAnnotations.AnnotationForbidden + // phpcs:disable /** * Splits the DocBlock into a template marker, summary, description and block of tags. * @@ -144,6 +149,7 @@ private function stripDocComment(string $comment) : string */ private function splitDocBlock(string $comment) : array { + // phpcs:enable // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the // performance impact of running a regular expression @@ -152,9 +158,8 @@ private function splitDocBlock(string $comment) : array } // clears all extra horizontal whitespace from the line endings to prevent parsing issues - /** @var string $comment */ $comment = preg_replace('/\h*$/Sum', '', $comment); - + Assert::string($comment); /* * Splits the docblock into a template marker, summary, description and tags section. * @@ -247,11 +252,11 @@ private function parseTagBlock(string $tags, Types\Context $context) : array private function splitTagBlockIntoTagLines(string $tags) : array { $result = []; - foreach (explode("\n", $tags) as $tag_line) { - if (isset($tag_line[0]) && ($tag_line[0] === '@')) { - $result[] = $tag_line; + foreach (explode("\n", $tags) as $tagLine) { + if (isset($tagLine[0]) && ($tagLine[0] === '@')) { + $result[] = $tagLine; } else { - $result[count($result) - 1] .= "\n" . $tag_line; + $result[count($result) - 1] .= "\n" . $tagLine; } } @@ -269,7 +274,9 @@ private function filterTagBlock(string $tags) : ?string // @codeCoverageIgnoreStart // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that // we didn't foresee. + throw new LogicException('A tag block started with text instead of an at-sign(@): ' . $tags); + // @codeCoverageIgnoreEnd } diff --git a/src/DocBlockFactoryInterface.php b/src/DocBlockFactoryInterface.php index c1619569..59e4d04f 100644 --- a/src/DocBlockFactoryInterface.php +++ b/src/DocBlockFactoryInterface.php @@ -4,13 +4,15 @@ namespace phpDocumentor\Reflection; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\StaticMethod; + // phpcs:ignore SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix interface DocBlockFactoryInterface { /** * Factory method for easy instantiation. * - * @param string[] $additionalTags + * @param array> $additionalTags */ public static function createInstance(array $additionalTags = []) : DocBlockFactory; diff --git a/tests/unit/DocBlock/StandardTagFactoryTest.php b/tests/unit/DocBlock/StandardTagFactoryTest.php index 33372045..2ea0aaa7 100644 --- a/tests/unit/DocBlock/StandardTagFactoryTest.php +++ b/tests/unit/DocBlock/StandardTagFactoryTest.php @@ -68,7 +68,6 @@ public function testCreatingAGenericTag() : void $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); $tagFactory->addService($descriptionFactory, DescriptionFactory::class); - /** @var Generic $tag */ $tag = $tagFactory->create('@' . $expectedTagName . ' This is a description', $context); $this->assertInstanceOf(Generic::class, $tag); @@ -89,7 +88,6 @@ public function testCreatingASpecificTag() : void $context = new Context(''); $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); - /** @var Author $tag */ $tag = $tagFactory->create('@author Mike van Riel ', $context); $this->assertInstanceOf(Author::class, $tag); @@ -120,7 +118,6 @@ public function testAnEmptyContextIsCreatedIfNoneIsProvided() : void $tagFactory = new StandardTagFactory($resolver); $tagFactory->addService($descriptionFactory, DescriptionFactory::class); - /** @var See $tag */ $tag = $tagFactory->create('@see Tag'); $this->assertInstanceOf(See::class, $tag); @@ -140,7 +137,6 @@ public function testPassingYourOwnSetOfTagHandlers() : void $context = new Context(''); $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class), ['user' => Author::class]); - /** @var Author $tag */ $tag = $tagFactory->create('@user Mike van Riel ', $context); $this->assertInstanceOf(Author::class, $tag); @@ -326,7 +322,6 @@ public function testReturnTagIsMappedCorrectly() : void $tagFactory->addService($descriptionFactory, DescriptionFactory::class); $tagFactory->addService($typeResolver, TypeResolver::class); - /** @var Return_ $tag */ $tag = $tagFactory->create('@return mixed', $context); $this->assertInstanceOf(Return_::class, $tag); @@ -337,7 +332,6 @@ public function testInvalidTagIsReturnedOnFailure() : void { $tagFactory = new StandardTagFactory(m::mock(FqsenResolver::class)); - /** @var InvalidTag $tag */ $tag = $tagFactory->create('@see $name some invalid tag'); $this->assertInstanceOf(InvalidTag::class, $tag);