8870630787ca343b1059937b0f2e7f4944bef8c7
[GitHub/WoltLab/WCF.git] /
1 <?php
2
3 declare(strict_types=1);
4
5 namespace CuyZ\Valinor\Definition\Repository\Cache\Compiler;
6
7 use CuyZ\Valinor\Definition\Attributes;
8 use CuyZ\Valinor\Definition\AttributesContainer;
9 use CuyZ\Valinor\Definition\NativeAttributes;
10
11 use function count;
12 use function implode;
13 use function is_array;
14 use function is_object;
15 use function var_export;
16
17 /** @internal */
18 final class AttributesCompiler
19 {
20 public function compile(Attributes $attributes): string
21 {
22 if (count($attributes) === 0) {
23 return AttributesContainer::class . '::empty()';
24 }
25
26 assert($attributes instanceof NativeAttributes);
27
28 $attributesListCode = $this->compileNativeAttributes($attributes);
29
30 return <<<PHP
31 new \CuyZ\Valinor\Definition\AttributesContainer($attributesListCode)
32 PHP;
33 }
34
35 private function compileNativeAttributes(NativeAttributes $attributes): string
36 {
37 $attributesListCode = [];
38
39 foreach ($attributes->definition() as $className => $arguments) {
40 $argumentsCode = $this->compileAttributeArguments($arguments);
41
42 $attributesListCode[] = "['class' => '$className', 'callback' => fn () => new $className($argumentsCode)]";
43 }
44
45 return implode(', ', $attributesListCode);
46 }
47
48 /**
49 * @param array<mixed> $arguments
50 */
51 private function compileAttributeArguments(array $arguments): string
52 {
53 if (count($arguments) === 0) {
54 return '';
55 }
56
57 $argumentsCode = [];
58
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) . ']';
64 } else {
65 $argumentsCode[] = var_export($argument, true);
66 }
67 }
68
69 return implode(', ', $argumentsCode);
70 }
71 }