Completed
Push — master ( 85b5ae...49cec2 )
by Дмитрий
02:50
created

FunctionCall::compile()   F

Complexity

Conditions 40
Paths 289

Size

Total Lines 201
Code Lines 137

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 55
CRAP Score 492.0939

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 40
eloc 137
c 5
b 0
f 0
nc 289
nop 2
dl 0
loc 201
ccs 55
cts 160
cp 0.3438
crap 492.0939
rs 3.3333

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
 * PHP Smart Analysis project 2015-2016
4
 *
5
 * @author Patsura Dmitry https://github.com/ovr <[email protected]>
6
 */
7
8
namespace PHPSA\Compiler\Expression;
9
10
use Ovr\PHPReflection\Reflector;
11
use PHPSA\CompiledExpression;
12
use PHPSA\Context;
13
use PHPSA\Compiler\Expression;
14
15
class FunctionCall extends AbstractExpressionCompiler
16
{
17
    protected $name = 'PhpParser\Node\Expr\FuncCall';
18
19
    /**
20
     * @param \PhpParser\Node\Expr\FuncCall $expr
21
     * @param Context $context
22
     * @return CompiledExpression
23
     */
24 6
    protected function compile($expr, Context $context)
0 ignored issues
show
Complexity introduced by
This operation has 43488 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
25
    {
26 6
        $expressionCompiler = $context->getExpressionCompiler();
27 6
        $fNameExpression = $expressionCompiler->compile($expr->name);
28
29 6
        if ($fNameExpression->isString() && $fNameExpression->isCorrectValue()) {
30 6
            $name = $fNameExpression->getValue();
31 6
        } else {
32
            $context->debug(
33
                'Unexpected function name type ' . $fNameExpression->getTypeName(),
34
                $expr->name
35
            );
36
37
            return new CompiledExpression;
38
        }
39
40 6
        $compiler = $context->application->compiler;
41
42 6
        $exists = false;
43 6
        $namespace = null;
44
45 6
        if ($context->scope) {
46 6
            $namespace = $context->scope->getNamespace();
47 6
        }
48
49 6
        if ($namespace === null) {
50
            $functionDefinition = $compiler->getFunction($name);
51
        } else {
52 6
            $functionDefinition = $compiler->getFunctionNS($name, $namespace);
53
        }
54
55 6
        if (!$functionDefinition) {
56 6
            $exists = function_exists($name);
57 6
        }
58
59 6
        if ($functionDefinition) {
60
            if (!$functionDefinition->isCompiled()) {
61
                $functionDefinition->compile(clone $context);
62
            }
63
64
            $exists = true;
65
        }
66
67 6
        $arguments = $this->parseArgs($expr, clone $context);
68
69 6
        if (!$functionDefinition) {
70 6
            $reflector = new Reflector(Reflector::manuallyFactory());
71 6
            $functionReflection = $reflector->getFunction($name);
72 6
            if ($functionReflection) {
73 3
                $argumentsSuccessPass = true;
74
75 3
                if (count($arguments) > 0) {
76 3
                    foreach ($arguments as $key => $argument) {
77 3
                        $parameter = $functionReflection->getParameter($key);
78 3
                        if (!$parameter) {
79
                            /**
80
                             * @todo Think a little bit more about it
81
                             */
82
                            continue;
83
                        }
84
85 3
                        switch ($parameter->getType()) {
86 3
                            case CompiledExpression::MIXED:
87
                                //continue
88 2
                                break;
89 1
                            case CompiledExpression::INTEGER:
90 1
                                switch ($argument->getType()) {
91 1
                                    case CompiledExpression::INTEGER:
92 1
                                        break;
93
                                    default:
94
                                        $argumentsSuccessPass = false;
95
                                        break;
96 1
                                }
97 1
                                break;
98
                            case CompiledExpression::DOUBLE:
99
                                switch ($argument->getType()) {
100
                                    case CompiledExpression::DOUBLE:
101
                                        break;
102
                                    default:
103
                                        $argumentsSuccessPass = false;
104
                                        break;
105
                                }
106
                                break;
107
                            case CompiledExpression::NUMBER:
108
                                switch ($argument->getType()) {
109
                                    case CompiledExpression::INTEGER:
110
                                    case CompiledExpression::STRING:
111
                                    case CompiledExpression::NUMBER:
112
                                        break;
113
                                    default:
114
                                        $argumentsSuccessPass = false;
115
                                        break;
116
                                }
117
                                break;
118
                            case CompiledExpression::RESOURCE:
119
                                switch ($argument->getType()) {
120
                                    case CompiledExpression::RESOURCE:
121
                                        break;
122
                                    default:
123
                                        $argumentsSuccessPass = false;
124
                                        break;
125
                                }
126
                                break;
127
                            case CompiledExpression::ARR:
128
                                switch ($argument->getType()) {
129
                                    case CompiledExpression::ARR:
130
                                        break;
131
                                    default:
132
                                        $argumentsSuccessPass = false;
133
                                        break;
134
                                }
135
                                break;
136
                            case CompiledExpression::STRING:
137
                                switch ($argument->getType()) {
138
                                    case CompiledExpression::STRING:
139
                                        break;
140
                                    default:
141
                                        $argumentsSuccessPass = false;
142
                                        break;
143
                                }
144
                                break;
145
                            case CompiledExpression::OBJECT:
146
                                switch ($argument->getType()) {
147
                                    case CompiledExpression::OBJECT:
148
                                        break;
149
                                    default:
150
                                        $argumentsSuccessPass = false;
151
                                        break;
152
                                }
153
                                break;
154
                            case CompiledExpression::BOOLEAN:
155
                                switch ($argument->getType()) {
156
                                    case CompiledExpression::OBJECT:
157
                                        break;
158
                                    default:
159
                                        $argumentsSuccessPass = false;
160
                                        break;
161
                                }
162
                                break;
163
                            case CompiledExpression::CALLABLE_TYPE:
164
                                switch ($argument->getType()) {
165
                                    case CompiledExpression::CALLABLE_TYPE:
166
                                        break;
167
                                    case CompiledExpression::STRING:
168
                                        /**
169
                                         * @todo We need additional check on it
170
                                         */
171
                                        break;
172
                                    /**
173
                                     * array($this, 'method')
174
                                     */
175
                                    case CompiledExpression::ARR:
176
                                        /**
177
                                         * @todo We need additional check on it
178
                                         */
179
                                        break;
180
                                    default:
181
                                        $argumentsSuccessPass = false;
182
                                        break;
183
                                }
184
                                break;
185
                            default:
186
                                $argumentsSuccessPass = false;
187
                                break;
188 3
                        }
189 3
                    }
190 3
                }
191
192 3
                if (count($arguments) < $functionReflection->getNumberOfRequiredParameters()) {
193
                    $argumentsSuccessPass = false;
194
                }
195
196 3
                if ($argumentsSuccessPass && $functionReflection->isRunnable()) {
197 3
                    array_walk(
198 3
                        $arguments,
199 3
                        function (&$item) {
200
                            /** @var CompiledExpression $item */
201 3
                            $item = $item->getValue();
202 3
                        }
203 3
                    );
204
205 3
                    return new CompiledExpression(
206 3
                        $functionReflection->getReturnType(),
207 3
                        $functionReflection->run($arguments)
208 3
                    );
209
                }
210
211
                return new CompiledExpression($functionReflection->getReturnType());
212
            }
213 5
        }
214
215 5
        if (!$exists) {
216
            $context->notice(
217
                'undefined-fcall',
218
                sprintf('Function %s() does not exist', $expr->name->parts[0]),
219
                $expr
220
            );
221
        }
222
223 5
        return new CompiledExpression();
224
    }
225
226
    /**
227
     * @param \PhpParser\Node\Expr\FuncCall $expr
228
     * @return CompiledExpression[]
229
     */
230 6
    protected function parseArgs($expr, Context $context)
231
    {
232 6
        $arguments = array();
233
234 6
        foreach ($expr->args as $argument) {
235 5
            $arguments[] = $context->getExpressionCompiler()->compile($argument->value);
236 6
        }
237
238 6
        return $arguments;
239
    }
240
}
241