01: package net.sourceforge.pmd.rules.strings;
02:
03: import net.sourceforge.pmd.AbstractRule;
04: import net.sourceforge.pmd.ast.ASTAdditiveExpression;
05: import net.sourceforge.pmd.ast.ASTAllocationExpression;
06: import net.sourceforge.pmd.ast.ASTArrayDimsAndInits;
07: import net.sourceforge.pmd.ast.ASTClassOrInterfaceType;
08: import net.sourceforge.pmd.ast.ASTExpression;
09: import net.sourceforge.pmd.ast.ASTName;
10: import net.sourceforge.pmd.symboltable.NameDeclaration;
11: import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
12: import net.sourceforge.pmd.typeresolution.TypeHelper;
13:
14: import java.util.List;
15:
16: public class StringInstantiation extends AbstractRule {
17:
18: public Object visit(ASTAllocationExpression node, Object data) {
19: if (!(node.jjtGetChild(0) instanceof ASTClassOrInterfaceType)) {
20: return data;
21: }
22:
23: if (!TypeHelper.isA((ASTClassOrInterfaceType) node
24: .jjtGetChild(0), String.class)) {
25: return data;
26: }
27:
28: List exp = node.findChildrenOfType(ASTExpression.class);
29: if (exp.size() >= 2) {
30: return data;
31: }
32:
33: if (node.getFirstChildOfType(ASTArrayDimsAndInits.class) != null
34: || node
35: .getFirstChildOfType(ASTAdditiveExpression.class) != null) {
36: return data;
37: }
38:
39: ASTName name = node.getFirstChildOfType(ASTName.class);
40: // Literal, i.e., new String("foo")
41: if (name == null) {
42: addViolation(data, node);
43: return data;
44: }
45:
46: NameDeclaration nd = name.getNameDeclaration();
47: if (!(nd instanceof VariableNameDeclaration)) {
48: return data;
49: }
50:
51: VariableNameDeclaration vnd = (VariableNameDeclaration) nd;
52: // nd == null in cases like: return new String(str);
53: if (vnd == null || TypeHelper.isA(vnd, String.class)) {
54: addViolation(data, node);
55: }
56: return data;
57: }
58: }
|