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