Skip to content

Commit

Permalink
fix: properly handle class sharing class name and namespace group name
Browse files Browse the repository at this point in the history
  • Loading branch information
romm authored Sep 24, 2024
1 parent e695b29 commit 6e68d6f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
27 changes: 13 additions & 14 deletions src/Type/Parser/Factory/Specifications/AliasSpecification.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
use ReflectionFunction;
use Reflector;

use function array_shift;
use function explode;
use function strtolower;

/** @internal */
final class AliasSpecification implements TypeParserSpecification
{
Expand Down Expand Up @@ -49,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);
$lastPart = array_shift($namespaceParts);

if ($lastPart) {
$alias = strtolower($lastPart);
$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;
}

if ($aliases[$alias] === $symbol) {
return $symbol;
}

$full = $aliases[$alias];

if (! empty($namespaceParts)) {
$full .= '\\' . implode('\\', $namespaceParts);
if ($namespaceParts === []) {
return $aliases[$alias];
}

return $full;
return $aliases[$alias] . '\\' . implode('\\', $namespaceParts);
}

private function resolveNamespaced(string $symbol): string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace CuyZ\Valinor\Tests\Integration\Mapping\Namespace;

use CuyZ\Valinor\Mapper\MappingError;
use CuyZ\Valinor\Tests\Integration\IntegrationTestCase;
use SomeNamespace\SomeClass;
use SomeNamespace\SomeNamespace;

final class SameClassNameAsNamespaceGroupMappingTest extends IntegrationTestCase
{
// @see https://github.com/CuyZ/Valinor/issues/554
public function test_class_name_has_same_name_as_namespace_group_dot_not_block_type_resolution(): void
{
require_once 'class-name-with-same-name-as-namespace-group.php';

try {
$result = $this->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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace SomeNamespace;

final class SomeNamespace
{
public string $stringValue;
}

final class SomeClass
{
public int $integerValue;
}

0 comments on commit 6e68d6f

Please sign in to comment.