Passed
Push — visitor ( 2d5566...06020c )
by Akihito
01:35
created

InstanceScript   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 14
eloc 33
c 1
b 0
f 0
dl 0
loc 72
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A pushMethod() 0 4 1
A pushClass() 0 4 1
A pushAspectBind() 0 15 4
A addInstanceArg() 0 3 1
A addArgDependency() 0 12 3
A getScript() 0 18 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Di\Compiler;
6
7
use Ray\Aop\Bind as AopBind;
8
use ReflectionParameter;
9
10
use function array_unshift;
11
use function implode;
12
use function sprintf;
13
use function unserialize;
14
15
use const PHP_EOL;
16
17
final class InstanceScript
18
{
19
    private $args = [];
20
    private $aopBindings = '';
21
    private $lines = [];
22
23
    public function addArgDependency(bool $isSingleton, string $index, ReflectionParameter $parameter): void
24
    {
25
        if ($index === 'Ray\Di\InjectorInterface-') {
26
            $this->args[] = '$injector()';
27
28
            return;
29
        }
30
31
        $ip = sprintf("['%s', '%s', '%s']", $parameter->getDeclaringClass()->name, $parameter->getDeclaringFunction()->getName(), $parameter->name);
32
        $func = $isSingleton ? '$singleton' : '$prototype';
33
            $arg = sprintf("%s('%s', %s)", $func, $index, $ip);
34
        $this->args[] = $arg;
35
    }
36
37
    public function addInstanceArg(string $default): void
38
    {
39
        $this->args[] = $default;
40
    }
41
42
    public function pushMethod(string $method): void
43
    {
44
        $this->lines[] = sprintf('$instance->%s(%s);', $method, implode(', ', $this->args));
45
        $this->args = [];
46
    }
47
48
    public function pushClass(string $class): void
49
    {
50
        array_unshift($this->lines, sprintf('$instance = new \%s(%s);', $class, implode(', ', $this->args)));
51
        $this->args = [];
52
    }
53
54
    public function pushAspectBind(AopBind $aopBind): void
55
    {
56
        $aopBindings = unserialize((string) ($aopBind));
57
        foreach ($aopBindings as $method => &$bindings) {
58
            foreach ($bindings as &$binding) {
59
                $binding = sprintf('$singleton(\'%s-\')', $binding);
60
            }
61
        }
62
63
        $interceptors = [];
64
        foreach ($aopBindings as $method => $bindings) {
65
            $interceptors[] =  sprintf('\'%s\' => [%s]', $method, implode(', ', $bindings));
66
        }
67
68
        $this->aopBindings = sprintf('$instance->bindings = [%s];', implode(', ', $interceptors));
69
    }
70
71
    public function getScript(?string $postConstruct, bool $isSingleton): string
72
    {
73
        if ($postConstruct) {
74
            $this->lines[] = sprintf('$instance->%s();', $postConstruct);
75
        }
76
77
        if ($this->aopBindings) {
78
            $this->lines[] = $this->aopBindings;
79
            $this->aopBindings = '';
80
        }
81
82
        $this->lines[] = sprintf('$isSingleton = %s;', $isSingleton ? 'true' : 'false');
83
        $this->lines[] = 'return $instance;';
84
85
        $script = implode(PHP_EOL, $this->lines);
86
        $this->lines = [];
87
88
        return $script;
89
    }
90
}
91