MethodCall::parseArgs()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 2
nop 2
dl 0
loc 12
ccs 0
cts 6
cp 0
crap 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Patsura Dmitry https://github.com/ovr <[email protected]>
4
 */
5
6
namespace PHPSA\Compiler\Expression;
7
8
use PHPSA\Check;
9
use PHPSA\CompiledExpression;
10
use PHPSA\Context;
11
use PHPSA\Definition\ClassDefinition;
12
13
class MethodCall extends AbstractExpressionCompiler
14
{
15
    protected $name = 'PhpParser\Node\Expr\MethodCall';
16
17
    /**
18
     * @param \PhpParser\Node\Expr\MethodCall $expr
19
     * @param Context $context
20
     * @return CompiledExpression
21
     */
22
    protected function compile($expr, Context $context)
23
    {
24
        $expressionCompiler = $context->getExpressionCompiler();
25
        $methodNameCE = $expressionCompiler->compile($expr->name);
26
27
        $compiledArguments = $this->parseArgs($expr->args, $context);
28
29
        $leftCE = $expressionCompiler->compile($expr->var);
30
        if ($leftCE->canBeObject()) {
31
            /** @var ClassDefinition $calledObject */
32
            $calledObject = $leftCE->getValue();
33
            if ($calledObject instanceof ClassDefinition) {
34
                $methodName = $methodNameCE->isString() ? $methodNameCE->getValue() : false;
35
                if ($methodName) {
36
                    if (!$calledObject->hasMethod($methodName, true)) {
37
                        $context->notice(
38
                            'language_error',
39
                            sprintf('Method %s() does not exist in %s scope', $methodName, $calledObject->getName()),
40
                            $expr
41
                        );
42
43
                        //it's needed to exit
44
                        return new CompiledExpression();
45
                    }
46
47
                    $method = $calledObject->getMethod($methodName, true);
48
                    if (!$method) {
49
                        $context->debug('getMethod is not working', $expr);
50
                        return new CompiledExpression();
51
                    }
52
53
                    if ($method->isStatic()) {
54
                        $context->notice(
55
                            'language_error',
56
                            "Method {$methodName}() is static but called like a class method",
57
                            $expr
58
                        );
59
                    }
60
61
                    return $method->run(clone $context, $compiledArguments);
62
                }
63
            }
64
65
            return new CompiledExpression();
66
        } else {
67
            $context->notice(
68
                'language_error',
69
                sprintf('$%s is not an object and cannot be called like this', $expr->var->name),
70
                $expr->var,
71
                Check::CHECK_ALPHA
72
            );
73
        }
74
75
        $context->debug('[Unknown] @todo MethodCall', $expr);
76
        return new CompiledExpression();
77
    }
78
79
    /**
80
     * @param \PhpParser\Node\Arg[] $arguments
81
     * @param Context $context
82
     * @return CompiledExpression[]
83
     */
84
    protected function parseArgs(array $arguments, Context $context)
85
    {
86
        $compiled = [];
87
88
        if ($arguments) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $arguments of type PhpParser\Node\Arg[] 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...
89
            foreach ($arguments as $argument) {
90
                $compiled[] = $context->getExpressionCompiler()->compile($argument->value);
91
            }
92
        }
93
94
        return $compiled;
95
    }
96
}
97