From 5b5b94b00237846b27d680a477736c275457da82 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 26 Aug 2021 14:48:49 +0700 Subject: [PATCH] [StaticTypeMapper] Add ParentStaticType support to NameNodeMapper for "parent" return type (#765) --- .../PhpParser/NameNodeMapper.php | 7 ++- .../DowngradeParentTypeDeclarationRector.php | 45 +++++-------------- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/packages/StaticTypeMapper/PhpParser/NameNodeMapper.php b/packages/StaticTypeMapper/PhpParser/NameNodeMapper.php index b547421f473..084a49da238 100644 --- a/packages/StaticTypeMapper/PhpParser/NameNodeMapper.php +++ b/packages/StaticTypeMapper/PhpParser/NameNodeMapper.php @@ -21,6 +21,7 @@ use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\StaticTypeMapper\Contract\PhpParser\PhpParserNodeMapperInterface; use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType; +use Rector\StaticTypeMapper\ValueObject\Type\ParentStaticType; final class NameNodeMapper implements PhpParserNodeMapperInterface { @@ -48,7 +49,7 @@ public function mapToPHPStan(Node $node): Type return new FullyQualifiedObjectType($name); } - if (in_array($name, ['static', 'self'], true)) { + if (in_array($name, ['static', 'self', 'parent'], true)) { return $this->createClassReferenceType($node, $name); } @@ -78,6 +79,10 @@ private function createClassReferenceType(Name $name, string $reference): MixedT return new StaticType($className); } + if ($reference === 'parent') { + return new ParentStaticType($className); + } + if ($this->reflectionProvider->hasClass($className)) { $classReflection = $this->reflectionProvider->getClass($className); return new ThisType($classReflection); diff --git a/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php b/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php index 55fb3c7be53..4d5555a36c5 100644 --- a/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php +++ b/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php @@ -5,13 +5,11 @@ namespace Rector\DowngradePhp70\Rector\ClassMethod; use PhpParser\Node; -use PhpParser\Node\Name; use PhpParser\Node\Stmt\ClassMethod; -use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode; use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ReflectionProvider; -use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\Core\Rector\AbstractRector; +use Rector\DowngradePhp71\TypeDeclaration\PhpDocFromTypeDeclarationDecorator; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\StaticTypeMapper\ValueObject\Type\ParentStaticType; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -23,7 +21,7 @@ final class DowngradeParentTypeDeclarationRector extends AbstractRector { public function __construct( - private PhpDocTypeChanger $phpDocTypeChanger, + private PhpDocFromTypeDeclarationDecorator $phpDocFromTypeDeclarationDecorator, private ReflectionProvider $reflectionProvider ) { } @@ -82,37 +80,10 @@ public function foo() */ public function refactor(Node $node): ?Node { - if (! $node->returnType instanceof Name) { - return null; - } - - if (! $this->nodeNameResolver->isName($node->returnType, 'parent')) { - return null; - } - - $node->returnType = null; - - $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); - if ($phpDocInfo->hasByType(ReturnTagValueNode::class)) { - return $node; - } - - $parentStaticType = $this->getType($node); - - if (! $parentStaticType instanceof ParentStaticType) { - return $node; - } - - $this->phpDocTypeChanger->changeReturnType($phpDocInfo, $parentStaticType); - return $node; - } - - private function getType(ClassMethod $classMethod): ?ParentStaticType - { - $scope = $classMethod->getAttribute(AttributeKey::SCOPE); + $scope = $node->getAttribute(AttributeKey::SCOPE); if ($scope === null) { // in a trait - $className = $classMethod->getAttribute(AttributeKey::CLASS_NAME); + $className = $node->getAttribute(AttributeKey::CLASS_NAME); $classReflection = $this->reflectionProvider->getClass($className); } else { $classReflection = $scope->getClassReflection(); @@ -122,6 +93,12 @@ private function getType(ClassMethod $classMethod): ?ParentStaticType return null; } - return new ParentStaticType($classReflection); + $parentStaticType = new ParentStaticType($classReflection); + + if (! $this->phpDocFromTypeDeclarationDecorator->decorateReturnWithSpecificType($node, $parentStaticType)) { + return null; + } + + return $node; } }