diff --git a/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Fixture/skip_class_with_function.php.inc b/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Fixture/skip_class_with_function.php.inc new file mode 100644 index 00000000000..736d78bdfee --- /dev/null +++ b/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Fixture/skip_class_with_function.php.inc @@ -0,0 +1,7 @@ + diff --git a/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Fixture/skip_class_with_side_effect.php.inc b/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Fixture/skip_class_with_side_effect.php.inc new file mode 100644 index 00000000000..761a82e8b6d --- /dev/null +++ b/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Fixture/skip_class_with_side_effect.php.inc @@ -0,0 +1,7 @@ + diff --git a/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Source/src/ClassWithFunction.php b/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Source/src/ClassWithFunction.php new file mode 100644 index 00000000000..1737cb3b73d --- /dev/null +++ b/rules-tests/DeadCode/Rector/Expression/RemovePsr4AutoloadedIncludeRector/Source/src/ClassWithFunction.php @@ -0,0 +1,13 @@ +rectorParser->parseFile($filePath); + // the autoloader replays only type declarations, so top-level side effects, functions or constants keep the require load-bearing + if (! $this->containsOnlyTypeDeclarations($stmts)) { + return null; + } + $classLikes = $this->betterNodeFinder->findInstanceOf($stmts, ClassLike::class); // require must define exactly one class, or removing it would drop the other definitions @@ -175,6 +186,35 @@ private function resolveSingleDeclaredClassName(string $filePath): ?string return $this->getName($classLikes[0]); } + /** + * @param Stmt[] $stmts + */ + private function containsOnlyTypeDeclarations(array $stmts): bool + { + foreach ($stmts as $stmt) { + if ($stmt instanceof ClassLike || $stmt instanceof Use_ || $stmt instanceof GroupUse || $stmt instanceof Nop) { + continue; + } + + // declare(strict_types=1); is fine, but the block form declare(...) { ... } executes its body + if ($stmt instanceof Declare_ && $stmt->stmts === null) { + continue; + } + + if ($stmt instanceof Namespace_) { + if (! $this->containsOnlyTypeDeclarations($stmt->stmts)) { + return false; + } + + continue; + } + + return false; + } + + return true; + } + /** * @return array list of [namespace prefix, absolute directory] pairs */