From bbb6a02b91c91ae7960d9f6cd534809548dacd2d Mon Sep 17 00:00:00 2001 From: AhJ Date: Tue, 16 Jul 2024 21:19:04 +0330 Subject: [PATCH 01/11] Add implements --- .../Tags/Factory/ImplementsFactory.php | 45 ++++++++++++++++ src/DocBlock/Tags/Implements_.php | 53 +++++++++++++++++++ src/DocBlockFactory.php | 5 +- 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/DocBlock/Tags/Factory/ImplementsFactory.php create mode 100644 src/DocBlock/Tags/Implements_.php diff --git a/src/DocBlock/Tags/Factory/ImplementsFactory.php b/src/DocBlock/Tags/Factory/ImplementsFactory.php new file mode 100644 index 00000000..ba7ac5f6 --- /dev/null +++ b/src/DocBlock/Tags/Factory/ImplementsFactory.php @@ -0,0 +1,45 @@ +descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; + } + + public function create(PhpDocTagNode $node, Context $context): Tag + { + $tagValue = $node->value; + Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class); + + return new Implements_( + $this->typeResolver->createType($tagValue->type, $context), + $this->descriptionFactory->create($tagValue->description, $context) + ); + } + + public function supports(PhpDocTagNode $node, Context $context): bool + { + return $node->value instanceof ImplementsTagValueNode && $node->name === '@implements'; + } +} diff --git a/src/DocBlock/Tags/Implements_.php b/src/DocBlock/Tags/Implements_.php new file mode 100644 index 00000000..679f3a14 --- /dev/null +++ b/src/DocBlock/Tags/Implements_.php @@ -0,0 +1,53 @@ +name = 'implements'; + $this->type = $type; + $this->description = $description; + } + + public static function create(string $body) + { + trigger_error( + 'Create using static factory is deprecated, this method should not be called directly + by library consumers', + E_USER_DEPRECATED + ); + } + + public function __toString(): string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $type = $this->type; + + return $type . ($description !== '' ? ' ' . $description : ''); + } +} diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php index 1f7faf1a..a37fd128 100644 --- a/src/DocBlockFactory.php +++ b/src/DocBlockFactory.php @@ -28,6 +28,7 @@ use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\ImplementsFactory; use Webmozart\Assert\Assert; use function array_shift; @@ -76,7 +77,8 @@ public static function createInstance(array $additionalTags = []): DocBlockFacto new PropertyFactory($typeResolver, $descriptionFactory), new PropertyReadFactory($typeResolver, $descriptionFactory), new PropertyWriteFactory($typeResolver, $descriptionFactory), - new MethodFactory($typeResolver, $descriptionFactory) + new MethodFactory($typeResolver, $descriptionFactory), + new ImplementsFactory($typeResolver, $descriptionFactory) ); $tagFactory->addService($descriptionFactory); @@ -88,6 +90,7 @@ public static function createInstance(array $additionalTags = []): DocBlockFacto $tagFactory->registerTagHandler('property-read', $phpstanTagFactory); $tagFactory->registerTagHandler('property-write', $phpstanTagFactory); $tagFactory->registerTagHandler('method', $phpstanTagFactory); + $tagFactory->registerTagHandler('implements', $phpstanTagFactory); $docBlockFactory = new self($descriptionFactory, $tagFactory); foreach ($additionalTags as $tagName => $tagHandler) { From a9794958475dd7154e0549e805dc0641de5554d6 Mon Sep 17 00:00:00 2001 From: AhJ Date: Tue, 16 Jul 2024 21:25:04 +0330 Subject: [PATCH 02/11] add doc --- src/DocBlock/Tags/Implements_.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/DocBlock/Tags/Implements_.php b/src/DocBlock/Tags/Implements_.php index 679f3a14..2e53f2cb 100644 --- a/src/DocBlock/Tags/Implements_.php +++ b/src/DocBlock/Tags/Implements_.php @@ -29,6 +29,10 @@ public function __construct(Type $type, ?Description $description = null) $this->description = $description; } + /** + * @deprecated Create using static factory is deprecated, + * this method should not be called directly by library consumers + */ public static function create(string $body) { trigger_error( From 6908c99a876777327c2169a02f5cb6ae48ff0821 Mon Sep 17 00:00:00 2001 From: AhJ Date: Tue, 23 Jul 2024 18:14:49 +0330 Subject: [PATCH 03/11] Add mixin tag --- src/DocBlock/StandardTagFactory.php | 38 +++++++++-------- src/DocBlock/Tags/Mixin.php | 64 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 18 deletions(-) create mode 100644 src/DocBlock/Tags/Mixin.php diff --git a/src/DocBlock/StandardTagFactory.php b/src/DocBlock/StandardTagFactory.php index 61ad9be8..75b000d2 100644 --- a/src/DocBlock/StandardTagFactory.php +++ b/src/DocBlock/StandardTagFactory.php @@ -22,6 +22,7 @@ use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; use phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag; use phpDocumentor\Reflection\DocBlock\Tags\Method; +use phpDocumentor\Reflection\DocBlock\Tags\Mixin; use phpDocumentor\Reflection\DocBlock\Tags\Param; use phpDocumentor\Reflection\DocBlock\Tags\Property; use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead; @@ -80,25 +81,26 @@ final class StandardTagFactory implements TagFactory * FQCN to a class that handles it as an array value. */ private array $tagHandlerMappings = [ - 'author' => Author::class, - 'covers' => Covers::class, - 'deprecated' => Deprecated::class, - // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', - 'link' => LinkTag::class, - 'method' => Method::class, - 'param' => Param::class, - 'property-read' => PropertyRead::class, - 'property' => Property::class, + 'author' => Author::class, + 'covers' => Covers::class, + 'deprecated' => Deprecated::class, + // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', + 'link' => LinkTag::class, + 'mixin' => Mixin::class, + 'method' => Method::class, + 'param' => Param::class, + 'property-read' => PropertyRead::class, + 'property' => Property::class, 'property-write' => PropertyWrite::class, - 'return' => Return_::class, - 'see' => SeeTag::class, - 'since' => Since::class, - 'source' => Source::class, - 'throw' => Throws::class, - 'throws' => Throws::class, - 'uses' => Uses::class, - 'var' => Var_::class, - 'version' => Version::class, + 'return' => Return_::class, + 'see' => SeeTag::class, + 'since' => Since::class, + 'source' => Source::class, + 'throw' => Throws::class, + 'throws' => Throws::class, + 'uses' => Uses::class, + 'var' => Var_::class, + 'version' => Version::class, ]; /** diff --git a/src/DocBlock/Tags/Mixin.php b/src/DocBlock/Tags/Mixin.php new file mode 100644 index 00000000..f0d1fa60 --- /dev/null +++ b/src/DocBlock/Tags/Mixin.php @@ -0,0 +1,64 @@ +name = 'mixin'; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ): self { + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$type, $description] = self::extractTypeFromBody($body); + + $type = $typeResolver->resolve($type, $context); + $description = $descriptionFactory->create($description, $context); + + return new static($type, $description); + } + + public function __toString(): string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $type = (string) $this->type; + + return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : ''); + } +} From a46da81e776e18aff722274d95bb639c5edc4a23 Mon Sep 17 00:00:00 2001 From: AhJ Date: Wed, 24 Jul 2024 12:09:41 +0330 Subject: [PATCH 04/11] Add Template tag --- src/DocBlock/Tags/Factory/TemplateFactory.php | 52 +++++++++++ src/DocBlock/Tags/Template.php | 87 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 src/DocBlock/Tags/Factory/TemplateFactory.php create mode 100644 src/DocBlock/Tags/Template.php diff --git a/src/DocBlock/Tags/Factory/TemplateFactory.php b/src/DocBlock/Tags/Factory/TemplateFactory.php new file mode 100644 index 00000000..63e0b034 --- /dev/null +++ b/src/DocBlock/Tags/Factory/TemplateFactory.php @@ -0,0 +1,52 @@ +descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; + } + + public function create(PhpDocTagNode $node, Context $context): Tag + { + $tagValue = $node->value; + Assert::isInstanceOf($tagValue, TemplateTagValueNode::class); + + $description = $tagValue->getAttribute('description'); + if (is_string($description) === false) { + $description = $tagValue->description; + } + + return new Template( + $tagValue->name, + $this->typeResolver->createType($tagValue->bound, $context), + $this->typeResolver->createType($tagValue->default, $context), + $this->descriptionFactory->create($tagValue->description, $context) + ); + } + + public function supports(PhpDocTagNode $node, Context $context): bool + { + return $node->value instanceof TemplateTagValueNode && $node->name === '@template'; + } +} diff --git a/src/DocBlock/Tags/Template.php b/src/DocBlock/Tags/Template.php new file mode 100644 index 00000000..b2df710d --- /dev/null +++ b/src/DocBlock/Tags/Template.php @@ -0,0 +1,87 @@ +name = 'template'; + $this->templateName = $templateName; + $this->bound = $bound; + $this->default = $default; + $this->description = $description; + } + + /** + * @deprecated Create using static factory is deprecated, + * this method should not be called directly by library consumers + */ + public static function create(string $body) + { + Deprecation::trigger( + 'phpdocumentor/reflection-docblock', + 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', + 'Create using static factory is deprecated, this method should not be called directly + by library consumers', + ); + return null; + } + + public function getTemplateName(): string + { + return $this->templateName; + } + + public function getBound(): ?Type + { + return $this->bound; + } + + public function getDefault(): ?Type + { + return $this->default; + } + + public function __toString(): string + { + $bound = $this->bound !== null ? " of {$this->bound}" : ''; + $default = $this->default !== null ? " = {$this->default}" : ''; + + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + return $this->templateName . $bound . $default . ($description !== '' ? ' ' . $description : ''); + } +} From f387e8faa9bb405289702eca7cc4bfb1390b00f2 Mon Sep 17 00:00:00 2001 From: AhJ Date: Wed, 24 Jul 2024 12:10:17 +0330 Subject: [PATCH 05/11] Add Extends tags --- src/DocBlock/Tags/Extends_.php | 47 +++++++++++++++++ src/DocBlock/Tags/Factory/ExtendsFactory.php | 53 ++++++++++++++++++++ src/DocBlock/Tags/TemplateExtends.php | 29 +++++++++++ 3 files changed, 129 insertions(+) create mode 100644 src/DocBlock/Tags/Extends_.php create mode 100644 src/DocBlock/Tags/Factory/ExtendsFactory.php create mode 100644 src/DocBlock/Tags/TemplateExtends.php diff --git a/src/DocBlock/Tags/Extends_.php b/src/DocBlock/Tags/Extends_.php new file mode 100644 index 00000000..7d54a889 --- /dev/null +++ b/src/DocBlock/Tags/Extends_.php @@ -0,0 +1,47 @@ +name = 'extends'; + $this->type = $type; + $this->description = $description; + } + + /** + * @deprecated Create using static factory is deprecated, + * this method should not be called directly by library consumers + */ + public static function create(string $body) + { + Deprecation::trigger( + 'phpdocumentor/reflection-docblock', + 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', + 'Create using static factory is deprecated, this method should not be called directly + by library consumers', + ); + return null; + } +} diff --git a/src/DocBlock/Tags/Factory/ExtendsFactory.php b/src/DocBlock/Tags/Factory/ExtendsFactory.php new file mode 100644 index 00000000..87611ab9 --- /dev/null +++ b/src/DocBlock/Tags/Factory/ExtendsFactory.php @@ -0,0 +1,53 @@ +descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; + } + + public function create(PhpDocTagNode $node, Context $context): Tag + { + $tagValue = $node->value; + Assert::isInstanceOf($tagValue, ExtendsTagValueNode::class); + + $description = $tagValue->getAttribute('description'); + if (is_string($description) === false) { + $description = $tagValue->description; + } + + $class = $node->name === '@extends' ? Extends_::class : TemplateExtends::class; + + return new $class( + $this->typeResolver->createType($tagValue->type, $context), + $this->descriptionFactory->create($tagValue->description, $context) + ); + } + + public function supports(PhpDocTagNode $node, Context $context): bool + { + return $node->value instanceof ExtendsTagValueNode && ($node->name === '@extends' || $node->name === '@template-extends'); + } +} diff --git a/src/DocBlock/Tags/TemplateExtends.php b/src/DocBlock/Tags/TemplateExtends.php new file mode 100644 index 00000000..4c9b2571 --- /dev/null +++ b/src/DocBlock/Tags/TemplateExtends.php @@ -0,0 +1,29 @@ +name = 'template-extends'; + } +} From 3acbe24b178e80b6a8f5f386c90c38ff380c051e Mon Sep 17 00:00:00 2001 From: AhJ Date: Wed, 24 Jul 2024 12:10:38 +0330 Subject: [PATCH 06/11] Add Implements tags --- .../Tags/Factory/ImplementsFactory.php | 16 +++++++--- src/DocBlock/Tags/Implements_.php | 22 ++++---------- src/DocBlock/Tags/TemplateImplements.php | 29 +++++++++++++++++++ 3 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 src/DocBlock/Tags/TemplateImplements.php diff --git a/src/DocBlock/Tags/Factory/ImplementsFactory.php b/src/DocBlock/Tags/Factory/ImplementsFactory.php index ba7ac5f6..5f1e9dbf 100644 --- a/src/DocBlock/Tags/Factory/ImplementsFactory.php +++ b/src/DocBlock/Tags/Factory/ImplementsFactory.php @@ -5,13 +5,14 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use Webmozart\Assert\Assert; +use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; -use phpDocumentor\Reflection\DocBlock\Tag; +use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use phpDocumentor\Reflection\DocBlock\Tags\Implements_; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\ImplementsTagValueNode; +use phpDocumentor\Reflection\DocBlock\Tags\TemplateImplements; /** * @internal This class is not part of the BC promise of this library. @@ -32,7 +33,14 @@ public function create(PhpDocTagNode $node, Context $context): Tag $tagValue = $node->value; Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class); - return new Implements_( + $description = $tagValue->getAttribute('description'); + if (is_string($description) === false) { + $description = $tagValue->description; + } + + $class = $node->name === '@implements' ? Implements_::class : TemplateImplements::class; + + return new $class( $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($tagValue->description, $context) ); @@ -40,6 +48,6 @@ public function create(PhpDocTagNode $node, Context $context): Tag public function supports(PhpDocTagNode $node, Context $context): bool { - return $node->value instanceof ImplementsTagValueNode && $node->name === '@implements'; + return $node->value instanceof ImplementsTagValueNode && ($node->name === '@implements' || $node->name === '@template-implements'); } } diff --git a/src/DocBlock/Tags/Implements_.php b/src/DocBlock/Tags/Implements_.php index 2e53f2cb..a871d438 100644 --- a/src/DocBlock/Tags/Implements_.php +++ b/src/DocBlock/Tags/Implements_.php @@ -13,6 +13,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags; +use Doctrine\Deprecations\Deprecation; use phpDocumentor\Reflection\Type; use phpDocumentor\Reflection\DocBlock\Description; use phpDocumentor\Reflection\DocBlock\Tags\TagWithType; @@ -20,7 +21,7 @@ /** * Reflection class for a {@}implements tag in a Docblock. */ -final class Implements_ extends TagWithType +class Implements_ extends TagWithType { public function __construct(Type $type, ?Description $description = null) { @@ -35,23 +36,12 @@ public function __construct(Type $type, ?Description $description = null) */ public static function create(string $body) { - trigger_error( + Deprecation::trigger( + 'phpdocumentor/reflection-docblock', + 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361', 'Create using static factory is deprecated, this method should not be called directly by library consumers', - E_USER_DEPRECATED ); - } - - public function __toString(): string - { - if ($this->description) { - $description = $this->description->render(); - } else { - $description = ''; - } - - $type = $this->type; - - return $type . ($description !== '' ? ' ' . $description : ''); + return null; } } diff --git a/src/DocBlock/Tags/TemplateImplements.php b/src/DocBlock/Tags/TemplateImplements.php new file mode 100644 index 00000000..d6cd689e --- /dev/null +++ b/src/DocBlock/Tags/TemplateImplements.php @@ -0,0 +1,29 @@ +name = 'template-implements'; + } +} From 19b5535d39b8244d253af3fb5f8486863023bc2d Mon Sep 17 00:00:00 2001 From: AhJ Date: Wed, 24 Jul 2024 12:10:58 +0330 Subject: [PATCH 07/11] Clean up --- src/DocBlock/Tags/Mixin.php | 13 ------------- src/DocBlock/Tags/Return_.php | 13 ------------- src/DocBlock/Tags/TagWithType.php | 13 +++++++++++++ src/DocBlock/Tags/Throws.php | 13 ------------- 4 files changed, 13 insertions(+), 39 deletions(-) diff --git a/src/DocBlock/Tags/Mixin.php b/src/DocBlock/Tags/Mixin.php index f0d1fa60..c15d30c1 100644 --- a/src/DocBlock/Tags/Mixin.php +++ b/src/DocBlock/Tags/Mixin.php @@ -48,17 +48,4 @@ public static function create( return new static($type, $description); } - - public function __toString(): string - { - if ($this->description) { - $description = $this->description->render(); - } else { - $description = ''; - } - - $type = (string) $this->type; - - return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : ''); - } } diff --git a/src/DocBlock/Tags/Return_.php b/src/DocBlock/Tags/Return_.php index f130760a..7e9b0c7a 100644 --- a/src/DocBlock/Tags/Return_.php +++ b/src/DocBlock/Tags/Return_.php @@ -60,17 +60,4 @@ public static function create( return new static($type, $description); } - - public function __toString(): string - { - if ($this->description) { - $description = $this->description->render(); - } else { - $description = ''; - } - - $type = $this->type ? '' . $this->type : 'mixed'; - - return $type . ($description !== '' ? ' ' . $description : ''); - } } diff --git a/src/DocBlock/Tags/TagWithType.php b/src/DocBlock/Tags/TagWithType.php index 271c41b5..89e29e5e 100644 --- a/src/DocBlock/Tags/TagWithType.php +++ b/src/DocBlock/Tags/TagWithType.php @@ -71,4 +71,17 @@ protected static function extractTypeFromBody(string $body): array return [$type, $description]; } + + public function __toString(): string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $type = (string) $this->type; + + return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : ''); + } } diff --git a/src/DocBlock/Tags/Throws.php b/src/DocBlock/Tags/Throws.php index f21c9101..e0818468 100644 --- a/src/DocBlock/Tags/Throws.php +++ b/src/DocBlock/Tags/Throws.php @@ -48,17 +48,4 @@ public static function create( return new static($type, $description); } - - public function __toString(): string - { - if ($this->description) { - $description = $this->description->render(); - } else { - $description = ''; - } - - $type = (string) $this->type; - - return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : ''); - } } From cca538efed288026ca67d2bf1bc9503ea097bd9d Mon Sep 17 00:00:00 2001 From: AhJ Date: Wed, 24 Jul 2024 12:11:07 +0330 Subject: [PATCH 08/11] Add TemplateCovariant tag --- src/DocBlock/Tags/TemplateCovariant.php | 51 +++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/DocBlock/Tags/TemplateCovariant.php diff --git a/src/DocBlock/Tags/TemplateCovariant.php b/src/DocBlock/Tags/TemplateCovariant.php new file mode 100644 index 00000000..d5d50987 --- /dev/null +++ b/src/DocBlock/Tags/TemplateCovariant.php @@ -0,0 +1,51 @@ +name = 'template-covariant'; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ): self { + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$type, $description] = self::extractTypeFromBody($body); + + $type = $typeResolver->resolve($type, $context); + $description = $descriptionFactory->create($description, $context); + + return new static($type, $description); + } +} From f93a6b70aa3912ffbe0f78648ff64e4374781beb Mon Sep 17 00:00:00 2001 From: AhJ Date: Wed, 24 Jul 2024 12:11:24 +0330 Subject: [PATCH 09/11] Register tags --- src/DocBlock/StandardTagFactory.php | 104 ++++++++++++++-------------- src/DocBlockFactory.php | 40 ++++++----- 2 files changed, 77 insertions(+), 67 deletions(-) diff --git a/src/DocBlock/StandardTagFactory.php b/src/DocBlock/StandardTagFactory.php index 75b000d2..ecafe74f 100644 --- a/src/DocBlock/StandardTagFactory.php +++ b/src/DocBlock/StandardTagFactory.php @@ -13,46 +13,47 @@ namespace phpDocumentor\Reflection\DocBlock; +use function trim; +use function count; +use function strpos; +use function sprintf; +use ReflectionMethod; +use function get_class; +use function is_object; +use function preg_match; +use ReflectionNamedType; +use ReflectionParameter; +use function array_merge; +use function array_slice; +use Webmozart\Assert\Assert; use InvalidArgumentException; +use function array_key_exists; +use function call_user_func_array; +use phpDocumentor\Reflection\FqsenResolver; +use phpDocumentor\Reflection\DocBlock\Tags\Uses; +use phpDocumentor\Reflection\DocBlock\Tags\Var_; +use phpDocumentor\Reflection\DocBlock\Tags\Mixin; +use phpDocumentor\Reflection\DocBlock\Tags\Param; +use phpDocumentor\Reflection\DocBlock\Tags\Since; use phpDocumentor\Reflection\DocBlock\Tags\Author; use phpDocumentor\Reflection\DocBlock\Tags\Covers; -use phpDocumentor\Reflection\DocBlock\Tags\Deprecated; -use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory; -use phpDocumentor\Reflection\DocBlock\Tags\Generic; -use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; -use phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag; use phpDocumentor\Reflection\DocBlock\Tags\Method; -use phpDocumentor\Reflection\DocBlock\Tags\Mixin; -use phpDocumentor\Reflection\DocBlock\Tags\Param; +use phpDocumentor\Reflection\DocBlock\Tags\Source; +use phpDocumentor\Reflection\DocBlock\Tags\Throws; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; + +use phpDocumentor\Reflection\DocBlock\Tags\Return_; +use phpDocumentor\Reflection\DocBlock\Tags\Version; use phpDocumentor\Reflection\DocBlock\Tags\Property; +use phpDocumentor\Reflection\DocBlock\Tags\Deprecated; +use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag; use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead; use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite; -use phpDocumentor\Reflection\DocBlock\Tags\Return_; use phpDocumentor\Reflection\DocBlock\Tags\See as SeeTag; -use phpDocumentor\Reflection\DocBlock\Tags\Since; -use phpDocumentor\Reflection\DocBlock\Tags\Source; -use phpDocumentor\Reflection\DocBlock\Tags\Throws; -use phpDocumentor\Reflection\DocBlock\Tags\Uses; -use phpDocumentor\Reflection\DocBlock\Tags\Var_; -use phpDocumentor\Reflection\DocBlock\Tags\Version; -use phpDocumentor\Reflection\FqsenResolver; use phpDocumentor\Reflection\Types\Context as TypeContext; -use ReflectionMethod; -use ReflectionNamedType; -use ReflectionParameter; -use Webmozart\Assert\Assert; - -use function array_key_exists; -use function array_merge; -use function array_slice; -use function call_user_func_array; -use function count; -use function get_class; -use function is_object; -use function preg_match; -use function sprintf; -use function strpos; -use function trim; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory; +use phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag; +use phpDocumentor\Reflection\DocBlock\Tags\TemplateCovariant; /** * Creates a Tag object given the contents of a tag. @@ -81,26 +82,27 @@ final class StandardTagFactory implements TagFactory * FQCN to a class that handles it as an array value. */ private array $tagHandlerMappings = [ - 'author' => Author::class, - 'covers' => Covers::class, - 'deprecated' => Deprecated::class, - // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', - 'link' => LinkTag::class, - 'mixin' => Mixin::class, - 'method' => Method::class, - 'param' => Param::class, - 'property-read' => PropertyRead::class, - 'property' => Property::class, - 'property-write' => PropertyWrite::class, - 'return' => Return_::class, - 'see' => SeeTag::class, - 'since' => Since::class, - 'source' => Source::class, - 'throw' => Throws::class, - 'throws' => Throws::class, - 'uses' => Uses::class, - 'var' => Var_::class, - 'version' => Version::class, + 'author' => Author::class, + 'covers' => Covers::class, + 'deprecated' => Deprecated::class, + // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', + 'link' => LinkTag::class, + 'mixin' => Mixin::class, + 'method' => Method::class, + 'param' => Param::class, + 'property-read' => PropertyRead::class, + 'property' => Property::class, + 'property-write' => PropertyWrite::class, + 'return' => Return_::class, + 'see' => SeeTag::class, + 'since' => Since::class, + 'source' => Source::class, + 'template-covariant' => TemplateCovariant::class, + 'throw' => Throws::class, + 'throws' => Throws::class, + 'uses' => Uses::class, + 'var' => Var_::class, + 'version' => Version::class, ]; /** diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php index a37fd128..581cb39e 100644 --- a/src/DocBlockFactory.php +++ b/src/DocBlockFactory.php @@ -13,35 +13,37 @@ namespace phpDocumentor\Reflection; -use InvalidArgumentException; use LogicException; -use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -use phpDocumentor\Reflection\DocBlock\StandardTagFactory; +use InvalidArgumentException; +use Webmozart\Assert\Assert; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\TagFactory; -use phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory; +use phpDocumentor\Reflection\DocBlock\DescriptionFactory; +use phpDocumentor\Reflection\DocBlock\StandardTagFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory; -use phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\ExtendsFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\ImplementsFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory; -use phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory; -use phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory; -use phpDocumentor\Reflection\DocBlock\Tags\Factory\ImplementsFactory; -use Webmozart\Assert\Assert; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory; -use function array_shift; +use function trim; use function count; +use function strpos; +use function substr; use function explode; use function is_object; -use function method_exists; use function preg_match; -use function preg_replace; +use function array_shift; use function str_replace; -use function strpos; -use function substr; -use function trim; +use function preg_replace; +use function method_exists; final class DocBlockFactory implements DocBlockFactoryInterface { @@ -78,7 +80,9 @@ public static function createInstance(array $additionalTags = []): DocBlockFacto new PropertyReadFactory($typeResolver, $descriptionFactory), new PropertyWriteFactory($typeResolver, $descriptionFactory), new MethodFactory($typeResolver, $descriptionFactory), - new ImplementsFactory($typeResolver, $descriptionFactory) + new ImplementsFactory($typeResolver, $descriptionFactory), + new TemplateFactory($typeResolver, $descriptionFactory), + new ExtendsFactory($typeResolver, $descriptionFactory), ); $tagFactory->addService($descriptionFactory); @@ -90,7 +94,11 @@ public static function createInstance(array $additionalTags = []): DocBlockFacto $tagFactory->registerTagHandler('property-read', $phpstanTagFactory); $tagFactory->registerTagHandler('property-write', $phpstanTagFactory); $tagFactory->registerTagHandler('method', $phpstanTagFactory); + $tagFactory->registerTagHandler('extends', $phpstanTagFactory); $tagFactory->registerTagHandler('implements', $phpstanTagFactory); + $tagFactory->registerTagHandler('template', $phpstanTagFactory); + $tagFactory->registerTagHandler('template-extends', $phpstanTagFactory); + $tagFactory->registerTagHandler('template-implements', $phpstanTagFactory); $docBlockFactory = new self($descriptionFactory, $tagFactory); foreach ($additionalTags as $tagName => $tagHandler) { From f17d98425c63079ef35af3f79e9e04f4a0bd84a2 Mon Sep 17 00:00:00 2001 From: AhJ Date: Sat, 27 Jul 2024 18:06:52 +0330 Subject: [PATCH 10/11] Seprate template-* tags --- .../Tags/Factory/AbstractExtendsFactory.php | 32 ++++++++++++++ .../Factory/AbstractImplementsFactory.php | 32 ++++++++++++++ src/DocBlock/Tags/Factory/ExtendsFactory.php | 21 +++------- .../Tags/Factory/ImplementsFactory.php | 21 +++------- .../Tags/Factory/TemplateExtendsFactory.php | 42 +++++++++++++++++++ src/DocBlock/Tags/Factory/TemplateFactory.php | 2 +- .../Factory/TemplateImplementsFactory.php | 42 +++++++++++++++++++ src/DocBlockFactory.php | 6 ++- 8 files changed, 164 insertions(+), 34 deletions(-) create mode 100644 src/DocBlock/Tags/Factory/AbstractExtendsFactory.php create mode 100644 src/DocBlock/Tags/Factory/AbstractImplementsFactory.php create mode 100644 src/DocBlock/Tags/Factory/TemplateExtendsFactory.php create mode 100644 src/DocBlock/Tags/Factory/TemplateImplementsFactory.php diff --git a/src/DocBlock/Tags/Factory/AbstractExtendsFactory.php b/src/DocBlock/Tags/Factory/AbstractExtendsFactory.php new file mode 100644 index 00000000..3325f2f5 --- /dev/null +++ b/src/DocBlock/Tags/Factory/AbstractExtendsFactory.php @@ -0,0 +1,32 @@ +descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; + } + + public function supports(PhpDocTagNode $node, Context $context): bool + { + return $node->value instanceof ExtendsTagValueNode && $node->name === $this->tagName; + } +} diff --git a/src/DocBlock/Tags/Factory/AbstractImplementsFactory.php b/src/DocBlock/Tags/Factory/AbstractImplementsFactory.php new file mode 100644 index 00000000..45341cf1 --- /dev/null +++ b/src/DocBlock/Tags/Factory/AbstractImplementsFactory.php @@ -0,0 +1,32 @@ +descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; + } + + public function supports(PhpDocTagNode $node, Context $context): bool + { + return $node->value instanceof ImplementsTagValueNode && $node->name === $this->tagName; + } +} diff --git a/src/DocBlock/Tags/Factory/ExtendsFactory.php b/src/DocBlock/Tags/Factory/ExtendsFactory.php index 87611ab9..37d36b0f 100644 --- a/src/DocBlock/Tags/Factory/ExtendsFactory.php +++ b/src/DocBlock/Tags/Factory/ExtendsFactory.php @@ -12,20 +12,16 @@ use phpDocumentor\Reflection\DocBlock\Tags\Extends_; use PHPStan\PhpDocParser\Ast\PhpDoc\ExtendsTagValueNode; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; -use phpDocumentor\Reflection\DocBlock\Tags\TemplateExtends; /** * @internal This class is not part of the BC promise of this library. */ -class ExtendsFactory implements PHPStanFactory +final class ExtendsFactory extends AbstractExtendsFactory { - private DescriptionFactory $descriptionFactory; - private TypeResolver $typeResolver; - public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->descriptionFactory = $descriptionFactory; - $this->typeResolver = $typeResolver; + parent::__construct($typeResolver, $descriptionFactory); + $this->tagName = '@extends'; } public function create(PhpDocTagNode $node, Context $context): Tag @@ -38,16 +34,9 @@ public function create(PhpDocTagNode $node, Context $context): Tag $description = $tagValue->description; } - $class = $node->name === '@extends' ? Extends_::class : TemplateExtends::class; - - return new $class( + return new Extends_( $this->typeResolver->createType($tagValue->type, $context), - $this->descriptionFactory->create($tagValue->description, $context) + $this->descriptionFactory->create($description, $context) ); } - - public function supports(PhpDocTagNode $node, Context $context): bool - { - return $node->value instanceof ExtendsTagValueNode && ($node->name === '@extends' || $node->name === '@template-extends'); - } } diff --git a/src/DocBlock/Tags/Factory/ImplementsFactory.php b/src/DocBlock/Tags/Factory/ImplementsFactory.php index 5f1e9dbf..e6266a23 100644 --- a/src/DocBlock/Tags/Factory/ImplementsFactory.php +++ b/src/DocBlock/Tags/Factory/ImplementsFactory.php @@ -12,20 +12,16 @@ use phpDocumentor\Reflection\DocBlock\Tags\Implements_; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use PHPStan\PhpDocParser\Ast\PhpDoc\ImplementsTagValueNode; -use phpDocumentor\Reflection\DocBlock\Tags\TemplateImplements; /** * @internal This class is not part of the BC promise of this library. */ -class ImplementsFactory implements PHPStanFactory +final class ImplementsFactory extends AbstractImplementsFactory { - private DescriptionFactory $descriptionFactory; - private TypeResolver $typeResolver; - public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->descriptionFactory = $descriptionFactory; - $this->typeResolver = $typeResolver; + parent::__construct($typeResolver, $descriptionFactory); + $this->tagName = '@implements'; } public function create(PhpDocTagNode $node, Context $context): Tag @@ -38,16 +34,9 @@ public function create(PhpDocTagNode $node, Context $context): Tag $description = $tagValue->description; } - $class = $node->name === '@implements' ? Implements_::class : TemplateImplements::class; - - return new $class( + return new Implements_( $this->typeResolver->createType($tagValue->type, $context), - $this->descriptionFactory->create($tagValue->description, $context) + $this->descriptionFactory->create($description, $context) ); } - - public function supports(PhpDocTagNode $node, Context $context): bool - { - return $node->value instanceof ImplementsTagValueNode && ($node->name === '@implements' || $node->name === '@template-implements'); - } } diff --git a/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php b/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php new file mode 100644 index 00000000..97475f78 --- /dev/null +++ b/src/DocBlock/Tags/Factory/TemplateExtendsFactory.php @@ -0,0 +1,42 @@ +tagName = '@template-extends'; + } + + public function create(PhpDocTagNode $node, Context $context): Tag + { + $tagValue = $node->value; + Assert::isInstanceOf($tagValue, ExtendsTagValueNode::class); + + $description = $tagValue->getAttribute('description'); + if (is_string($description) === false) { + $description = $tagValue->description; + } + + return new TemplateExtends( + $this->typeResolver->createType($tagValue->type, $context), + $this->descriptionFactory->create($description, $context) + ); + } +} diff --git a/src/DocBlock/Tags/Factory/TemplateFactory.php b/src/DocBlock/Tags/Factory/TemplateFactory.php index 63e0b034..3c1aafdf 100644 --- a/src/DocBlock/Tags/Factory/TemplateFactory.php +++ b/src/DocBlock/Tags/Factory/TemplateFactory.php @@ -41,7 +41,7 @@ public function create(PhpDocTagNode $node, Context $context): Tag $tagValue->name, $this->typeResolver->createType($tagValue->bound, $context), $this->typeResolver->createType($tagValue->default, $context), - $this->descriptionFactory->create($tagValue->description, $context) + $this->descriptionFactory->create($description, $context) ); } diff --git a/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php b/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php new file mode 100644 index 00000000..0f69981f --- /dev/null +++ b/src/DocBlock/Tags/Factory/TemplateImplementsFactory.php @@ -0,0 +1,42 @@ +tagName = '@template-implements'; + } + + public function create(PhpDocTagNode $node, Context $context): Tag + { + $tagValue = $node->value; + Assert::isInstanceOf($tagValue, ImplementsTagValueNode::class); + + $description = $tagValue->getAttribute('description'); + if (is_string($description) === false) { + $description = $tagValue->description; + } + + return new TemplateImplements( + $this->typeResolver->createType($tagValue->type, $context), + $this->descriptionFactory->create($description, $context) + ); + } +} diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php index 581cb39e..408fbc32 100644 --- a/src/DocBlockFactory.php +++ b/src/DocBlockFactory.php @@ -32,6 +32,8 @@ use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory; use phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateExtendsFactory; +use phpDocumentor\Reflection\DocBlock\Tags\Factory\TemplateImplementsFactory; use function trim; use function count; @@ -81,8 +83,10 @@ public static function createInstance(array $additionalTags = []): DocBlockFacto new PropertyWriteFactory($typeResolver, $descriptionFactory), new MethodFactory($typeResolver, $descriptionFactory), new ImplementsFactory($typeResolver, $descriptionFactory), - new TemplateFactory($typeResolver, $descriptionFactory), new ExtendsFactory($typeResolver, $descriptionFactory), + new TemplateFactory($typeResolver, $descriptionFactory), + new TemplateImplementsFactory($typeResolver, $descriptionFactory), + new TemplateExtendsFactory($typeResolver, $descriptionFactory), ); $tagFactory->addService($descriptionFactory); From 47fea84af111566c9de535da0c63259bd7430937 Mon Sep 17 00:00:00 2001 From: AhJ Date: Sat, 27 Jul 2024 18:07:00 +0330 Subject: [PATCH 11/11] Add description --- src/DocBlock/Tags/Template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DocBlock/Tags/Template.php b/src/DocBlock/Tags/Template.php index b2df710d..b5c7bc53 100644 --- a/src/DocBlock/Tags/Template.php +++ b/src/DocBlock/Tags/Template.php @@ -26,7 +26,7 @@ final class Template extends TagWithType /** @var non-empty-string */ private $templateName; - /** @var ?Type */ + /** @var ?Type The real type */ private $bound; /** @var ?Type */