3
3
namespace PHPStan \Rules \Variables ;
4
4
5
5
use PhpParser \Node ;
6
+ use PhpParser \Node \Expr \BinaryOp \Identical ;
6
7
use PhpParser \Node \Expr \Variable ;
8
+ use PhpParser \Node \Scalar \String_ ;
7
9
use PHPStan \Analyser \Scope ;
10
+ use PHPStan \Rules \IdentifierRuleError ;
8
11
use PHPStan \Rules \Rule ;
9
12
use PHPStan \Rules \RuleErrorBuilder ;
13
+ use function array_merge ;
10
14
use function in_array ;
11
15
use function is_string ;
12
16
use function sprintf ;
@@ -31,11 +35,31 @@ public function getNodeType(): string
31
35
32
36
public function processNode (Node $ node , Scope $ scope ): array
33
37
{
34
- if (!is_string ($ node ->name )) {
35
- return [];
38
+ $ errors = [];
39
+ if (is_string ($ node ->name )) {
40
+ $ variableNameScopes = [$ node ->name => $ scope ];
41
+ } else {
42
+ $ nameType = $ scope ->getType ($ node ->name );
43
+ $ variableNameScopes = [];
44
+ foreach ($ nameType ->getConstantStrings () as $ constantString ) {
45
+ $ name = $ constantString ->getValue ();
46
+ $ variableNameScopes [$ name ] = $ scope ->filterByTruthyValue (new Identical ($ node ->name , new String_ ($ name )));
47
+ }
48
+ }
49
+
50
+ foreach ($ variableNameScopes as $ name => $ variableScope ) {
51
+ $ errors = array_merge ($ errors , $ this ->processSingleVariable ($ variableScope , $ node , $ name ));
36
52
}
37
53
38
- if ($ this ->cliArgumentsVariablesRegistered && in_array ($ node ->name , [
54
+ return $ errors ;
55
+ }
56
+
57
+ /**
58
+ * @return list<IdentifierRuleError>
59
+ */
60
+ private function processSingleVariable (Scope $ scope , Variable $ node , string $ variableName ): array
61
+ {
62
+ if ($ this ->cliArgumentsVariablesRegistered && in_array ($ variableName , [
39
63
'argc ' ,
40
64
'argv ' ,
41
65
], true )) {
@@ -49,18 +73,18 @@ public function processNode(Node $node, Scope $scope): array
49
73
return [];
50
74
}
51
75
52
- if ($ scope ->hasVariableType ($ node -> name )->no ()) {
76
+ if ($ scope ->hasVariableType ($ variableName )->no ()) {
53
77
return [
54
- RuleErrorBuilder::message (sprintf ('Undefined variable: $%s ' , $ node -> name ))
78
+ RuleErrorBuilder::message (sprintf ('Undefined variable: $%s ' , $ variableName ))
55
79
->identifier ('variable.undefined ' )
56
80
->build (),
57
81
];
58
82
} elseif (
59
83
$ this ->checkMaybeUndefinedVariables
60
- && !$ scope ->hasVariableType ($ node -> name )->yes ()
84
+ && !$ scope ->hasVariableType ($ variableName )->yes ()
61
85
) {
62
86
return [
63
- RuleErrorBuilder::message (sprintf ('Variable $%s might not be defined. ' , $ node -> name ))
87
+ RuleErrorBuilder::message (sprintf ('Variable $%s might not be defined. ' , $ variableName ))
64
88
->identifier ('variable.undefined ' )
65
89
->build (),
66
90
];
0 commit comments