From 594d5cd5183061d3f886c9dbc76c26f92ae8a8d0 Mon Sep 17 00:00:00 2001 From: Romain Canon Date: Mon, 2 Sep 2024 18:04:21 +0200 Subject: [PATCH 1/2] fix: properly handle class sharing class name and namespace group name --- .../Specifications/AliasSpecification.php | 24 +- src/Utility/Reflection/PhpParser.php | 6 +- src/Utility/Reflection/TokenParser.php | 15 +- ...meClassNameAsNamespaceGroupMappingTest.php | 37 +++ ...name-with-same-name-as-namespace-group.php | 13 + .../Unit/Utility/Reflection/PhpParserTest.php | 272 ++++++++++++++---- 6 files changed, 295 insertions(+), 72 deletions(-) create mode 100644 tests/Integration/Mapping/Namespace/SameClassNameAsNamespaceGroupMappingTest.php create mode 100644 tests/Integration/Mapping/Namespace/class-name-with-same-name-as-namespace-group.php diff --git a/src/Type/Parser/Factory/Specifications/AliasSpecification.php b/src/Type/Parser/Factory/Specifications/AliasSpecification.php index be71ec10..3d927787 100644 --- a/src/Type/Parser/Factory/Specifications/AliasSpecification.php +++ b/src/Type/Parser/Factory/Specifications/AliasSpecification.php @@ -12,6 +12,10 @@ use ReflectionFunction; use Reflector; +use function array_shift; +use function explode; +use function strtolower; + /** @internal */ final class AliasSpecification implements TypeParserSpecification { @@ -52,10 +56,10 @@ private function resolveAlias(string $symbol): string $alias = $symbol; $namespaceParts = explode('\\', $symbol); - $lastPart = array_shift($namespaceParts); + $firstPart = array_shift($namespaceParts); - if ($lastPart) { - $alias = strtolower($lastPart); + if ($firstPart) { + $alias = strtolower($firstPart); } $aliases = PhpParser::parseUseStatements($this->reflection); @@ -64,17 +68,17 @@ private function resolveAlias(string $symbol): string return $symbol; } - if ($aliases[$alias] === $symbol) { - return $symbol; - } + $fqcn = $aliases[$alias]['fqcn']; - $full = $aliases[$alias]; + if ($namespaceParts === []) { + return $fqcn; + } - if (! empty($namespaceParts)) { - $full .= '\\' . implode('\\', $namespaceParts); + if (! $aliases[$alias]['isExplicitAlias']) { + return $symbol; } - return $full; + return $fqcn . '\\' . implode('\\', $namespaceParts); } private function resolveNamespaced(string $symbol): string diff --git a/src/Utility/Reflection/PhpParser.php b/src/Utility/Reflection/PhpParser.php index 9f08755d..3024c331 100644 --- a/src/Utility/Reflection/PhpParser.php +++ b/src/Utility/Reflection/PhpParser.php @@ -17,12 +17,12 @@ */ final class PhpParser { - /** @var array> */ + /** @var array> */ private static array $statements = []; /** * @param ReflectionClass|ReflectionFunction|ReflectionMethod $reflection - * @return array + * @return array */ public static function parseUseStatements(\ReflectionClass|\ReflectionFunction|\ReflectionMethod $reflection): array { @@ -34,7 +34,7 @@ public static function parseUseStatements(\ReflectionClass|\ReflectionFunction|\ /** * @param ReflectionClass|ReflectionFunction|ReflectionMethod $reflection - * @return array + * @return array */ private static function fetchUseStatements(\ReflectionClass|\ReflectionFunction|\ReflectionMethod $reflection): array { diff --git a/src/Utility/Reflection/TokenParser.php b/src/Utility/Reflection/TokenParser.php index e97bd34c..68dc04ee 100644 --- a/src/Utility/Reflection/TokenParser.php +++ b/src/Utility/Reflection/TokenParser.php @@ -29,7 +29,7 @@ public function __construct(string $content) } /** - * @return array + * @return array */ public function parseUseStatements(string $namespaceName): array { @@ -58,7 +58,7 @@ public function parseUseStatements(string $namespaceName): array } /** - * @return array + * @return array */ private function parseUseStatement(): array { @@ -86,12 +86,18 @@ private function parseUseStatement(): array $explicitAlias = true; $alias = ''; } elseif ($name === ',') { - $statements[strtolower($alias)] = $groupRoot . $class; + $statements[strtolower($alias)] = [ + 'fqcn' => $groupRoot . $class, + 'isExplicitAlias' => $explicitAlias, + ]; $class = $alias = ''; $explicitAlias = false; } elseif ($name === ';') { if ($alias !== '') { - $statements[strtolower($alias)] = $groupRoot . $class; + $statements[strtolower($alias)] = [ + 'fqcn' => $groupRoot . $class, + 'isExplicitAlias' => $explicitAlias, + ]; } break; } elseif ($name === '{') { @@ -100,6 +106,7 @@ private function parseUseStatement(): array } } + /** @var array */ return $statements; } diff --git a/tests/Integration/Mapping/Namespace/SameClassNameAsNamespaceGroupMappingTest.php b/tests/Integration/Mapping/Namespace/SameClassNameAsNamespaceGroupMappingTest.php new file mode 100644 index 00000000..c8ebe69f --- /dev/null +++ b/tests/Integration/Mapping/Namespace/SameClassNameAsNamespaceGroupMappingTest.php @@ -0,0 +1,37 @@ +mapperBuilder()->mapper()->map(ClassContainingNamespacedClasses::class, [ + 'objectA' => ['stringValue' => 'foo'], + 'objectB' => ['integerValue' => 42], + ]); + } catch (MappingError $error) { + $this->mappingFail($error); + } + + self::assertSame('foo', $result->objectA->stringValue); + self::assertSame(42, $result->objectB->integerValue); + } +} + +final class ClassContainingNamespacedClasses +{ + public SomeNamespace $objectA; + public SomeClass $objectB; +} diff --git a/tests/Integration/Mapping/Namespace/class-name-with-same-name-as-namespace-group.php b/tests/Integration/Mapping/Namespace/class-name-with-same-name-as-namespace-group.php new file mode 100644 index 00000000..948931a3 --- /dev/null +++ b/tests/Integration/Mapping/Namespace/class-name-with-same-name-as-namespace-group.php @@ -0,0 +1,13 @@ +|ReflectionFunction|ReflectionMethod $reflection - * @param array $expectedMap + * @param array $expectedMap */ #[DataProvider('use_statements_data_provider')] public function test_parse_use_statements(\ReflectionClass|\ReflectionFunction|\ReflectionMethod $reflection, array $expectedMap): void @@ -46,120 +46,282 @@ public static function use_statements_data_provider(): Generator yield 'one namespace' => [ new ReflectionClass(ClassInSingleNamespace::class), [ - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'multiple namespaces, class A' => [ new ReflectionClass(ClassA::class), [ - 'classb' => ClassB::class, - 'classbalias' => ClassB::class, - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'classb' => [ + 'fqcn' => ClassB::class, + 'isExplicitAlias' => false, + ], + 'classbalias' => [ + 'fqcn' => ClassB::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'multiple namespaces, class B' => [ new ReflectionClass(ClassB::class), [ - 'classa' => ClassA::class, - 'classaalias' => ClassA::class, - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'classa' => [ + 'fqcn' => ClassA::class, + 'isExplicitAlias' => false, + ], + 'classaalias' => [ + 'fqcn' => ClassA::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'multiple namespaces, function A' => [ new ReflectionFunction('\CuyZ\Valinor\Tests\Fixtures\WithAliasA\functionA'), [ - 'classb' => ClassB::class, - 'classbalias' => ClassB::class, - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'classb' => [ + 'fqcn' => ClassB::class, + 'isExplicitAlias' => false, + ], + 'classbalias' => [ + 'fqcn' => ClassB::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'multiple namespaces, function B' => [ new ReflectionFunction('\CuyZ\Valinor\Tests\Fixtures\WithAliasB\functionB'), [ - 'classa' => ClassA::class, - 'classaalias' => ClassA::class, - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'classa' => [ + 'fqcn' => ClassA::class, + 'isExplicitAlias' => false, + ], + 'classaalias' => [ + 'fqcn' => ClassA::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'one namespace, method' => [ new ReflectionMethod(ClassInSingleNamespace::class, '__construct'), [ - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'multiple namespaces, class A method' => [ new ReflectionMethod(ClassA::class, '__construct'), [ - 'classb' => ClassB::class, - 'classbalias' => ClassB::class, - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'classb' => [ + 'fqcn' => ClassB::class, + 'isExplicitAlias' => false, + ], + 'classbalias' => [ + 'fqcn' => ClassB::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'multiple namespaces, class B method' => [ new ReflectionMethod(ClassB::class, '__construct'), [ - 'classa' => ClassA::class, - 'classaalias' => ClassA::class, - 'baralias' => Bar::class, - 'foo' => Foo::class, - 'datetimeimmutable' => \DateTimeImmutable::class, - 'stdclassalias' => \stdClass::class, + 'classa' => [ + 'fqcn' => ClassA::class, + 'isExplicitAlias' => false, + ], + 'classaalias' => [ + 'fqcn' => ClassA::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'foo' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => false, + ], + 'datetimeimmutable' => [ + 'fqcn' => \DateTimeImmutable::class, + 'isExplicitAlias' => false, + ], + 'stdclassalias' => [ + 'fqcn' => \stdClass::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'function in root namespace' => [ new ReflectionFunction('function_in_root_namespace'), [ - 'fooalias' => Foo::class, - 'baralias' => Bar::class, + 'fooalias' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'one namespace, one use statement, two import statements' => [ new ReflectionFunction('CuyZ\Valinor\Tests\Unit\Utility\Reflection\Fixtures\function_with_several_import_statements_in_same_use_statement'), [ - 'fooalias' => Foo::class, - 'baralias' => Bar::class, - 'anotherfooalias' => Foo::class, - 'anotherbaralias' => Bar::class, + 'fooalias' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'anotherfooalias' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => true, + ], + 'anotherbaralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], ] ]; yield 'one namespace, one use statement, two grouped import statements' => [ new ReflectionFunction('\CuyZ\Valinor\Tests\Unit\Utility\Reflection\Fixtures\function_with_grouped_import_statements'), [ - 'fooalias' => Foo::class, - 'baralias' => Bar::class, - 'anotherfooalias' => Foo::class, - 'anotherbaralias' => Bar::class, + 'fooalias' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => true, + ], + 'baralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], + 'anotherfooalias' => [ + 'fqcn' => Foo::class, + 'isExplicitAlias' => true, + ], + 'anotherbaralias' => [ + 'fqcn' => Bar::class, + 'isExplicitAlias' => true, + ], ], ]; } From ae0f5bd340d25bf741b4cedf0872f4baa9719b32 Mon Sep 17 00:00:00 2001 From: Romain Canon Date: Wed, 18 Sep 2024 06:08:22 +0200 Subject: [PATCH 2/2] misc: simplify alias handling --- .../Specifications/AliasSpecification.php | 21 +- src/Utility/Reflection/PhpParser.php | 6 +- src/Utility/Reflection/TokenParser.php | 15 +- .../Unit/Utility/Reflection/PhpParserTest.php | 272 ++++-------------- 4 files changed, 70 insertions(+), 244 deletions(-) diff --git a/src/Type/Parser/Factory/Specifications/AliasSpecification.php b/src/Type/Parser/Factory/Specifications/AliasSpecification.php index 3d927787..236a1586 100644 --- a/src/Type/Parser/Factory/Specifications/AliasSpecification.php +++ b/src/Type/Parser/Factory/Specifications/AliasSpecification.php @@ -53,32 +53,27 @@ public function manipulateToken(TraversingToken $token): TraversingToken private function resolveAlias(string $symbol): string { - $alias = $symbol; + $aliases = PhpParser::parseUseStatements($this->reflection); $namespaceParts = explode('\\', $symbol); - $firstPart = array_shift($namespaceParts); - if ($firstPart) { - $alias = strtolower($firstPart); + $lastPart = strtolower(end($namespaceParts)); + + if (isset($aliases[$lastPart])) { + return $aliases[$lastPart]; } - $aliases = PhpParser::parseUseStatements($this->reflection); + $alias = strtolower(array_shift($namespaceParts)); if (! isset($aliases[$alias])) { return $symbol; } - $fqcn = $aliases[$alias]['fqcn']; - if ($namespaceParts === []) { - return $fqcn; - } - - if (! $aliases[$alias]['isExplicitAlias']) { - return $symbol; + return $aliases[$alias]; } - return $fqcn . '\\' . implode('\\', $namespaceParts); + return $aliases[$alias] . '\\' . implode('\\', $namespaceParts); } private function resolveNamespaced(string $symbol): string diff --git a/src/Utility/Reflection/PhpParser.php b/src/Utility/Reflection/PhpParser.php index 3024c331..9f08755d 100644 --- a/src/Utility/Reflection/PhpParser.php +++ b/src/Utility/Reflection/PhpParser.php @@ -17,12 +17,12 @@ */ final class PhpParser { - /** @var array> */ + /** @var array> */ private static array $statements = []; /** * @param ReflectionClass|ReflectionFunction|ReflectionMethod $reflection - * @return array + * @return array */ public static function parseUseStatements(\ReflectionClass|\ReflectionFunction|\ReflectionMethod $reflection): array { @@ -34,7 +34,7 @@ public static function parseUseStatements(\ReflectionClass|\ReflectionFunction|\ /** * @param ReflectionClass|ReflectionFunction|ReflectionMethod $reflection - * @return array + * @return array */ private static function fetchUseStatements(\ReflectionClass|\ReflectionFunction|\ReflectionMethod $reflection): array { diff --git a/src/Utility/Reflection/TokenParser.php b/src/Utility/Reflection/TokenParser.php index 68dc04ee..e97bd34c 100644 --- a/src/Utility/Reflection/TokenParser.php +++ b/src/Utility/Reflection/TokenParser.php @@ -29,7 +29,7 @@ public function __construct(string $content) } /** - * @return array + * @return array */ public function parseUseStatements(string $namespaceName): array { @@ -58,7 +58,7 @@ public function parseUseStatements(string $namespaceName): array } /** - * @return array + * @return array */ private function parseUseStatement(): array { @@ -86,18 +86,12 @@ private function parseUseStatement(): array $explicitAlias = true; $alias = ''; } elseif ($name === ',') { - $statements[strtolower($alias)] = [ - 'fqcn' => $groupRoot . $class, - 'isExplicitAlias' => $explicitAlias, - ]; + $statements[strtolower($alias)] = $groupRoot . $class; $class = $alias = ''; $explicitAlias = false; } elseif ($name === ';') { if ($alias !== '') { - $statements[strtolower($alias)] = [ - 'fqcn' => $groupRoot . $class, - 'isExplicitAlias' => $explicitAlias, - ]; + $statements[strtolower($alias)] = $groupRoot . $class; } break; } elseif ($name === '{') { @@ -106,7 +100,6 @@ private function parseUseStatement(): array } } - /** @var array */ return $statements; } diff --git a/tests/Unit/Utility/Reflection/PhpParserTest.php b/tests/Unit/Utility/Reflection/PhpParserTest.php index 8f444af2..23eed74e 100644 --- a/tests/Unit/Utility/Reflection/PhpParserTest.php +++ b/tests/Unit/Utility/Reflection/PhpParserTest.php @@ -26,7 +26,7 @@ final class PhpParserTest extends TestCase { /** * @param ReflectionClass|ReflectionFunction|ReflectionMethod $reflection - * @param array $expectedMap + * @param array $expectedMap */ #[DataProvider('use_statements_data_provider')] public function test_parse_use_statements(\ReflectionClass|\ReflectionFunction|\ReflectionMethod $reflection, array $expectedMap): void @@ -46,282 +46,120 @@ public static function use_statements_data_provider(): Generator yield 'one namespace' => [ new ReflectionClass(ClassInSingleNamespace::class), [ - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'multiple namespaces, class A' => [ new ReflectionClass(ClassA::class), [ - 'classb' => [ - 'fqcn' => ClassB::class, - 'isExplicitAlias' => false, - ], - 'classbalias' => [ - 'fqcn' => ClassB::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'classb' => ClassB::class, + 'classbalias' => ClassB::class, + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'multiple namespaces, class B' => [ new ReflectionClass(ClassB::class), [ - 'classa' => [ - 'fqcn' => ClassA::class, - 'isExplicitAlias' => false, - ], - 'classaalias' => [ - 'fqcn' => ClassA::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'classa' => ClassA::class, + 'classaalias' => ClassA::class, + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'multiple namespaces, function A' => [ new ReflectionFunction('\CuyZ\Valinor\Tests\Fixtures\WithAliasA\functionA'), [ - 'classb' => [ - 'fqcn' => ClassB::class, - 'isExplicitAlias' => false, - ], - 'classbalias' => [ - 'fqcn' => ClassB::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'classb' => ClassB::class, + 'classbalias' => ClassB::class, + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'multiple namespaces, function B' => [ new ReflectionFunction('\CuyZ\Valinor\Tests\Fixtures\WithAliasB\functionB'), [ - 'classa' => [ - 'fqcn' => ClassA::class, - 'isExplicitAlias' => false, - ], - 'classaalias' => [ - 'fqcn' => ClassA::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'classa' => ClassA::class, + 'classaalias' => ClassA::class, + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'one namespace, method' => [ new ReflectionMethod(ClassInSingleNamespace::class, '__construct'), [ - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'multiple namespaces, class A method' => [ new ReflectionMethod(ClassA::class, '__construct'), [ - 'classb' => [ - 'fqcn' => ClassB::class, - 'isExplicitAlias' => false, - ], - 'classbalias' => [ - 'fqcn' => ClassB::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'classb' => ClassB::class, + 'classbalias' => ClassB::class, + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'multiple namespaces, class B method' => [ new ReflectionMethod(ClassB::class, '__construct'), [ - 'classa' => [ - 'fqcn' => ClassA::class, - 'isExplicitAlias' => false, - ], - 'classaalias' => [ - 'fqcn' => ClassA::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'foo' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => false, - ], - 'datetimeimmutable' => [ - 'fqcn' => \DateTimeImmutable::class, - 'isExplicitAlias' => false, - ], - 'stdclassalias' => [ - 'fqcn' => \stdClass::class, - 'isExplicitAlias' => true, - ], + 'classa' => ClassA::class, + 'classaalias' => ClassA::class, + 'baralias' => Bar::class, + 'foo' => Foo::class, + 'datetimeimmutable' => \DateTimeImmutable::class, + 'stdclassalias' => \stdClass::class, ] ]; yield 'function in root namespace' => [ new ReflectionFunction('function_in_root_namespace'), [ - 'fooalias' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], + 'fooalias' => Foo::class, + 'baralias' => Bar::class, ] ]; yield 'one namespace, one use statement, two import statements' => [ new ReflectionFunction('CuyZ\Valinor\Tests\Unit\Utility\Reflection\Fixtures\function_with_several_import_statements_in_same_use_statement'), [ - 'fooalias' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'anotherfooalias' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => true, - ], - 'anotherbaralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], + 'fooalias' => Foo::class, + 'baralias' => Bar::class, + 'anotherfooalias' => Foo::class, + 'anotherbaralias' => Bar::class, ] ]; yield 'one namespace, one use statement, two grouped import statements' => [ new ReflectionFunction('\CuyZ\Valinor\Tests\Unit\Utility\Reflection\Fixtures\function_with_grouped_import_statements'), [ - 'fooalias' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => true, - ], - 'baralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], - 'anotherfooalias' => [ - 'fqcn' => Foo::class, - 'isExplicitAlias' => true, - ], - 'anotherbaralias' => [ - 'fqcn' => Bar::class, - 'isExplicitAlias' => true, - ], + 'fooalias' => Foo::class, + 'baralias' => Bar::class, + 'anotherfooalias' => Foo::class, + 'anotherbaralias' => Bar::class, ], ]; }