Passed
Push — master ( 272451...167000 )
by Marco
03:48
created

DefinedSymbolCollector   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Test Coverage

Coverage 94.55%

Importance

Changes 0
Metric Value
wmc 27
eloc 37
dl 0
loc 117
ccs 52
cts 55
cp 0.9455
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A getDefinedSymbols() 0 3 1
A __construct() 0 2 1
A recordInterfaceDefinition() 0 4 2
A recordClassDefinition() 0 4 3
A recordFunctionDefinition() 0 4 2
A recordDefinitionOfStringSymbol() 0 3 1
A recordConstDefinition() 0 5 3
A enterNode() 0 8 1
B recordDefinedConstDefinition() 0 12 8
A beforeTraverse() 0 5 1
A recordDefinitionOf() 0 12 2
A recordTraitDefinition() 0 4 2
1
<?php
2
3
namespace ComposerRequireChecker\NodeVisitor;
4
5
use PhpParser\Node;
6
use PhpParser\NodeVisitorAbstract;
7
8
final class DefinedSymbolCollector extends NodeVisitorAbstract
9
{
10
    /**
11
     * @var mixed[]
12
     */
13
    private $definedSymbols = [];
14
15 4
    public function __construct()
16
    {
17 4
    }
18
19
    /**
20
     * {@inheritDoc}
21
     */
22 1
    public function beforeTraverse(array $nodes)
23
    {
24 1
        $this->definedSymbols = [];
25
26 1
        return parent::beforeTraverse($nodes);
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::beforeTraverse($nodes) targeting PhpParser\NodeVisitorAbstract::beforeTraverse() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
27
    }
28
29
    /**
30
     * @return string[]
31
     */
32 3
    public function getDefinedSymbols(): array
33
    {
34 3
        return array_keys($this->definedSymbols);
35
    }
36
37
    /**
38
     * {@inheritDoc}
39
     */
40 4
    public function enterNode(Node $node)
41
    {
42 4
        $this->recordClassDefinition($node);
43 3
        $this->recordInterfaceDefinition($node);
44 3
        $this->recordTraitDefinition($node);
45 3
        $this->recordFunctionDefinition($node);
46 3
        $this->recordConstDefinition($node);
47 3
        $this->recordDefinedConstDefinition($node);
48 3
    }
49
50 4
    private function recordClassDefinition(Node $node)
51
    {
52 4
        if ($node instanceof Node\Stmt\Class_ && !$node->isAnonymous()) {
53 2
            $this->recordDefinitionOf($node);
54
        }
55 3
    }
56
57 3
    private function recordInterfaceDefinition(Node $node)
58
    {
59 3
        if ($node instanceof Node\Stmt\Interface_) {
60 1
            $this->recordDefinitionOf($node);
61
        }
62 3
    }
63
64 3
    private function recordTraitDefinition(Node $node)
65
    {
66 3
        if ($node instanceof Node\Stmt\Trait_) {
67 1
            $this->recordDefinitionOf($node);
68
        }
69 3
    }
70
71 3
    private function recordFunctionDefinition(Node $node)
72
    {
73 3
        if ($node instanceof Node\Stmt\Function_) {
74
            $this->recordDefinitionOf($node);
75
        }
76 3
    }
77
78 3
    private function recordConstDefinition(Node $node)
79
    {
80 3
        if ($node instanceof Node\Stmt\Const_) {
81
            foreach ($node->consts as $const) {
82
                $this->recordDefinitionOf($const);
83
            }
84
        }
85 3
    }
86
87 3
    private function recordDefinedConstDefinition(Node $node)
88
    {
89 3
        if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && $node->name->toString() === 'define') {
90 2
            if ($node->name->hasAttribute('namespacedName')
91 2
                && $node->name->getAttribute('namespacedName') instanceof Node\Name\FullyQualified
92 2
                && $node->name->getAttribute('namespacedName')->toString() !== 'define'
93
            ) {
94 1
                return;
95
            }
96
97 1
            if ($node->args[0]->value instanceof Node\Scalar\String_) {
98 1
                $this->recordDefinitionOfStringSymbol((string)$node->args[0]->value->value);
99
            }
100
        }
101 2
    }
102
103
    /**
104
     * @param Node $node
105
     *
106
     * @return void
107
     */
108 2
    private function recordDefinitionOf(Node $node)
109
    {
110 2
        if (!isset($node->namespacedName)) {
0 ignored issues
show
Bug introduced by
Accessing namespacedName on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
111 1
            throw new \UnexpectedValueException(sprintf(
112
                'Given node of type "%s" (defined at line %s)does not have an assigned "namespacedName" property: '
113 1
                . 'did you pass it through a name resolver visitor?',
114 1
                get_class($node),
115 1
                $node->getLine()
116
            ));
117
        }
118
119 1
        $this->recordDefinitionOfStringSymbol((string)$node->namespacedName);
120 1
    }
121
122 2
    private function recordDefinitionOfStringSymbol(string $symbolName)
123
    {
124 2
        $this->definedSymbols[$symbolName] = $symbolName;
125 2
    }
126
}
127