Completed
Pull Request — master (#335)
by Дмитрий
02:26
created

ClassMethod::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0438

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 3
dl 0
loc 12
ccs 7
cts 9
cp 0.7778
crap 2.0438
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Patsura Dmitry https://github.com/ovr <[email protected]>
4
 */
5
6
namespace PHPSA\Definition;
7
8
use PhpParser\Node;
9
use PHPSA\CompiledExpression;
10
use PHPSA\Compiler\Parameter;
11
use PHPSA\Compiler\Types;
12
use PHPSA\Compiler\Event;
13
use PHPSA\Context;
14
use PHPSA\ControlFlow\ControlFlowGraph;
15
16
/**
17
 * Class Method Definition
18
 */
19
class ClassMethod extends AbstractDefinition
20
{
21
    /**
22
     * Contains a number representing all modifiers (public, static, ...)
23
     *
24
     * @var int
25
     */
26
    protected $type;
27
28
    /**
29
     * @var Node\Stmt\ClassMethod
30
     */
31
    protected $statement;
32
33
    /**
34
     * @var \PHPSA\ControlFlow\ControlFlowGraph
35
     */
36
    protected $cfg;
37
38
    /**
39
     * Return type
40
     *
41
     * @var int
42
     */
43
    protected $returnType = CompiledExpression::UNKNOWN;
44
45
    /**
46
     * Array of possible return values
47
     *
48
     * @var array
49
     */
50
    protected $possibleReturnValues = [];
51
52
    /**
53
     * @param string $name
54
     * @param Node\Stmt\ClassMethod $statement
55
     * @param integer $type
56
     */
57 1
    public function __construct($name, Node\Stmt\ClassMethod $statement, $type)
58
    {
59 1
        $this->name = $name;
60 1
        $this->statement = $statement;
61 1
        $this->type = $type;
62
63
        // @todo Better support...
64 1
        $returnType = $statement->getReturnType();
65 1
        if ($returnType == 'void') {
66
            $this->returnType = CompiledExpression::VOID;
67
        }
68 1
    }
69
70
    /**
71
     * @param Context $context
72
     * @return boolean|null
73
     */
74 1
    public function compile(Context $context)
75
    {
76 1
        $context->getEventManager()->fire(
77 1
            Event\StatementBeforeCompile::EVENT_NAME,
78 1
            new Event\StatementBeforeCompile(
79 1
                $this->statement,
80
                $context
81 1
            )
82 1
        );
83
84 1
        $this->compiled = true;
85 1
        $context->scopePointer = $this->getPointer();
86
87
        /**
88
         * It's not needed to compile empty method via it's abstract
89
         */
90 1
        if ($this->isAbstract()) {
91
            /** @var ClassDefinition $scope */
92
            $scope = $context->scope;
93
            if (!$scope->isAbstract()) {
94
                $context->notice(
95
                    'not-abstract-class-with-abstract-method',
96
                    'Class must be abstract',
97
                    $this->statement
98
                );
99
            }
100
101
            return true;
102
        }
103
104 1
        if ($this->statement->params) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->statement->params of type PhpParser\Node\Param[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
105
            foreach ($this->statement->params as $parameter) {
106
                $type = CompiledExpression::UNKNOWN;
107
108
                if ($parameter->type) {
109
                    if (is_string($parameter->type)) {
110
                        $type = Types::getType($parameter->type);
111
                    } elseif ($parameter->type instanceof Node\Name) {
112
                        $type = CompiledExpression::OBJECT;
113
                    }
114
                }
115
116
                $context->addVariable(
117
                    new Parameter($parameter->name, null, $type, $parameter->byRef)
118
                );
119
            }
120
        }
121
122
//      Disabled because We stop compiling all code, only what we need
123
//        foreach ($this->statement->stmts as $st) {
124
//            \PHPSA\nodeVisitorFactory($st, $context);
125
//        }
126
127 1
        $this->cfg = new ControlFlowGraph(
128 1
            $this->statement,
129
            $context
130 1
        );
131 1
    }
132
133
    /**
134
     * @param Context $context
135
     * @param CompiledExpression[] $args
136
     * @return CompiledExpression
137
     * @throws \PHPSA\Exception\RuntimeException
138
     */
139
    public function run(Context $context, array $args = null)
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
140
    {
141
        return new CompiledExpression();
142
    }
143
144
    /**
145
     * @return bool
146
     */
147 1
    public function isAbstract()
148
    {
149 1
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_ABSTRACT);
150
    }
151
152
    /**
153
     * @return bool
154
     */
155 1
    public function isStatic()
156
    {
157 1
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_STATIC);
158
    }
159
160
    /**
161
     * @return bool
162
     */
163
    public function isPublic()
164
    {
165
        return ($this->type & Node\Stmt\Class_::MODIFIER_PUBLIC) !== 0 || $this->type === 0;
166
    }
167
168
    /**
169
     * @return bool
170
     */
171
    public function isProtected()
172
    {
173
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PROTECTED);
174
    }
175
176
    /**
177
     * @return bool
178
     */
179
    public function isPrivate()
180
    {
181
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PRIVATE);
182
    }
183
184
    /**
185
     * @param integer $newType
186
     */
187
    public function addNewType($newType)
188
    {
189
        if ($this->returnType != CompiledExpression::VOID) {
190
            $this->returnType = $this->returnType | $newType;
191
        } else {
192
            $this->returnType = $newType;
193
        }
194
    }
195
196
    /**
197
     * @return int
198
     */
199
    public function getReturnType()
200
    {
201
        return $this->returnType;
202
    }
203
204
    /**
205
     * @param $value
206
     */
207
    public function addReturnPossibleValue($value)
208
    {
209
        $this->possibleReturnValues[] = $value;
210
    }
211
212
    /**
213
     * @return array
214
     */
215
    public function getPossibleReturnValues()
216
    {
217
        return $this->possibleReturnValues;
218
    }
219
220
    /**
221
    * @return Node\Param[]
222
    */
223
    public function getParams()
224
    {
225
        return $this->statement->params;
226
    }
227
228
    /**
229
     * @return int
230
     */
231
    public function getModifier()
232
    {
233
        return $this->type;
234
    }
235
236
    /**
237
     * @param int $type
238
     */
239
    public function setModifier($type)
240
    {
241
        $this->type = $type;
242
    }
243
244
    /**
245
     * @return \PHPSA\ControlFlow\ControlFlowGraph
246
     */
247
    public function getCFG()
248
    {
249
        return $this->cfg;
250
    }
251
}
252