forked from phoedos/pmd
moved to net.sourceforge
git-svn-id: https://pmd.svn.sourceforge.net/svnroot/pmd/trunk@15 51baf565-9d33-0410-a72c-fc3788e3496d
This commit is contained in:
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 17, 2002
|
|
||||||
* Time: 5:44:22 PM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitorAdapter;
|
|
||||||
|
|
||||||
public abstract class AbstractRule extends JavaParserVisitorAdapter {
|
|
||||||
public String getName() {return getClass().getName();}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
Rule r = (Rule)o;
|
|
||||||
return r.getName().equals(getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return getName().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitorAdapter;
|
|
||||||
import com.infoether.pmd.ast.ASTAllocationExpression;
|
|
||||||
import com.infoether.pmd.ast.ASTName;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitorAdapter;
|
|
||||||
import com.infoether.pmd.ast.ASTAllocationExpression;
|
|
||||||
import com.infoether.pmd.ast.ASTName;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 14, 2002
|
|
||||||
* Time: 12:13:55 PM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.*;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 17, 2002
|
|
||||||
* Time: 4:23:30 PM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitorAdapter;
|
|
||||||
import com.infoether.pmd.ast.ASTBlock;
|
|
||||||
import com.infoether.pmd.ast.ASTTryStatement;
|
|
||||||
import com.infoether.pmd.ast.ASTIfStatement;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 21, 2002
|
|
||||||
* Time: 2:11:15 PM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Here's the problem:
|
|
||||||
*
|
|
||||||
* public class Outer
|
|
||||||
* {
|
|
||||||
* private String foo;
|
|
||||||
* public void foo() {
|
|
||||||
* bar(new Runnable() {public void run() {String foo;}});
|
|
||||||
* }
|
|
||||||
* private void bar(Runnable r) {}
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* In this example, Outer.foo and the Runnable.foo are two different variables - even though
|
|
||||||
* Runnable.foo looks like its inside Outer, they don't conflict.
|
|
||||||
*
|
|
||||||
* So, a couple of SymbolTables are grouped into a Namespace. SymbolTables are grouped so that inner classes have their own
|
|
||||||
* "group" of symbol tables. So a class with an inner class would look like this:
|
|
||||||
*
|
|
||||||
* ST
|
|
||||||
* ST
|
|
||||||
* NS2
|
|
||||||
* ST ST ST
|
|
||||||
* ST ST ST
|
|
||||||
* NS1 NS1 NS1
|
|
||||||
*
|
|
||||||
* That way the scopes work out nicely and inner classes can be arbitrarily nested.
|
|
||||||
*/
|
|
||||||
public class Namespace {
|
|
||||||
|
|
||||||
private Stack tables = new Stack();
|
|
||||||
|
|
||||||
public void addTable() {
|
|
||||||
if (tables.empty()) {
|
|
||||||
tables.push(new SymbolTable());
|
|
||||||
} else {
|
|
||||||
tables.push(new SymbolTable((SymbolTable)tables.peek()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeTable() {
|
|
||||||
tables.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public SymbolTable peek() {
|
|
||||||
return (SymbolTable)tables.peek();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
|
||||||
return tables.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 17, 2002
|
|
||||||
* Time: 3:23:17 PM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParser;
|
|
||||||
import com.infoether.pmd.ast.ASTCompilationUnit;
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitor;
|
|
||||||
import com.infoether.pmd.ast.ParseException;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class PMD {
|
|
||||||
|
|
||||||
public Report processFile(InputStream is) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Report processFile(FileReader fr) {
|
|
||||||
return null; }
|
|
||||||
|
|
||||||
public Report processFile(File file, String ruleSetType) {
|
|
||||||
Report report = new Report(file.getAbsolutePath());
|
|
||||||
List rules = RuleFactory.createRules(ruleSetType);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Reader reader = new BufferedReader(new FileReader(file));
|
|
||||||
JavaParser parser = new JavaParser(reader);
|
|
||||||
ASTCompilationUnit c = parser.CompilationUnit();
|
|
||||||
//c.dump("");
|
|
||||||
for (Iterator iterator = rules.iterator(); iterator.hasNext();) {
|
|
||||||
JavaParserVisitor rule = (JavaParserVisitor)iterator.next();
|
|
||||||
c.childrenAccept(rule, report);
|
|
||||||
}
|
|
||||||
reader.close();
|
|
||||||
} catch (FileNotFoundException fnfe) {
|
|
||||||
fnfe.printStackTrace();
|
|
||||||
} catch (ParseException pe) {
|
|
||||||
System.out.println("Error while parsing " + file.getAbsolutePath() + " at line " + pe.currentToken.beginLine + "; continuing...");
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
System.out.println("Error while parsing " + file.getAbsolutePath() + "; "+ t.getMessage() + "; continuing...");
|
|
||||||
//t.printStackTrace();
|
|
||||||
}
|
|
||||||
return report;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
if (args.length == 0) {
|
|
||||||
throw new RuntimeException("Pass a filename in");
|
|
||||||
}
|
|
||||||
File input = new File(args[0]);
|
|
||||||
if (!input.exists()) {
|
|
||||||
throw new RuntimeException("File " + args[0] + " doesn't exist");
|
|
||||||
}
|
|
||||||
PMD pmd = new PMD();
|
|
||||||
Report report = pmd.processFile(input, RuleFactory.ALL);
|
|
||||||
System.out.println(report.renderToText());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import org.apache.tools.ant.*;
|
|
||||||
import org.apache.tools.ant.types.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParser;
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitor;
|
|
||||||
import com.infoether.pmd.ast.ParseException;
|
|
||||||
import com.infoether.pmd.ast.ASTCompilationUnit;
|
|
||||||
|
|
||||||
public class PMDTask extends Task {
|
|
||||||
|
|
||||||
private List filesets = new ArrayList();
|
|
||||||
private String reportFile;
|
|
||||||
private boolean verbose;
|
|
||||||
private String ruleSetType;
|
|
||||||
|
|
||||||
public void setVerbose(boolean verbose) {
|
|
||||||
this.verbose = verbose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRuleSetType(String ruleSetType) {
|
|
||||||
this.ruleSetType = ruleSetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFileset(FileSet set) {
|
|
||||||
filesets.add(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReportFile(String reportFile) {
|
|
||||||
this.reportFile = reportFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute() throws BuildException {
|
|
||||||
if (reportFile == null) {
|
|
||||||
throw new BuildException("No report file specified");
|
|
||||||
}
|
|
||||||
if (ruleSetType == null) {
|
|
||||||
throw new BuildException("No rule set type specified");
|
|
||||||
}
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
for (Iterator i = filesets.iterator(); i.hasNext();) {
|
|
||||||
FileSet fs = (FileSet) i.next();
|
|
||||||
DirectoryScanner ds = fs.getDirectoryScanner(project);
|
|
||||||
String[] srcFiles = ds.getIncludedFiles();
|
|
||||||
for (int j=0; j<srcFiles.length; j++) {
|
|
||||||
File file = new File(ds.getBasedir() + System.getProperty("file.separator") + srcFiles[j]);
|
|
||||||
if (verbose) System.out.println(file.getAbsoluteFile());
|
|
||||||
PMD pmd = new PMD();
|
|
||||||
Report report = pmd.processFile(file, ruleSetType);
|
|
||||||
if (!report.empty()) {
|
|
||||||
buf.append(report.renderToText());
|
|
||||||
buf.append(System.getProperty("line.separator"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(reportFile)));
|
|
||||||
writer.write(buf.toString(), 0, buf.length());
|
|
||||||
writer.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new BuildException(ioe.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class Report {
|
|
||||||
|
|
||||||
private List violations = new ArrayList();
|
|
||||||
private String filename;
|
|
||||||
|
|
||||||
public Report(String filename) {
|
|
||||||
this.filename = filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addRuleViolation(RuleViolation violation) {
|
|
||||||
violations.add(violation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String renderToText() {
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
for (Iterator i = violations.iterator(); i.hasNext();) {
|
|
||||||
if (buf.length() != 0) {
|
|
||||||
buf.append(System.getProperty("line.separator"));
|
|
||||||
}
|
|
||||||
buf.append(filename + ":" + ((RuleViolation)i.next()).getText());
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean empty() {
|
|
||||||
return violations.size() == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator iterator() {
|
|
||||||
return violations.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return violations.size();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public interface Rule {
|
|
||||||
public String getName();
|
|
||||||
public String getDescription();
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 10, 2002
|
|
||||||
* Time: 11:27:51 AM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class RuleFactory {
|
|
||||||
|
|
||||||
public static final String ALL = "all";
|
|
||||||
public static final String GENERAL = "general";
|
|
||||||
public static final String COUGAAR = "cougaar";
|
|
||||||
|
|
||||||
public static List createRules(String ruleSetType) {
|
|
||||||
if (ruleSetType.equals(ALL)) {
|
|
||||||
return createAllRules();
|
|
||||||
} else if (ruleSetType.equals(GENERAL)) {
|
|
||||||
return createGeneralRules();
|
|
||||||
} else if (ruleSetType.equals(COUGAAR)) {
|
|
||||||
return createCougaarRules();
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Unknown rule set type " + ruleSetType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List createAllRules() {
|
|
||||||
List list = new ArrayList();
|
|
||||||
list.addAll(createCougaarRules());
|
|
||||||
list.addAll(createGeneralRules());
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List createCougaarRules() {
|
|
||||||
List list = new ArrayList();
|
|
||||||
list.add(new DontCreateThreadsRule());
|
|
||||||
list.add(new DontCreateTimersRule());
|
|
||||||
list.add(new SystemOutRule());
|
|
||||||
list.add(new SystemPropsRule());
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List createGeneralRules() {
|
|
||||||
List list = new ArrayList();
|
|
||||||
list.add(new EmptyCatchBlockRule());
|
|
||||||
list.add(new EmptyIfStmtRule());
|
|
||||||
list.add(new UnnecessaryConversionTemporaryRule());
|
|
||||||
list.add(new UnusedLocalVariableRule());
|
|
||||||
//list.add(new UnusedPrivateInstanceVariableRule());
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
public class RuleViolation {
|
|
||||||
|
|
||||||
private int line;
|
|
||||||
private Rule rule;
|
|
||||||
private String specificDescription;
|
|
||||||
|
|
||||||
public RuleViolation(Rule rule, int line) {
|
|
||||||
this(rule, line, rule.getDescription());
|
|
||||||
}
|
|
||||||
|
|
||||||
public RuleViolation(Rule rule, int line, String specificDescription) {
|
|
||||||
this.line = line;
|
|
||||||
this.rule = rule;
|
|
||||||
this.specificDescription = specificDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return rule.getName() +":" + specificDescription + ":" + line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rule getRule() {
|
|
||||||
return rule;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 19, 2002
|
|
||||||
* Time: 11:48:50 AM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
public class Symbol {
|
|
||||||
|
|
||||||
private String image;
|
|
||||||
private int line;
|
|
||||||
|
|
||||||
public Symbol(String image, int line) {
|
|
||||||
this.image = image;
|
|
||||||
this.line = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLine() {
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getImage() {
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
Symbol s = (Symbol)o;
|
|
||||||
return s.image.equals(this.image);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return image.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return image + ":" + line;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 19, 2002
|
|
||||||
* Time: 9:31:16 AM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class SymbolTable {
|
|
||||||
|
|
||||||
private SymbolTable parent;
|
|
||||||
private HashMap usageCounts = new HashMap();
|
|
||||||
|
|
||||||
public SymbolTable() {}
|
|
||||||
|
|
||||||
public SymbolTable(SymbolTable parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SymbolTable getParent() {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add(Symbol symbol) {
|
|
||||||
if (usageCounts.containsKey(symbol)) {
|
|
||||||
throw new RuntimeException(symbol + " is already in the symbol table");
|
|
||||||
}
|
|
||||||
if (parent != null && parent.contains(symbol)) {
|
|
||||||
throw new RuntimeException(symbol + " is already in the parent symbol table");
|
|
||||||
}
|
|
||||||
usageCounts.put(symbol, new Integer(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recordPossibleUsageOf(Symbol symbol) {
|
|
||||||
if (!usageCounts.containsKey(symbol) && parent != null) {
|
|
||||||
parent.recordPossibleUsageOf(symbol);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!usageCounts.containsKey(symbol) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Integer usageCount = (Integer)usageCounts.get(symbol);
|
|
||||||
usageCount = new Integer(usageCount.intValue() + 1);
|
|
||||||
usageCounts.put(symbol, usageCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator getUnusedSymbols() {
|
|
||||||
List list = new ArrayList();
|
|
||||||
for (Iterator i = usageCounts.keySet().iterator(); i.hasNext();) {
|
|
||||||
Symbol symbol = (Symbol)i.next();
|
|
||||||
int usageCount = ((Integer)(usageCounts.get(symbol))).intValue();
|
|
||||||
if (usageCount == 0) {
|
|
||||||
list.add(symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer buf = new StringBuffer();
|
|
||||||
for (Iterator i = usageCounts.keySet().iterator(); i.hasNext();) {
|
|
||||||
Symbol symbol = (Symbol)i.next();
|
|
||||||
int usageCount = ((Integer)(usageCounts.get(symbol))).intValue();
|
|
||||||
buf.append(symbol + "," + usageCount +":");
|
|
||||||
}
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean contains(Symbol symbol) {
|
|
||||||
if (usageCounts.containsKey(symbol)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (parent == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return parent.contains(symbol);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitorAdapter;
|
|
||||||
import com.infoether.pmd.ast.ASTName;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.ASTName;
|
|
||||||
import com.infoether.pmd.ast.JavaParserVisitorAdapter;
|
|
||||||
import com.infoether.pmd.ast.SimpleNode;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 20, 2002
|
|
||||||
* Time: 1:35:27 PM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.*;
|
|
||||||
|
|
||||||
public class UnnecessaryConversionTemporaryRule extends AbstractRule implements Rule{
|
|
||||||
|
|
||||||
private boolean inPrimaryExpressionContext;
|
|
||||||
private boolean usingPrimitiveWrapperAllocation;
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (!isPrimitiveWrapperType(child.getImage())) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPrimitiveWrapperType(String name) {
|
|
||||||
return name.equals("Integer") || name.equals("Boolean") || name.equals("Double") || name.equals("Long") || name.equals("Short") || name.equals("Byte") || name.equals("Float");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 18, 2002
|
|
||||||
* Time: 11:02:09 AM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.*;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// these AST types trigger creation of a new symbol table group
|
|
||||||
public Object visit(ASTClassBody node, Object data) {return createGroup(node, data);}
|
|
||||||
public Object visit(ASTInterfaceDeclaration node, Object data) {return createGroup(node, data);}
|
|
||||||
// these AST types trigger creation of a new symbol table group
|
|
||||||
|
|
||||||
// these AST types trigger creation of a new symbol table
|
|
||||||
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();
|
|
||||||
Object RC = super.visit(node, data);
|
|
||||||
reportUnusedLocals((Report)data, group.peek());
|
|
||||||
group.removeTable();
|
|
||||||
return RC;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* User: tom
|
|
||||||
* Date: Jun 21, 2002
|
|
||||||
* Time: 11:26:34 AM
|
|
||||||
*/
|
|
||||||
package com.infoether.pmd;
|
|
||||||
|
|
||||||
import com.infoether.pmd.ast.*;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
doingIDTraversal = true;
|
|
||||||
Namespace nameSpace = new Namespace();
|
|
||||||
nameSpaces.push(nameSpace);
|
|
||||||
nameSpace.addTable();
|
|
||||||
Object report = super.visit(node, data);
|
|
||||||
|
|
||||||
doingIDTraversal = false;
|
|
||||||
//System.out.println("data = " + data);
|
|
||||||
report = super.visit(node, data);
|
|
||||||
reportUnusedInstanceVars((Report)report, nameSpace.peek());
|
|
||||||
|
|
||||||
nameSpace.removeTable();
|
|
||||||
nameSpaces.pop();
|
|
||||||
return report;
|
|
||||||
}
|
|
||||||
|
|
||||||
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() + "'"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user