@ -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)
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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>
|
||||
|
@ -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
|
||||
}
|
@ -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>
|
Reference in New Issue
Block a user