LogicException: Namespace not found
JanMikes opened this issue · comments
Jan Mikeš commented
Hi, seems that token parser does not expect namespace without backslash - when trying to map nested classes in same (single level) namespace, i get Namespace not found
exception.
namespace Acme;
readonly final class Foo
{
public function __construct(
/** @var list<Bar> */
public array $items,
) {
}
}
namespace Acme;
readonly final class Bar
{
public function __construct(
public string $value,
) {
}
}
(new MapperBuilder())->mapper()->map(Foo::class, Source::array([
'items' => [
['value' => 'baz'],
],
]));
Stacktrace:
LogicException: Namespace not found.
vendor/cuyz/valinor/src/Utility/Reflection/TokenParser.php:129
vendor/cuyz/valinor/src/Utility/Reflection/TokenParser.php:49
vendor/cuyz/valinor/src/Utility/Reflection/PhpParser.php:61
vendor/cuyz/valinor/src/Utility/Reflection/PhpParser.php:30
vendor/cuyz/valinor/src/Type/Parser/Lexer/AliasLexer.php:65
vendor/cuyz/valinor/src/Type/Parser/Lexer/AliasLexer.php:39
vendor/cuyz/valinor/src/Type/Parser/Lexer/AliasLexer.php:28
vendor/cuyz/valinor/src/Type/Parser/Lexer/TypeAliasLexer.php:27
vendor/cuyz/valinor/src/Type/Parser/LexingParser.php:30
vendor/cuyz/valinor/src/Type/Parser/LexingParser.php:29
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionTypeResolver.php:90
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionTypeResolver.php:65
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionTypeResolver.php:30
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionPropertyDefinitionBuilder.php:26
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php:81
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php:77
vendor/cuyz/valinor/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php:65
vendor/cuyz/valinor/src/Definition/Repository/Cache/CacheClassDefinitionRepository.php:32
vendor/cuyz/valinor/src/Mapper/Tree/Builder/InterfaceNodeBuilder.php:48
vendor/cuyz/valinor/src/Mapper/Tree/Builder/CasterProxyNodeBuilder.php:26
vendor/cuyz/valinor/src/Mapper/Tree/Builder/IterableNodeBuilder.php:28
vendor/cuyz/valinor/src/Mapper/Tree/Builder/StrictNodeBuilder.php:37
vendor/cuyz/valinor/src/Mapper/Tree/Builder/ErrorCatcherNodeBuilder.php:33
vendor/cuyz/valinor/src/Mapper/Tree/Builder/RootNodeBuilder.php:18
vendor/cuyz/valinor/src/Mapper/TypeTreeMapper.php:45
vendor/cuyz/valinor/src/Mapper/TypeTreeMapper.php:26
Script.php:26
Alexander Wühr commented
We probably have the same problem with the infer
method, which is currently a showstopper for us.
<?php
declare(strict_types=1);
namespace Dev;
use CuyZ\Valinor\Mapper\Source\Source;
use CuyZ\Valinor\MapperBuilder;
use RuntimeException;
require_once __DIR__ . '/../vendor/autoload.php';
interface SomeInterface {}
final readonly class ImplementationOne implements SomeInterface {}
final readonly class ImplementationTwo implements SomeInterface {}
$mapper = (new MapperBuilder())->infer(
SomeInterface::class,
/** @return class-string<ImplementationOne|ImplementationTwo> */
static fn (string $type): string => match ($type) {
'one' => ImplementationOne::class,
'two' => ImplementationTwo::class,
default => throw new RuntimeException(),
},
)
->mapper();
$mapper->map(
SomeInterface::class,
Source::array(
[
'type' => 'one',
],
),
);
throws
PHP Fatal error: Uncaught CuyZ\Valinor\Mapper\Tree\Exception\MissingObjectImplementationRegistration: No implementation of `Dev\SomeInterface` found with return type `class-string<ImplementationOne|ImplementationTwo>` of `Closure (lines 22 to 26 of ...
Changing the line
/** @return class-string<ImplementationOne|ImplementationTwo> */
to
/** @return class-string<\Dev\ImplementationOne|\Dev\ImplementationTwo> */
or removing
namespace Dev;
solves the issue, which both violates our CS.
Even the official example at https://valinor.cuyz.io/1.6/how-to/infer-interfaces/ fails, when put into a namespace.
Romain Canon commented
Should be fixed by #446.
Romain Canon commented