Completed
Pull Request — 2.x (#216)
by Akihito
09:22
created

AopCode::getMethodBinding()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
c 0
b 0
f 0
rs 9.6666
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Compiler;
6
7
use PhpParser\Node;
8
use PhpParser\Node\Expr;
9
use PhpParser\Node\Expr\Assign;
10
use PhpParser\Node\Scalar;
11
use Ray\Di\Dependency;
12
use Ray\Di\Name;
13
14
final class AopCode
15
{
16
    /**
17
     * @var PrivateProperty
18
     */
19
    private $privateProperty;
20
21
    public function __construct(PrivateProperty $privateProperty)
22
    {
23
        $this->privateProperty = $privateProperty;
24
    }
25
26
    /**
27
     * Add aop factory code if bindings are given
28
     *
29
     * @param array<Expr> $node
30
     *
31
     * @param-out array<Expr|mixed> $node
32
     */
33
    public function __invoke(Dependency $dependency, array &$node) : void
34
    {
35
        $prop = $this->privateProperty;
36
        $newInstance = $prop($dependency, 'newInstance');
37
        $bind = $prop($newInstance, 'bind');
38
        $bind = $prop($bind, 'bind');
39
        /** @var null|string[][] $bindings */
40
        $bindings = $prop($bind, 'bindings', null);
41
        if (! \is_array($bindings)) {
42
            return;
43
        }
44
        $methodBinding = $this->getMethodBinding($bindings);
45
        $bindingsProp = new Expr\PropertyFetch(new Expr\Variable('instance'), 'bindings');
46
        $bindingsAssign = new Assign($bindingsProp, new Expr\Array_($methodBinding));
47
        $this->setBindingAssignAfterInitialization($node, [$bindingsAssign], 1);
48
    }
49
50
    /**
51
     * @param array<Expr>   $array
52
     * @param array<Assign> $insertValue
53
     *
54
     * @param-out array<Expr|mixed> $array
55
     */
56
    private function setBindingAssignAfterInitialization(array &$array, array $insertValue, int $position) : void
57
    {
58
        $array = \array_merge(\array_splice($array, 0, $position), $insertValue, $array);
59
    }
60
61
    /**
62
     * @param string[][] $bindings
63
     *
64
     * @return Expr\ArrayItem[]
65
     */
66
    private function getMethodBinding(array $bindings) : array
67
    {
68
        $methodBinding = [];
69
        foreach ($bindings as $method => $interceptors) {
70
            $items = [];
71
            foreach ($interceptors as $interceptor) {
72
                // $singleton('FakeAopInterface-*');
73
                $dependencyIndex = "{$interceptor}-" . Name::ANY;
74
                $singleton = new Expr\FuncCall(new Expr\Variable('singleton'), [new Node\Arg(new Scalar\String_($dependencyIndex))]);
75
                // [$singleton('FakeAopInterface-*'), $singleton('FakeAopInterface-*');]
76
                $items[] = new Expr\ArrayItem($singleton);
77
            }
78
            $arr = new Expr\Array_($items);
79
            $methodBinding[] = new Expr\ArrayItem($arr, new Scalar\String_($method));
80
        }
81
82
        return $methodBinding;
83
    }
84
}
85