KickJava   Java API By Example, From Geeks To Geeks.

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


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.TokenTypes;
24 import java.util.HashSet JavaDoc;
25 import java.util.Set JavaDoc;
26 import java.util.Stack JavaDoc;
27
28 /**
29  * <p>
30  * Disallow assignment of parameters.
31  * </p>
32  * <p>
33  * Rationale:
34  * Parameter assignment is often considered poor
35  * programming practice. Forcing developers to declare
36  * parameters as final is often onerous. Having a check
37  * ensure that parameters are never assigned would give
38  * the best of both worlds.
39  * </p>
40  * @author <a HREF="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
41  */

42 public final class ParameterAssignmentCheck extends Check
43 {
44     /** Stack of methods' parameters. */
45     private final Stack JavaDoc mParameterNamesStack = new Stack JavaDoc();
46     /** Current set of perameters. */
47     private Set JavaDoc mParameterNames;
48
49     /** {@inheritDoc} */
50     public int[] getDefaultTokens()
51     {
52         return new int[] {
53             TokenTypes.CTOR_DEF,
54             TokenTypes.METHOD_DEF,
55             TokenTypes.ASSIGN,
56             TokenTypes.PLUS_ASSIGN,
57             TokenTypes.MINUS_ASSIGN,
58             TokenTypes.STAR_ASSIGN,
59             TokenTypes.DIV_ASSIGN,
60             TokenTypes.MOD_ASSIGN,
61             TokenTypes.SR_ASSIGN,
62             TokenTypes.BSR_ASSIGN,
63             TokenTypes.SL_ASSIGN,
64             TokenTypes.BAND_ASSIGN,
65             TokenTypes.BXOR_ASSIGN,
66             TokenTypes.BOR_ASSIGN,
67             TokenTypes.INC,
68             TokenTypes.POST_INC,
69             TokenTypes.DEC,
70             TokenTypes.POST_DEC,
71         };
72     }
73
74     /** {@inheritDoc} */
75     public int[] getRequiredTokens()
76     {
77         return getDefaultTokens();
78     }
79
80     /** {@inheritDoc} */
81     public void beginTree(DetailAST aRootAST)
82     {
83         // clear data
84
mParameterNamesStack.clear();
85         mParameterNames = null;
86     }
87
88     /** {@inheritDoc} */
89     public void visitToken(DetailAST aAST)
90     {
91         switch (aAST.getType()) {
92         case TokenTypes.CTOR_DEF:
93         case TokenTypes.METHOD_DEF:
94             visitMethodDef(aAST);
95             break;
96         case TokenTypes.ASSIGN:
97         case TokenTypes.PLUS_ASSIGN:
98         case TokenTypes.MINUS_ASSIGN:
99         case TokenTypes.STAR_ASSIGN:
100         case TokenTypes.DIV_ASSIGN:
101         case TokenTypes.MOD_ASSIGN:
102         case TokenTypes.SR_ASSIGN:
103         case TokenTypes.BSR_ASSIGN:
104         case TokenTypes.SL_ASSIGN:
105         case TokenTypes.BAND_ASSIGN:
106         case TokenTypes.BXOR_ASSIGN:
107         case TokenTypes.BOR_ASSIGN:
108             visitAssign(aAST);
109             break;
110         case TokenTypes.INC:
111         case TokenTypes.POST_INC:
112         case TokenTypes.DEC:
113         case TokenTypes.POST_DEC:
114             visitIncDec(aAST);
115             break;
116         default:
117             throw new IllegalStateException JavaDoc(aAST.toString());
118         }
119     }
120
121     /** {@inheritDoc} */
122     public void leaveToken(DetailAST aAST)
123     {
124         switch (aAST.getType()) {
125         case TokenTypes.CTOR_DEF:
126         case TokenTypes.METHOD_DEF:
127             leaveMethodDef();
128             break;
129         case TokenTypes.ASSIGN:
130         case TokenTypes.PLUS_ASSIGN:
131         case TokenTypes.MINUS_ASSIGN:
132         case TokenTypes.STAR_ASSIGN:
133         case TokenTypes.DIV_ASSIGN:
134         case TokenTypes.MOD_ASSIGN:
135         case TokenTypes.SR_ASSIGN:
136         case TokenTypes.BSR_ASSIGN:
137         case TokenTypes.SL_ASSIGN:
138         case TokenTypes.BAND_ASSIGN:
139         case TokenTypes.BXOR_ASSIGN:
140         case TokenTypes.BOR_ASSIGN:
141         case TokenTypes.INC:
142         case TokenTypes.POST_INC:
143         case TokenTypes.DEC:
144         case TokenTypes.POST_DEC:
145             // Do nothing
146
break;
147         default:
148             throw new IllegalStateException JavaDoc(aAST.toString());
149         }
150     }
151
152     /**
153      * Ckecks if this is assignments of parameter.
154      * @param aAST assignment to check.
155      */

156     private void visitAssign(DetailAST aAST)
157     {
158         checkIdent(aAST);
159     }
160
161     /**
162      * Checks if this is increment/decrement of parameter.
163      * @param aAST dec/inc to check.
164      */

165     private void visitIncDec(DetailAST aAST)
166     {
167         checkIdent(aAST);
168     }
169
170     /**
171      * Check if ident is parameter.
172      * @param aAST ident to check.
173      */

174     private void checkIdent(DetailAST aAST)
175     {
176         if ((mParameterNames != null) && !mParameterNames.isEmpty()) {
177             final DetailAST identAST = (DetailAST) aAST.getFirstChild();
178
179             if ((identAST != null)
180                 && (identAST.getType() == TokenTypes.IDENT)
181                 && mParameterNames.contains(identAST.getText()))
182             {
183                 log(aAST.getLineNo(), aAST.getColumnNo(),
184                     "parameter.assignment", identAST.getText());
185             }
186         }
187     }
188
189     /**
190      * Creates new set of parameters and store old one in stack.
191      * @param aAST a method to process.
192      */

193     private void visitMethodDef(DetailAST aAST)
194     {
195         mParameterNamesStack.push(mParameterNames);
196         mParameterNames = new HashSet JavaDoc();
197
198         visitMethodParameters(aAST.findFirstToken(TokenTypes.PARAMETERS));
199     }
200
201     /** Restores old set of parameters. */
202     private void leaveMethodDef()
203     {
204         mParameterNames = (Set JavaDoc) mParameterNamesStack.pop();
205     }
206
207     /**
208      * Creates new parameter set for given method.
209      * @param aAST a method for process.
210      */

211     private void visitMethodParameters(DetailAST aAST)
212     {
213         DetailAST parameterDefAST =
214             aAST.findFirstToken(TokenTypes.PARAMETER_DEF);
215
216         for (; parameterDefAST != null;
217              parameterDefAST = (DetailAST) parameterDefAST.getNextSibling())
218         {
219             if (parameterDefAST.getType() == TokenTypes.PARAMETER_DEF) {
220                 final DetailAST param =
221                     parameterDefAST.findFirstToken(TokenTypes.IDENT);
222                 mParameterNames.add(param.getText());
223             }
224         }
225     }
226 }
227
Popular Tags