Skip to content

Commit ad1b668

Browse files
authored
Fix unused-before-used detection (#171)
* Add test for unused params after used with global * Make sure areFollowingArgumentsUsed only examines params * Remove unused function arguments
1 parent a91f64f commit ad1b668

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

Tests/VariableAnalysisSniff/VariableAnalysisTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public function testFunctionWithGlobalVarWarnings() {
9797
28,
9898
29,
9999
39,
100+
54,
100101
];
101102
$this->assertEquals($expectedWarnings, $lines);
102103
}
@@ -766,6 +767,7 @@ public function testValidUndefinedVariableNamesIgnoresVarsInGlobalScope() {
766767
7,
767768
23,
768769
39,
770+
54,
769771
];
770772
$this->assertEquals($expectedWarnings, $lines);
771773
}
@@ -806,6 +808,8 @@ public function testUnusedArgumentsBeforeUsedArgumentsAreFoundIfFalse() {
806808
8,
807809
16,
808810
19,
811+
28,
812+
34,
809813
];
810814
$this->assertEquals($expectedWarnings, $lines);
811815
}
@@ -818,6 +822,8 @@ public function testUnusedArgumentsBeforeUsedArgumentsAreIgnoredByDefault() {
818822
$expectedWarnings = [
819823
8,
820824
19,
825+
28,
826+
34,
821827
];
822828
$this->assertEquals($expectedWarnings, $lines);
823829
}

Tests/VariableAnalysisSniff/fixtures/FunctionWithGlobalVarFixture.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,8 @@ function updateGlobalWithListShorthand($newVal) {
5050
[ $myGlobal, $otherVar ] = my_function($newVal);
5151
echo $otherVar;
5252
}
53+
54+
function globalWithUnusedFunctionArg($user_type, $text, $testvar) { // should warn that testvar is unused
55+
global $config;
56+
return $config . $text . $user_type;
57+
}

Tests/VariableAnalysisSniff/fixtures/UnusedAfterUsedFixture.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,17 @@ function inner_function() {
2323
};
2424
$foo();
2525
}
26+
27+
// The following line should report an unused variable (unused after used)
28+
function function_with_one_unused_param($used, $used_two, $unused_three) {
29+
echo $used;
30+
echo $used_two;
31+
}
32+
33+
// The following line should report an unused variable (unused after used)
34+
function function_with_local_and_unused_params($used, $used_two, $unused_three) {
35+
$foobar = 'hello';
36+
echo $used;
37+
echo $foobar;
38+
echo $used_two;
39+
}

VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ protected function areFollowingArgumentsUsed($varInfo, $scopeInfo) {
284284
if (! $foundVarPosition) {
285285
continue;
286286
}
287+
if ($variable->scopeType !== 'param') {
288+
continue;
289+
}
287290
if ($variable->firstRead) {
288291
return true;
289292
}
@@ -523,12 +526,10 @@ protected function checkForFunctionPrototype(File $phpcsFile, $stackPtr, $varNam
523526
/**
524527
* @param File $phpcsFile
525528
* @param int $stackPtr
526-
* @param string $varName
527-
* @param int $currScope
528529
*
529530
* @return bool
530531
*/
531-
protected function checkForClassProperty(File $phpcsFile, $stackPtr, $varName, $currScope) {
532+
protected function checkForClassProperty(File $phpcsFile, $stackPtr) {
532533
$propertyDeclarationKeywords = [
533534
T_PUBLIC,
534535
T_PRIVATE,
@@ -661,12 +662,10 @@ protected function checkForSuperGlobal(File $phpcsFile, $stackPtr, $varName) {
661662
/**
662663
* @param File $phpcsFile
663664
* @param int $stackPtr
664-
* @param string $varName
665-
* @param int $currScope
666665
*
667666
* @return bool
668667
*/
669-
protected function checkForStaticMember(File $phpcsFile, $stackPtr, $varName, $currScope) {
668+
protected function checkForStaticMember(File $phpcsFile, $stackPtr) {
670669
$tokens = $phpcsFile->getTokens();
671670

672671
$doubleColonPtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, $stackPtr - 1, null, true);
@@ -697,11 +696,10 @@ protected function checkForStaticMember(File $phpcsFile, $stackPtr, $varName, $c
697696
* @param File $phpcsFile
698697
* @param int $stackPtr
699698
* @param string $varName
700-
* @param int $currScope
701699
*
702700
* @return bool
703701
*/
704-
protected function checkForStaticOutsideClass(File $phpcsFile, $stackPtr, $varName, $currScope) {
702+
protected function checkForStaticOutsideClass(File $phpcsFile, $stackPtr, $varName) {
705703
// Are we refering to self:: outside a class?
706704
707705
$tokens = $phpcsFile->getTokens();
@@ -753,7 +751,7 @@ protected function checkForAssignment(File $phpcsFile, $stackPtr, $varName, $cur
753751
}
754752

755753
// Is this a variable variable? If so, it's not an assignment to the current variable.
756-
if ($this->checkForVariableVariable($phpcsFile, $stackPtr, $varName, $currScope)) {
754+
if ($this->checkForVariableVariable($phpcsFile, $stackPtr)) {
757755
Helpers::debug('found variable variable');
758756
return false;
759757
}
@@ -780,12 +778,10 @@ protected function checkForAssignment(File $phpcsFile, $stackPtr, $varName, $cur
780778
/**
781779
* @param File $phpcsFile
782780
* @param int $stackPtr
783-
* @param string $varName
784-
* @param int $currScope
785781
*
786782
* @return bool
787783
*/
788-
protected function checkForVariableVariable(File $phpcsFile, $stackPtr, $varName, $currScope) {
784+
protected function checkForVariableVariable(File $phpcsFile, $stackPtr) {
789785
$tokens = $phpcsFile->getTokens();
790786

791787
$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
@@ -1198,18 +1194,18 @@ protected function processVariable(File $phpcsFile, $stackPtr) {
11981194
}
11991195

12001196
// Check for static members used outside a class
1201-
if ($this->checkForStaticOutsideClass($phpcsFile, $stackPtr, $varName, $currScope)) {
1197+
if ($this->checkForStaticOutsideClass($phpcsFile, $stackPtr, $varName)) {
12021198
Helpers::debug('found static usage outside of class');
12031199
return;
12041200
}
12051201

12061202
// $var part of class::$var static member
1207-
if ($this->checkForStaticMember($phpcsFile, $stackPtr, $varName, $currScope)) {
1203+
if ($this->checkForStaticMember($phpcsFile, $stackPtr)) {
12081204
Helpers::debug('found static member');
12091205
return;
12101206
}
12111207

1212-
if ($this->checkForClassProperty($phpcsFile, $stackPtr, $varName, $currScope)) {
1208+
if ($this->checkForClassProperty($phpcsFile, $stackPtr)) {
12131209
Helpers::debug('found class property definition');
12141210
return;
12151211
}
@@ -1417,6 +1413,7 @@ protected function processScopeCloseForVariable(File $phpcsFile, VariableInfo $v
14171413
return;
14181414
}
14191415
if ($this->allowUnusedParametersBeforeUsed && $varInfo->scopeType === 'param' && $this->areFollowingArgumentsUsed($varInfo, $scopeInfo)) {
1416+
Helpers::debug("variable {$varInfo->name} at end of scope has unused following args");
14201417
return;
14211418
}
14221419
if ($this->allowUnusedForeachVariables && $varInfo->isForeachLoopAssociativeValue) {

0 commit comments

Comments
 (0)