Completed
Pull Request — master (#124)
by Enrico
03:44
created

ClassMethod::compile()   C

Complexity

Conditions 11
Paths 14

Size

Total Lines 68
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 14.078

Importance

Changes 0
Metric Value
cc 11
eloc 38
c 0
b 0
f 0
nc 14
nop 1
dl 0
loc 68
ccs 36
cts 51
cp 0.7059
crap 14.078
rs 5.8371

How to fix   Long Method    Complexity   

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