From 915fec0ff890a13c423bf5efd52c2f453b002271 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 5 Aug 2018 18:12:11 +0200 Subject: [PATCH] Turn InterfaceTypeResolver to PHPStan reflection --- .../src/PHPStanNodeScopeResolver.php | 3 +- .../AbstractClassLikeTypeResolver.php | 121 ------------------ .../InterfaceTypeResolver.php | 21 ++- .../PerNodeTypeResolver/TraitTypeResolver.php | 14 +- 4 files changed, 33 insertions(+), 126 deletions(-) delete mode 100644 packages/NodeTypeResolver/src/PerNodeTypeResolver/AbstractClassLikeTypeResolver.php diff --git a/packages/NodeTypeResolver/src/PHPStanNodeScopeResolver.php b/packages/NodeTypeResolver/src/PHPStanNodeScopeResolver.php index 47de76b08f3..276a1e968eb 100644 --- a/packages/NodeTypeResolver/src/PHPStanNodeScopeResolver.php +++ b/packages/NodeTypeResolver/src/PHPStanNodeScopeResolver.php @@ -4,6 +4,7 @@ namespace Rector\NodeTypeResolver; use PhpParser\Node; use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\Interface_; use PhpParser\NodeVisitor\NameResolver; use PHPStan\Analyser\NodeScopeResolver; use PHPStan\Analyser\Scope; @@ -103,7 +104,7 @@ final class PHPStanNodeScopeResolver function (Node $node, Scope $scope): void { // the class reflection is resolved AFTER entering to class node // so we need to get it from the first after this one - if ($node instanceof Class_) { + if ($node instanceof Class_ || $node instanceof Interface_) { if (isset($node->namespacedName)) { $scope = $scope->enterClass($this->phpstanBroker->getClass((string) $node->namespacedName)); } else { diff --git a/packages/NodeTypeResolver/src/PerNodeTypeResolver/AbstractClassLikeTypeResolver.php b/packages/NodeTypeResolver/src/PerNodeTypeResolver/AbstractClassLikeTypeResolver.php deleted file mode 100644 index 02d3de076fa..00000000000 --- a/packages/NodeTypeResolver/src/PerNodeTypeResolver/AbstractClassLikeTypeResolver.php +++ /dev/null @@ -1,121 +0,0 @@ -smartClassReflector = $smartClassReflector; - } - - /** - * @param Name|ClassLike $node - */ - protected function resolveNameNode(Node $node): string - { - $name = (string) $node->getAttribute(Attribute::CLASS_NAME); - if ($name) { - return $name; - } - - $namespacedName = $node->getAttribute(Attribute::NAMESPACED_NAME); - if ($namespacedName instanceof FullyQualified) { - return $namespacedName->toString(); - } - - $nameNode = $node->getAttribute(Attribute::RESOLVED_NAME); - if ($nameNode instanceof Name) { - return $nameNode->toString(); - } - - if ($node instanceof Name) { - return $node->toString(); - } - - return (string) $node->name; - } - - /** - * @param Class_|Interface_ $classLikeNode - * @return string[] - */ - protected function resolveExtendsTypes(ClassLike $classLikeNode, ?string $className = null): array - { - if (! $classLikeNode->extends) { - return []; - } - - if ($classLikeNode instanceof Interface_ && $className) { - return $this->smartClassReflector->getInterfaceParents($className); - } - - return $this->smartClassReflector->getClassParents($className, $classLikeNode); - } - - /** - * @param Class_|Trait_ $classOrTraitNode - * @return string[] - */ - protected function resolveUsedTraitTypes(ClassLike $classOrTraitNode): array - { - foreach ($classOrTraitNode->stmts as $stmt) { - if (! $stmt instanceof TraitUse) { - continue; - } - - return $this->resolveTraitNamesFromTraitUse($stmt); - } - - return []; - } - - /** - * @return string[] - */ - protected function resolveImplementsTypes(Class_ $classNode): array - { - return array_map(function (Name $interface): string { - if ($interface->hasAttribute(Attribute::RESOLVED_NAME)) { - return (string) $interface->getAttribute(Attribute::RESOLVED_NAME); - } - - return $interface->toString(); - }, $classNode->implements); - } - - /** - * @return string[] - */ - private function resolveTraitNamesFromTraitUse(TraitUse $traitUse): array - { - $usedTraits = []; - - foreach ($traitUse->traits as $trait) { - if ($trait->hasAttribute(Attribute::RESOLVED_NAME)) { - $usedTraits[] = (string) $trait->getAttribute(Attribute::RESOLVED_NAME); - } - } - - return $usedTraits; - } -} diff --git a/packages/NodeTypeResolver/src/PerNodeTypeResolver/InterfaceTypeResolver.php b/packages/NodeTypeResolver/src/PerNodeTypeResolver/InterfaceTypeResolver.php index ded8b4f478f..e7be6ff9a1c 100644 --- a/packages/NodeTypeResolver/src/PerNodeTypeResolver/InterfaceTypeResolver.php +++ b/packages/NodeTypeResolver/src/PerNodeTypeResolver/InterfaceTypeResolver.php @@ -4,9 +4,12 @@ namespace Rector\NodeTypeResolver\PerNodeTypeResolver; use PhpParser\Node; use PhpParser\Node\Stmt\Interface_; +use PHPStan\Analyser\Scope; +use PHPStan\Reflection\ClassReflection; +use Rector\Node\Attribute; use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface; -final class InterfaceTypeResolver extends AbstractClassLikeTypeResolver implements PerNodeTypeResolverInterface +final class InterfaceTypeResolver implements PerNodeTypeResolverInterface { /** * @return string[] @@ -22,8 +25,20 @@ final class InterfaceTypeResolver extends AbstractClassLikeTypeResolver implemen */ public function resolve(Node $interfaceNode): array { - $interfaceName = $this->resolveNameNode($interfaceNode); + /** @var Scope $interfaceNodeScope */ + $interfaceNodeScope = $interfaceNode->getAttribute(Attribute::SCOPE); - return array_merge([$interfaceName], $this->resolveExtendsTypes($interfaceNode, $interfaceName)); + /** @var ClassReflection $classReflection */ + $classReflection = $interfaceNodeScope->getClassReflection(); + + $types = []; + $types[] = $classReflection->getName(); + + // interfaces + foreach ($classReflection->getInterfaces() as $classReflection) { + $types[] = $classReflection->getName(); + } + + return $types; } } diff --git a/packages/NodeTypeResolver/src/PerNodeTypeResolver/TraitTypeResolver.php b/packages/NodeTypeResolver/src/PerNodeTypeResolver/TraitTypeResolver.php index ef4f7a23bac..260286694eb 100644 --- a/packages/NodeTypeResolver/src/PerNodeTypeResolver/TraitTypeResolver.php +++ b/packages/NodeTypeResolver/src/PerNodeTypeResolver/TraitTypeResolver.php @@ -4,9 +4,12 @@ namespace Rector\NodeTypeResolver\PerNodeTypeResolver; use PhpParser\Node; use PhpParser\Node\Stmt\Trait_; +use PHPStan\Analyser\Scope; +use PHPStan\Reflection\ClassReflection; +use Rector\Node\Attribute; use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface; -final class TraitTypeResolver extends AbstractClassLikeTypeResolver implements PerNodeTypeResolverInterface +final class TraitTypeResolver implements PerNodeTypeResolverInterface { /** * @return string[] @@ -22,6 +25,15 @@ final class TraitTypeResolver extends AbstractClassLikeTypeResolver implements P */ public function resolve(Node $traitNode): array { + /** @var Scope $traitNodeScope */ + $traitNodeScope = $traitNode->getAttribute(Attribute::SCOPE); + + /** @var ClassReflection $classReflection */ + $classReflection = $traitNodeScope->getClassReflection(); + + dump($classReflection); + die; + $types[] = $this->resolveNameNode($traitNode); return array_merge($types, $this->resolveUsedTraitTypes($traitNode)); }