Skip to content

Commit

Permalink
misc: refactor attribute definition to include class definition
Browse files Browse the repository at this point in the history
  • Loading branch information
romm committed Jan 23, 2024
1 parent 9597407 commit 4b8cf65
Show file tree
Hide file tree
Showing 47 changed files with 548 additions and 620 deletions.
33 changes: 33 additions & 0 deletions src/Definition/AttributeDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace CuyZ\Valinor\Definition;

/** @internal */
final class AttributeDefinition
{
public function __construct(
private ClassDefinition $class,
/** @var list<mixed> */
private array $arguments,
) {}

public function class(): ClassDefinition
{
return $this->class;
}

/**
* @return list<mixed>
*/
public function arguments(): array
{
return $this->arguments;
}

public function instantiate(): object
{
return new ($this->class->type()->className())(...$this->arguments);
}
}
70 changes: 61 additions & 9 deletions src/Definition/Attributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,76 @@

use Countable;
use IteratorAggregate;
use Traversable;

use function array_filter;
use function count;
use function is_a;

/**
* @internal
*
* @extends IteratorAggregate<object>
* @implements IteratorAggregate<AttributeDefinition>
*/
interface Attributes extends IteratorAggregate, Countable
final class Attributes implements IteratorAggregate, Countable
{
private static self $empty;

/** @var list<AttributeDefinition> */
private array $attributes;

/**
* @no-named-arguments
*/
public function __construct(AttributeDefinition ...$attributes)
{
$this->attributes = $attributes;
}

public static function empty(): self
{
return self::$empty ??= new self();
}

public function has(string $className): bool
{
foreach ($this->attributes as $attribute) {
if (is_a($attribute->class()->type()->className(), $className, true)) {
return true;
}
}

return false;
}

/**
* @param callable(AttributeDefinition): bool $callback
*/
public function filter(callable $callback): self
{
return new self(
...array_filter($this->attributes, $callback)
);
}

public function count(): int
{
return count($this->attributes);
}

/**
* @param class-string $className
* @return list<AttributeDefinition>
*/
public function has(string $className): bool;
public function toArray(): array
{
return $this->attributes;
}

/**
* @template T of object
*
* @param class-string<T> $className
* @return list<T>
* @return Traversable<AttributeDefinition>
*/
public function ofType(string $className): array;
public function getIterator(): Traversable
{
yield from $this->attributes;
}
}
80 changes: 0 additions & 80 deletions src/Definition/AttributesContainer.php

This file was deleted.

89 changes: 0 additions & 89 deletions src/Definition/NativeAttributes.php

This file was deleted.

12 changes: 4 additions & 8 deletions src/Definition/Repository/AttributesRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,14 @@

namespace CuyZ\Valinor\Definition\Repository;

use CuyZ\Valinor\Definition\Attributes;
use ReflectionClass;
use ReflectionFunction;
use ReflectionMethod;
use ReflectionParameter;
use ReflectionProperty;
use CuyZ\Valinor\Definition\AttributeDefinition;
use ReflectionAttribute;

/** @internal */
interface AttributesRepository
{
/**
* @param ReflectionClass<object>|ReflectionProperty|ReflectionMethod|ReflectionFunction|ReflectionParameter $reflector
* @param ReflectionAttribute<object> $reflection
*/
public function for(ReflectionClass|ReflectionProperty|ReflectionMethod|ReflectionFunction|ReflectionParameter $reflector): Attributes;
public function for(ReflectionAttribute $reflection): AttributeDefinition;
}
26 changes: 15 additions & 11 deletions src/Definition/Repository/Cache/Compiler/AttributesCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
namespace CuyZ\Valinor\Definition\Repository\Cache\Compiler;

use CuyZ\Valinor\Definition\Attributes;
use CuyZ\Valinor\Definition\AttributesContainer;
use CuyZ\Valinor\Definition\NativeAttributes;

use function count;
use function implode;
Expand All @@ -17,29 +15,35 @@
/** @internal */
final class AttributesCompiler
{
public function __construct(private ClassDefinitionCompiler $classDefinitionCompiler) {}

public function compile(Attributes $attributes): string
{
if (count($attributes) === 0) {
return AttributesContainer::class . '::empty()';
return Attributes::class . '::empty()';
}

assert($attributes instanceof NativeAttributes);

$attributesListCode = $this->compileNativeAttributes($attributes);
$attributesListCode = $this->compileAttributes($attributes);

return <<<PHP
new \CuyZ\Valinor\Definition\AttributesContainer($attributesListCode)
new \CuyZ\Valinor\Definition\Attributes($attributesListCode)
PHP;
}

private function compileNativeAttributes(NativeAttributes $attributes): string
private function compileAttributes(Attributes $attributes): string
{
$attributesListCode = [];

foreach ($attributes->definition() as $className => $arguments) {
$argumentsCode = $this->compileAttributeArguments($arguments);
foreach ($attributes as $attribute) {
$class = $this->classDefinitionCompiler->compile($attribute->class());
$arguments = $this->compileAttributeArguments($attribute->arguments());

$attributesListCode[] = "['class' => '$className', 'callback' => fn () => new $className($argumentsCode)]";
$attributesListCode[] = <<<PHP
new \CuyZ\Valinor\Definition\AttributeDefinition(
$class,
[$arguments],
)
PHP;
}

return implode(', ', $attributesListCode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final class ClassDefinitionCompiler implements CacheCompiler
public function __construct()
{
$this->typeCompiler = new TypeCompiler();
$this->attributesCompiler = new AttributesCompiler();
$this->attributesCompiler = new AttributesCompiler($this);

$this->methodCompiler = new MethodDefinitionCompiler($this->typeCompiler, $this->attributesCompiler);
$this->propertyCompiler = new PropertyDefinitionCompiler($this->typeCompiler, $this->attributesCompiler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ final class FunctionDefinitionCompiler implements CacheCompiler
public function __construct()
{
$this->typeCompiler = new TypeCompiler();
$this->attributesCompiler = new AttributesCompiler();
$this->attributesCompiler = new AttributesCompiler(new ClassDefinitionCompiler());

$this->parameterCompiler = new ParameterDefinitionCompiler($this->typeCompiler, new AttributesCompiler());
$this->parameterCompiler = new ParameterDefinitionCompiler($this->typeCompiler, $this->attributesCompiler);
}

public function compile(mixed $value): string
Expand Down
Loading

0 comments on commit 4b8cf65

Please sign in to comment.