mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-25 16:22:42 +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;
|
||||
};
|
||||
}
|
||||
|
||||
function some_func($x, $y) {
|
||||
$func = function ($z) use ($x) {
|
||||
echo "$x/$y/$z";
|
||||
};
|
||||
}
|
||||
~~~~~~~~~~
|
||||
warning:9:3
|
||||
error:28:3
|
||||
|
@ -201,3 +207,4 @@ error:150:9
|
|||
error:164:9
|
||||
error:171:5
|
||||
error:178:10
|
||||
error:185:14
|
||||
|
|
|
@ -68,6 +68,7 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
|||
) + array_fill_keys($this->getSuperGlobalNames(), 0);
|
||||
$declaration_tokens = array();
|
||||
$exclude_tokens = array();
|
||||
$exclude_strings = array();
|
||||
$vars = array();
|
||||
|
||||
// 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) {
|
||||
$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
|
||||
|
@ -316,6 +327,10 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
|||
foreach (array('n_STRING_SCALAR', 'n_HEREDOC') as $type) {
|
||||
foreach ($body->selectDescendantsOfType($type) as $string) {
|
||||
foreach ($string->getStringVariables() as $offset => $var) {
|
||||
if (isset($exclude_strings[$string->getID()][$var])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$all[$string->getOffset() + $offset - 1] = '$'.$var;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue