Completed
Pull Request — master (#119)
by T
03:06
created

ClassMethod::isAbstract()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
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
15
class ClassMethod extends AbstractDefinition
16
{
17
    protected $type;
18
19
    /**
20
     * @var Node\Stmt\ClassMethod
21
     */
22
    protected $statement;
23
24
    /**
25
     * Return type
26
     *
27
     * @var int
28
     */
29
    protected $returnType = CompiledExpression::VOID;
30
31
    /**
32
     * Array of possible return values
33
     *
34
     * @var array
35
     */
36
    protected $possibleReturnValues = array();
37
38
    /**
39
     * @param string $name
40
     * @param Node\Stmt\ClassMethod $statement
41
     * @param integer $type
42
     */
43 17
    public function __construct($name, Node\Stmt\ClassMethod $statement, $type)
44 1
    {
45 17
        $this->name = $name;
46 17
        $this->statement = $statement;
47 17
        $this->type = $type;
48 17
    }
49
50
    /**
51
     * @param Context $context
52
     * @return boolean|null
53
     */
54 16
    public function compile(Context $context)
55
    {
56 16
        $context->getEventManager()->fire(
57 16
            Event\StatementBeforeCompile::EVENT_NAME,
58 16
            new Event\StatementBeforeCompile(
59 16
                $this->statement,
60
                $context
61 16
            )
62 16
        );
63
64 16
        $this->compiled = true;
65 16
        $context->scopePointer = $this->getPointer();
66
67 16
        if ($this->statement->getDocComment() === null) {
68 4
            $context->notice(
69 4
                'missing-docblock',
70 4
                sprintf('Missing docblock for %s() method', $this->name),
71 4
                $this->statement
72 4
            );
73 4
        }
74
75
        /**
76
         * It's not needed to compile empty method via it's abstract
77
         */
78 16
        if ($this->isAbstract()) {
79
            /** @var ClassDefinition $scope */
80
            $scope = $context->scope;
81
            if (!$scope->isAbstract()) {
82
                $context->notice(
83
                    'not-abstract-class-with-abstract-method',
84
                    'Class must be an abstract',
85
                    $this->statement
86
                );
87
            }
88
89
            return true;
90
        }
91
92 16
        if (count($this->statement->stmts) == 0) {
93 1
            return $context->notice(
94 1
                'not-implemented-method',
95 1
                sprintf('Method %s() is not implemented', $this->name),
96 1
                $this->statement
97 1
            );
98
        }
99
100 16
        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...
101 2
            foreach ($this->statement->params as $parameter) {
102 2
                $type = CompiledExpression::UNKNOWN;
103
104 2
                if ($parameter->type) {
105
                    if (is_string($parameter->type)) {
106
                        $type = Types::getType($parameter->type);
107
                    } elseif ($parameter->type instanceof Node\Name\FullyQualified) {
108
                        $type = CompiledExpression::OBJECT;
109
                    }
110
                }
111
112 2
                $context->addVariable(
113 2
                    new Parameter($parameter->name, null, $type, $parameter->byRef)
114 2
                );
115 2
            }
116 2
        }
117
118 16
        foreach ($this->statement->stmts as $st) {
119 16
            \PHPSA\nodeVisitorFactory($st, $context);
120 16
        }
121 16
    }
122
123
    /**
124
     * @param Context $context
125
     * @param CompiledExpression[] $args
126
     * @return CompiledExpression
127
     * @throws \PHPSA\Exception\RuntimeException
128
     */
129
    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...
130
    {
131
        return new CompiledExpression();
132
    }
133
134
    /**
135
     * @return bool
136
     */
137 16
    public function isAbstract()
138
    {
139 16
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_ABSTRACT);
140
    }
141
142
    /**
143
     * @return bool
144
     */
145 16
    public function isStatic()
146
    {
147 16
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_STATIC);
148
    }
149
150
    /**
151
     * @return bool
152
     */
153
    public function isPublic()
154
    {
155
        return ($this->type & Node\Stmt\Class_::MODIFIER_PUBLIC) !== 0 || $this->type === 0;
156
    }
157
158
    /**
159
     * @return bool
160
     */
161
    public function isProtected()
162
    {
163
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PROTECTED);
164
    }
165
166
    /**
167
     * @return bool
168
     */
169
    public function isPrivate()
170
    {
171
        return (bool) ($this->type & Node\Stmt\Class_::MODIFIER_PRIVATE);
172
    }
173
174
    /**
175
     * @param integer $newType
176
     */
177 14
    public function addNewType($newType)
178
    {
179 14
        if ($this->returnType != CompiledExpression::VOID) {
180 1
            $this->returnType = $this->returnType | $newType;
181 1
        } else {
182 14
            $this->returnType = $newType;
183
        }
184 14
    }
185
186
    /**
187
     * @return int
188
     */
189
    public function getReturnType()
190
    {
191
        return $this->returnType;
192
    }
193
194
    /**
195
     * @param $value
196
     */
197 14
    public function addReturnPossibleValue($value)
198
    {
199 14
        $this->possibleReturnValues[] = $value;
200 14
    }
201
202
    /**
203
     * @return array
204
     */
205
    public function getPossibleReturnValues()
206
    {
207
        return $this->possibleReturnValues;
208
    }
209
210
    /**
211
    * @return array
212
    */
213 1
    public function getParams()
214
    {
215 1
        return $this->statement->params;
216
    }
217
}
218