Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow unused function arguments as regexp #22

Merged
merged 11 commits into from
Apr 27, 2018
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,24 @@ If you already have installed paths, [use a comma to separate them](https://gith

## Customization

There's a variety of options to customize the behaviour of VariableAnalysis, take
a look at the included ruleset.xml.example for commented examples of a configuration.
There's a variety of options to customize the behaviour of VariableAnalysis, take a look at the included ruleset.xml.example for commented examples of a configuration.

The available options are as follows:

- `allowUnusedFunctionParameters` (bool, default `false`): if set to true, function arguments will never be marked as unused.
- `allowUnusedCaughtExceptions` (bool, default `false`): if set to true, caught Exception variables will never be marked as unused.
- `validUnusedVariableNames` (string, default `null`): a space-separated list of names of placeholder variables that you want to ignore from unused variable warnings. For example, to ignore the variables `$junk` and `$unused`, this could be set to `'junk unused'`.
- `ignoreUnusedRegexp` (string, default `null`): a PHP regexp string (note that this requires explicit delimiters) for variables that you want to ignore from unused variable warnings. For example, to ignore the variables `$_junk` and `$_unused`, this could be set to `'/^_/'`.

To set these these options, you must use XML in your ruleset. For details, see the [phpcs customizable sniff properties page](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Customisable-Sniff-Properties). Here is an example that ignores all variables that start with an underscore:

```xml
<rule ref="VariableAnalysis.CodeAnalysis.VariableAnalysis">
<properties>
<property name="ignoreUnusedRegexp" value="/^_/"/>
</properties>
</rule>
```

## Original

Expand Down
24 changes: 17 additions & 7 deletions VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,20 @@ class VariableAnalysisSniff implements Sniff {
public $allowUnusedFunctionParameters = false;

/**
* A list of names of placeholder variables that you want to ignore from
* unused variable warnings, ie things like $junk.
* A space-separated list of names of placeholder variables that you want to
* ignore from unused variable warnings. For example, to ignore the variables
* `$junk` and `$unused`, this could be set to `'junk unused'`.
*/
public $validUnusedVariableNames = null;

/**
* A PHP regexp string for variables that you want to ignore from unused
* variable warnings. For example, to ignore the variables `$_junk` and
* `$_unused`, this could be set to `'/^_/'`.
*/
public $ignoreUnusedRegexp = null;

public function register() {
if (!empty($this->validUnusedVariableNames)) {
$this->validUnusedVariableNames =
preg_split('/\s+/', trim($this->validUnusedVariableNames));
}
return [
T_VARIABLE,
T_DOUBLE_QUOTED_STRING,
Expand Down Expand Up @@ -123,7 +127,13 @@ protected function getOrCreateVariableInfo($varName, $currScope) {
$scopeInfo = $this->getOrCreateScopeInfo($currScope);
if (!isset($scopeInfo->variables[$varName])) {
$scopeInfo->variables[$varName] = new VariableInfo($varName);
if ($this->validUnusedVariableNames && in_array($varName, $this->validUnusedVariableNames)) {
$validUnusedVariableNames = (empty($this->validUnusedVariableNames))
? []
: preg_split('/\s+/', trim($this->validUnusedVariableNames));
if (in_array($varName, $validUnusedVariableNames)) {
$scopeInfo->variables[$varName]->ignoreUnused = true;
}
if (isset($this->ignoreUnusedRegexp) && preg_match($this->ignoreUnusedRegexp, $varName) === 1) {
$scopeInfo->variables[$varName]->ignoreUnused = true;
}
}
Expand Down
95 changes: 95 additions & 0 deletions VariableAnalysis/Tests/CodeAnalysis/VariableAnalysisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,99 @@ public function testTraitsAllowPropertyDefinitions() {
$expectedErrors = [];
$this->assertEquals($expectedErrors, $lines);
}

public function testUnusedParamsAreReported() {
$fixtureFile = $this->getFixture('FunctionWithUnusedParamsFixture.php');
$phpcsFile = $this->prepareLocalFileForSniffs($this->getSniffFiles(), $fixtureFile);
$phpcsFile->process();
$lines = $this->getWarningLineNumbersFromFile($phpcsFile);
$expectedWarnings = [
4,
16,
27,
39,
66,
72,
73,
];
$this->assertEquals($expectedWarnings, $lines);
}

public function testValidUnusedVariableNamesIgnoresUnusedVariables() {
$fixtureFile = $this->getFixture('FunctionWithUnusedParamsFixture.php');
$phpcsFile = $this->prepareLocalFileForSniffs($this->getSniffFiles(), $fixtureFile);
$phpcsFile->ruleset->setSniffProperty(
'VariableAnalysis\Sniffs\CodeAnalysis\VariableAnalysisSniff',
'validUnusedVariableNames',
'ignored'
);
$phpcsFile->process();
$lines = $this->getWarningLineNumbersFromFile($phpcsFile);
$expectedWarnings = [
4,
16,
39,
66,
72,
73,
];
$this->assertEquals($expectedWarnings, $lines);
}

public function testAllowUnusedFunctionParametersIgnoresUnusedVariables() {
$fixtureFile = $this->getFixture('FunctionWithUnusedParamsFixture.php');
$phpcsFile = $this->prepareLocalFileForSniffs($this->getSniffFiles(), $fixtureFile);
$phpcsFile->ruleset->setSniffProperty(
'VariableAnalysis\Sniffs\CodeAnalysis\VariableAnalysisSniff',
'allowUnusedFunctionParameters',
'true'
);
$phpcsFile->process();
$lines = $this->getWarningLineNumbersFromFile($phpcsFile);
$expectedWarnings = [
66,
];
$this->assertEquals($expectedWarnings, $lines);
}

public function testAllowUnusedCaughtExceptionsIgnoresUnusedVariables() {
$fixtureFile = $this->getFixture('FunctionWithUnusedParamsFixture.php');
$phpcsFile = $this->prepareLocalFileForSniffs($this->getSniffFiles(), $fixtureFile);
$phpcsFile->ruleset->setSniffProperty(
'VariableAnalysis\Sniffs\CodeAnalysis\VariableAnalysisSniff',
'allowUnusedCaughtExceptions',
'true'
);
$phpcsFile->process();
$lines = $this->getWarningLineNumbersFromFile($phpcsFile);
$expectedWarnings = [
4,
16,
27,
39,
72,
73,
];
$this->assertEquals($expectedWarnings, $lines);
}

public function testIgnoreUnusedRegexpIgnoresUnusedVariables() {
$fixtureFile = $this->getFixture('FunctionWithUnusedParamsFixture.php');
$phpcsFile = $this->prepareLocalFileForSniffs($this->getSniffFiles(), $fixtureFile);
$phpcsFile->ruleset->setSniffProperty(
'VariableAnalysis\Sniffs\CodeAnalysis\VariableAnalysisSniff',
'ignoreUnusedRegexp',
'/^unused_/'
);
$phpcsFile->process();
$lines = $this->getWarningLineNumbersFromFile($phpcsFile);
$expectedWarnings = [
4,
16,
27,
39,
72,
];
$this->assertEquals($expectedWarnings, $lines);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

// The following line should report an unused variable
function function_with_first_unused_param($unused, $param) {
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
$param = 'set the param';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
return $param;
}

// The following line should report an unused variable
function function_with_second_unused_param($param, $unused) {
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
$param = 'set the param';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
return $param;
}

function function_with_second_unused_param_ignored($param, $ignored) {
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
$param = 'set the param';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
return $param;
}

// The following line should report an unused variable
function function_with_all_unused_params($unused, $unused_two) {
$param = 'hello';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
$param = 'set the param';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
return $param;
}

function function_with_no_unused_params($param, $param_two) {
echo $param;
echo $param_two;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
$param = 'set the param';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
return $param;
}

function function_with_try_catch_and_unused_exception() {
try {
doAThing();
} catch (Exception $unused_param) {
echo "unused";
}
}

function function_with_multi_line_unused_params(
$unused,
$unused_two
) {
$param = 'hello';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
$param = 'set the param';
echo $param;
echo "xxx $param xxx";
echo "xxx {$param} xxx";
return $param;
}