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