3 declare(strict_types=1);
5 namespace CuyZ\Valinor\Definition\Repository\Cache\Compiler;
7 use CuyZ\Valinor\Definition\Attributes;
8 use CuyZ\Valinor\Definition\AttributesContainer;
9 use CuyZ\Valinor\Definition\NativeAttributes;
13 use function is_array;
14 use function is_object;
15 use function var_export;
18 final class AttributesCompiler
20 public function compile(Attributes $attributes): string
22 if (count($attributes) === 0) {
23 return AttributesContainer::class . '::empty()';
26 assert($attributes instanceof NativeAttributes);
28 $attributesListCode = $this->compileNativeAttributes($attributes);
31 new \CuyZ\Valinor\Definition\AttributesContainer($attributesListCode)
35 private function compileNativeAttributes(NativeAttributes $attributes): string
37 $attributesListCode = [];
39 foreach ($attributes->definition() as $className => $arguments) {
40 $argumentsCode = $this->compileAttributeArguments($arguments);
42 $attributesListCode[] = "['class' => '$className', 'callback' => fn () => new $className($argumentsCode)]";
45 return implode(', ', $attributesListCode);
49 * @param array<mixed> $arguments
51 private function compileAttributeArguments(array $arguments): string
53 if (count($arguments) === 0) {
59 foreach ($arguments as $argument) {
60 if (is_object($argument)) {
61 $argumentsCode[] = 'unserialize(' . var_export(serialize($argument), true) . ')';
62 } elseif (is_array($argument)) {
63 $argumentsCode[] = '[' . $this->compileAttributeArguments($argument) . ']';
65 $argumentsCode[] = var_export($argument, true);
69 return implode(', ', $argumentsCode);