KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > blocks > LeftCurlyCheck


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.blocks;
20
21 import com.puppycrawl.tools.checkstyle.api.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
23 import com.puppycrawl.tools.checkstyle.api.Utils;
24 import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
25
26 /**
27  * <p>
28  * Checks the placement of left curly braces on types, methods and
29  * other blocks:
30  * {@link TokenTypes#LITERAL_CATCH LITERAL_CATCH}, {@link
31  * TokenTypes#LITERAL_DO LITERAL_DO}, {@link TokenTypes#LITERAL_ELSE
32  * LITERAL_ELSE}, {@link TokenTypes#LITERAL_FINALLY LITERAL_FINALLY}, {@link
33  * TokenTypes#LITERAL_FOR LITERAL_FOR}, {@link TokenTypes#LITERAL_IF
34  * LITERAL_IF}, {@link TokenTypes#LITERAL_SWITCH LITERAL_SWITCH}, {@link
35  * TokenTypes#LITERAL_SYNCHRONIZED LITERAL_SYNCHRONIZED}, {@link
36  * TokenTypes#LITERAL_TRY LITERAL_TRY}, {@link TokenTypes#LITERAL_WHILE
37  * LITERAL_WHILE}.
38  * </p>
39  *
40  * <p>
41  * The policy to verify is specified using the {@link LeftCurlyOption} class and
42  * defaults to {@link LeftCurlyOption#EOL}. Policies {@link LeftCurlyOption#EOL}
43  * and {@link LeftCurlyOption#NLOW} take into account property maxLineLength.
44  * The default value for maxLineLength is 80.
45  * </p>
46  * <p>
47  * An example of how to configure the check is:
48  * </p>
49  * <pre>
50  * &lt;module name="LeftCurly"/&gt;
51  * </pre>
52  * <p>
53  * An example of how to configure the check with policy
54  * {@link LeftCurlyOption#NLOW} and maxLineLength 120 is:
55  * </p>
56  * <pre>
57  * &lt;module name="LeftCurly"&gt;
58  * &lt;property name="option"
59  * value="nlow"/&gt; &lt;property name="maxLineLength" value="120"/&gt; &lt;
60  * /module&gt;
61  * </pre>
62  *
63  * @author Oliver Burn
64  * @author lkuehne
65  * @version 1.0
66  */

67 public class LeftCurlyCheck
68     extends AbstractOptionCheck
69 {
70     /** default maximum line length */
71     private static final int DEFAULT_MAX_LINE_LENGTH = 80;
72
73     /** TODO: replace this ugly hack **/
74     private int mMaxLineLength = DEFAULT_MAX_LINE_LENGTH;
75
76     /**
77      * Creates a default instance and sets the policy to EOL.
78      */

79     public LeftCurlyCheck()
80     {
81         super(LeftCurlyOption.EOL);
82     }
83
84     /**
85      * Sets the maximum line length used in calculating the placement of the
86      * left curly brace.
87      * @param aMaxLineLength the max allowed line length
88      */

89     public void setMaxLineLength(int aMaxLineLength)
90     {
91         mMaxLineLength = aMaxLineLength;
92     }
93
94     /** {@inheritDoc} */
95     public int[] getDefaultTokens()
96     {
97         return new int[] {
98             TokenTypes.INTERFACE_DEF,
99             TokenTypes.CLASS_DEF,
100             TokenTypes.ANNOTATION_DEF,
101             TokenTypes.ENUM_DEF,
102             TokenTypes.CTOR_DEF,
103             TokenTypes.METHOD_DEF,
104             TokenTypes.ENUM_CONSTANT_DEF,
105             TokenTypes.LITERAL_WHILE,
106             TokenTypes.LITERAL_TRY,
107             TokenTypes.LITERAL_CATCH,
108             TokenTypes.LITERAL_FINALLY,
109             TokenTypes.LITERAL_SYNCHRONIZED,
110             TokenTypes.LITERAL_SWITCH,
111             TokenTypes.LITERAL_DO,
112             TokenTypes.LITERAL_IF,
113             TokenTypes.LITERAL_ELSE,
114             TokenTypes.LITERAL_FOR,
115             // TODO: need to handle....
116
//TokenTypes.STATIC_INIT,
117
};
118     }
119
120     /** {@inheritDoc} */
121     public void visitToken(DetailAST aAST)
122     {
123         final DetailAST startToken;
124         final DetailAST brace;
125
126         switch (aAST.getType()) {
127         case TokenTypes.CTOR_DEF :
128         case TokenTypes.METHOD_DEF :
129             startToken = aAST;
130             brace = aAST.findFirstToken(TokenTypes.SLIST);
131             break;
132
133         case TokenTypes.INTERFACE_DEF :
134         case TokenTypes.CLASS_DEF :
135         case TokenTypes.ANNOTATION_DEF :
136         case TokenTypes.ENUM_DEF :
137         case TokenTypes.ENUM_CONSTANT_DEF :
138             startToken = (DetailAST) aAST.getFirstChild();
139             final DetailAST objBlock = aAST.findFirstToken(TokenTypes.OBJBLOCK);
140             brace = (objBlock == null)
141                 ? null
142                 : (DetailAST) objBlock.getFirstChild();
143             break;
144
145         case TokenTypes.LITERAL_WHILE:
146         case TokenTypes.LITERAL_CATCH:
147         case TokenTypes.LITERAL_SYNCHRONIZED:
148         case TokenTypes.LITERAL_FOR:
149         case TokenTypes.LITERAL_TRY:
150         case TokenTypes.LITERAL_FINALLY:
151         case TokenTypes.LITERAL_DO:
152         case TokenTypes.LITERAL_IF :
153             startToken = aAST;
154             brace = aAST.findFirstToken(TokenTypes.SLIST);
155             break;
156
157         case TokenTypes.LITERAL_ELSE :
158             startToken = aAST;
159             final DetailAST candidate = (DetailAST) aAST.getFirstChild();
160             brace =
161                 (candidate.getType() == TokenTypes.SLIST)
162                 ? candidate
163                 : null; // silently ignore
164
break;
165
166         case TokenTypes.LITERAL_SWITCH :
167             startToken = aAST;
168             brace = aAST.findFirstToken(TokenTypes.LCURLY);
169             break;
170
171         default :
172             startToken = null;
173             brace = null;
174         }
175
176         if ((brace != null) && (startToken != null)) {
177             verifyBrace(brace, startToken);
178         }
179     }
180
181     /**
182      * Verifies that a specified left curly brace is placed correctly
183      * according to policy.
184      * @param aBrace token for left curly brace
185      * @param aStartToken token for start of expression
186      */

187     private void verifyBrace(final DetailAST aBrace,
188                              final DetailAST aStartToken)
189     {
190         final String JavaDoc braceLine = getLines()[aBrace.getLineNo() - 1];
191
192         // calculate the previous line length without trailing whitespace. Need
193
// to handle the case where there is no previous line, cause the line
194
// being check is the first line in the file.
195
final int prevLineLen = (aBrace.getLineNo() == 1)
196             ? mMaxLineLength
197             : Utils.lengthMinusTrailingWhitespace(
198                 getLines()[aBrace.getLineNo() - 2]);
199
200         // Check for being told to ignore, or have '{}' which is a special case
201
if ((braceLine.length() > (aBrace.getColumnNo() + 1))
202             && (braceLine.charAt(aBrace.getColumnNo() + 1) == '}'))
203         {
204             ; // ignore
205
}
206         else if (getAbstractOption() == LeftCurlyOption.NL) {
207             if (!Utils.whitespaceBefore(aBrace.getColumnNo(), braceLine)) {
208                 log(aBrace.getLineNo(), aBrace.getColumnNo(),
209                     "line.new", "{");
210             }
211         }
212         else if (getAbstractOption() == LeftCurlyOption.EOL) {
213             if (Utils.whitespaceBefore(aBrace.getColumnNo(), braceLine)
214                 && ((prevLineLen + 2) <= mMaxLineLength))
215             {
216                 log(aBrace.getLineNo(), aBrace.getColumnNo(),
217                     "line.previous", "{");
218             }
219         }
220         else if (getAbstractOption() == LeftCurlyOption.NLOW) {
221             if (aStartToken.getLineNo() == aBrace.getLineNo()) {
222                 ; // all ok as on the same line
223
}
224             else if ((aStartToken.getLineNo() + 1) == aBrace.getLineNo()) {
225                 if (!Utils.whitespaceBefore(aBrace.getColumnNo(), braceLine)) {
226                     log(aBrace.getLineNo(), aBrace.getColumnNo(),
227                         "line.new", "{");
228                 }
229                 else if ((prevLineLen + 2) <= mMaxLineLength) {
230                     log(aBrace.getLineNo(), aBrace.getColumnNo(),
231                         "line.previous", "{");
232                 }
233             }
234             else if (!Utils.whitespaceBefore(aBrace.getColumnNo(), braceLine)) {
235                 log(aBrace.getLineNo(), aBrace.getColumnNo(),
236                     "line.new", "{");
237             }
238         }
239     }
240 }
241
Popular Tags