Completed
Push — master ( c942e5...9bcb42 )
by Дмитрий
11:51 queued 06:01
created

StaticCall   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 7

Test Coverage

Coverage 48.39%

Importance

Changes 0
Metric Value
dl 0
loc 68
ccs 15
cts 31
cp 0.4839
rs 10
c 0
b 0
f 0
wmc 8
lcom 0
cbo 7

2 Methods

Rating   Name   Duplication   Size   Complexity  
B compile() 0 37 5
A parseArgs() 0 12 3
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 PHPSA\CompiledExpression;
11
use PHPSA\Context;
12
use PHPSA\Definition\ClassDefinition;
13
14
class StaticCall extends AbstractExpressionCompiler
15
{
16
    protected $name = 'PhpParser\Node\Expr\StaticCall';
17
18
    /**
19
     * {expr}::{expr}();
20
     *
21
     * @param \PhpParser\Node\Expr\StaticCall $expr
22
     * @param Context $context
23
     * @return CompiledExpression
24
     */
25 1
    protected function compile($expr, Context $context)
26
    {
27 1
        $expressionCompiler = $context->getExpressionCompiler();
28 1
        $leftCE = $expressionCompiler->compile($expr->class);
29
30 1
        $this->parseArgs($expr->args, $context);
31
32 1
        if ($leftCE->isObject()) {
33 1
            $name = $expr->name;
34
35
            /** @var ClassDefinition $classDefinition */
36 1
            $classDefinition = $context->scope;
37 1
            if (!$classDefinition->hasMethod($name, true)) {
0 ignored issues
show
Bug introduced by
It seems like $name defined by $expr->name on line 33 can also be of type object<PhpParser\Node\Expr>; however, PHPSA\Definition\ClassDefinition::hasMethod() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
38
                $context->notice(
39
                    'language_error',
40
                    sprintf('Static method %s() does not exist in %s scope', $name, $expr->class),
41
                    $expr
42
                );
43
44
                return new CompiledExpression();
45
            }
46
47 1
            $method = $classDefinition->getMethod($name, true);
48 1
            if ($expr->class->parts[0] !== 'parent' && !$method->isStatic()) {
49
                $context->notice(
50
                    'language_error',
51
                    sprintf('Method %s() is not static but was called in a static way', $name),
52
                    $expr
53
                );
54
            }
55
56 1
            return new CompiledExpression();
57
        }
58
59
        $context->debug('Unknown static function call', $expr);
60
        return new CompiledExpression();
61
    }
62
63
64
    /**
65
     * @param \PhpParser\Node\Arg[] $arguments
66
     * @param Context $context
67
     * @return CompiledExpression[]
68
     */
69 1
    protected function parseArgs(array $arguments, Context $context)
70
    {
71 1
        $compiled = [];
72
73 1
        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...
74
            foreach ($arguments as $argument) {
75
                $compiled[] = $context->getExpressionCompiler()->compile($argument->value);
76
            }
77
        }
78
79 1
        return $compiled;
80
    }
81
}
82