Completed
Push — master ( 2cf8eb...09dcac )
by Дмитрий
04:07
created

ClassMethod::compile()   B

Complexity

Conditions 9
Paths 6

Size

Total Lines 57
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 11.0312

Importance

Changes 0
Metric Value
cc 9
eloc 31
nc 6
nop 1
dl 0
loc 57
ccs 29
cts 41
cp 0.7073
crap 11.0312
rs 7.0745
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 50
    public function __construct($name, Node\Stmt\ClassMethod $statement, $type)
58
    {
59 50
        $this->name = $name;
60 50
        $this->statement = $statement;
61 50
        $this->type = $type;
62
63
        // @todo Better support...
64 50
        $returnType = $statement->getReturnType();
65 50
        if ($returnType == 'void') {
66 1
            $this->returnType = CompiledExpression::VOID;
67 1
        }
68 50
    }
69
70
    /**
71
     * @param Context $context
72
     * @return boolean|null
73
     */
74 49
    public function compile(Context $context)
75
    {
76 49
        $context->getEventManager()->fire(
77 49
            Event\StatementBeforeCompile::EVENT_NAME,
78 49
            new Event\StatementBeforeCompile(
79 49
                $this->statement,
80
                $context
81 49
            )
82 49
        );
83
84 49
        $this->compiled = true;
85 49
        $context->scopePointer = $this->getPointer();
86
87
        /**
88
         * It's not needed to compile empty method via it's abstract
89
         */
90 49
        if ($this->isAbstract()) {
91
            /** @var ClassDefinition $scope */
92 1
            $scope = $context->scope;
93 1
            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 1
            return true;
102
        }
103
104 49
        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 6
            foreach ($this->statement->params as $parameter) {
106 6
                $type = CompiledExpression::UNKNOWN;
107
108 6
                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 6
                $context->addVariable(
117 6
                    new Parameter($parameter->name, null, $type, $parameter->byRef)
118 6
                );
119 6
            }
120 6
        }
121
122 49
        foreach ($this->statement->stmts as $st) {
123 48
            \PHPSA\nodeVisitorFactory($st, $context);
124 49
        }
125
126 49
        $this->cfg = new ControlFlowGraph(
127 49
            $this->statement,
128
            $context
129 49
        );
130 49
    }
131
132
    /**
133
     * @param Context $context
134
     * @param CompiledExpression[] $args
135
     * @return CompiledExpression
136
     * @throws \PHPSA\Exception\RuntimeException
137
     */
138
    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...
139
    {
140
        return new CompiledExpression();
141
    }
142
143
    /**
144
     * @return bool
145
     */
146 49
    public function isAbstract()
147
    {
148 49
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_ABSTRACT);
149
    }
150
151
    /**
152
     * @return bool
153
     */
154 49
    public function isStatic()
155
    {
156 49
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_STATIC);
157
    }
158
159
    /**
160
     * @return bool
161
     */
162
    public function isPublic()
163
    {
164
        return ($this->type & Node\Stmt\Class_::MODIFIER_PUBLIC) !== 0 || $this->type === 0;
165
    }
166
167
    /**
168
     * @return bool
169
     */
170
    public function isProtected()
171
    {
172
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PROTECTED);
173
    }
174
175
    /**
176
     * @return bool
177
     */
178
    public function isPrivate()
179
    {
180
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PRIVATE);
181
    }
182
183
    /**
184
     * @param integer $newType
185
     */
186 35
    public function addNewType($newType)
187
    {
188 35
        if ($this->returnType != CompiledExpression::VOID) {
189 35
            $this->returnType = $this->returnType | $newType;
190 35
        } else {
191 1
            $this->returnType = $newType;
192
        }
193 35
    }
194
195
    /**
196
     * @return int
197
     */
198 1
    public function getReturnType()
199
    {
200 1
        return $this->returnType;
201
    }
202
203
    /**
204
     * @param $value
205
     */
206 35
    public function addReturnPossibleValue($value)
207
    {
208 35
        $this->possibleReturnValues[] = $value;
209 35
    }
210
211
    /**
212
     * @return array
213
     */
214
    public function getPossibleReturnValues()
215
    {
216
        return $this->possibleReturnValues;
217
    }
218
219
    /**
220
    * @return Node\Param[]
221
    */
222 1
    public function getParams()
223
    {
224 1
        return $this->statement->params;
225
    }
226
227
    /**
228
     * @return int
229
     */
230
    public function getModifier()
231
    {
232
        return $this->type;
233
    }
234
235
    /**
236
     * @param int $type
237
     */
238
    public function setModifier($type)
239
    {
240
        $this->type = $type;
241
    }
242
243
    /**
244
     * @return \PHPSA\ControlFlow\ControlFlowGraph
245
     */
246
    public function getCFG()
247
    {
248
        return $this->cfg;
249
    }
250
}
251