moved fm net.sourceforge.pmd

git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@72 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
Tom Copeland
2002-06-26 18:13:17 +00:00
parent 2192cb0e20
commit 5e7a082b6b
10 changed files with 485 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.ast.ASTAllocationExpression;
import net.sourceforge.pmd.ast.ASTName;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
import java.util.*;
public class DontCreateThreadsRule extends AbstractRule implements Rule {
public String getDescription() {return "Don't create threads, use the ThreadService instead";}
public Object visit(ASTAllocationExpression node, Object data){
if ((node.jjtGetChild(0) instanceof ASTName) // this avoids "new <primitive-type>", i.e., "new int[]"
&& ((ASTName)node.jjtGetChild(0)).getImage().equals("Thread")) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node, data);
}
}

View File

@@ -0,0 +1,24 @@
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.ast.ASTAllocationExpression;
import net.sourceforge.pmd.ast.ASTName;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
import java.util.*;
public class DontCreateTimersRule extends AbstractRule implements Rule {
public String getDescription() {return "Don't create java.util.Timers, use the Cougaar alarm service instead";}
public Object visit(ASTAllocationExpression node, Object data){
if ((node.jjtGetChild(0) instanceof ASTName) // this avoids "new <primitive-type>", i.e., "new int[]"
&& ((ASTName)node.jjtGetChild(0)).getImage().equals("Timer")) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node, data);
}
}

View File

@@ -0,0 +1,26 @@
/*
* User: tom
* Date: Jun 14, 2002
* Time: 12:13:55 PM
*/
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.ASTBlock;
import net.sourceforge.pmd.ast.ASTTryStatement;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
public class EmptyCatchBlockRule extends AbstractRule implements Rule {
public String getDescription() {return "Avoid empty catch blocks";}
public Object visit(ASTBlock node, Object data){
if ((node.jjtGetParent() instanceof ASTTryStatement) && node.jjtGetNumChildren()==0) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node, data);
}
}

View File

@@ -0,0 +1,27 @@
/*
* User: tom
* Date: Jun 17, 2002
* Time: 4:23:30 PM
*/
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.ast.ASTBlock;
import net.sourceforge.pmd.ast.ASTTryStatement;
import net.sourceforge.pmd.ast.ASTIfStatement;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
public class EmptyIfStmtRule extends AbstractRule implements Rule {
public String getDescription() {return "Avoid empty IF statements";}
public Object visit(ASTBlock node, Object data){
if ((node.jjtGetParent().jjtGetParent() instanceof ASTIfStatement) && node.jjtGetNumChildren()==0) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node, data);
}
}

View File

@@ -0,0 +1,76 @@
/*
* User: tom
* Date: Jun 26, 2002
* Time: 10:21:05 AM
*/
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.ASTIfStatement;
import net.sourceforge.pmd.ast.SimpleNode;
import net.sourceforge.pmd.ast.ASTBlock;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
public class IfElseStmtsMustUseBracesRule extends AbstractRule implements Rule {
private int lineNumberOfLastViolation;
public String getDescription() {
return "Avoid using IF...ELSE statements without curly braces";
}
/**
* If..else stmt structure seems to be like this:
* IfStmt
* Expression
* Stmt
* Block
* Stmt
* Block
* if (foo == null) {
* return bar;
* } else {
* return buz;
* }
*
* Sometimes people get lazy and leave out the Blocks, like this:
* if (foo== null)
* return bar;
* else
* return buz;
*
* The following usage is OK though:
* IfStmt
* Expression
* Stmt
* i.e.:
* if (foo == null)
* return bar;
*
*/
public Object visit(ASTIfStatement node, Object data) {
// filter out if stmts without an else
if (node.jjtGetNumChildren() < 3) {
return super.visit(node, data);
}
// the first child is a Expression, so skip that and get the first 2 stmts
SimpleNode firstStmt = (SimpleNode)node.jjtGetChild(1);
SimpleNode secondStmt = (SimpleNode)node.jjtGetChild(2);
if (!hasBlockAsFirstChild(firstStmt) && !hasBlockAsFirstChild(secondStmt)) {
if (node.getBeginLine() != this.lineNumberOfLastViolation) {
Report rpt = (Report)data;
rpt.addRuleViolation(new RuleViolation(this, node.getBeginLine()));
this.lineNumberOfLastViolation = node.getBeginLine();
}
}
return super.visit(node,data);
}
private boolean hasBlockAsFirstChild(SimpleNode node) {
return (node.jjtGetNumChildren() != 0 && (node.jjtGetChild(0) instanceof ASTBlock));
}
}

View File

@@ -0,0 +1,22 @@
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.ast.ASTName;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
import java.util.*;
public class SystemOutRule extends AbstractRule implements Rule {
public String getDescription() {return "Don't use System.out/in/err, use the Cougaar logging service instead";}
public Object visit(ASTName node, Object data){
if (node.getImage() != null && (node.getImage().startsWith("System.out") || node.getImage().startsWith("System.err") || node.getImage().startsWith("System.in"))) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node,data);
}
}

