Merge branch 'pr-2395'

[apex] New Rule: Unused local variables #2395
This commit is contained in:
Andreas Dangel
2020-04-04 18:08:41 +02:00
5 changed files with 156 additions and 0 deletions

View File

@ -35,6 +35,9 @@ Note that XPath 1.0 support, the default XPath version, is deprecated since PMD
* The new Apex rule {% rule "apex/codestyle/FieldDeclarationsShouldBeAtStart" %} (`apex-codestyle`)
helps to ensure that field declarations are always at the beginning of a class.
* The new Apex rule {% rule "apex/bestpractices/UnusedLocalVariable" %} (`apex-bestpractices`) detects unused
local variables.
### Fixed Issues
* apex-design
@ -123,6 +126,7 @@ implementations, and their corresponding Parser if it exists (in the same packag
* [#2314](https://github.com/pmd/pmd/pull/2314): \[doc] maven integration - Add version to plugin - [Pham Hai Trung](https://github.com/gpbp)
* [#2353](https://github.com/pmd/pmd/pull/2353): \[plsql] xmlforest with optional AS - [Piotr Szymanski](https://github.com/szyman23)
* [#2383](https://github.com/pmd/pmd/pull/2383): \[apex] Fix invalid apex in documentation - [Gwilym Kuiper](https://github.com/gwilymatgearset)
* [#2395](https://github.com/pmd/pmd/pull/2395): \[apex] New Rule: Unused local variables - [Gwilym Kuiper](https://github.com/gwilymatgearset)
* [#2396](https://github.com/pmd/pmd/pull/2396): \[apex] New rule: field declarations should be at start - [Gwilym Kuiper](https://github.com/gwilymatgearset)
* [#2397](https://github.com/pmd/pmd/pull/2397): \[apex] fixed WITH SECURITY_ENFORCED regex to recognise line break characters - [Kieran Black](https://github.com/kieranlblack)

View File

@ -0,0 +1,38 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.bestpractices;
import java.util.List;
import net.sourceforge.pmd.lang.apex.ast.ASTBlockStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTVariableDeclaration;
import net.sourceforge.pmd.lang.apex.ast.ASTVariableExpression;
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
public class UnusedLocalVariableRule extends AbstractApexRule {
public UnusedLocalVariableRule() {
addRuleChainVisit(ASTVariableDeclaration.class);
}
@Override
public Object visit(ASTVariableDeclaration node, Object data) {
String variableName = node.getImage();
ASTBlockStatement variableContext = node.getFirstParentOfType(ASTBlockStatement.class);
List<ASTVariableExpression> potentialUsages = variableContext.findDescendantsOfType(ASTVariableExpression.class);
for (ASTVariableExpression usage : potentialUsages) {
if (usage.getParent() == node) {
continue;
}
if (usage.getImage().equals(variableName)) {
return data;
}
}
addViolation(data, node, variableName);
return data;
}
}

View File

@ -208,4 +208,25 @@ public class Foo {
</example>
</rule>
<rule name="UnusedLocalVariable"
since="6.23.0"
language="apex"
message="Variable ''{0}'' defined but not used"
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.UnusedLocalVariableRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_bestpractices.html#unusedlocalvariable">
<description>
Detects when a local variable is declared and/or assigned but not used.
</description>
<example>
<![CDATA[
public Boolean bar(String z) {
String x = 'some string'; // not used
String y = 'some other string'; // used in the next line
return z.equals(y);
}
]]>
</example>
</rule>
</ruleset>

View File

@ -0,0 +1,11 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.bestpractices;
import net.sourceforge.pmd.testframework.PmdRuleTst;
public class UnusedLocalVariableTest extends PmdRuleTst {
// no additional unit tests
}

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8" ?>
<test-data
xmlns="http://pmd.sourceforge.net/rule-tests"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
<test-code>
<description>Unused variables should result in errors</description>
<expected-problems>2</expected-problems>
<expected-linenumbers>3,7</expected-linenumbers>
<expected-messages>
<message>Variable 'foo' defined but not used</message>
<message>Variable 'foo' defined but not used</message>
</expected-messages>
<code>
<![CDATA[
public class Foo {
public void assignedVariable() {
String foo = 'unused string';
}
public void justADeclaration() {
String foo;
}
}
]]>
</code>
</test-code>
<test-code>
<description>Used variables should not result in errors</description>
<expected-problems>0</expected-problems>
<code>
<![CDATA[
public class Foo {
public String basicUsage() {
String x = 'used variable';
return x;
}
public Account moreComplexUsage() {
String x = 'blah';
return [SELECT Id FROM Account WHERE Name = :x];
}
public String usageInBlocks(Boolean y) {
String x = 'used variable';
if (y) {
return x;
} else {
return 'some other string';
}
}
}
]]>
</code>
</test-code>
<test-code>
<description>Shadowing a field</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>5</expected-linenumbers>
<code><![CDATA[
public class Foo {
private String myfield;
public void unused() {
String myfield = 'unused string';
}
public String usedDifferentMethod() {
String myfield = 'used';
return myfield;
}
public String fieldUsage() {
return myfield;
}
}
]]></code>
</test-code>
</test-data>