Passed
Branch master (da5350)
by Timur
02:19
created

Signature::bindVars()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Murtukov\PHPCodeGenerator;
6
7
use function implode;
8
9
class Signature extends DependencyAwareGenerator
10
{
11
    use DocBlockTrait;
12
13
    public string $name;
14
    public bool   $isStatic = false;
15
    public string $modifier;
16
17
    protected string $returnType = '';
18
    protected array  $args = [];
19
    protected array  $uses = []; // variables of parent scope
20
    protected string $qualifier;
21
22
    public function __construct(
23
        string $name = '',
24
        string $modifier = Modifier::NONE,
25
        string $returnType = '',
26
        string $qualifier = 'function '
27
    ) {
28
        $this->name = $name;
29
        $this->modifier = $modifier;
30
        $this->returnType = $this->resolveQualifier($returnType);
31
        $this->qualifier = $qualifier;
32
33
        $this->dependencyAwareChildren = [&$this->args];
34
    }
35
36
    public function getReturnType(): string
37
    {
38
        return $this->returnType;
39
    }
40
41
    public function setReturnType(string $returnType): self
42
    {
43
        $this->returnType = $this->resolveQualifier($returnType);
44
45
        return $this;
46
    }
47
48
    /**
49
     * Some arguments are stored as simple strings for better performance.
50
     * If they are requested, they are first converted into objects then
51
     * returned back.
52
     *
53
     * @return Argument
54
     */
55
    public function getArgument(int $index = 1): ?Argument
56
    {
57
        if ($index-- < 1) {
58
            return null;
59
        }
60
61
        if (isset($this->args[$index])) {
62
            $arg = $this->args[$index];
63
64
            if (is_string($arg)) {
65
                return $this->args[$index] = new Argument($arg);
66
            }
67
68
            return $arg;
69
        }
70
71
        return null;
72
    }
73
74
    public function removeArgument(int $index): self
75
    {
76
        unset($this->args[--$index]);
77
78
        return $this;
79
    }
80
81
    public function removeArguments()
82
    {
83
        $this->args = [];
84
85
        return $this;
86
    }
87
88
    public function createArgument(string $name, string $type = '', $defaultValue = Argument::NO_PARAM): Argument
89
    {
90
        return $this->args[] = new Argument($name, $type, $defaultValue);
91
    }
92
93
    public function addArgument(string $name, string $type = '', $defaultValue = Argument::NO_PARAM): self
94
    {
95
        if (1 === func_num_args()) {
96
            $this->args[] = "$$name";
97
        } else {
98
            $this->args[] = new Argument($name, $type, $defaultValue);
99
        }
100
101
        return $this;
102
    }
103
104
    public function addArguments(string ...$names)
105
    {
106
        foreach ($names as $name) {
107
            $this->addArgument($name);
108
        }
109
110
        return $this;
111
    }
112
113
    public function add(FunctionMemberInterface $member): self
114
    {
115
        if ($member instanceof Argument) {
116
            $this->args[] = $member;
117
        }
118
119
        return $this;
120
    }
121
122
    public function bindVar(string $name, bool $isByReference = false): self
123
    {
124
        $name = ltrim($name, '$');
125
126
        $this->uses[] = $isByReference ? "&$$name" : "$$name";
127
128
        return $this;
129
    }
130
131
    public function bindVars(string ...$names)
132
    {
133
        foreach ($names as $name) {
134
            $this->bindVar($name);
135
        }
136
137
        return $this;
138
    }
139
140
    public function generate(bool $withDocBlock = true): string
141
    {
142
        $args = join(', ', $this->args);
143
        $uses = '';
144
        $isStatic = $this->isStatic ? 'static ' : '';
145
        $modifier = $this->modifier ? "$this->modifier " : '';
146
        $returnType = '';
147
148
        if (!empty($this->uses)) {
149
            $uses = ' use ('.implode(', ', $this->uses).')';
150
        }
151
152
        if ('' !== $this->returnType) {
153
            $returnType = ": $this->returnType";
154
        }
155
156
        $docBlock = '';
157
        if ($withDocBlock) {
158
            $docBlock = $this->buildDocBlock();
159
        }
160
161
        return "{$docBlock}{$modifier}{$isStatic}{$this->qualifier}{$this->name}($args){$uses}{$returnType}";
162
    }
163
164
    public function removeBindVars()
165
    {
166
        $this->uses = [];
167
    }
168
}
169