1 | <?php |
||
13 | final class Compiler implements CompilerInterface |
||
14 | { |
||
15 | /** |
||
16 | * @var string |
||
17 | */ |
||
18 | public $classDir; |
||
19 | |||
20 | /** |
||
21 | * @var CodeGenInterface |
||
22 | */ |
||
23 | private $codeGen; |
||
24 | |||
25 | /** |
||
26 | * @throws \Doctrine\Common\Annotations\AnnotationException |
||
27 | 24 | */ |
|
28 | public function __construct(string $classDir) |
||
29 | 24 | { |
|
30 | 1 | if (! is_writable($classDir)) { |
|
31 | throw new NotWritableException($classDir); |
||
32 | 24 | } |
|
33 | 24 | $this->classDir = $classDir; |
|
34 | 24 | $this->codeGen = new CodeGen( |
|
35 | 24 | (new ParserFactory)->newInstance(), |
|
36 | 24 | new BuilderFactory, |
|
37 | new Standard(['shortArraySyntax' => true]) |
||
38 | 24 | ); |
|
39 | } |
||
40 | 1 | ||
41 | public function __sleep() |
||
42 | 1 | { |
|
43 | return ['classDir']; |
||
44 | } |
||
45 | 1 | ||
46 | /** |
||
47 | 1 | * @throws \Doctrine\Common\Annotations\AnnotationException |
|
48 | 1 | */ |
|
49 | public function __wakeup() |
||
50 | { |
||
51 | $this->__construct($this->classDir); |
||
52 | } |
||
53 | 10 | ||
54 | /** |
||
55 | 10 | * {@inheritdoc} |
|
56 | 10 | * |
|
57 | 10 | * @throws \ReflectionException |
|
58 | */ |
||
59 | 10 | public function newInstance(string $class, array $args, BindInterface $bind) |
|
60 | { |
||
61 | $compiledClass = $this->compile($class, $bind); |
||
62 | $instance = (new ReflectionClass($compiledClass))->newInstanceArgs($args); |
||
63 | $instance->bindings = $bind->getBindings(); |
||
64 | |||
65 | 18 | return $instance; |
|
66 | } |
||
67 | 18 | ||
68 | 1 | /** |
|
69 | * {@inheritdoc} |
||
70 | 17 | * |
|
71 | 17 | * @throws \ReflectionException |
|
72 | 7 | */ |
|
73 | public function compile(string $class, BindInterface $bind) : string |
||
74 | 10 | { |
|
75 | 10 | if ($this->hasNoBinding($class, $bind)) { |
|
76 | return $class; |
||
77 | } |
||
78 | 1 | $aopClassName = $this->getAopClassName($class, $bind); |
|
79 | if (class_exists($aopClassName, false)) { |
||
80 | 1 | return $aopClassName; |
|
81 | } |
||
82 | 9 | $this->requireFile($aopClassName, new ReflectionClass($class), $bind); |
|
83 | |||
84 | 9 | return $aopClassName; |
|
85 | } |
||
86 | |||
87 | 18 | private function hasNoBinding($class, BindInterface $bind) : bool |
|
93 | |||
94 | 17 | private function hasBoundMethod(string $class, BindInterface $bind) : bool |
|
95 | { |
||
96 | 17 | $bindingMethods = array_keys($bind->getBindings()); |
|
97 | $hasMethod = false; |
||
98 | 17 | foreach ($bindingMethods as $bindingMethod) { |
|
106 | 17 | ||
107 | 17 | private function requireFile(string $aopClassName, \ReflectionClass $sourceClass, BindInterface $bind) : void |
|
114 | 9 | ||
115 | private function getAopClassName(string $class, BindInterface $bind) |
||
119 | } |
||
120 |