Completed
Push — master ( 480c88...01d8db )
by Valentin
08:43
created

AddMagicDebugInfo::leaveNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Cycle\ORM\Promise\Visitor;
5
6
use Cycle\ORM\Promise\Expressions;
7
use PhpParser\Builder;
8
use PhpParser\Node;
9
use PhpParser\NodeVisitorAbstract;
10
11
class AddMagicDebugInfo extends NodeVisitorAbstract
12
{
13
    /** @var string */
14
    private $resolverProperty;
15
16
    /** @var string */
17
    private $resolveMethod;
18
19
    /** @var array */
20
    private $unsetPropertiesValues;
21
22
    public function __construct(string $resolverProperty, string $resolveMethod, array $unsetPropertiesValues)
23
    {
24
        $this->resolverProperty = $resolverProperty;
25
        $this->resolveMethod = $resolveMethod;
26
        $this->unsetPropertiesValues = $unsetPropertiesValues;
27
    }
28
29
    public function leaveNode(Node $node)
30
    {
31
        if ($node instanceof Node\Stmt\Class_) {
32
            $method = new Builder\Method('__debugInfo');
33
            $method->makePublic();
34
            $method->addStmt(Expressions::resolveIntoVar('entity', 'this', $this->resolverProperty, $this->resolveMethod));
35
            $method->addStmt($this->buildExpression());
36
37
            $node->stmts[] = $method->getNode();
38
        }
39
40
        return null;
41
    }
42
43
    private function buildExpression(): Node\Stmt\If_
44
    {
45
        $if = new Node\Stmt\If_(Expressions::notNull(new Node\Expr\Variable('entity')));
46
        $if->stmts[] = new Node\Stmt\Return_($this->resolvedProperties());
47
        $if->else = new Node\Stmt\Else_();
48
        $if->else->stmts[] = new Node\Stmt\Return_($this->unresolvedProperties());
49
50
        return $if;
51
    }
52
53
    private function resolvedProperties(): Node\Expr\Array_
54
    {
55
        $array = [];
56
        foreach ($this->unsetPropertiesValues as $value) {
57
            $array[] = $this->arrayItem(new Node\Expr\PropertyFetch(new Node\Expr\Variable('entity'), $value), $value);
58
        }
59
60
        return $this->array($array);
61
    }
62
63
    private function unresolvedProperties(): Node\Expr\Array_
64
    {
65
        $array = [];
66
        $array[] = $this->arrayItem(Expressions::const('true'), '~unresolved');
67
        foreach ($this->unsetPropertiesValues as $value) {
68
            $array[] = $this->arrayItem(Expressions::const('null'), $value);
69
        }
70
71
        return $this->array($array);
72
    }
73
74
    private function arrayItem(Node\Expr $value, string $key = null): Node\Expr\ArrayItem
75
    {
76
        return new Node\Expr\ArrayItem($value, new Node\Scalar\String_($key));
77
    }
78
79
    private function array(array $array): Node\Expr\Array_
80
    {
81
        return new Node\Expr\Array_($array, ['kind' => Node\Expr\Array_::KIND_SHORT]);
82
    }
83
}