Completed
Push — refactor ( 1ac315 )
by Akihito
05:56
created

DiCompiler   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 9
dl 0
loc 72
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 2
A getInstance() 0 6 1
A compile() 0 11 2
A dumpGraph() 0 5 1
A savePointcuts() 0 7 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Compiler;
6
7
use Ray\Aop\Compiler;
8
use Ray\Di\AbstractModule;
9
use Ray\Di\Bind;
10
use Ray\Di\Container;
11
use Ray\Di\InjectorInterface;
12
use Ray\Di\Name;
13
use ReflectionProperty;
14
15
use function serialize;
16
use function sys_get_temp_dir;
17
18
final class DiCompiler implements InjectorInterface
19
{
20
    /** @var string */
21
    private $scriptDir;
22
23
    /** @var Container */
24
    private $container;
25
26
    /** @var DependencyCode */
27
    private $dependencyCompiler;
28
29
    /** @var AbstractModule|null */
30
    private $module;
31
32
    /** @var DependencySaver */
33
    private $dependencySaver;
34
35
    /** @var FilePutContents */
36
    private $filePutContents;
37
38
    public function __construct(AbstractModule $module, string $scriptDir)
39
    {
40
        $this->scriptDir = $scriptDir ?: sys_get_temp_dir();
41
        $this->container = $module->getContainer();
42
        $this->dependencyCompiler = new DependencyCode($this->container);
43
        $this->module = $module;
44
        $this->dependencySaver = new DependencySaver($scriptDir);
45
        $this->filePutContents = new FilePutContents();
46
        // Weave AssistedInterceptor and bind InjectorInterface for self
47
        $module->getContainer()->weaveAspects(new Compiler($scriptDir));
48
        (new Bind($this->container, InjectorInterface::class))->toInstance($this);
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function getInstance($interface, $name = Name::ANY)
55
    {
56
        $this->compile();
57
58
        return (new ScriptInjector($this->scriptDir))->getInstance($interface, $name);
59
    }
60
61
    /**
62
     * Compile all dependencies in container
63
     */
64
    public function compile(): void
65
    {
66
        $container = $this->container->getContainer();
67
        foreach ($container as $dependencyIndex => $dependency) {
68
            $code = $this->dependencyCompiler->getCode($dependency);
69
            ($this->dependencySaver)($dependencyIndex, $code);
70
        }
71
72
        $this->savePointcuts($this->container);
73
        ($this->filePutContents)($this->scriptDir . ScriptInjector::MODULE, serialize($this->module));
74
    }
75
76
    public function dumpGraph(): void
77
    {
78
        $dumper = new GraphDumper($this->container, $this->scriptDir);
79
        $dumper();
80
    }
81
82
    public function savePointcuts(Container $container): void
83
    {
84
        $ref = (new ReflectionProperty($container, 'pointcuts'));
85
        $ref->setAccessible(true);
86
        $pointcuts = $ref->getValue($container);
87
        ($this->filePutContents)($this->scriptDir . ScriptInjector::AOP, serialize($pointcuts));
88
    }
89
}
90