mirror of
https://github.com/danog/Valinor.git
synced 2024-11-30 04:39:05 +01:00
fix: handle inferring methods with same names properly
This commit is contained in:
parent
3020db20bf
commit
dc45dd8ac5
@ -12,7 +12,6 @@ use Reflector;
|
||||
|
||||
use function array_shift;
|
||||
use function explode;
|
||||
use function get_class;
|
||||
use function implode;
|
||||
use function strtolower;
|
||||
|
||||
@ -63,6 +62,6 @@ final class ClassAliasParser
|
||||
private function aliases(Reflector $reflection): array
|
||||
{
|
||||
/** @infection-ignore-all */
|
||||
return $this->aliases[get_class($reflection) . $reflection->name] ??= Singleton::phpParser()->parseUseStatements($reflection);
|
||||
return $this->aliases[Reflection::signature($reflection)] ??= Singleton::phpParser()->parseUseStatements($reflection);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\A;
|
||||
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceA;
|
||||
|
||||
final class ClassThatInheritsInterfaceA implements InterfaceA
|
||||
{
|
||||
public string $value;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\A;
|
||||
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceA;
|
||||
|
||||
final class OtherClassThatInheritsInterfaceA implements InterfaceA
|
||||
{
|
||||
public string $value;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\B;
|
||||
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceB;
|
||||
|
||||
final class ClassThatInheritsInterfaceB implements InterfaceB
|
||||
{
|
||||
public string $value;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\B;
|
||||
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceB;
|
||||
|
||||
final class OtherClassThatInheritsInterfaceB implements InterfaceB
|
||||
{
|
||||
public string $value;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces;
|
||||
|
||||
final class ClassWithBothInterfaces
|
||||
{
|
||||
public InterfaceA $a;
|
||||
|
||||
public InterfaceB $b;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces;
|
||||
|
||||
interface InterfaceA
|
||||
{
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces;
|
||||
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\A\ClassThatInheritsInterfaceA;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\A\OtherClassThatInheritsInterfaceA;
|
||||
|
||||
final class InterfaceAInferer
|
||||
{
|
||||
/**
|
||||
* @return class-string<ClassThatInheritsInterfaceA|OtherClassThatInheritsInterfaceA>
|
||||
*/
|
||||
public static function infer(bool $classic): string
|
||||
{
|
||||
return $classic
|
||||
? ClassThatInheritsInterfaceA::class
|
||||
: OtherClassThatInheritsInterfaceA::class;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces;
|
||||
|
||||
interface InterfaceB
|
||||
{
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces;
|
||||
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\B\ClassThatInheritsInterfaceB;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\B\OtherClassThatInheritsInterfaceB;
|
||||
|
||||
final class InterfaceBInferer
|
||||
{
|
||||
/**
|
||||
* @return class-string<ClassThatInheritsInterfaceB|OtherClassThatInheritsInterfaceB>
|
||||
*/
|
||||
public static function infer(bool $classic): string
|
||||
{
|
||||
return $classic
|
||||
? ClassThatInheritsInterfaceB::class
|
||||
: OtherClassThatInheritsInterfaceB::class;
|
||||
}
|
||||
}
|
@ -12,6 +12,13 @@ use CuyZ\Valinor\Mapper\Tree\Exception\ObjectImplementationCallbackError;
|
||||
use CuyZ\Valinor\Mapper\Tree\Exception\ObjectImplementationNotRegistered;
|
||||
use CuyZ\Valinor\Mapper\Tree\Exception\ResolvedImplementationIsNotAccepted;
|
||||
use CuyZ\Valinor\MapperBuilder;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\A\ClassThatInheritsInterfaceA;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\B\ClassThatInheritsInterfaceB;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\ClassWithBothInterfaces;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceA;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceAInferer;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceB;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\InterfaceBInferer;
|
||||
use CuyZ\Valinor\Tests\Integration\IntegrationTest;
|
||||
use CuyZ\Valinor\Type\Resolver\Exception\CannotResolveObjectType;
|
||||
use DateTime;
|
||||
@ -146,6 +153,39 @@ final class InterfaceInferringMappingTest extends IntegrationTest
|
||||
self::assertSame('bar', $resultB->valueB);
|
||||
}
|
||||
|
||||
public function test_infer_with_two_functions_with_same_name_works_properly(): void
|
||||
{
|
||||
try {
|
||||
$result = (new MapperBuilder())
|
||||
->infer(
|
||||
InterfaceA::class,
|
||||
// @PHP8.1 first-class callable syntax
|
||||
[InterfaceAInferer::class, 'infer']
|
||||
)
|
||||
->infer(
|
||||
InterfaceB::class,
|
||||
// @PHP8.1 first-class callable syntax
|
||||
[InterfaceBInferer::class, 'infer']
|
||||
)
|
||||
->mapper()
|
||||
->map(ClassWithBothInterfaces::class, [
|
||||
'a' => [
|
||||
'classic' => true,
|
||||
'value' => 'foo',
|
||||
],
|
||||
'b' => [
|
||||
'classic' => true,
|
||||
'value' => 'bar',
|
||||
],
|
||||
]);
|
||||
} catch (MappingError $error) {
|
||||
$this->mappingFail($error);
|
||||
}
|
||||
|
||||
self::assertInstanceOf(ClassThatInheritsInterfaceA::class, $result->a);
|
||||
self::assertInstanceOf(ClassThatInheritsInterfaceB::class, $result->b);
|
||||
}
|
||||
|
||||
public function test_unresolvable_implementation_throws_exception(): void
|
||||
{
|
||||
$this->expectException(CannotResolveObjectType::class);
|
||||
|
Loading…
Reference in New Issue
Block a user