More code in the framework, less code in the rule... good times

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@4064 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Tom Copeland
2005-12-14 22:20:47 +00:00
parent fd9b9b6e3e
commit c0a4006dec
6 changed files with 40 additions and 60 deletions

View File

@ -7,4 +7,5 @@ that contains this fix.
Thanks,
Tom
Using PMD? Get the book, "PMD Applied"! http://pmdapplied.com/
Using PMD? Get the book, "PMD Applied"! http://pmdapplied.com/

View File

@ -6,33 +6,26 @@
These are new rules that are still in progress
</description>
<rule name="NullAssignment"
message="Assigning an Object to null is a code smell. Consider refactoring."
class="net.sourceforge.pmd.rules.design.NullAssignmentRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/controversial.html#NullAssignment">
<description>
Assigning a "null" to a variable (outside of its declaration) is usually
bad form. Some times, the assignment is an indication that the programmer doesn't
completely understand what is going on in the code. NOTE: This sort of assignment
may in rare cases be useful to encourage garbage collection. If that's what you're using
it for, by all means, disregard this rule :-)
</description>
<rule name="UnusedLocalVariable"
message="Avoid unused local variables such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedLocalVariableRule"
externalInfoUrl="http://pmd.sourceforge.net/rules/unusedcode.html#UnusedLocalVariable">
<description>
Detects when a local variable is declared and/or assigned, but not used.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
public void bar() {
Object x = null; // This is OK.
x = new Object();
// Big, complex piece of code here.
x = null; // This is BAD.
// Big, complex piece of code here.
}
}
]]>
</example>
</rule>
<example>
<![CDATA[
public class Foo {
public void doSomething() {
int i = 5; // Unused
}
}
]]>
</example>
</rule>
<!--

View File

@ -48,8 +48,6 @@ public class Foo {
</example>
</rule>
<rule name="UnusedPrivateMethod"
message="Avoid unused private methods such as ''{0}''"
class="net.sourceforge.pmd.rules.UnusedPrivateMethodRule"

View File

@ -2,6 +2,9 @@
package net.sourceforge.pmd.ast;
import net.sourceforge.pmd.symboltable.NameDeclaration;
import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
public class ASTVariableDeclaratorId extends SimpleNode {
public ASTVariableDeclaratorId(int id) {
@ -20,6 +23,14 @@ public class ASTVariableDeclaratorId extends SimpleNode {
}
private int arrayDepth;
private VariableNameDeclaration nameDeclaration;
public VariableNameDeclaration getNameDeclaration() {
return nameDeclaration;
}
public void setNameDeclaration(VariableNameDeclaration decl) {
nameDeclaration = decl;
}
public void bumpArrayDepth() {
arrayDepth++;

View File

@ -4,49 +4,24 @@
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.ast.ASTCompilationUnit;
import net.sourceforge.pmd.ast.ASTLocalVariableDeclaration;
import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
import net.sourceforge.pmd.symboltable.NameOccurrence;
import net.sourceforge.pmd.symboltable.Scope;
import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class UnusedLocalVariableRule extends AbstractRule {
private Set visited = new HashSet();
public Object visit(ASTCompilationUnit acu, Object data) {
visited.clear();
return super.visit(acu, data);
}
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (node.jjtGetParent().jjtGetParent() instanceof ASTLocalVariableDeclaration) {
Scope scope = node.getScope();
if (visited.contains(scope)) {
return data;
} else {
visited.add(scope);
}
Map locals = scope.getVariableDeclarations();
for (Iterator i = locals.keySet().iterator(); i.hasNext();) {
VariableNameDeclaration decl = (VariableNameDeclaration) i.next();
// TODO this misses some cases
// need to add DFAish code to determine if an array
// is initialized locally or gotten from somewhere else
if (decl.isArray()) {
continue;
}
List usages = (List) locals.get(decl);
if (!actuallyUsed(usages)) {
addViolation(data, decl.getNode(), decl.getImage());
}
VariableNameDeclaration decl = (VariableNameDeclaration)node.getNameDeclaration();
// TODO this isArray() check misses some cases
// need to add DFAish code to determine if an array
// is initialized locally or gotten from somewhere else
if (!decl.isArray() && !actuallyUsed((List)node.getScope().getVariableDeclarations().get(decl))) {
addViolation(data, decl.getNode(), decl.getImage());
}
}
return data;

View File

@ -199,7 +199,9 @@ public class ScopeAndDeclarationFinder extends JavaParserVisitorAdapter {
}
public Object visit(ASTVariableDeclaratorId node, Object data) {
node.getScope().addDeclaration(new VariableNameDeclaration(node));
VariableNameDeclaration decl = new VariableNameDeclaration(node);
node.getScope().addDeclaration(decl);
node.setNameDeclaration(decl);
return super.visit(node, data);
}