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
|
16 |
|
public function __construct() |
16
|
|
|
{ |
17
|
16 |
|
} |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* {@inheritDoc} |
21
|
|
|
*/ |
22
|
12 |
|
public function beforeTraverse(array $nodes) |
23
|
|
|
{ |
24
|
12 |
|
$this->definedSymbols = []; |
25
|
|
|
|
26
|
12 |
|
return parent::beforeTraverse($nodes); |
|
|
|
|
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @return string[] |
31
|
|
|
*/ |
32
|
14 |
|
public function getDefinedSymbols(): array |
33
|
|
|
{ |
34
|
14 |
|
return array_keys($this->definedSymbols); |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* {@inheritDoc} |
39
|
|
|
*/ |
40
|
15 |
|
public function enterNode(Node $node) |
41
|
|
|
{ |
42
|
15 |
|
$this->recordClassDefinition($node); |
43
|
14 |
|
$this->recordInterfaceDefinition($node); |
44
|
14 |
|
$this->recordTraitDefinition($node); |
45
|
14 |
|
$this->recordFunctionDefinition($node); |
46
|
14 |
|
$this->recordConstDefinition($node); |
47
|
14 |
|
$this->recordDefinedConstDefinition($node); |
48
|
|
|
|
49
|
14 |
|
return $node; |
50
|
|
|
} |
51
|
|
|
|
52
|
15 |
|
private function recordClassDefinition(Node $node) |
53
|
|
|
{ |
54
|
15 |
|
if ($node instanceof Node\Stmt\Class_ && !$node->isAnonymous()) { |
55
|
9 |
|
$this->recordDefinitionOf($node); |
56
|
|
|
} |
57
|
14 |
|
} |
58
|
|
|
|
59
|
14 |
|
private function recordInterfaceDefinition(Node $node) |
60
|
|
|
{ |
61
|
14 |
|
if ($node instanceof Node\Stmt\Interface_) { |
62
|
5 |
|
$this->recordDefinitionOf($node); |
63
|
|
|
} |
64
|
14 |
|
} |
65
|
|
|
|
66
|
14 |
|
private function recordTraitDefinition(Node $node) |
67
|
|
|
{ |
68
|
14 |
|
if ($node instanceof Node\Stmt\Trait_) { |
69
|
5 |
|
$this->recordDefinitionOf($node); |
70
|
|
|
} |
71
|
14 |
|
} |
72
|
|
|
|
73
|
14 |
|
private function recordFunctionDefinition(Node $node) |
74
|
|
|
{ |
75
|
14 |
|
if ($node instanceof Node\Stmt\Function_) { |
76
|
1 |
|
$this->recordDefinitionOf($node); |
77
|
|
|
} |
78
|
14 |
|
} |
79
|
|
|
|
80
|
14 |
|
private function recordConstDefinition(Node $node) |
81
|
|
|
{ |
82
|
14 |
|
if ($node instanceof Node\Stmt\Const_) { |
83
|
1 |
|
foreach ($node->consts as $const) { |
84
|
1 |
|
$this->recordDefinitionOf($const); |
85
|
|
|
} |
86
|
|
|
} |
87
|
14 |
|
} |
88
|
|
|
|
89
|
14 |
|
private function recordDefinedConstDefinition(Node $node) |
90
|
|
|
{ |
91
|
14 |
|
if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && $node->name->toString() === 'define') { |
92
|
6 |
|
if ($node->name->hasAttribute('namespacedName') |
93
|
6 |
|
&& $node->name->getAttribute('namespacedName') instanceof Node\Name\FullyQualified |
94
|
6 |
|
&& $node->name->getAttribute('namespacedName')->toString() !== 'define' |
95
|
|
|
) { |
96
|
1 |
|
return; |
97
|
|
|
} |
98
|
|
|
|
99
|
5 |
|
if ($node->args[0]->value instanceof Node\Scalar\String_) { |
100
|
5 |
|
$this->recordDefinitionOfStringSymbol($node->args[0]->value->value); |
101
|
|
|
} |
102
|
|
|
} |
103
|
13 |
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @param Node $node |
107
|
|
|
* |
108
|
|
|
* @return void |
109
|
|
|
*/ |
110
|
13 |
|
private function recordDefinitionOf(Node $node) |
111
|
|
|
{ |
112
|
13 |
|
if (!isset($node->namespacedName)) { |
|
|
|
|
113
|
1 |
|
throw new \UnexpectedValueException(sprintf( |
114
|
|
|
'Given node of type "%s" (defined at line %s)does not have an assigned "namespacedName" property: ' |
115
|
1 |
|
. 'did you pass it through a name resolver visitor?', |
116
|
1 |
|
get_class($node), |
117
|
1 |
|
$node->getLine() |
118
|
|
|
)); |
119
|
|
|
} |
120
|
|
|
|
121
|
12 |
|
$this->recordDefinitionOfStringSymbol((string)$node->namespacedName); |
122
|
12 |
|
} |
123
|
|
|
|
124
|
13 |
|
private function recordDefinitionOfStringSymbol(string $symbolName) |
125
|
|
|
{ |
126
|
13 |
|
$this->definedSymbols[$symbolName] = $symbolName; |
127
|
13 |
|
} |
128
|
|
|
} |
129
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
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.