AddMagicDebugInfoMethod   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 0
Metric Value
dl 0
loc 138
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 11

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
A leaveNode() 0 12 2
A buildExpression() 0 17 1
A resolvedProperties() 0 9 2
A unresolvedProperties() 0 19 2
A arrayItem() 0 4 1
A array() 0 4 1
1
<?php
2
3
/**
4
 * Spiral Framework. Cycle ProxyFactory
5
 *
6
 * @license MIT
7
 * @author  Valentin V (Vvval)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\ORM\Promise\Visitor;
13
14
use PhpParser\Builder;
15
use PhpParser\Node;
16
use PhpParser\NodeVisitorAbstract;
17
18
use function Cycle\ORM\Promise\constFetch;
19
use function Cycle\ORM\Promise\ifEqualsFalse;
20
use function Cycle\ORM\Promise\ifNotNull;
21
use function Cycle\ORM\Promise\resolveIntoVar;
22
use function Cycle\ORM\Promise\resolveMethodCall;
23
24
final class AddMagicDebugInfoMethod extends NodeVisitorAbstract
25
{
26
    /** @var string */
27
    private $resolverProperty;
28
29
    /** @var string */
30
    private $resolveMethod;
31
32
    /** @var string */
33
    private $loadedMethod;
34
35
    /** @var string */
36
    private $roleMethod;
37
38
    /** @var string */
39
    private $scopeMethod;
40
41
    /** @var array */
42
    private $unsetPropertiesValues;
43
44
    /**
45
     * @param string $resolverProperty
46
     * @param string $resolveMethod
47
     * @param string $loadedMethod
48
     * @param string $roleMethod
49
     * @param string $scopeMethod
50
     * @param array  $unsetPropertiesValues
51
     */
52
    public function __construct(
53
        string $resolverProperty,
54
        string $resolveMethod,
55
        string $loadedMethod,
56
        string $roleMethod,
57
        string $scopeMethod,
58
        array $unsetPropertiesValues
59
    ) {
60
        $this->resolverProperty = $resolverProperty;
61
        $this->resolveMethod = $resolveMethod;
62
        $this->loadedMethod = $loadedMethod;
63
        $this->roleMethod = $roleMethod;
64
        $this->scopeMethod = $scopeMethod;
65
        $this->unsetPropertiesValues = $unsetPropertiesValues;
66
    }
67
68
    /**
69
     * @param Node $node
70
     * @return int|Node|Node[]|null
71
     */
72
    public function leaveNode(Node $node)
73
    {
74
        if ($node instanceof Node\Stmt\Class_) {
75
            $method = new Builder\Method('__debugInfo');
76
            $method->makePublic();
77
            $method->addStmt($this->buildExpression());
78
79
            $node->stmts[] = $method->getNode();
80
        }
81
82
        return null;
83
    }
84
85
    /**
86
     * @return Node\Stmt\If_
87
     */
88
    private function buildExpression(): Node\Stmt\If_
89
    {
90
        $loaded = resolveMethodCall('this', $this->resolverProperty, $this->loadedMethod);
91
        $if = ifEqualsFalse($loaded);
92
        $if->stmts[] = new Node\Stmt\Return_($this->unresolvedProperties('false'));
93
        $if->else = new Node\Stmt\Else_([
94
            resolveIntoVar('entity', 'this', $this->resolverProperty, $this->resolveMethod),
95
            ifNotNull(new Node\Expr\Variable('entity'), [
96
                'stmts' => [new Node\Stmt\Return_($this->resolvedProperties())],
97
                'else'  => new Node\Stmt\Else_([
98
                    new Node\Stmt\Return_($this->unresolvedProperties('true'))
99
                ])
100
            ])
101
        ]);
102
103
        return $if;
104
    }
105
106
    /**
107
     * @return Node\Expr\Array_
108
     */
109
    private function resolvedProperties(): Node\Expr\Array_
110
    {
111
        $array = [];
112
        foreach ($this->unsetPropertiesValues as $value) {
113
            $array[] = $this->arrayItem(new Node\Expr\PropertyFetch(new Node\Expr\Variable('entity'), $value), $value);
114
        }
115
116
        return $this->array($array);
117
    }
118
119
    /**
120
     * @param string $loaded
121
     * @return Node\Expr\Array_
122
     */
123
    private function unresolvedProperties(string $loaded): Node\Expr\Array_
124
    {
125
        $array = [];
126
        $array[] = $this->arrayItem(constFetch($loaded), ':loaded');
127
        $array[] = $this->arrayItem(constFetch('false'), ':resolved');
128
        $array[] = $this->arrayItem(
129
            resolveMethodCall('this', $this->resolverProperty, $this->roleMethod),
130
            ':role'
131
        );
132
        $array[] = $this->arrayItem(
133
            resolveMethodCall('this', $this->resolverProperty, $this->scopeMethod),
134
            ':scope'
135
        );
136
        foreach ($this->unsetPropertiesValues as $value) {
137
            $array[] = $this->arrayItem(constFetch('null'), $value);
138
        }
139
140
        return $this->array($array);
141
    }
142
143
    /**
144
     * @param Node\Expr   $value
145
     * @param string|null $key
146
     * @return Node\Expr\ArrayItem
147
     */
148
    private function arrayItem(Node\Expr $value, string $key = null): Node\Expr\ArrayItem
149
    {
150
        return new Node\Expr\ArrayItem($value, new Node\Scalar\String_($key));
151
    }
152
153
    /**
154
     * @param array $array
155
     * @return Node\Expr\Array_
156
     */
157
    private function array(array $array): Node\Expr\Array_
158
    {
159
        return new Node\Expr\Array_($array, ['kind' => Node\Expr\Array_::KIND_SHORT]);
160
    }
161
}
162