mirror of
https://we.phorge.it/source/arcanist.git
synced 2025-02-20 10:48:39 +01:00
Exclude variables used in strings inside closures when checking for undeclared variables
Summary: Improves upon D13795 to correctly handle variables within strings. Specifically, the following code currently (incorrectly) warns about `$x` being undeclared: ```lang=php function some_func() { return function ($x) { echo "$x"; }; } ``` It's worth noting that the situation would be improved if XHPAST properly parsed strings (see T8049). Test Plan: Added test case. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D13938
This commit is contained in:
parent
e56f326cf7
commit
9b8c9d280e
2 changed files with 22 additions and 0 deletions
|
@ -179,6 +179,12 @@ function some_func($x, $y) {
|
||||||
echo $z;
|
echo $z;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function some_func($x, $y) {
|
||||||
|
$func = function ($z) use ($x) {
|
||||||
|
echo "$x/$y/$z";
|
||||||
|
};
|
||||||
|
}
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
warning:9:3
|
warning:9:3
|
||||||
error:28:3
|
error:28:3
|
||||||
|
@ -201,3 +207,4 @@ error:150:9
|
||||||
error:164:9
|
error:164:9
|
||||||
error:171:5
|
error:171:5
|
||||||
error:178:10
|
error:178:10
|
||||||
|
error:185:14
|
||||||
|
|
|
@ -68,6 +68,7 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
||||||
) + array_fill_keys($this->getSuperGlobalNames(), 0);
|
) + array_fill_keys($this->getSuperGlobalNames(), 0);
|
||||||
$declaration_tokens = array();
|
$declaration_tokens = array();
|
||||||
$exclude_tokens = array();
|
$exclude_tokens = array();
|
||||||
|
$exclude_strings = array();
|
||||||
$vars = array();
|
$vars = array();
|
||||||
|
|
||||||
// First up, find all the different kinds of declarations, as explained
|
// First up, find all the different kinds of declarations, as explained
|
||||||
|
@ -175,6 +176,16 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
||||||
foreach ($func_decl->selectDescendantsOfType('n_VARIABLE') as $var) {
|
foreach ($func_decl->selectDescendantsOfType('n_VARIABLE') as $var) {
|
||||||
$exclude_tokens[$var->getID()] = true;
|
$exclude_tokens[$var->getID()] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (array('n_STRING_SCALAR', 'n_HEREDOC') as $type) {
|
||||||
|
foreach ($func_decl->selectDescendantsOfType($type) as $string) {
|
||||||
|
$exclude_strings[$string->getID()] = array();
|
||||||
|
|
||||||
|
foreach ($string->getStringVariables() as $offset => $var) {
|
||||||
|
$exclude_strings[$string->getID()][$var] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have every declaration except foreach(), handled below. Build
|
// Now we have every declaration except foreach(), handled below. Build
|
||||||
|
@ -316,6 +327,10 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
||||||
foreach (array('n_STRING_SCALAR', 'n_HEREDOC') as $type) {
|
foreach (array('n_STRING_SCALAR', 'n_HEREDOC') as $type) {
|
||||||
foreach ($body->selectDescendantsOfType($type) as $string) {
|
foreach ($body->selectDescendantsOfType($type) as $string) {
|
||||||
foreach ($string->getStringVariables() as $offset => $var) {
|
foreach ($string->getStringVariables() as $offset => $var) {
|
||||||
|
if (isset($exclude_strings[$string->getID()][$var])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$all[$string->getOffset() + $offset - 1] = '$'.$var;
|
$all[$string->getOffset() + $offset - 1] = '$'.$var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue