KickJava   Java API By Example, From Geeks To Geeks.

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


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.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
23
24 import com.puppycrawl.tools.checkstyle.checks.AbstractFormatCheck;
25
26 import java.util.Stack JavaDoc;
27
28 /**
29  * <p>
30  * Restricts return statements to a specified count (default = 2).
31  * Ignores specified methods (<code>equals()</code> by default).
32  * </p>
33  * <p>
34  * Rationale: Too many return points can be indication that code is
35  * attempting to do too much or may be difficult to understand.
36  * </p>
37  *
38  * @author <a HREF="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
39  * TODO: Test for inside a static block
40  */

41 public final class ReturnCountCheck extends AbstractFormatCheck
42 {
43     /** Default allowed number of return statements. */
44     private static final int DEFAULT_MAX = 2;
45
46     /** Stack of method contexts. */
47     private final Stack JavaDoc mContextStack = new Stack JavaDoc();
48     /** Maximum allowed number of return stmts. */
49     private int mMax;
50     /** Current method context. */
51     private Context mContext;
52
53     /** Creates new instance of the checks. */
54     public ReturnCountCheck()
55     {
56         super("^equals$");
57         setMax(DEFAULT_MAX);
58     }
59
60     /** {@inheritDoc} */
61     public int[] getDefaultTokens()
62     {
63         return new int[] {
64             TokenTypes.CTOR_DEF,
65             TokenTypes.METHOD_DEF,
66             TokenTypes.LITERAL_RETURN,
67         };
68     }
69
70     /** {@inheritDoc} */
71     public int[] getRequiredTokens()
72     {
73         return new int[]{
74             TokenTypes.CTOR_DEF,
75             TokenTypes.METHOD_DEF,
76         };
77     }
78
79     /**
80      * Getter for max property.
81      * @return maximum allowed number of return statements.
82      */

83     public int getMax()
84     {
85         return mMax;
86     }
87
88     /**
89      * Setter for max property.
90      * @param aMax maximum allowed number of return statements.
91      */

92     public void setMax(int aMax)
93     {
94         mMax = aMax;
95     }
96
97     /** {@inheritDoc} */
98     public void beginTree(DetailAST aRootAST)
99     {
100         mContext = null;
101         mContextStack.clear();
102     }
103
104     /** {@inheritDoc} */
105     public void visitToken(DetailAST aAST)
106     {
107         switch (aAST.getType()) {
108         case TokenTypes.CTOR_DEF:
109         case TokenTypes.METHOD_DEF:
110             visitMethodDef(aAST);
111             break;
112         case TokenTypes.LITERAL_RETURN:
113             mContext.visitLiteralReturn();
114             break;
115         default:
116             throw new IllegalStateException JavaDoc(aAST.toString());
117         }
118     }
119
120     /** {@inheritDoc} */
121     public void leaveToken(DetailAST aAST)
122     {
123         switch (aAST.getType()) {
124         case TokenTypes.CTOR_DEF:
125         case TokenTypes.METHOD_DEF:
126             leaveMethodDef(aAST);
127             break;
128         case TokenTypes.LITERAL_RETURN:
129             // Do nothing
130
break;
131         default:
132             throw new IllegalStateException JavaDoc(aAST.toString());
133         }
134     }
135
136     /**
137      * Creates new method context and places old one on the stack.
138      * @param aAST method definition for check.
139      */

140     private void visitMethodDef(DetailAST aAST)
141     {
142         mContextStack.push(mContext);
143         final DetailAST methodNameAST = aAST.findFirstToken(TokenTypes.IDENT);
144         mContext =
145             new Context(!getRegexp().matcher(methodNameAST.getText()).find());
146     }
147
148     /**
149      * Checks number of return statments and restore
150      * previous method context.
151      * @param aAST method def node.
152      */

153     private void leaveMethodDef(DetailAST aAST)
154     {
155         mContext.checkCount(aAST);
156         mContext = (Context) mContextStack.pop();
157     }
158
159     /**
160      * Class to encapsulate information about one method.
161      * @author <a HREF="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
162      */

163     private class Context
164     {
165         /** Whether we should check this method or not. */
166         private final boolean mChecking;
167         /** Counter for return statements. */
168         private int mCount;
169
170         /**
171          * Creates new method context.
172          * @param aChecking should we check this method or not.
173          */

174         public Context(boolean aChecking)
175         {
176             mChecking = aChecking;
177             mCount = 0;
178         }
179
180         /** Increase number of return statements. */
181         public void visitLiteralReturn()
182         {
183             ++mCount;
184         }
185
186         /**
187          * Checks if number of return statements in method more
188          * than allowed.
189          * @param aAST method def associated with this context.
190          */

191         public void checkCount(DetailAST aAST)
192         {
193             if (mChecking && (mCount > getMax())) {
194                 log(aAST.getLineNo(), aAST.getColumnNo(), "return.count",
195                     new Integer JavaDoc(mCount), new Integer JavaDoc(getMax()));
196             }
197         }
198     }
199 }
200
Popular Tags