From 4501e367cfcbf7dbe8514a8b4cf79fa89c9d19b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= <5175937+theofidry@users.noreply.github.com> Date: Mon, 7 Nov 2022 22:31:07 +0100 Subject: [PATCH] Use the recorded symbols to decide when to add the class_alias statements (#724) This makes the feature more reliable as avoid to have to keep synchronized the logic of when a symbol is aliased. --- .../NodeVisitor/ClassAliasStmtAppender.php | 28 ++++++++++--------- src/PhpParser/TraverserFactory.php | 3 +- src/Symbol/SymbolsRegistry.php | 8 ++++++ tests/Symbol/SymbolsRegistryTest.php | 16 +++++++++++ 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php b/src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php index e31eb903..126796c8 100644 --- a/src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php +++ b/src/PhpParser/NodeVisitor/ClassAliasStmtAppender.php @@ -15,10 +15,9 @@ namespace Humbug\PhpScoper\PhpParser\NodeVisitor; use Humbug\PhpScoper\PhpParser\Node\ClassAliasFuncCall; -use Humbug\PhpScoper\PhpParser\Node\FullyQualifiedFactory; use Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver\IdentifierResolver; use Humbug\PhpScoper\PhpParser\UnexpectedParsingScenario; -use Humbug\PhpScoper\Symbol\EnrichedReflector; +use Humbug\PhpScoper\Symbol\SymbolsRegistry; use PhpParser\Node; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt; @@ -57,9 +56,8 @@ final class ClassAliasStmtAppender extends NodeVisitorAbstract { public function __construct( - private readonly string $prefix, - private readonly EnrichedReflector $enrichedReflector, private readonly IdentifierResolver $identifierResolver, + private readonly SymbolsRegistry $symbolsRegistry, ) { } @@ -112,23 +110,27 @@ private function createNamespaceStmts(array $stmts, Stmt $stmt): array $resolvedName = $this->identifierResolver->resolveIdentifier($name); - if ($resolvedName instanceof FullyQualified - && $this->enrichedReflector->isExposedClass((string) $resolvedName) - ) { - $stmts[] = self::createAliasStmt($resolvedName, $stmt, $this->prefix); + if (!($resolvedName instanceof FullyQualified)) { + return $stmts; + } + + $record = $this->symbolsRegistry->getRecordedClass((string) $resolvedName); + + if (null !== $record) { + $stmts[] = self::createAliasStmt($record[0], $record[1], $stmt); } return $stmts; } private static function createAliasStmt( - FullyQualified $originalName, - Node $stmt, - string $prefix + string $originalName, + string $prefixedName, + Node $stmt ): Expression { $call = new ClassAliasFuncCall( - FullyQualifiedFactory::concat($prefix, $originalName), - $originalName, + new FullyQualified($prefixedName), + new FullyQualified($originalName), $stmt->getAttributes(), ); diff --git a/src/PhpParser/TraverserFactory.php b/src/PhpParser/TraverserFactory.php index 5778fe32..8271b276 100644 --- a/src/PhpParser/TraverserFactory.php +++ b/src/PhpParser/TraverserFactory.php @@ -130,9 +130,8 @@ private static function createNodeVisitors( new NodeVisitor\EvalPrefixer($stringNodePrefixer), new NodeVisitor\ClassAliasStmtAppender( - $prefix, - $reflector, $identifierResolver, + $symbolsRegistry, ), new NodeVisitor\MultiConstStmtReplacer(), new NodeVisitor\ConstStmtReplacer( diff --git a/src/Symbol/SymbolsRegistry.php b/src/Symbol/SymbolsRegistry.php index 0c1dc5a6..dff46f2b 100644 --- a/src/Symbol/SymbolsRegistry.php +++ b/src/Symbol/SymbolsRegistry.php @@ -71,6 +71,14 @@ public function recordClass(FullyQualified $original, FullyQualified $alias): vo $this->recordedClasses[(string) $original] = [(string) $original, (string) $alias]; } + /** + * @return array{string, string}|null + */ + public function getRecordedClass(string $original): ?array + { + return $this->recordedClasses[$original] ?? null; + } + /** * @return list */ diff --git a/tests/Symbol/SymbolsRegistryTest.php b/tests/Symbol/SymbolsRegistryTest.php index c69cab0f..7009dcb1 100644 --- a/tests/Symbol/SymbolsRegistryTest.php +++ b/tests/Symbol/SymbolsRegistryTest.php @@ -361,6 +361,22 @@ public static function provideRegistriesToMerge(): iterable ]; } + public function test_it_exposes_recorded_classes(): void + { + $registry = self::createRegistry( + [[new FullyQualified('foo'), new FullyQualified('Humbug\foo')]], + [[new FullyQualified('Bar'), new FullyQualified('Humbug\Bar')]], + ); + + self::assertNull($registry->getRecordedClass('foo')); + self::assertNull($registry->getRecordedClass('bar')); + self::assertNull($registry->getRecordedClass('Humbug\Bar')); + self::assertEquals( + ['Bar', 'Humbug\Bar'], + $registry->getRecordedClass('Bar'), + ); + } + private static function assertStateIs( SymbolsRegistry $symbolsRegistry, array $expectedRecordedFunctions,