Completed
Pull Request — master (#354)
by Strahinja
05:29 queued 01:12
created

ClassMethod::isPublic()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 6
rs 10
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 53
    public function __construct($name, Node\Stmt\ClassMethod $statement, $type)
58
    {
59 53
        $this->name = $name;
60 53
        $this->statement = $statement;
61 53
        $this->type = $type;
62
63
        // @todo Better support...
64 53
        $returnType = $statement->getReturnType();
65 53
        if ($returnType == 'void') {
66 1
            $this->returnType = CompiledExpression::VOID;
67
        }
68 53
    }
69
70
    /**
71
     * @param Context $context
72
     * @return boolean|null
73
     */
74 52
    public function compile(Context $context)
75
    {
76 52
        $context->getEventManager()->fire(
77 52
            Event\StatementBeforeCompile::EVENT_NAME,
78 52
            new Event\StatementBeforeCompile(
79 52
                $this->statement,
80 52
                $context
81
            )
82
        );
83
84 52
        $this->compiled = true;
85 52
        $context->scopePointer = $this->getPointer();
86
87
        /**
88
         * It's not needed to compile empty method via it's abstract
89
         */
90 52
        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 52
        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
                );
119
            }
120
        }
121
122 52
        foreach ($this->statement->stmts as $st) {
0 ignored issues
show
Bug introduced by
The expression $this->statement->stmts of type array<integer,object<PhpParser\Node>>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
123 51
            \PHPSA\nodeVisitorFactory($st, $context);
124
        }
125
126 52
        $this->cfg = new ControlFlowGraph(
127 52
            $this->statement,
128 52
            $context
129
        );
130 52
    }
131
132
    /**
133
     * @param Context $context
134
     * @param CompiledExpression[] $args
135
     * @return CompiledExpression
136
     * @throws \PHPSA\Exception\RuntimeException
137
     */
138 2
    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 2
        return new CompiledExpression();
141
    }
142
143
    /**
144
     * @return bool
145
     */
146 52
    public function isAbstract()
147
    {
148 52
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_ABSTRACT);
149
    }
150
151
    /**
152
     * @return bool
153
     */
154 52
    public function isStatic()
155
    {
156 52
        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 37
    public function addNewType($newType)
187
    {
188 37
        if ($this->returnType != CompiledExpression::VOID) {
189 37
            $this->returnType = $this->returnType | $newType;
190
        } else {
191 1
            $this->returnType = $newType;
192
        }
193 37
    }
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 37
    public function addReturnPossibleValue($value)
207
    {
208 37
        $this->possibleReturnValues[] = $value;
209 37
    }
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