View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.basic;
5   
6   import java.math.BigDecimal;
7   import java.math.BigInteger;
8   
9   import net.sourceforge.pmd.RuleContext;
10  import net.sourceforge.pmd.lang.LanguageRegistry;
11  import net.sourceforge.pmd.lang.ast.Node;
12  import net.sourceforge.pmd.lang.java.JavaLanguageModule;
13  import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
14  import net.sourceforge.pmd.lang.java.ast.ASTArguments;
15  import net.sourceforge.pmd.lang.java.ast.ASTArrayDimsAndInits;
16  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
17  import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
18  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
19  import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
20  
21  /**
22   * Rule that marks instantiations of new {@link BigInteger} or {@link BigDecimal} objects,
23   * when there is a well-known constant available, such as {@link BigInteger#ZERO}.
24   */
25  public class BigIntegerInstantiationRule extends AbstractJavaRule {
26  
27      @Override
28      public Object visit(ASTAllocationExpression node, Object data) {
29          Node type = node.jjtGetChild(0);
30  
31          if (!(type instanceof ASTClassOrInterfaceType)) {
32              return super.visit(node, data);
33          }
34  
35          boolean jdk15 = ((RuleContext) data).getLanguageVersion().compareTo(LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getVersion("1.5")) >= 0;
36          if ((TypeHelper.isA((ASTClassOrInterfaceType) type, BigInteger.class) || jdk15 && TypeHelper.isA((ASTClassOrInterfaceType) type, BigDecimal.class)) &&
37                  !node.hasDescendantOfType(ASTArrayDimsAndInits.class)
38          ) {
39              ASTArguments args = node.getFirstChildOfType(ASTArguments.class);
40              if (args.getArgumentCount() == 1) {
41                  ASTLiteral literal = node.getFirstDescendantOfType(ASTLiteral.class);
42                  if (literal == null || literal.jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent().jjtGetParent() != args) {
43                      return super.visit(node, data);
44                  }
45  
46                  String img = literal.getImage();
47                  if (literal.isStringLiteral()) {
48                      img = img.substring(1, img.length() - 1);
49                  }
50  
51                  if ("0".equals(img) || "1".equals(img) || jdk15 && "10".equals(img)) {
52                      addViolation(data, node);
53                      return data;
54                  }
55              }
56          }
57          return super.visit(node, data);
58      }
59  
60  }