From 6a92bc3ce91ed40e8b1fc478f167ae5b8de17f5f Mon Sep 17 00:00:00 2001 From: Jaapio Date: Fri, 11 Nov 2022 12:30:14 +0100 Subject: [PATCH] Remove type logic from this package --- composer.json | 4 +- composer.lock | 46 +-- .../Tags/Factory/AbstractPHPStanFactory.php | 4 + src/DocBlock/Tags/Factory/MethodFactory.php | 17 +- src/DocBlock/Tags/Factory/PHPStanFactory.php | 4 +- src/DocBlock/Tags/Factory/ParamFactory.php | 13 +- src/DocBlock/Tags/Factory/PropertyFactory.php | 13 +- .../Tags/Factory/PropertyReadFactory.php | 13 +- .../Tags/Factory/PropertyWriteFactory.php | 13 +- src/DocBlock/Tags/Factory/ReturnFactory.php | 13 +- src/DocBlock/Tags/Factory/TypeFactory.php | 230 -------------- src/DocBlock/Tags/Factory/VarFactory.php | 13 +- src/DocBlockFactory.php | 13 +- src/PseudoTypes/ArrayShape.php | 34 -- src/PseudoTypes/ArrayShapeItem.php | 53 ---- src/PseudoTypes/ConstExpression.php | 44 --- src/PseudoTypes/FloatValue.php | 34 -- src/PseudoTypes/IntegerValue.php | 34 -- src/PseudoTypes/StringValue.php | 36 --- .../Tags/Factory/MethodFactoryTest.php | 14 +- .../Tags/Factory/ParamFactoryTest.php | 2 +- .../Tags/Factory/PropertyFactoryTest.php | 2 +- .../Tags/Factory/PropertyReadFactoryTest.php | 2 +- .../Tags/Factory/PropertyWriteFactoryTest.php | 2 +- .../Tags/Factory/ReturnFactoryTest.php | 2 +- .../Tags/Factory/TagFactoryTestCase.php | 4 +- .../DocBlock/Tags/Factory/TypeFactoryTest.php | 291 ------------------ .../DocBlock/Tags/Factory/VarFactoryTest.php | 2 +- 28 files changed, 108 insertions(+), 844 deletions(-) delete mode 100644 src/DocBlock/Tags/Factory/TypeFactory.php delete mode 100644 src/PseudoTypes/ArrayShape.php delete mode 100644 src/PseudoTypes/ArrayShapeItem.php delete mode 100644 src/PseudoTypes/ConstExpression.php delete mode 100644 src/PseudoTypes/FloatValue.php delete mode 100644 src/PseudoTypes/IntegerValue.php delete mode 100644 src/PseudoTypes/StringValue.php delete mode 100644 tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php diff --git a/composer.json b/composer.json index 8a91cb2..c4348f1 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ } ], "require": { - "php": "^7.4 || ^8.0", - "phpdocumentor/type-resolver": "^1.3", + "php": "^7.2 || ^8.0", + "phpdocumentor/type-resolver": "1.x-dev@dev", "webmozart/assert": "^1.9.1", "phpdocumentor/reflection-common": "^2.2", "ext-filter": "*", diff --git a/composer.lock b/composer.lock index b5912bb..55b451a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "99af646bb3e1fa0d77d855f0f5995c9f", + "content-hash": "829061026cc6b2284953cbe816406760", "packages": [ { "name": "phpdocumentor/reflection-common", @@ -61,26 +61,34 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.1", + "version": "1.x-dev", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" + "reference": "662b17f56786e34354684f6c141c1909b1ee3ac0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/662b17f56786e34354684f6c141c1909b1ee3ac0", + "reference": "662b17f56786e34354684f6c141c1909b1ee3ac0", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -105,22 +113,22 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.x" }, - "time": "2022-03-15T21:29:03+00:00" + "time": "2022-11-11T10:44:03+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.7.0", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "367a8d9d5f7da2a0136422d27ce8840583926955" + "reference": "33aefcdab42900e36366d0feab6206e2dd68f947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/367a8d9d5f7da2a0136422d27ce8840583926955", - "reference": "367a8d9d5f7da2a0136422d27ce8840583926955", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/33aefcdab42900e36366d0feab6206e2dd68f947", + "reference": "33aefcdab42900e36366d0feab6206e2dd68f947", "shasum": "" }, "require": { @@ -150,9 +158,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.7.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.13.0" }, - "time": "2022-08-09T12:23:23+00:00" + "time": "2022-10-21T09:57:39+00:00" }, { "name": "webmozart/assert", @@ -4049,11 +4057,13 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "phpdocumentor/type-resolver": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.4 || ^8.0", + "php": "^7.2 || ^8.0", "ext-filter": "*" }, "platform-dev": [], diff --git a/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php index 62d32f2..7d96d31 100644 --- a/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php +++ b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php @@ -50,6 +50,10 @@ class AbstractPHPStanFactory implements Factory $tokens = $this->lexer->tokenize($tagLine); $ast = $this->parser->parseTag(new TokenIterator($tokens)); + if ($context === null) { + $context = new TypeContext(''); + } + foreach ($this->factories as $factory) { if ($factory->supports($ast, $context)) { return $factory->create($ast, $context); diff --git a/src/DocBlock/Tags/Factory/MethodFactory.php b/src/DocBlock/Tags/Factory/MethodFactory.php index 6a12204..c884743 100644 --- a/src/DocBlock/Tags/Factory/MethodFactory.php +++ b/src/DocBlock/Tags/Factory/MethodFactory.php @@ -9,6 +9,7 @@ use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Method; use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter; use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use phpDocumentor\Reflection\Types\Mixed_; use phpDocumentor\Reflection\Types\Void_; @@ -25,16 +26,16 @@ use function trim; */ final class MethodFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; $this->descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, MethodTagValueNode::class); @@ -50,7 +51,7 @@ final class MethodFactory implements PHPStanFactory function (MethodTagValueParameterNode $param) use ($context) { return new MethodParameter( trim($param->parameterName, '$'), - $this->typeFactory->createType($param->type, $context) ?? new Mixed_(), + $this->typeResolver->createType($param->type, $context) ?? new Mixed_(), $param->isReference, $param->isVariadic, (string) $param->defaultValue @@ -61,13 +62,13 @@ final class MethodFactory implements PHPStanFactory ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof MethodTagValueNode; } - private function createReturnType(MethodTagValueNode $tagValue, ?Context $context): Type + private function createReturnType(MethodTagValueNode $tagValue, Context $context): Type { - return $this->typeFactory->createType($tagValue->returnType, $context) ?? new Void_(); + return $this->typeResolver->createType($tagValue->returnType, $context) ?? new Void_(); } } diff --git a/src/DocBlock/Tags/Factory/PHPStanFactory.php b/src/DocBlock/Tags/Factory/PHPStanFactory.php index 8f352df..cf04a06 100644 --- a/src/DocBlock/Tags/Factory/PHPStanFactory.php +++ b/src/DocBlock/Tags/Factory/PHPStanFactory.php @@ -10,7 +10,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; interface PHPStanFactory { - public function create(PhpDocTagNode $node, ?Context $context): Tag; + public function create(PhpDocTagNode $node, Context $context): Tag; - public function supports(PhpDocTagNode $node, ?Context $context): bool; + public function supports(PhpDocTagNode $node, Context $context): bool; } diff --git a/src/DocBlock/Tags/Factory/ParamFactory.php b/src/DocBlock/Tags/Factory/ParamFactory.php index 6dbab3d..fd0c006 100644 --- a/src/DocBlock/Tags/Factory/ParamFactory.php +++ b/src/DocBlock/Tags/Factory/ParamFactory.php @@ -7,6 +7,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Param; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; @@ -19,30 +20,30 @@ use function trim; */ final class ParamFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; $this->descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, ParamTagValueNode::class); return new Param( trim($tagValue->parameterName, '$'), - $this->typeFactory->createType($tagValue->type, $context), + $this->typeResolver->createType($tagValue->type, $context), $tagValue->isVariadic, $this->descriptionFactory->create($tagValue->description, $context), $tagValue->isReference ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof ParamTagValueNode; } diff --git a/src/DocBlock/Tags/Factory/PropertyFactory.php b/src/DocBlock/Tags/Factory/PropertyFactory.php index 9e7ec66..83a18e8 100644 --- a/src/DocBlock/Tags/Factory/PropertyFactory.php +++ b/src/DocBlock/Tags/Factory/PropertyFactory.php @@ -7,6 +7,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Property; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode; @@ -19,28 +20,28 @@ use function trim; */ final class PropertyFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; $this->descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, PropertyTagValueNode::class); return new Property( trim($tagValue->propertyName, '$'), - $this->typeFactory->createType($tagValue->type, $context), + $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($tagValue->description, $context) ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof PropertyTagValueNode && $node->name === '@property'; } diff --git a/src/DocBlock/Tags/Factory/PropertyReadFactory.php b/src/DocBlock/Tags/Factory/PropertyReadFactory.php index 3173428..be443ab 100644 --- a/src/DocBlock/Tags/Factory/PropertyReadFactory.php +++ b/src/DocBlock/Tags/Factory/PropertyReadFactory.php @@ -7,6 +7,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode; @@ -19,28 +20,28 @@ use function trim; */ final class PropertyReadFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; + $this->typeResolver = $typeResolver; $this->descriptionFactory = $descriptionFactory; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, PropertyTagValueNode::class); return new PropertyRead( trim($tagValue->propertyName, '$'), - $this->typeFactory->createType($tagValue->type, $context), + $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($tagValue->description, $context) ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof PropertyTagValueNode && $node->name === '@property-read'; } diff --git a/src/DocBlock/Tags/Factory/PropertyWriteFactory.php b/src/DocBlock/Tags/Factory/PropertyWriteFactory.php index 0b6ba42..08cf753 100644 --- a/src/DocBlock/Tags/Factory/PropertyWriteFactory.php +++ b/src/DocBlock/Tags/Factory/PropertyWriteFactory.php @@ -7,6 +7,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode; @@ -19,28 +20,28 @@ use function trim; */ final class PropertyWriteFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; $this->descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, PropertyTagValueNode::class); return new PropertyWrite( trim($tagValue->propertyName, '$'), - $this->typeFactory->createType($tagValue->type, $context), + $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($tagValue->description, $context) ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof PropertyTagValueNode && $node->name === '@property-write'; } diff --git a/src/DocBlock/Tags/Factory/ReturnFactory.php b/src/DocBlock/Tags/Factory/ReturnFactory.php index f01a111..8ebe5ad 100644 --- a/src/DocBlock/Tags/Factory/ReturnFactory.php +++ b/src/DocBlock/Tags/Factory/ReturnFactory.php @@ -7,6 +7,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Return_; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; @@ -17,27 +18,27 @@ use Webmozart\Assert\Assert; */ final class ReturnFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; $this->descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, ReturnTagValueNode::class); return new Return_( - $this->typeFactory->createType($tagValue->type, $context), + $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($tagValue->description, $context) ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof ReturnTagValueNode; } diff --git a/src/DocBlock/Tags/Factory/TypeFactory.php b/src/DocBlock/Tags/Factory/TypeFactory.php deleted file mode 100644 index 5745d99..0000000 --- a/src/DocBlock/Tags/Factory/TypeFactory.php +++ /dev/null @@ -1,230 +0,0 @@ -resolver = $resolver; - $this->fqsenResolver = $fqsenResolver; - } - - public function createType(?TypeNode $type, ?Context $context): ?Type - { - if ($type === null) { - return null; - } - - switch (get_class($type)) { - case ArrayTypeNode::class: - return new Array_( - $this->createType($type->type, $context) - ); - - case ArrayShapeNode::class: - return new ArrayShape( - ...array_map( - fn (ArrayShapeItemNode $item) => new ArrayShapeItem( - (string) $item->keyName, - $this->createType($item->valueType, $context), - $item->optional - ), - $type->items - ) - ); - - case CallableTypeNode::class: - return $this->createFromCallable($type, $context); - - case ConstTypeNode::class: - return $this->createFromConst($type, $context); - - case GenericTypeNode::class: - return $this->createFromGeneric($type, $context); - - case IdentifierTypeNode::class: - return $this->resolver->resolve($type->name, $context); - - case IntersectionTypeNode::class: - return new Intersection( - array_filter( - array_map( - fn (TypeNode $nestedType) => $this->createType($nestedType, $context), - $type->types - ) - ) - ); - - case NullableTypeNode::class: - $nestedType = $this->createType($type->type, $context); - if ($nestedType === null) { - return null; - } - - return new Nullable($nestedType); - - case UnionTypeNode::class: - return new Compound( - array_filter( - array_map( - fn (TypeNode $nestedType) => $this->createType($nestedType, $context), - $type->types - ) - ) - ); - - case ThisTypeNode::class: - return new This(); - - case ConditionalTypeNode::class: - case ConditionalTypeForParameterNode::class: - case OffsetAccessTypeNode::class: - default: - return null; - } - } - - private function createFromGeneric(GenericTypeNode $type, ?Context $context): Type - { - switch (strtolower($type->type->name)) { - case 'array': - return new Array_( - ...array_reverse( - array_map( - fn (TypeNode $genericType) => $this->createType($genericType, $context), - $type->genericTypes - ) - ) - ); - - case 'class-string': - return new ClassString( - $this->fqsenResolver->resolve((string) $type->genericTypes[0], $context) - ); - - case 'interface-string': - return new InterfaceString( - $this->fqsenResolver->resolve((string) $type->genericTypes[0], $context) - ); - - case 'list': - return new List_( - $this->createType($type->genericTypes[0], $context) - ); - - case 'int': - return new IntegerRange( - (string) $type->genericTypes[0], - (string) ($type->genericTypes[1] ?? ''), - ); - - default: - return new Collection( - $this->createType($type->type, $context)->getFqsen(), - ...array_reverse( - array_map( - fn (TypeNode $genericType) => $this->createType($genericType, $context), - $type->genericTypes - ) - ) - ); - } - } - - private function createFromCallable(CallableTypeNode $type, ?Context $context): Callable_ - { - return new Callable_( - array_map( - function (CallableTypeParameterNode $param) use ($context) { - return new CallableParameter( - $param->parameterName !== '' ? trim($param->parameterName, '$') : null, - $this->createType($param->type, $context), - $param->isReference, - $param->isVariadic, - $param->isOptional - ); - }, - $type->parameters - ), - $this->createType($type->returnType, $context), - ); - } - - private function createFromConst(ConstTypeNode $type, ?Context $context): ?Type - { - switch (get_class($type->constExpr)) { - case ConstExprIntegerNode::class: - return new IntegerValue((int) $type->constExpr->value); - - case ConstExprFloatNode::class: - return new FloatValue((float) $type->constExpr->value); - - case ConstExprStringNode::class: - return new StringValue($type->constExpr->value); - - case ConstFetchNode::class: - return new ConstExpression( - $this->fqsenResolver->resolve($type->constExpr->className, $context), - $type->constExpr->name - ); - } - } -} diff --git a/src/DocBlock/Tags/Factory/VarFactory.php b/src/DocBlock/Tags/Factory/VarFactory.php index 1af6f76..79ffdf1 100644 --- a/src/DocBlock/Tags/Factory/VarFactory.php +++ b/src/DocBlock/Tags/Factory/VarFactory.php @@ -7,6 +7,7 @@ namespace phpDocumentor\Reflection\DocBlock\Tags\Factory; use phpDocumentor\Reflection\DocBlock\DescriptionFactory; use phpDocumentor\Reflection\DocBlock\Tag; use phpDocumentor\Reflection\DocBlock\Tags\Var_; +use phpDocumentor\Reflection\TypeResolver; use phpDocumentor\Reflection\Types\Context; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode; @@ -19,28 +20,28 @@ use function trim; */ final class VarFactory implements PHPStanFactory { - private TypeFactory $typeFactory; private DescriptionFactory $descriptionFactory; + private TypeResolver $typeResolver; - public function __construct(TypeFactory $typeFactory, DescriptionFactory $descriptionFactory) + public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory) { - $this->typeFactory = $typeFactory; $this->descriptionFactory = $descriptionFactory; + $this->typeResolver = $typeResolver; } - public function create(PhpDocTagNode $node, ?Context $context): Tag + public function create(PhpDocTagNode $node, Context $context): Tag { $tagValue = $node->value; Assert::isInstanceOf($tagValue, VarTagValueNode::class); return new Var_( trim($tagValue->variableName, '$'), - $this->typeFactory->createType($tagValue->type, $context), + $this->typeResolver->createType($tagValue->type, $context), $this->descriptionFactory->create($tagValue->description, $context) ); } - public function supports(PhpDocTagNode $node, ?Context $context): bool + public function supports(PhpDocTagNode $node, Context $context): bool { return $node->value instanceof VarTagValueNode; } diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php index 8610dbb..102d220 100644 --- a/src/DocBlockFactory.php +++ b/src/DocBlockFactory.php @@ -70,15 +70,14 @@ final class DocBlockFactory implements DocBlockFactoryInterface $tagFactory = new StandardTagFactory($fqsenResolver); $descriptionFactory = new DescriptionFactory($tagFactory); $typeResolver = new TypeResolver($fqsenResolver); - $typeFactory = new TypeFactory($typeResolver, $fqsenResolver); $phpstanTagFactory = new AbstractPHPStanFactory( - new ParamFactory($typeFactory, $descriptionFactory), - new VarFactory($typeFactory, $descriptionFactory), - new ReturnFactory($typeFactory, $descriptionFactory), - new PropertyFactory($typeFactory, $descriptionFactory), - new PropertyReadFactory($typeFactory, $descriptionFactory), - new PropertyWriteFactory($typeFactory, $descriptionFactory), + new ParamFactory($typeResolver, $descriptionFactory), + new VarFactory($typeResolver, $descriptionFactory), + new ReturnFactory($typeResolver, $descriptionFactory), + new PropertyFactory($typeResolver, $descriptionFactory), + new PropertyReadFactory($typeResolver, $descriptionFactory), + new PropertyWriteFactory($typeResolver, $descriptionFactory), ); $tagFactory->addService($descriptionFactory); diff --git a/src/PseudoTypes/ArrayShape.php b/src/PseudoTypes/ArrayShape.php deleted file mode 100644 index 93380a3..0000000 --- a/src/PseudoTypes/ArrayShape.php +++ /dev/null @@ -1,34 +0,0 @@ -items = $items; - } - - public function underlyingType(): Type - { - return new Array_(new Mixed_(), new ArrayKey()); - } - - public function __toString(): string - { - return 'array{' . implode(', ', $this->items) . '}'; - } -} diff --git a/src/PseudoTypes/ArrayShapeItem.php b/src/PseudoTypes/ArrayShapeItem.php deleted file mode 100644 index 6231782..0000000 --- a/src/PseudoTypes/ArrayShapeItem.php +++ /dev/null @@ -1,53 +0,0 @@ -key = $key; - $this->value = $value ?? new Mixed_(); - $this->optional = $optional; - } - - public function getKey(): ?string - { - return $this->key; - } - - public function getValue(): Type - { - return $this->value; - } - - public function isOptional(): bool - { - return $this->optional; - } - - public function __toString(): string - { - if ($this->key !== null) { - return sprintf( - '%s%s: %s', - $this->key, - $this->optional ? '?' : '', - $this->value - ); - } - - return (string) $this->value; - } -} diff --git a/src/PseudoTypes/ConstExpression.php b/src/PseudoTypes/ConstExpression.php deleted file mode 100644 index b7189ce..0000000 --- a/src/PseudoTypes/ConstExpression.php +++ /dev/null @@ -1,44 +0,0 @@ -owner = $owner; - $this->expression = $expression; - } - - public function getOwner(): Fqsen - { - return $this->owner; - } - - public function getExpression(): string - { - return $this->expression; - } - - public function underlyingType(): Type - { - return new Mixed_(); - } - - public function __toString(): string - { - return sprintf('%s::%s', $this->owner, $this->expression); - } -} diff --git a/src/PseudoTypes/FloatValue.php b/src/PseudoTypes/FloatValue.php deleted file mode 100644 index 07e0156..0000000 --- a/src/PseudoTypes/FloatValue.php +++ /dev/null @@ -1,34 +0,0 @@ -value = $value; - } - - public function getValue(): float - { - return $this->value; - } - - public function underlyingType(): Type - { - return new Float_(); - } - - public function __toString(): string - { - return (string) $this->value; - } -} diff --git a/src/PseudoTypes/IntegerValue.php b/src/PseudoTypes/IntegerValue.php deleted file mode 100644 index 2a56ad4..0000000 --- a/src/PseudoTypes/IntegerValue.php +++ /dev/null @@ -1,34 +0,0 @@ -value = $value; - } - - public function getValue(): int - { - return $this->value; - } - - public function underlyingType(): Type - { - return new Integer(); - } - - public function __toString(): string - { - return (string) $this->value; - } -} diff --git a/src/PseudoTypes/StringValue.php b/src/PseudoTypes/StringValue.php deleted file mode 100644 index f4909cd..0000000 --- a/src/PseudoTypes/StringValue.php +++ /dev/null @@ -1,36 +0,0 @@ -value = $value; - } - - public function getValue(): string - { - return $this->value; - } - - public function underlyingType(): Type - { - return new Float_(); - } - - public function __toString(): string - { - return sprintf('"%s"', $this->value); - } -} diff --git a/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php index 17ac469..a8ab6ea 100644 --- a/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php @@ -33,7 +33,7 @@ final class MethodFactoryTest extends TagFactoryTestCase public function testIsCreated(string $tagLine, Method $tag): void { $ast = $this->parseTag($tagLine); - $factory = new MethodFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new MethodFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context)); @@ -76,7 +76,7 @@ final class MethodFactoryTest extends TagFactoryTestCase new Method( 'myMethod', [], - new Void_(), + new Mixed_(), false, new Description(''), false, @@ -88,7 +88,7 @@ final class MethodFactoryTest extends TagFactoryTestCase new Method( 'myMethod', [], - new Void_(), + new Mixed_(), false, new Description(''), false, @@ -100,7 +100,7 @@ final class MethodFactoryTest extends TagFactoryTestCase new Method( 'myMethod', [], - new Void_(), + new Mixed_(), false, new Description(''), false, @@ -112,7 +112,7 @@ final class MethodFactoryTest extends TagFactoryTestCase new Method( 'myMethod', [], - new Void_(), + new Mixed_(), false, new Description(''), false, @@ -124,7 +124,7 @@ final class MethodFactoryTest extends TagFactoryTestCase new Method( 'myMethod', [], - new Void_(), + new Mixed_(), false, new Description(''), false, @@ -136,7 +136,7 @@ final class MethodFactoryTest extends TagFactoryTestCase new Method( 'myMethod', [], - new Void_(), + new Mixed_(), false, new Description(''), false, diff --git a/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php index 86b0f6f..df2c23c 100644 --- a/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php @@ -28,7 +28,7 @@ final class ParamFactoryTest extends TagFactoryTestCase public function testParamIsCreated(): void { $ast = $this->parseTag('@param string $var'); - $factory = new ParamFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new ParamFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context)); diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php index c1ae0cd..738275c 100644 --- a/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php @@ -28,7 +28,7 @@ final class PropertyFactoryTest extends TagFactoryTestCase public function testParamIsCreated(): void { $ast = $this->parseTag('@property string $var'); - $factory = new PropertyFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new PropertyFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context)); diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php index 2e1f4cd..40fd122 100644 --- a/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php @@ -28,7 +28,7 @@ final class PropertyReadFactoryTest extends TagFactoryTestCase public function testParamIsCreated(): void { $ast = $this->parseTag('@property-read string $var'); - $factory = new PropertyReadFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new PropertyReadFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context)); diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php index af6e903..0f3e239 100644 --- a/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php @@ -28,7 +28,7 @@ final class PropertyWriteFactoryTest extends TagFactoryTestCase public function testParamIsCreated(): void { $ast = $this->parseTag('@property-write string $var'); - $factory = new PropertyWriteFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new PropertyWriteFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context)); diff --git a/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php index 95d1e14..5b664cc 100644 --- a/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php @@ -28,7 +28,7 @@ final class ReturnFactoryTest extends TagFactoryTestCase public function testParamIsCreated(): void { $ast = $this->parseTag('@return string'); - $factory = new ReturnFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new ReturnFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context)); diff --git a/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php index 4b2c7be..8684ba5 100644 --- a/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php +++ b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php @@ -37,9 +37,9 @@ abstract class TagFactoryTestCase extends TestCase return (new PhpDocParser(new TypeParser($constParser), $constParser))->parseTag(new TokenIterator($tokens)); } - public function giveTypeFactory(): TypeFactory + public function giveTypeResolver(): TypeResolver { - return new TypeFactory(new TypeResolver(new FqsenResolver()), new FqsenResolver()); + return new TypeResolver(new FqsenResolver()); } public function givenDescriptionFactory(): DescriptionFactory diff --git a/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php deleted file mode 100644 index bb5a126..0000000 --- a/tests/unit/DocBlock/Tags/Factory/TypeFactoryTest.php +++ /dev/null @@ -1,291 +0,0 @@ -tokenize($type); - $constParser = new ConstExprParser(); - $parser = new TypeParser($constParser); - $ast = $parser->parse(new TokenIterator($tokens)); - $fqsenResolver = new FqsenResolver(); - - $factory = new TypeFactory(new TypeResolver($fqsenResolver), $fqsenResolver); - $actual = $factory->createType($ast, new Context('phpDocumentor')); - - self::assertEquals($expected, $actual); - } - - /** - * @return array - */ - public function typeProvider(): array - { - return [ - [ - 'string', - new String_(), - ], - [ - '( string )', - new String_(), - ], - [ - '\\Foo\Bar\\Baz', - new Object_(new Fqsen('\\Foo\Bar\\Baz')), - ], - [ - 'string|int', - new Compound( - [ - new String_(), - new Integer(), - ] - ), - ], - [ - 'string&int', - new Intersection( - [ - new String_(), - new Integer(), - ] - ), - ], - [ - 'string & (int | float)', - new Intersection( - [ - new String_(), - new Compound( - [ - new Integer(), - new Float_(), - ] - ), - ] - ), - ], - [ - 'string[]', - new Array_( - new String_() - ), - ], - [ - '$this', - new This(), - ], - [ - '?int', - new Nullable( - new Integer() - ), - ], - [ - 'self', - new Self_(), - ], - ]; - } - - /** - * @return array - */ - public function genericsProvider(): array - { - return [ - [ - 'array', - new Array_( - new Object_(new Fqsen('\\phpDocumentor\\Foo\\Bar')), - new Integer() - ), - ], - [ - 'Collection[]', - new Array_( - new Collection( - new Fqsen('\\phpDocumentor\\Collection'), - new Integer(), - new ArrayKey() - ) - ), - ], - [ - 'class-string', - new ClassString(null), - ], - [ - 'class-string', - new ClassString(new Fqsen('\\phpDocumentor\\Foo')), - ], - [ - 'interface-string', - new InterfaceString(new Fqsen('\\phpDocumentor\\Foo')), - ], - [ - 'List', - new List_(new Object_(new Fqsen('\\phpDocumentor\\Foo'))), - ], - [ - 'int<1, 100>', - new IntegerRange('1', '100'), - ], - ]; - } - - /** - * @return array - */ - public function callableProvider(): array - { - return [ - [ - 'callable', - new Callable_(), - ], - [ - 'callable()', - new Callable_(), - ], - [ - 'callable(): Foo', - new Callable_([], new Object_(new Fqsen('\\phpDocumentor\\Foo'))), - ], - [ - 'callable(): (Foo&Bar)', - new Callable_( - [], - new Intersection( - [ - new Object_(new Fqsen('\\phpDocumentor\\Foo')), - new Object_(new Fqsen('\\phpDocumentor\\Bar')) - ] - ) - ), - ], - [ - 'callable(A&...$a=, B&...=, C): Foo', - new Callable_( - [ - new CallableParameter( - 'a', - new Object_(new Fqsen('\\phpDocumentor\\A')), - true, - true, - true - ), - new CallableParameter( - null, - new Object_(new Fqsen('\\phpDocumentor\\B')), - true, - true, - true - ), - new CallableParameter( - null, - new Object_(new Fqsen('\\phpDocumentor\\C')), - false, - false, - false - ), - ], - new Object_(new Fqsen('\\phpDocumentor\\Foo') - ) - ), - ], - ]; - } - - /** - * @return array - */ - public function constExpressions(): array - { - return [ - [ - '123', - new IntegerValue(123), - ], - [ - 'true', - new True_(), - ], - [ - '123.2', - new FloatValue(123.2), - ], - [ - '"bar"', - new StringValue('bar'), - ], - [ - 'Foo::FOO_CONSTANT', - new ConstExpression(new Fqsen('\\phpDocumentor\\Foo'), 'FOO_CONSTANT'), - ], - [ - 'Foo::FOO_*', - new ConstExpression(new Fqsen('\\phpDocumentor\\Foo'), 'FOO_*'), - ], - ]; - } -} diff --git a/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php index a37193b..06befbb 100644 --- a/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php +++ b/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php @@ -28,7 +28,7 @@ final class VarFactoryTest extends TagFactoryTestCase public function testParamIsCreated(): void { $ast = $this->parseTag('@var string $var'); - $factory = new VarFactory($this->giveTypeFactory(), $this->givenDescriptionFactory()); + $factory = new VarFactory($this->giveTypeResolver(), $this->givenDescriptionFactory()); $context = new Context('global'); self::assertTrue($factory->supports($ast, $context));