Completed
Pull Request — master (#3)
by Valentin
01:55
created

AddInitMethod   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 15

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 15
dl 0
loc 80
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
A leaveNode() 0 18 4
A unsetProperties() 0 8 1
A assignResolverProperty() 0 7 1
A packResolverPropertyArgs() 0 9 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Cycle\ORM\Promise\Visitor;
5
6
use Cycle\ORM\Promise\Expressions;
7
use Cycle\ORM\Promise\Utils;
8
use PhpParser\Builder;
9
use PhpParser\Node;
10
use PhpParser\NodeVisitorAbstract;
11
12
class AddInitMethod extends NodeVisitorAbstract
13
{
14
    /** @var string */
15
    private $property;
16
17
    /** @var string */
18
    private $type;
19
20
    /** @var array */
21
    private $dependencies;
22
23
    /** @var string */
24
    private $unsetPropertiesConst;
25
26
    /** @var string */
27
    private $initMethod;
28
29
    public function __construct(
30
        string $property,
31
        string $propertyType,
32
        array $dependencies,
33
        string $unsetPropertiesConst,
34
        string $initMethod
35
    ) {
36
        $this->property = $property;
37
        $this->type = $propertyType;
38
        $this->dependencies = $dependencies;
39
        $this->unsetPropertiesConst = $unsetPropertiesConst;
40
        $this->initMethod = $initMethod;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function leaveNode(Node $node)
47
    {
48
        if ($node instanceof Node\Stmt\Class_) {
49
            $method = new Builder\Method($this->initMethod);
50
            $method->makePublic();
51
            foreach ($this->dependencies as $name => $type) {
52
                if ($type !== null) {
53
                    $method->addParam((new Builder\Param($name))->setType(Utils::shortName($type)));
54
                }
55
            }
56
            $method->addStmt($this->unsetProperties());
57
            $method->addStmt($this->assignResolverProperty());
58
59
            $node->stmts[] = $method->getNode();
60
        }
61
62
        return null;
63
    }
64
65
    private function unsetProperties(): Node\Stmt\Foreach_
66
    {
67
        $prop = new Node\Expr\ClassConstFetch(new Node\Name('self'), $this->unsetPropertiesConst);
68
        $foreach = new Node\Stmt\Foreach_($prop, new Node\Expr\Variable('property'));
69
        $foreach->stmts[] = new Node\Stmt\Expression(Expressions::unsetFunc('this', '{$property}'));
70
71
        return $foreach;
72
    }
73
74
    private function assignResolverProperty(): Node\Stmt\Expression
75
    {
76
        $prop = new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $this->property);
77
        $instance = new Node\Expr\New_(new Node\Name($this->type), $this->packResolverPropertyArgs());
78
79
        return new Node\Stmt\Expression(new Node\Expr\Assign($prop, $instance));
80
    }
81
82
    private function packResolverPropertyArgs(): array
83
    {
84
        $args = [];
85
        foreach ($this->dependencies as $name => $type) {
86
            $args[] = new Node\Arg(new Node\Expr\Variable($name));
87
        }
88
89
        return $args;
90
    }
91
}