From 4bb41138f0facfa02871ce20c27d4d7b92fe5ce8 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 18 Feb 2019 20:30:10 +0100 Subject: [PATCH] fix for anonymous classes --- .../RemoveUnusedPrivateMethodRector.php | 2 +- .../RemoveUnusedPrivateConstantRectorTest.php | 5 +---- .../Fixture/keep_anonymous.php.inc | 17 +++++++++++++++++ .../RemoveUnusedPrivateMethodRectorTest.php | 6 +++++- .../Application/FunctionLikeNodeCollector.php | 5 ++--- .../NodeVisitor/ClassAndMethodNodeVisitor.php | 17 ++++++++++++++++- .../NodeVisitor/NodeCollectorNodeVisitor.php | 17 ++++++++++++++++- .../FunctionLike/ParamTypeDeclarationRector.php | 4 ++++ 8 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/keep_anonymous.php.inc diff --git a/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php b/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php index 9fd38d938d5..87ce5e87071 100644 --- a/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php +++ b/packages/DeadCode/src/Rector/ClassMethod/RemoveUnusedPrivateMethodRector.php @@ -75,6 +75,6 @@ CODE_SAMPLE $this->removeNode($node); } - return null; + return $node; } } diff --git a/packages/DeadCode/tests/Rector/ClassConst/RemoveUnusedPrivateConstantRector/RemoveUnusedPrivateConstantRectorTest.php b/packages/DeadCode/tests/Rector/ClassConst/RemoveUnusedPrivateConstantRector/RemoveUnusedPrivateConstantRectorTest.php index b021952b15c..b131b0c4e52 100644 --- a/packages/DeadCode/tests/Rector/ClassConst/RemoveUnusedPrivateConstantRector/RemoveUnusedPrivateConstantRectorTest.php +++ b/packages/DeadCode/tests/Rector/ClassConst/RemoveUnusedPrivateConstantRector/RemoveUnusedPrivateConstantRectorTest.php @@ -9,10 +9,7 @@ final class RemoveUnusedPrivateConstantRectorTest extends AbstractRectorTestCase { public function test(): void { - $this->doTestFiles([ - __DIR__ . '/Fixture/fixture.php.inc', - __DIR__ . '/Fixture/keep_constant.php.inc', - ]); + $this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc', __DIR__ . '/Fixture/keep_constant.php.inc']); } protected function getRectorClass(): string diff --git a/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/keep_anonymous.php.inc b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/keep_anonymous.php.inc new file mode 100644 index 00000000000..d333ac004cc --- /dev/null +++ b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/Fixture/keep_anonymous.php.inc @@ -0,0 +1,17 @@ +createKernelFromKernelClass($kernelClass); + $anonymous = new class {}; + } + + private function createKernelFromKernelClass($kernelClass) + { + return $kernelClass; + } +} diff --git a/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php index a868a0dee1b..3a830019303 100644 --- a/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php +++ b/packages/DeadCode/tests/Rector/ClassMethod/RemoveUnusedPrivateMethodRector/RemoveUnusedPrivateMethodRectorTest.php @@ -9,7 +9,11 @@ final class RemoveUnusedPrivateMethodRectorTest extends AbstractRectorTestCase { public function test(): void { - $this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc', __DIR__ . '/Fixture/static_method.php.inc']); + $this->doTestFiles([ + __DIR__ . '/Fixture/fixture.php.inc', + __DIR__ . '/Fixture/static_method.php.inc', + __DIR__ . '/Fixture/keep_anonymous.php.inc', + ]); } protected function getRectorClass(): string diff --git a/packages/NodeTypeResolver/src/Application/FunctionLikeNodeCollector.php b/packages/NodeTypeResolver/src/Application/FunctionLikeNodeCollector.php index e8117707628..91df83badc2 100644 --- a/packages/NodeTypeResolver/src/Application/FunctionLikeNodeCollector.php +++ b/packages/NodeTypeResolver/src/Application/FunctionLikeNodeCollector.php @@ -5,7 +5,6 @@ namespace Rector\NodeTypeResolver\Application; use Nette\Utils\Strings; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; -use Rector\Exception\ShouldNotHappenException; use Rector\NodeTypeResolver\Node\Attribute; use Rector\PhpParser\Node\Resolver\NameResolver; use ReflectionClass; @@ -35,8 +34,8 @@ final class FunctionLikeNodeCollector public function addMethod(ClassMethod $classMethodNode): void { $className = $classMethodNode->getAttribute(Attribute::CLASS_NAME); - if ($className === null) { - throw new ShouldNotHappenException(); + if ($className === null) { // anonymous + return; } $methodName = $this->nameResolver->resolve($classMethodNode); diff --git a/packages/NodeTypeResolver/src/NodeVisitor/ClassAndMethodNodeVisitor.php b/packages/NodeTypeResolver/src/NodeVisitor/ClassAndMethodNodeVisitor.php index 7d0ef263c9e..ebdfc5d970b 100644 --- a/packages/NodeTypeResolver/src/NodeVisitor/ClassAndMethodNodeVisitor.php +++ b/packages/NodeTypeResolver/src/NodeVisitor/ClassAndMethodNodeVisitor.php @@ -2,6 +2,7 @@ namespace Rector\NodeTypeResolver\NodeVisitor; +use Nette\Utils\Strings; use PhpParser\Node; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt\Class_; @@ -51,7 +52,7 @@ final class ClassAndMethodNodeVisitor extends NodeVisitorAbstract */ public function enterNode(Node $node) { - if ($node instanceof Class_ && $node->isAnonymous()) { + if ($node instanceof Class_ && $this->isClassAnonymous($node)) { return null; } @@ -100,4 +101,18 @@ final class ClassAndMethodNodeVisitor extends NodeVisitorAbstract $node->setAttribute(Attribute::PARENT_CLASS_NAME, $parentClassResolvedName); } + + private function isClassAnonymous(Class_ $classNode): bool + { + if ($classNode->isAnonymous()) { + return true; + } + + if ($classNode->name === null) { + return false; + } + + // PHPStan polution + return Strings::startsWith($classNode->name->toString(), 'AnonymousClass'); + } } diff --git a/packages/NodeTypeResolver/src/NodeVisitor/NodeCollectorNodeVisitor.php b/packages/NodeTypeResolver/src/NodeVisitor/NodeCollectorNodeVisitor.php index d8ad07f8ca0..65d7bbac82a 100644 --- a/packages/NodeTypeResolver/src/NodeVisitor/NodeCollectorNodeVisitor.php +++ b/packages/NodeTypeResolver/src/NodeVisitor/NodeCollectorNodeVisitor.php @@ -2,6 +2,7 @@ namespace Rector\NodeTypeResolver\NodeVisitor; +use Nette\Utils\Strings; use PhpParser\Node; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassConst; @@ -46,7 +47,7 @@ final class NodeCollectorNodeVisitor extends NodeVisitorAbstract */ public function enterNode(Node $node) { - if ($node instanceof Class_ && $node->isAnonymous() === false) { + if ($node instanceof Class_ && $this->isClassAnonymous($node) === false) { $this->classLikeNodeCollector->addClass($node); return; } @@ -76,4 +77,18 @@ final class NodeCollectorNodeVisitor extends NodeVisitorAbstract return; } } + + private function isClassAnonymous(Class_ $classNode): bool + { + if ($classNode->isAnonymous()) { + return true; + } + + if ($classNode->name === null) { + return false; + } + + // PHPStan polution + return Strings::startsWith($classNode->name->toString(), 'AnonymousClass'); + } } diff --git a/packages/Php/src/Rector/FunctionLike/ParamTypeDeclarationRector.php b/packages/Php/src/Rector/FunctionLike/ParamTypeDeclarationRector.php index 77e93e8dbe7..09540f68ebb 100644 --- a/packages/Php/src/Rector/FunctionLike/ParamTypeDeclarationRector.php +++ b/packages/Php/src/Rector/FunctionLike/ParamTypeDeclarationRector.php @@ -169,6 +169,10 @@ CODE_SAMPLE /** @var string $className */ $className = $node->getAttribute(Attribute::CLASS_NAME); + // anonymous class + if ($className === null) { + return; + } $childrenClassLikes = $this->classLikeNodeCollector->findClassesAndInterfacesByType($className);