View File

@@ -0,0 +1,23 @@
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.ASTName;
import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
import net.sourceforge.pmd.ast.SimpleNode;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
import java.util.*;
public class SystemPropsRule extends AbstractRule implements Rule {
public String getDescription() {return "Don't use System.getProperty()/getProperties()/setProperty";}
public Object visit(ASTName node, Object data){
if (node.getImage() != null && (node.getImage().startsWith("System.getProperty") || node.getImage().startsWith("System.setProperty") || node.getImage().startsWith("System.getProperties"))) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node,data);
}
}

View File

@@ -0,0 +1,74 @@
/*
* User: tom
* Date: Jun 20, 2002
* Time: 1:35:27 PM
*/
package net.sourceforge.pmd.rules;
import net.sourceforge.pmd.ast.*;
import net.sourceforge.pmd.AbstractRule;
import net.sourceforge.pmd.Rule;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
import java.util.Set;
import java.util.HashSet;
public class UnnecessaryConversionTemporaryRule extends AbstractRule implements Rule{
private boolean inPrimaryExpressionContext;
private boolean usingPrimitiveWrapperAllocation;
private Set primitiveTypes = new HashSet();
public UnnecessaryConversionTemporaryRule() {
primitiveTypes.add("Integer");
primitiveTypes.add("Boolean");
primitiveTypes.add("Double");
primitiveTypes.add("Long");
primitiveTypes.add("Short");
primitiveTypes.add("Byte");
primitiveTypes.add("Float");
}
public String getDescription() {
return "Avoid unnecessay temporaries when converting primitives to Strings";
}
public Object visit(ASTPrimaryExpression node, Object data) {
if (node.jjtGetNumChildren() == 0 || ((SimpleNode)node.jjtGetChild(0)).jjtGetNumChildren() == 0 || !(node.jjtGetChild(0).jjtGetChild(0) instanceof ASTAllocationExpression)) {
return super.visit(node, data);
}
inPrimaryExpressionContext = true;
Object report = super.visit(node, data);
inPrimaryExpressionContext = false;
usingPrimitiveWrapperAllocation = false;
return report;
}
public Object visit(ASTAllocationExpression node, Object data) {
if (!inPrimaryExpressionContext) {
return super.visit(node, data);
}
if (!(node.jjtGetChild(0) instanceof ASTName)) {
return super.visit(node, data);
}
SimpleNode child = (SimpleNode)node.jjtGetChild(0);
String name = child.getImage();
if (!primitiveTypes.contains(name)) {
return super.visit(node, data);
}
usingPrimitiveWrapperAllocation = true;
return super.visit(node, data);
}
public Object visit(ASTPrimarySuffix node, Object data) {
if (!inPrimaryExpressionContext || !usingPrimitiveWrapperAllocation) {
return super.visit(node, data);
}
if (node.getImage() != null && node.getImage().equals("toString")) {
((Report)data).addRuleViolation(new RuleViolation(this, node.getBeginLine()));
}
return super.visit(node, data);
}
}

View File

@@ -0,0 +1,90 @@
/*
* User: tom
* Date: Jun 18, 2002
* Time: 11:02:09 AM
*/
package net.sourceforge.pmd.rules;
import java.util.Iterator;
import java.util.Stack;
import net.sourceforge.pmd.ast.*;
import net.sourceforge.pmd.*;
public class UnusedLocalVariableRule extends AbstractRule implements Rule{
private Stack tableGroups = new Stack();
public String getDescription() {
return "Avoid unused local variables";
}
public Object createGroup(SimpleNode node, Object data) {
tableGroups.push(new Namespace());
Object report = super.visit(node, data);
tableGroups.pop();
return report;
}
/**
* Skip interfaces because they don't have local variables.
*/
public Object visit(ASTInterfaceDeclaration node, Object data) {
return data;
}
/**
* A new ClassBody triggers a new namespace
*/
public Object visit(ASTClassBody node, Object data) {
return createGroup(node, data);
}
// these AST types trigger creation of a new symbol table scope
public Object visit(ASTBlock node, Object data){return addTable(node, data);}
public Object visit(ASTConstructorDeclaration node, Object data){return addTable(node, data);}
public Object visit(ASTMethodDeclaration node, Object data){return addTable(node, data);}
public Object visit(ASTFieldDeclaration node, Object data){return addTable(node, data);}
public Object visit(ASTTryStatement node, Object data){return addTable(node, data);}
public Object visit(ASTForStatement node, Object data){return addTable(node, data);}
// these AST types trigger creation of a new symbol table
// these AST types are variable/name usages
public Object visit(ASTVariableDeclaratorId node, Object data) {
//System.out.println("ASTVariableDeclaratorId.getImage() = " + node.getImage());
if (!(node.jjtGetParent().jjtGetParent() instanceof ASTLocalVariableDeclaration)) {
return super.visit(node, data);
}
Namespace group = (Namespace)tableGroups.peek();
group.peek().add(new Symbol(node.getImage(), node.getBeginLine()));
return super.visit(node, data);
}
public Object visit(ASTName node, Object data) {
//System.out.println("ASTName.getImage() = " + node.getImage() + "; " + node.getBeginLine());
if (node.jjtGetParent() instanceof ASTPrimaryPrefix) {
String img = (node.getImage().indexOf('.') == -1) ? node.getImage() : node.getImage().substring(0, node.getImage().indexOf('.'));
Namespace group = (Namespace)tableGroups.peek();
group.peek().recordPossibleUsageOf(new Symbol(img, node.getBeginLine()));
}
return super.visit(node, data);
}
// these AST types are variable/name usages
private void reportUnusedLocals(Report report, SymbolTable table) {
for (Iterator i = table.getUnusedSymbols(); i.hasNext();) {
Symbol symbol = (Symbol)i.next();
report.addRuleViolation(new RuleViolation(this, symbol.getLine(), "Found unused local variable '" + symbol.getImage() + "'"));
}
}
private Object addTable(SimpleNode node, Object data) {
Namespace group = (Namespace)tableGroups.peek();
group.addTable();
super.visit(node, data);
reportUnusedLocals((Report)data, group.peek());
group.removeTable();
return data;
}
}

View File

@@ -0,0 +1,99 @@
/*
* User: tom
* Date: Jun 21, 2002
* Time: 11:26:34 AM
*/
package net.sourceforge.pmd.rules;
import java.util.Iterator;
import java.util.Stack;
import net.sourceforge.pmd.ast.*;
import net.sourceforge.pmd.*;
public class UnusedPrivateInstanceVariableRule extends AbstractRule implements Rule {
private Stack nameSpaces = new Stack();
// TODO
// this being an instance variable totally hoses up the recursion
// need to attach it to the report or the stack or something
// TODO
private boolean doingIDTraversal;
// TODO
// this means we don't process nested or inner classes, which is sloppy
// TODO
private boolean alreadyWorking;
public String getDescription() {
return "Avoid unused private instance variables";
}
/**
* Skip interfaces because they don't have instance variables.
*/
public Object visit(ASTInterfaceDeclaration node, Object data) {
return data;
}
public Object visit(ASTClassBody node, Object data) {
if (alreadyWorking) {
return data;
}
alreadyWorking = true;
doingIDTraversal = true;
Namespace nameSpace = new Namespace();
nameSpaces.push(nameSpace);
nameSpace.addTable();
super.visit(node, null);
doingIDTraversal = false;
super.visit(node, null);
reportUnusedInstanceVars((Report)data, nameSpace.peek());
nameSpace.removeTable();
nameSpaces.pop();
alreadyWorking = false;
return data;
}
public Object visit(ASTVariableDeclaratorId node, Object data) {
if (!doingIDTraversal) {
return super.visit(node, data);
}
//System.out.println("ASTVariableDeclaratorId.getImage() = " + node.getImage() + "; " + node.getBeginLine());
SimpleNode grandparent = (SimpleNode)node.jjtGetParent().jjtGetParent();
if (!(grandparent instanceof ASTFieldDeclaration) || grandparent.getImage().indexOf("private") == -1 || grandparent.getImage().indexOf("static") != -1) {
return super.visit(node, data);
}
Namespace group = (Namespace)nameSpaces.peek();
group.peek().add(new Symbol(node.getImage(), node.getBeginLine()));
return super.visit(node, data);
}
public Object visit(ASTPrimarySuffix node, Object data) {
if (!doingIDTraversal && (node.jjtGetParent() instanceof ASTPrimaryExpression) && (node.getImage() != null)) {
recordPossibleUsage(node, data);
}
return super.visit(node, data);
}
public Object visit(ASTName node, Object data) {
if (!doingIDTraversal && (node.jjtGetParent() instanceof ASTPrimaryPrefix)) {
recordPossibleUsage(node, data);
}
return super.visit(node, data);
}
private void recordPossibleUsage(SimpleNode node, Object data) {
String img = (node.getImage().indexOf('.') == -1) ? node.getImage() : node.getImage().substring(0, node.getImage().indexOf('.'));
Namespace group = (Namespace)nameSpaces.peek();
group.peek().recordPossibleUsageOf(new Symbol(img, node.getBeginLine()));
}
private void reportUnusedInstanceVars(Report report, SymbolTable table) {
for (Iterator i = table.getUnusedSymbols(); i.hasNext();) {
Symbol symbol = (Symbol)i.next();
report.addRuleViolation(new RuleViolation(this, symbol.getLine(), "Found unused private instance variable '" + symbol.getImage() + "'"));
}
}
}