KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > coding > ExplicitInitializationCheck


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle.checks.coding;
20
21 import com.puppycrawl.tools.checkstyle.api.Check;
22 import com.puppycrawl.tools.checkstyle.api.DetailAST;
23 import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
24 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
25
26 import com.puppycrawl.tools.checkstyle.checks.CheckUtils;
27
28 /**
29  * <p>
30  * Checks if any class or object member explicitly initialized
31  * to default for its type value (<code>null</code> for object
32  * references, zero for numeric types and <code>char</code>
33  * and <code>false</code> for <code>boolean</code>.
34  * </p>
35  * <p>
36  * Rationale: each instance variable gets
37  * initialized twice, to the same value. Java
38  * initializes each instance variable to its default
39  * value (0 or null) before performing any
40  * initialization specified in the code. So in this case,
41  * x gets initialized to 0 twice, and bar gets initialized
42  * to null twice. So there is a minor inefficiency. This style of
43  * coding is a hold-over from C/C++ style coding,
44  * and it shows that the developer isn't really confident that
45  * Java really initializes instance variables to default
46  * values.
47  * </p>
48  *
49  * @author o_sukhodolsky
50  */

51 public class ExplicitInitializationCheck extends Check
52 {
53     /** {@inheritDoc} */
54     public final int[] getDefaultTokens()
55     {
56         return new int[] {TokenTypes.VARIABLE_DEF};
57     }
58
59     /** {@inheritDoc} */
60     public final int[] getRequiredTokens()
61     {
62         return getDefaultTokens();
63     }
64
65     /** {@inheritDoc} */
66     public void visitToken(DetailAST aAST)
67     {
68         // do not check local variables and
69
// fields declared in interface/annotations
70
if (ScopeUtils.isLocalVariableDef(aAST)
71             || ScopeUtils.inInterfaceOrAnnotationBlock(aAST))
72         {
73             return;
74         }
75
76         final DetailAST assign = aAST.findFirstToken(TokenTypes.ASSIGN);
77         if (assign == null) {
78             // no assign - no check
79
return;
80         }
81
82         final DetailAST modifiers = aAST.findFirstToken(TokenTypes.MODIFIERS);
83         if ((modifiers != null)
84             && modifiers.branchContains(TokenTypes.FINAL))
85         {
86             // do not check final variables
87
return;
88         }
89
90         final DetailAST type = aAST.findFirstToken(TokenTypes.TYPE);
91         final DetailAST ident = aAST.findFirstToken(TokenTypes.IDENT);
92         final DetailAST exprStart =
93             (DetailAST) assign.getFirstChild().getFirstChild();
94         if (isObjectType(type)
95             && (exprStart.getType() == TokenTypes.LITERAL_NULL))
96         {
97             log(ident, "explicit.init", ident.getText(), "null");
98         }
99
100         final int primitiveType = type.getFirstChild().getType();
101         if ((primitiveType == TokenTypes.LITERAL_BOOLEAN)
102             && (exprStart.getType() == TokenTypes.LITERAL_FALSE))
103         {
104             log(ident, "explicit.init", ident.getText(), "false");
105         }
106         if (isNumericType(primitiveType) && isZero(exprStart)) {
107             log(ident, "explicit.init", ident.getText(), "0");
108         }
109         if ((primitiveType == TokenTypes.LITERAL_CHAR)
110             && (isZero(exprStart)
111                 || ((exprStart.getType() == TokenTypes.CHAR_LITERAL)
112                 && "'\\0'".equals(exprStart.getText()))))
113         {
114             log(ident, "explicit.init", ident.getText(), "\\0");
115         }
116     }
117
118     /**
119      * Determines if a giiven type is an object type.
120      * @param aType type to check.
121      * @return true if it is an object type.
122      */

123     private boolean isObjectType(DetailAST aType)
124     {
125         final int type = aType.getFirstChild().getType();
126         return ((type == TokenTypes.IDENT) || (type == TokenTypes.DOT)
127                 || (type == TokenTypes.ARRAY_DECLARATOR));
128     }
129
130     /**
131      * Determine if a given type is a numeric type.
132      * @param aType code of the type for check.
133      * @return true if it's a numeric type.
134      * @see TokenTypes
135      */

136     private boolean isNumericType(int aType)
137     {
138         return ((aType == TokenTypes.LITERAL_BYTE)
139                 || (aType == TokenTypes.LITERAL_SHORT)
140                 || (aType == TokenTypes.LITERAL_INT)
141                 || (aType == TokenTypes.LITERAL_FLOAT)
142                 || (aType == TokenTypes.LITERAL_LONG)
143                 || (aType == TokenTypes.LITERAL_DOUBLE));
144     }
145
146     /**
147      * @param aExpr node to check.
148      * @return true if given node contains numeric constant for zero.
149      */

150     private boolean isZero(DetailAST aExpr)
151     {
152         final int type = aExpr.getType();
153         switch (type) {
154         case TokenTypes.NUM_FLOAT:
155         case TokenTypes.NUM_DOUBLE:
156         case TokenTypes.NUM_INT:
157         case TokenTypes.NUM_LONG:
158             final String JavaDoc text = aExpr.getText();
159             return (0 == CheckUtils.parseFloat(text, type));
160         default:
161             return false;
162         }
163     }
164 }
165
Popular Tags