Completed
Push — master ( 50a702...21c34e )
by Дмитрий
02:56
created

FunctionCall::parseArgs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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