1 package net.sourceforge.pmd.lang.java.rule.optimizations;
2
3 import net.sourceforge.pmd.lang.ast.Node;
4 import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
5 import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
6 import net.sourceforge.pmd.lang.java.ast.ASTExpression;
7 import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
8 import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
9 import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral;
10 import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
11 import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
12 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclarator;
13 import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId;
14 import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
15
16
17
18
19
20
21
22 public class RedundantFieldInitializerRule extends AbstractJavaRule {
23
24 public RedundantFieldInitializerRule() {
25 addRuleChainVisit(ASTFieldDeclaration.class);
26 }
27
28 public Object visit(ASTFieldDeclaration fieldDeclaration, Object data) {
29
30 if (fieldDeclaration.isFinal()) {
31 return data;
32 }
33
34
35
36 for (ASTVariableDeclarator variableDeclarator : fieldDeclaration
37 .findChildrenOfType(ASTVariableDeclarator.class)) {
38 if (variableDeclarator.jjtGetNumChildren() > 1) {
39 final Node variableInitializer = variableDeclarator.jjtGetChild(1);
40 if (variableInitializer.jjtGetChild(0) instanceof ASTExpression) {
41 final Node expression = variableInitializer.jjtGetChild(0);
42 final Node primaryExpression;
43 if (expression.jjtGetNumChildren() == 1) {
44 if (expression.jjtGetChild(0) instanceof ASTPrimaryExpression) {
45 primaryExpression = expression.jjtGetChild(0);
46 } else if (expression.jjtGetChild(0) instanceof ASTCastExpression
47 && expression.jjtGetChild(0).jjtGetChild(1) instanceof ASTPrimaryExpression) {
48 primaryExpression = expression.jjtGetChild(0).jjtGetChild(1);
49 } else {
50 continue;
51 }
52 } else {
53 continue;
54 }
55 final Node primaryPrefix = primaryExpression.jjtGetChild(0);
56 if (primaryPrefix.jjtGetNumChildren() == 1 && primaryPrefix.jjtGetChild(0) instanceof ASTLiteral) {
57 final ASTLiteral literal = (ASTLiteral) primaryPrefix.jjtGetChild(0);
58 if (isRef(fieldDeclaration, variableDeclarator)) {
59
60 if (literal.jjtGetNumChildren() == 1 && literal.jjtGetChild(0) instanceof ASTNullLiteral) {
61 addViolation(data, variableDeclarator);
62 }
63 } else {
64
65 if (literal.jjtGetNumChildren() == 1 && literal.jjtGetChild(0) instanceof ASTBooleanLiteral) {
66
67 ASTBooleanLiteral booleanLiteral = (ASTBooleanLiteral) literal.jjtGetChild(0);
68 if (!booleanLiteral.isTrue()) {
69 addViolation(data, variableDeclarator);
70 }
71 } else if (literal.jjtGetNumChildren() == 0) {
72
73
74 double value = -1;
75 if (literal.isIntLiteral()) {
76 String s = literal.getImage();
77 if (s.endsWith("l") || s.endsWith("L")) {
78 s = s.substring(0, s.length() - 1);
79 }
80 value = Long.decode(s).doubleValue();
81 } else if (literal.isFloatLiteral()) {
82 value = Double.parseDouble(literal.getImage());
83 } else if (literal.isCharLiteral()) {
84 value = literal.getImage().charAt(1);
85 }
86
87 if (value == 0) {
88 addViolation(data, variableDeclarator);
89 }
90 }
91 }
92 }
93 }
94 }
95 }
96
97 return data;
98 }
99
100
101
102
103
104
105
106
107
108
109 private boolean isRef(ASTFieldDeclaration fieldDeclaration, ASTVariableDeclarator variableDeclarator) {
110 Node type = fieldDeclaration.jjtGetChild(0).jjtGetChild(0);
111 if (type instanceof ASTReferenceType) {
112
113 return true;
114 } else {
115
116 return ((ASTVariableDeclaratorId) variableDeclarator.jjtGetChild(0)).isArray();
117 }
118 }
119
120 private void addViolation(Object data, ASTVariableDeclarator variableDeclarator) {
121 super.addViolation(data, variableDeclarator, variableDeclarator.jjtGetChild(0).getImage());
122 }
123 }