mirror of
https://github.com/danog/Valinor.git
synced 2024-11-26 20:24:40 +01:00
misc: fetch attributes for function definition
This commit is contained in:
parent
c37ac1e259
commit
ec494cec48
@ -7,6 +7,7 @@ namespace CuyZ\Valinor\Definition;
|
||||
use CuyZ\Valinor\Definition\Exception\InvalidReflectionParameter;
|
||||
use CuyZ\Valinor\Utility\Singleton;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use ReflectionParameter;
|
||||
use ReflectionProperty;
|
||||
@ -73,6 +74,10 @@ final class DoctrineAnnotations implements Attributes
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($reflection instanceof ReflectionFunction) {
|
||||
return [];
|
||||
}
|
||||
|
||||
throw new InvalidReflectionParameter($reflection);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ final class FunctionDefinition
|
||||
|
||||
private string $signature;
|
||||
|
||||
private Attributes $attributes;
|
||||
|
||||
private ?string $fileName;
|
||||
|
||||
/** @var class-string|null */
|
||||
@ -30,6 +32,7 @@ final class FunctionDefinition
|
||||
public function __construct(
|
||||
string $name,
|
||||
string $signature,
|
||||
Attributes $attributes,
|
||||
?string $fileName,
|
||||
?string $class,
|
||||
bool $isStatic,
|
||||
@ -38,6 +41,7 @@ final class FunctionDefinition
|
||||
) {
|
||||
$this->name = $name;
|
||||
$this->signature = $signature;
|
||||
$this->attributes = $attributes;
|
||||
$this->fileName = $fileName;
|
||||
$this->class = $class;
|
||||
$this->isStatic = $isStatic;
|
||||
@ -55,6 +59,11 @@ final class FunctionDefinition
|
||||
return $this->signature;
|
||||
}
|
||||
|
||||
public function attributes(): Attributes
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
public function fileName(): ?string
|
||||
{
|
||||
return $this->fileName;
|
||||
|
@ -4,15 +4,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Definition;
|
||||
|
||||
use CuyZ\Valinor\Definition\Exception\InvalidReflectionParameter;
|
||||
use Error;
|
||||
use ReflectionAttribute;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use ReflectionParameter;
|
||||
use ReflectionProperty;
|
||||
use Reflector;
|
||||
|
||||
use Traversable;
|
||||
|
||||
use function array_map;
|
||||
@ -25,6 +24,10 @@ final class NativeAttributes implements Attributes
|
||||
/** @var array<ReflectionAttribute<object>> */
|
||||
private array $reflectionAttributes;
|
||||
|
||||
/**
|
||||
* @PHP8.0 union
|
||||
* @param ReflectionClass<object>|ReflectionProperty|ReflectionMethod|ReflectionFunction|ReflectionParameter $reflection
|
||||
*/
|
||||
public function __construct(Reflector $reflection)
|
||||
{
|
||||
$this->reflectionAttributes = $this->attributes($reflection);
|
||||
@ -80,26 +83,12 @@ final class NativeAttributes implements Attributes
|
||||
}
|
||||
|
||||
/**
|
||||
* @PHP8.0 union
|
||||
* @param ReflectionClass<object>|ReflectionProperty|ReflectionMethod|ReflectionFunction|ReflectionParameter $reflection
|
||||
* @return array<ReflectionAttribute<object>>
|
||||
*/
|
||||
private function attributes(Reflector $reflection): array
|
||||
{
|
||||
if ($reflection instanceof ReflectionClass) {
|
||||
return $reflection->getAttributes();
|
||||
}
|
||||
|
||||
if ($reflection instanceof ReflectionProperty) {
|
||||
return $reflection->getAttributes();
|
||||
}
|
||||
|
||||
if ($reflection instanceof ReflectionMethod) {
|
||||
return $reflection->getAttributes();
|
||||
}
|
||||
|
||||
if ($reflection instanceof ReflectionParameter) {
|
||||
return $reflection->getAttributes();
|
||||
}
|
||||
|
||||
throw new InvalidReflectionParameter($reflection);
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,18 @@ declare(strict_types=1);
|
||||
namespace CuyZ\Valinor\Definition\Repository;
|
||||
|
||||
use CuyZ\Valinor\Definition\Attributes;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use ReflectionParameter;
|
||||
use ReflectionProperty;
|
||||
use Reflector;
|
||||
|
||||
/** @internal */
|
||||
interface AttributesRepository
|
||||
{
|
||||
/**
|
||||
* @param ReflectionClass<object>|ReflectionProperty|ReflectionMethod|ReflectionFunction|ReflectionParameter $reflector
|
||||
*/
|
||||
public function for(Reflector $reflector): Attributes;
|
||||
}
|
||||
|
@ -15,11 +15,15 @@ final class FunctionDefinitionCompiler implements CacheCompiler
|
||||
{
|
||||
private TypeCompiler $typeCompiler;
|
||||
|
||||
private AttributesCompiler $attributesCompiler;
|
||||
|
||||
private ParameterDefinitionCompiler $parameterCompiler;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->typeCompiler = new TypeCompiler();
|
||||
$this->attributesCompiler = new AttributesCompiler();
|
||||
|
||||
$this->parameterCompiler = new ParameterDefinitionCompiler($this->typeCompiler, new AttributesCompiler());
|
||||
}
|
||||
|
||||
@ -32,6 +36,7 @@ final class FunctionDefinitionCompiler implements CacheCompiler
|
||||
iterator_to_array($value->parameters())
|
||||
);
|
||||
|
||||
$attributes = $this->attributesCompiler->compile($value->attributes());
|
||||
$fileName = var_export($value->fileName(), true);
|
||||
$class = var_export($value->class(), true);
|
||||
$isStatic = var_export($value->isStatic(), true);
|
||||
@ -42,6 +47,7 @@ final class FunctionDefinitionCompiler implements CacheCompiler
|
||||
new \CuyZ\Valinor\Definition\FunctionDefinition(
|
||||
'{$value->name()}',
|
||||
'{$value->signature()}',
|
||||
$attributes,
|
||||
$fileName,
|
||||
$class,
|
||||
$isStatic,
|
||||
|
@ -23,9 +23,13 @@ final class ReflectionFunctionDefinitionRepository implements FunctionDefinition
|
||||
|
||||
private ReflectionParameterDefinitionBuilder $parameterBuilder;
|
||||
|
||||
private AttributesRepository $attributesRepository;
|
||||
|
||||
public function __construct(TypeParserFactory $typeParserFactory, AttributesRepository $attributesRepository)
|
||||
{
|
||||
$this->typeParserFactory = $typeParserFactory;
|
||||
$this->attributesRepository = $attributesRepository;
|
||||
|
||||
$this->parameterBuilder = new ReflectionParameterDefinitionBuilder($attributesRepository);
|
||||
}
|
||||
|
||||
@ -46,6 +50,7 @@ final class ReflectionFunctionDefinitionRepository implements FunctionDefinition
|
||||
return new FunctionDefinition(
|
||||
$reflection->getName(),
|
||||
Reflection::signature($reflection),
|
||||
$this->attributesRepository->for($reflection),
|
||||
$reflection->getFileName() ?: null,
|
||||
// @PHP 8.0 nullsafe operator
|
||||
$class ? $class->name : null,
|
||||
|
@ -18,6 +18,7 @@ final class FakeFunctionDefinition
|
||||
return new FunctionDefinition(
|
||||
'foo',
|
||||
'foo:42-1337',
|
||||
new FakeAttributes(),
|
||||
$fileName ?? 'foo/bar',
|
||||
stdClass::class,
|
||||
true,
|
||||
|
@ -9,6 +9,7 @@ use CuyZ\Valinor\Definition\FunctionDefinition;
|
||||
use CuyZ\Valinor\Definition\ParameterDefinition;
|
||||
use CuyZ\Valinor\Definition\Parameters;
|
||||
use CuyZ\Valinor\Definition\Repository\Cache\Compiler\FunctionDefinitionCompiler;
|
||||
use CuyZ\Valinor\Tests\Fake\Definition\FakeAttributes;
|
||||
use CuyZ\Valinor\Type\Types\NativeStringType;
|
||||
use Error;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
@ -30,6 +31,7 @@ final class FunctionDefinitionCompilerTest extends TestCase
|
||||
$function = new FunctionDefinition(
|
||||
'foo',
|
||||
'foo:42-1337',
|
||||
new FakeAttributes(),
|
||||
'foo/bar',
|
||||
stdClass::class,
|
||||
true,
|
||||
|
@ -4,14 +4,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace CuyZ\Valinor\Tests\Unit\Definition;
|
||||
|
||||
use CuyZ\Valinor\Definition\Exception\InvalidReflectionParameter;
|
||||
use CuyZ\Valinor\Definition\NativeAttributes;
|
||||
use CuyZ\Valinor\Tests\Fake\FakeReflector;
|
||||
use CuyZ\Valinor\Tests\Fixture\Attribute\AttributeWithArguments;
|
||||
use CuyZ\Valinor\Tests\Fixture\Attribute\BasicAttribute;
|
||||
use CuyZ\Valinor\Tests\Fixture\Object\ObjectWithAttributes;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
use ReflectionFunction;
|
||||
use ReflectionMethod;
|
||||
use ReflectionParameter;
|
||||
use ReflectionProperty;
|
||||
@ -96,11 +95,16 @@ final class NativeAttributesTest extends TestCase
|
||||
self::assertCount(1, $attributes->ofType(BasicAttribute::class));
|
||||
}
|
||||
|
||||
public function test_throws_on_incompatible_reflection(): void
|
||||
public function test_function_attributes_are_fetched_correctly(): void
|
||||
{
|
||||
$this->expectException(InvalidReflectionParameter::class);
|
||||
$this->expectExceptionCode(1534263918);
|
||||
$reflection = new ReflectionFunction(
|
||||
#[BasicAttribute]
|
||||
fn () => 'foo'
|
||||
);
|
||||
$attributes = new NativeAttributes($reflection);
|
||||
|
||||
new NativeAttributes(new FakeReflector());
|
||||
self::assertCount(1, $attributes);
|
||||
self::assertTrue($attributes->has(BasicAttribute::class));
|
||||
self::assertCount(1, $attributes->ofType(BasicAttribute::class));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user