AddInitMethod::assignResolverProperty()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\exprUnsetFunc;
19
use function Cycle\ORM\Promise\shortName;
20
21
final class AddInitMethod extends NodeVisitorAbstract
22
{
23
    /** @var string */
24
    private $property;
25
26
    /** @var string */
27
    private $type;
28
29
    /** @var array */
30
    private $dependencies;
31
32
    /** @var string */
33
    private $unsetPropertiesConst;
34
35
    /** @var string */
36
    private $initMethod;
37
38
    /**
39
     * @param string $property
40
     * @param string $propertyType
41
     * @param array  $dependencies
42
     * @param string $unsetPropertiesConst
43
     * @param string $initMethod
44
     */
45
    public function __construct(
46
        string $property,
47
        string $propertyType,
48
        array $dependencies,
49
        string $unsetPropertiesConst,
50
        string $initMethod
51
    ) {
52
        $this->property = $property;
53
        $this->type = $propertyType;
54
        $this->dependencies = $dependencies;
55
        $this->unsetPropertiesConst = $unsetPropertiesConst;
56
        $this->initMethod = $initMethod;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function leaveNode(Node $node)
63
    {
64
        if ($node instanceof Node\Stmt\Class_) {
65
            $method = new Builder\Method($this->initMethod);
66
            $method->makePublic();
67
            foreach ($this->dependencies as $name => $type) {
68
                if ($type !== null) {
69
                    $method->addParam((new Builder\Param($name))->setType(shortName($type)));
70
                }
71
            }
72
            $method->addStmt($this->unsetProperties());
73
            $method->addStmt($this->assignResolverProperty());
74
75
            $node->stmts[] = $method->getNode();
76
        }
77
78
        return null;
79
    }
80
81
    /**
82
     * @return Node\Stmt\Foreach_
83
     */
84
    private function unsetProperties(): Node\Stmt\Foreach_
85
    {
86
        $prop = new Node\Expr\ClassConstFetch(new Node\Name('self'), $this->unsetPropertiesConst);
87
        $foreach = new Node\Stmt\Foreach_($prop, new Node\Expr\Variable('property'));
88
        $foreach->stmts[] = exprUnsetFunc('this', '{$property}');
89
90
        return $foreach;
91
    }
92
93
    /**
94
     * @return Node\Stmt\Expression
95
     */
96
    private function assignResolverProperty(): Node\Stmt\Expression
97
    {
98
        $prop = new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $this->property);
99
        $instance = new Node\Expr\New_(new Node\Name($this->type), $this->packResolverPropertyArgs());
100
101
        return new Node\Stmt\Expression(new Node\Expr\Assign($prop, $instance));
102
    }
103
104
    /**
105
     * @return array
106
     */
107
    private function packResolverPropertyArgs(): array
108
    {
109
        $args = [];
110
        foreach ($this->dependencies as $name => $type) {
111
            $args[] = new Node\Arg(new Node\Expr\Variable($name));
112
        }
113
114
        return $args;
115
    }
116
}
117