Skip to content

Commit

Permalink
Support shorthand list assignment (#50)
Browse files Browse the repository at this point in the history
* Tests: add test for destructuring assignment

* Support shorthand list assignment
  • Loading branch information
sirbrillig authored Oct 12, 2018
1 parent 8ff2790 commit 25823a9
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
19 changes: 19 additions & 0 deletions VariableAnalysis/Lib/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@
use PHP_CodeSniffer\Files\File;

class Helpers {
public static function findContainingOpeningSquareBracket(File $phpcsFile, $stackPtr) {
$tokens = $phpcsFile->getTokens();
$previousStatementPtr = self::getPreviousStatementPtr($phpcsFile, $stackPtr);
return $phpcsFile->findPrevious(T_OPEN_SHORT_ARRAY, $stackPtr - 1, $previousStatementPtr);
}

public static function findContainingClosingSquareBracket(File $phpcsFile, $stackPtr) {
$tokens = $phpcsFile->getTokens();
$endOfStatementPtr = $phpcsFile->findNext([T_SEMICOLON], $stackPtr + 1);
if (! $endOfStatementPtr) {
return false;
}
return $phpcsFile->findNext(T_CLOSE_SHORT_ARRAY, $stackPtr + 1, $endOfStatementPtr);
}

public static function getPreviousStatementPtr(File $phpcsFile, $stackPtr) {
return $phpcsFile->findPrevious([T_SEMICOLON, T_CLOSE_CURLY_BRACKET], $stackPtr - 1) ?: 1;
}

public static function findContainingOpeningBracket(File $phpcsFile, $stackPtr) {
$tokens = $phpcsFile->getTokens();
if (isset($tokens[$stackPtr]['nested_parenthesis'])) {
Expand Down
28 changes: 28 additions & 0 deletions VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,29 @@ protected function checkForAssignment(File $phpcsFile, $stackPtr, $varName, $cur
return true;
}

protected function checkForListShorthandAssignment(File $phpcsFile, $stackPtr, $varName, $currScope) {
$tokens = $phpcsFile->getTokens();
$token = $tokens[$stackPtr];

// OK, are we within a [ ... ] construct?
$openPtr = Helpers::findContainingOpeningSquareBracket($phpcsFile, $stackPtr);
if ($openPtr === false) {
return false;
}

// OK, we're a [ ... ] construct... are we being assigned to?
$closePtr = Helpers::findContainingClosingSquareBracket($phpcsFile, $stackPtr);
$assignPtr = Helpers::isNextThingAnAssign($phpcsFile, $closePtr);
if ($assignPtr === false) {
return false;
}

// Yes, we're being assigned.
$writtenPtr = Helpers::findWhereAssignExecuted($phpcsFile, $assignPtr);
$this->markVariableAssignment($varName, $writtenPtr, $currScope);
return true;
}

protected function checkForListAssignment(File $phpcsFile, $stackPtr, $varName, $currScope) {
$tokens = $phpcsFile->getTokens();
$token = $tokens[$stackPtr];
Expand Down Expand Up @@ -745,6 +768,11 @@ protected function processVariable(File $phpcsFile, $stackPtr) {
return;
}

// OK, are we within a [...] = construct?
if ($this->checkForListShorthandAssignment($phpcsFile, $stackPtr, $varName, $currScope)) {
return;
}

// Are we a global declaration?
if ($this->checkForGlobalDeclaration($phpcsFile, $stackPtr, $varName, $currScope)) {
return;
Expand Down
12 changes: 12 additions & 0 deletions VariableAnalysis/Tests/CodeAnalysis/VariableAnalysisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -541,4 +541,16 @@ public function testIgnoreUnusedRegexpIgnoresUnusedVariables() {
];
$this->assertEquals($expectedWarnings, $lines);
}

public function testAllowDestructuringAssignment() {
$fixtureFile = $this->getFixture('DestructuringFixture.php');
$phpcsFile = $this->prepareLocalFileForSniffs($this->getSniffFiles(), $fixtureFile);
$phpcsFile->process();
$lines = $this->getWarningLineNumbersFromFile($phpcsFile);
$expectedWarnings = [
4,
12,
];
$this->assertEquals($expectedWarnings, $lines);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
function function_with_destructuring_assignment() {
[$a, $b] = [1, 2];
[$c, $d] = [3, 4]; // unused
echo $a;
echo $b;
echo $c;
}

function function_with_destructuring_assignment_using_list() {
list( $a, $b ) = [1, 2];
list( $c, $d ) = [3, 4]; // unused
echo $a;
echo $b;
echo $c;
}

0 comments on commit 25823a9

Please sign in to comment.