Completed
Push — master ( 28368b...f9f779 )
by Дмитрий
05:23 queued 02:40
created

FunctionCall::compile()   F

Complexity

Conditions 43
Paths 579

Size

Total Lines 210
Code Lines 142

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 1462.6999

Importance

Changes 7
Bugs 0 Features 0
Metric Value
cc 43
eloc 142
c 7
b 0
f 0
nc 579
nop 2
dl 0
loc 210
ccs 14
cts 166
cp 0.0843
crap 1462.6999
rs 2.1995

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