StringInstantiationRule.java
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(0instanceof ASTClassOrInterfaceType)) {
21       return data;
22   }
23 
24   if (!TypeHelper.isA((ASTClassOrInterfaceTypenode.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 = (VariableNameDeclarationnd;
51   if (TypeHelper.isA(vnd, String.class)) {
52       addViolation(data, node);
53   }
54   return data;
55     }
56 }