KickJava   Java API By Example, From Geeks To Geeks.

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


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.Scope;
24 import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
25 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
26 import java.util.Stack JavaDoc;
27
28 /**
29  * <p>
30  * Checks that the parts of a class or interface declaration
31  * appear in the order suggested by the
32  * <a
33  * HREF="http://java.sun.com/docs/codeconv/html/CodeConventions.doc2.html#1852"
34  * >Code Conventions for the Java Programming Language</a>.
35  * </p>
36  * <p>
37  * <ol>
38  * <li> Class (static) variables. First the public class variables, then
39  * the protected, then package level (no access modifier), and then
40  * the private. </li>
41  * <li> Instance variables. First the public class variables, then
42  * the protected, then package level (no access modifier), and then
43  * the private. </li>
44  * <li> Constructors </li>
45  * <li> Methods </li>
46  * </ol>
47  * </p>
48  * <p>
49  * An example of how to configure the check is:
50  * </p>
51  * <pre>
52  * &lt;module name="DeclarationOrder"/&gt;
53  * </pre>
54  *
55  * @author r_auckenthaler
56  */

57 public class DeclarationOrderCheck extends Check
58 {
59     /** State for the VARIABLE_DEF */
60     private static final int STATE_STATIC_VARIABLE_DEF = 1;
61
62     /** State for the VARIABLE_DEF */
63     private static final int STATE_INSTANCE_VARIABLE_DEF = 2;
64
65     /** State for the CTOR_DEF */
66     private static final int STATE_CTOR_DEF = 3;
67
68     /** State for the METHOD_DEF */
69     private static final int STATE_METHOD_DEF = 4;
70
71     /**
72      * List of Declaration States. This is necessary due to
73      * inner classes that have their own state
74      */

75     private final Stack JavaDoc mScopeStates = new Stack JavaDoc();
76
77     /**
78      * private class to encapsulate the state
79      */

80     private class ScopeState
81     {
82         /** The state the check is in */
83         private int mScopeState = STATE_STATIC_VARIABLE_DEF;
84
85         /** The sub-state the check is in */
86         private Scope mDeclarationAccess = Scope.PUBLIC;
87     }
88
89     /** {@inheritDoc} */
90     public int[] getDefaultTokens()
91     {
92         return new int[] {
93             TokenTypes.CTOR_DEF,
94             TokenTypes.METHOD_DEF,
95             TokenTypes.MODIFIERS,
96             TokenTypes.OBJBLOCK,
97         };
98     }
99
100     /** {@inheritDoc} */
101     public void visitToken(DetailAST aAST)
102     {
103         final int parentType = aAST.getParent().getType();
104         ScopeState state;
105
106         switch(aAST.getType()) {
107         case TokenTypes.OBJBLOCK:
108             mScopeStates.push(new ScopeState());
109             break;
110
111         case TokenTypes.CTOR_DEF:
112             if (parentType != TokenTypes.OBJBLOCK) {
113                 return;
114             }
115
116             state = (ScopeState) mScopeStates.peek();
117             if (state.mScopeState > STATE_CTOR_DEF) {
118                 log(aAST, "declaration.order.constructor");
119             }
120             else {
121                 state.mScopeState = STATE_CTOR_DEF;
122             }
123             break;
124
125         case TokenTypes.METHOD_DEF:
126             state = (ScopeState) mScopeStates.peek();
127             if (parentType != TokenTypes.OBJBLOCK) {
128                 return;
129             }
130
131             if (state.mScopeState > STATE_METHOD_DEF) {
132                 log(aAST, "declaration.order.method");
133             }
134             else {
135                 state.mScopeState = STATE_METHOD_DEF;
136             }
137             break;
138
139         case TokenTypes.MODIFIERS:
140             if ((parentType != TokenTypes.VARIABLE_DEF)
141                 || (aAST.getParent().getParent().getType()
142                     != TokenTypes.OBJBLOCK))
143             {
144                 return;
145             }
146
147             state = (ScopeState) mScopeStates.peek();
148             if (aAST.findFirstToken(TokenTypes.LITERAL_STATIC) != null) {
149                 if (state.mScopeState > STATE_STATIC_VARIABLE_DEF) {
150                     log(aAST, "declaration.order.static");
151                 }
152                 else {
153                     state.mScopeState = STATE_STATIC_VARIABLE_DEF;
154                 }
155             }
156             else {
157                 if (state.mScopeState > STATE_INSTANCE_VARIABLE_DEF) {
158                     log(aAST, "declaration.order.instance");
159                 }
160                 else if (state.mScopeState == STATE_STATIC_VARIABLE_DEF) {
161                     state.mDeclarationAccess = Scope.PUBLIC;
162                     state.mScopeState = STATE_INSTANCE_VARIABLE_DEF;
163                 }
164             }
165
166             final Scope access = ScopeUtils.getScopeFromMods(aAST);
167             if (state.mDeclarationAccess.compareTo(access) > 0) {
168                 log(aAST, "declaration.order.access");
169             }
170             else {
171                 state.mDeclarationAccess = access;
172             }
173             break;
174
175         default:
176         }
177     }
178
179     /** {@inheritDoc} */
180     public void leaveToken(DetailAST aAST)
181     {
182         switch(aAST.getType()) {
183         case TokenTypes.OBJBLOCK:
184             mScopeStates.pop();
185             break;
186
187         default:
188         }
189     }
190 }
191
Popular Tags