1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-12-29 17:00:58 +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:
Joshua Spence 2015-08-21 07:26:52 +10:00
parent e56f326cf7
commit 9b8c9d280e
2 changed files with 22 additions and 0 deletions

View file

@ -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

View file

@ -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;
}
}