Completed
Push — master ( cfa785...3f4fca )
by Дмитрий
02:53
created

FunctionCall::compile()   F

Complexity

Conditions 38
Paths 289

Size

Total Lines 192
Code Lines 129

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 55
CRAP Score 409.1323

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 38
eloc 129
c 4
b 0
f 0
nc 289
nop 2
dl 0
loc 192
ccs 55
cts 151
cp 0.3642
crap 409.1323
rs 3.3583

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 5
    protected function compile($expr, Context $context)
0 ignored issues
show
Complexity introduced by
This operation has 40032 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 5
        $expressionCompiler = $context->getExpressionCompiler();
27 5
        $fNameExpression = $expressionCompiler->compile($expr->name);
28
29 5
        if ($fNameExpression->isString() && $fNameExpression->isCorrectValue()) {
30 5
            $name = $fNameExpression->getValue();
31 5
        } else {
32
            $context->debug(
33
                'Unexpected function name type ' . $fNameExpression->getTypeName(),
34
                $expr->name
35
            );
36
37
            return new CompiledExpression;
38
        }
39
40 5
        $compiler = $context->application->compiler;
41
42 5
        $exists = false;
43 5
        $namespace = null;
44
45 5
        if ($context->scope) {
46 5
            $namespace = $context->scope->getNamespace();
47 5
        }
48
49 5
        if ($namespace === null) {
50
            $functionDefinition = $compiler->getFunction($name);
51
        } else {
52 5
            $functionDefinition = $compiler->getFunctionNS($name, $namespace);
53
        }
54
55 5
        if (!$functionDefinition) {
56 5
            $exists = function_exists($name);
57 5
        }
58
59 5
        if ($functionDefinition) {
60
            if (!$functionDefinition->isCompiled()) {
61
                $functionDefinition->compile(clone $context);
62
            }
63
64
            $exists = true;
65
        }
66
67 5
        $arguments = $this->parseArgs($expr, clone $context);
68
69 5
        if (!$functionDefinition) {
70 5
            $reflector = new Reflector(Reflector::manuallyFactory());
71 5
            $functionReflection = $reflector->getFunction($name);
72 5
            if ($functionReflection) {
73 2
                $argumentsSuccessPass = true;
74
75 2
                if (count($arguments) > 0) {
76 2
                    foreach ($arguments as $key => $argument) {
77 2
                        $parameter = $functionReflection->getParameter($key);
78 2
                        if (!$parameter) {
79
                            /**
80
                             * @todo Think a little bit more about it
81
                             */
82
                            continue;
83
                        }
84
85 2
                        switch ($parameter->getType()) {
86 2
                            case CompiledExpression::MIXED:
87
                                //continue
88 1
                                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::CALLABLE_TYPE:
155
                                switch ($argument->getType()) {
156
                                    case CompiledExpression::CALLABLE_TYPE:
157
                                        break;
158
                                    case CompiledExpression::STRING:
159
                                        /**
160
                                         * @todo We need additional check on it
161
                                         */
162
                                        break;
163
                                    /**
164
                                     * array($this, 'method')
165
                                     */
166
                                    case CompiledExpression::ARR:
167
                                        /**
168
                                         * @todo We need additional check on it
169
                                         */
170
                                        break;
171
                                    default:
172
                                        $argumentsSuccessPass = false;
173
                                        break;
174
                                }
175
                                break;
176
                            default:
177
                                $argumentsSuccessPass = false;
178
                                break;
179 2
                        }
180 2
                    }
181 2
                }
182
183 2
                if (count($arguments) < $functionReflection->getNumberOfRequiredParameters()) {
184
                    $argumentsSuccessPass = false;
185
                }
186
187 2
                if ($argumentsSuccessPass && $functionReflection->isRunnable()) {
188 2
                    array_walk(
189 2
                        $arguments,
190 2
                        function (&$item) {
191
                            /** @var CompiledExpression $item */
192 2
                            $item = $item->getValue();
193 2
                        }
194 2
                    );
195
196 2
                    return new CompiledExpression(
197 2
                        $functionReflection->getReturnType(),
198 2
                        $functionReflection->run($arguments)
199 2
                    );
200
                }
201
202
                return new CompiledExpression($functionReflection->getReturnType());
203
            }
204 4
        }
205
206 4
        if (!$exists) {
207
            $context->notice(
208
                'undefined-fcall',
209
                sprintf('Function %s() does not exist', $expr->name->parts[0]),
210
                $expr
211
            );
212
        }
213
214 4
        return new CompiledExpression();
215
    }
216
217
    /**
218
     * @param \PhpParser\Node\Expr\FuncCall $expr
219
     * @return CompiledExpression[]
220
     */
221 5
    protected function parseArgs($expr, Context $context)
222
    {
223 5
        $arguments = array();
224
225 5
        foreach ($expr->args as $argument) {
226 5
            $arguments[] = $context->getExpressionCompiler()->compile($argument->value);
227 5
        }
228
229 5
        return $arguments;
230
    }
231
}
232