Passed
Push — master ( 327a11...1a5769 )
by Valentin
58s
created

UpdateConstructor::packResolverPropertyArgs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Cycle\ORM\Promise\Visitor;
5
6
use Cycle\ORM\Promise\Expressions;
7
use PhpParser\Node;
8
use PhpParser\NodeVisitorAbstract;
9
10
/**
11
 * Add constructor
12
 */
13
class UpdateConstructor extends NodeVisitorAbstract
14
{
15
    /** @var bool */
16
    private $hasConstructor;
17
18
    /** @var string */
19
    private $property;
20
21
    /** @var string */
22
    private $type;
23
24
    /** @var array */
25
    private $dependencies;
26
27
    /** @var string */
28
    private $unsetPropertiesProperty;
29
30
    public function __construct(
31
        bool $hasConstructor,
32
        string $property,
33
        string $propertyType,
34
        array $dependencies,
35
        string $unsetPropertiesProperty
36
    ) {
37
        $this->hasConstructor = $hasConstructor;
38
        $this->property = $property;
39
        $this->type = $propertyType;
40
        $this->dependencies = $dependencies;
41
        $this->unsetPropertiesProperty = $unsetPropertiesProperty;
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function leaveNode(Node $node)
48
    {
49
        if ($node instanceof Node\Stmt\ClassMethod && $node->name->name === '__construct') {
50
            $node->stmts[] = $this->unsetProperties();
51
            $node->stmts[] = $this->assignResolverProperty();
52
53
            if ($this->hasConstructor) {
54
                $node->stmts[] = $this->callParentConstruct();
55
            }
56
        }
57
58
        return null;
59
    }
60
61
    private function unsetProperties(): Node\Stmt\Foreach_
62
    {
63
        $prop = new Node\Expr\ClassConstFetch(new Node\Name('self'), $this->unsetPropertiesProperty);
64
        $foreach = new Node\Stmt\Foreach_($prop, new Node\Expr\Variable('property'));
65
        $foreach->stmts[] = Expressions::unsetFunc('this', '{$property}');
66
67
        return $foreach;
68
    }
69
70
    private function assignResolverProperty(): Node\Stmt\Expression
71
    {
72
        $prop = new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $this->property);
73
        $instance = new Node\Expr\New_(new Node\Name($this->type), $this->packResolverPropertyArgs());
74
75
        return new Node\Stmt\Expression(new Node\Expr\Assign($prop, $instance));
76
    }
77
78
    private function packResolverPropertyArgs(): array
79
    {
80
        $args = [];
81
        foreach ($this->dependencies as $name => $type) {
82
            $args[] = new Node\Arg(new Node\Expr\Variable($name));
83
        }
84
85
        return $args;
86
    }
87
88
    private function callParentConstruct(): Node\Stmt\Expression
89
    {
90
        return new Node\Stmt\Expression(new Node\Expr\StaticCall(new Node\Name('parent'), '__construct'));
91
    }
92
}