Skip to content

Commit

Permalink
VariableVariables: improve code style independent sniffing
Browse files Browse the repository at this point in the history
Whitespace and comments are allowed to be interspersed in variables, so the sniff should take this into account.

Includes additional unit tests.
  • Loading branch information
jrfnl committed Dec 24, 2017
1 parent a1de588 commit 0405b27
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 5 deletions.
9 changes: 5 additions & 4 deletions PHPCompatibility/Sniffs/PHP/VariableVariablesSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
return;
}

// The previous token has to be a $, -> or ::.
if (isset($tokens[($stackPtr - 1)]) === false || in_array($tokens[($stackPtr - 1)]['code'], array(T_DOLLAR, T_OBJECT_OPERATOR, T_DOUBLE_COLON), true) === false) {
// The previous non-empty token has to be a $, -> or ::.
$prevToken = $phpcsFile->findPrevious(\PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
if ($prevToken === false || in_array($tokens[$prevToken]['code'], array(T_DOLLAR, T_OBJECT_OPERATOR, T_DOUBLE_COLON), true) === false) {
return;
}

// For static object calls, it only applies when this is a function call.
if ($tokens[($stackPtr - 1)]['code'] === T_DOUBLE_COLON) {
if ($tokens[$prevToken]['code'] === T_DOUBLE_COLON) {
$hasBrackets = $tokens[$nextToken]['bracket_closer'];
while (($hasBrackets = $phpcsFile->findNext(\PHP_CodeSniffer_Tokens::$emptyTokens, ($hasBrackets + 1), null, true, null, true)) !== false) {
if ($tokens[$hasBrackets]['code'] === T_OPEN_SQUARE_BRACKET) {
Expand All @@ -90,7 +91,7 @@ public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
}

// Now let's also prevent false positives when used with self and static which still work fine.
$classToken = $phpcsFile->findPrevious(\PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 2), null, true, null, true);
$classToken = $phpcsFile->findPrevious(\PHP_CodeSniffer_Tokens::$emptyTokens, ($prevToken - 1), null, true, null, true);
if ($classToken !== false) {
if ($tokens[$classToken]['code'] === T_STATIC || $tokens[$classToken]['code'] === T_SELF) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function dataVariableVariables()
array(6),
array(7),
array(8),
array(37),
array(38),
);
}

Expand Down Expand Up @@ -103,7 +105,7 @@ public function dataNoFalsePositives()
array(28),
array(29),
array(32),
array(37),
array(42),
);
}

Expand Down
5 changes: 5 additions & 0 deletions PHPCompatibility/Tests/sniff-examples/variable_variables.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,10 @@ function foo() {
}
}

// Test code style independent sniffing.
echo $ $var['key1']['key2']; // Bad.
echo $obj -> /* comment */ $var['key']; // Bad.
echo myClass :: { /* comment */ $var['key']}(); // OK.

// Live coding.
echo $$var['key'

0 comments on commit 0405b27

Please sign in to comment.