Completed
Push — master ( f3a461...296f07 )
by Дмитрий
09:44
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
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 2
eloc 2
nc 2
nop 0
crap 6
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\Expression;
11
use PHPSA\Compiler\Parameter;
12
use PHPSA\Compiler\Types;
13
use PHPSA\Context;
14
use PHPSA\ScopePointer;
15
use PHPSA\Variable;
16
17
class ClassMethod extends AbstractDefinition
18
{
19
    protected $type;
20
21
    /**
22
     * @var Node\Stmt\ClassMethod
23
     */
24
    protected $statement;
25
26
    /**
27
     * Return type
28
     *
29
     * @var int
30
     */
31
    protected $returnType = CompiledExpression::VOID;
32
33
    /**
34
     * Array of possible return values
35
     *
36
     * @var array
37
     */
38
    protected $possibleReturnValues = array();
39
40
    /**
41
     * @param $name
42
     * @param Node\Stmt\ClassMethod $statement
43
     * @param $type
44
     */
45 1
    public function __construct($name, Node\Stmt\ClassMethod $statement, $type)
46
    {
47 1
        $this->name = $name;
48 1
        $this->statement = $statement;
49 1
        $this->type = $type;
50 1
    }
51
52
    /**
53
     * @param Context $context
54
     * @return boolean|null
55
     */
56
    public function compile(Context $context)
57
    {
58
        $this->compiled = true;
59
        $context->scopePointer = $this->getPointer();
60
61
        if ($this->statement->getDocComment() === null) {
62
            $context->notice(
63
                'missing-docblock',
64
                sprintf('Missing docblock for %s() method', $this->name),
65
                $this->statement
66
            );
67
        }
68
69
        /**
70
         * It's not needed to compile empty method via it's abstract
71
         */
72
        if ($this->isAbstract()) {
73
            /** @var ClassDefinition $scope */
74
            $scope = $context->scope;
75
            if (!$scope->isAbstract()) {
76
                $context->notice(
77
                    'not-abstract-class-with-abstract-method',
78
                    'Class must be an abstract',
79
                    $this->statement
80
                );
81
            }
82
83
            return true;
84
        }
85
86
        if (count($this->statement->stmts) == 0) {
87
            return $context->notice(
88
                'not-implemented-method',
89
                sprintf('Method %s() is not implemented', $this->name),
90
                $this->statement
91
            );
92
        }
93
94
        if (count($this->statement->params) > 0) {
95
            /** @var  Node\Param $parameter */
96
            foreach ($this->statement->params as $parameter) {
97
                $type = CompiledExpression::UNKNOWN;
98
99
                if ($parameter->type) {
100
                    if (is_string($parameter->type)) {
101
                        $type = Types::getType($parameter->type);
102
                    }
103
                }
104
105
                $context->addVariable(
106
                    new Parameter($parameter->name, $type, null, $parameter->byRef)
107
                );
108
            }
109
        }
110
111
        foreach ($this->statement->stmts as $st) {
112
            \PHPSA\nodeVisitorFactory($st, $context);
113
        }
114
    }
115
116
    public function run(array $args = null, Context $context)
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
117
    {
118
        if ($args) {
119
            foreach ($args as $argument) {
120
                $expression = new Expression($context);
121
                $arguments[] = $expression->compile($argument->value);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arguments was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arguments = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
122
            }
123
        }
124
    }
125
126
    /**
127
     * @return bool
128
     */
129
    public function isAbstract()
130
    {
131
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_ABSTRACT);
132
    }
133
134
    /**
135
     * @return bool
136
     */
137
    public function isStatic()
138
    {
139
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_STATIC);
140
    }
141
142
    /**
143
     * @return bool
144
     */
145
    public function isPublic()
146
    {
147
        return ($this->type & Node\Stmt\Class_::MODIFIER_PUBLIC) !== 0 || $this->type === 0;
148
    }
149
150
    /**
151
     * @return bool
152
     */
153
    public function isProtected()
154
    {
155
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PROTECTED);
156
    }
157
158
    /**
159
     * @return bool
160
     */
161
    public function isPrivate()
162
    {
163
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PRIVATE);
164
    }
165
166
    /**
167
     * @param $newType
168
     */
169
    public function addNewType($newType)
170
    {
171
        if ($this->returnType != CompiledExpression::VOID) {
172
            $this->returnType = $this->returnType | $newType;
173
        } else {
174
            $this->returnType = $newType;
175
        }
176
    }
177
178
    /**
179
     * @return int
180
     */
181
    public function getReturnType()
182
    {
183
        return $this->returnType;
184
    }
185
186
    /**
187
     * @param $value
188
     */
189
    public function addReturnPossibleValue($value)
190
    {
191
        $this->possibleReturnValues[] = $value;
192
    }
193
194
    /**
195
     * @return array
196
     */
197
    public function getPossibleReturnValues()
198
    {
199
        return $this->possibleReturnValues;
200
    }
201
}
202