KickJava   Java API By Example, From Geeks To Geeks.

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


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 import com.puppycrawl.tools.checkstyle.checks.CheckUtils;
26
27 /**
28  * <p>
29  * Checks the placement of right curly braces.
30  * The policy to verify is specified using the {@link RightCurlyOption} class
31  * and defaults to {@link RightCurlyOption#SAME}.
32  * </p>
33  * <p> By default the check will check the following tokens:
34  * {@link TokenTypes#LITERAL_TRY LITERAL_TRY}.
35  * {@link TokenTypes#LITERAL_CATCH LITERAL_CATCH},
36  * {@link TokenTypes#LITERAL_FINALLY LITERAL_FINALLY}.
37  * {@link TokenTypes#LITERAL_IF LITERAL_IF},
38  * {@link TokenTypes#LITERAL_ELSE LITERAL_ELSE},
39  * </p>
40  * <p>
41  * An example of how to configure the check is:
42  * </p>
43  * <pre>
44  * &lt;module name="RightCurly"/&gt;
45  * </pre>
46  * <p>
47  * An example of how to configure the check with policy
48  * {@link RightCurlyOption#ALONE} for <code>else</code> tokens is:
49  * </p>
50  * <pre>
51  * &lt;module name="RightCurly"&gt;
52  * &lt;property name="tokens" value="LITERAL_ELSE"/&gt;
53  * &lt;property name="option" value="alone"/&gt;
54  * &lt;/module&gt;
55  * </pre>
56  *
57  * @author Oliver Burn
58  * @author lkuehne
59  * @author o_sukhodolsky
60  * @version 2.0
61  */

62 public class RightCurlyCheck extends AbstractOptionCheck
63 {
64     /** Do we need to check if rculry starts line. */
65     private boolean mShouldStartLine = true;
66
67     /**
68      * Sets the right curly option to same.
69      */

70     public RightCurlyCheck()
71     {
72         super(RightCurlyOption.SAME);
73     }
74
75     /**
76      * Does the check need to check if rcurly starts line.
77      * @param aFlag new value of this property.
78      */

79     public void setShouldStartLine(boolean aFlag)
80     {
81         mShouldStartLine = aFlag;
82     }
83
84     /** {@inheritDoc} */
85     public int[] getDefaultTokens()
86     {
87         return new int[] {
88             TokenTypes.LITERAL_TRY,
89             TokenTypes.LITERAL_CATCH,
90             TokenTypes.LITERAL_FINALLY,
91             TokenTypes.LITERAL_IF,
92             TokenTypes.LITERAL_ELSE,
93         };
94     }
95
96     /** {@inheritDoc} */
97     public void visitToken(DetailAST aAST)
98     {
99         // Attempt to locate the tokens to do the check
100
DetailAST rcurly;
101         DetailAST lcurly;
102         DetailAST nextToken;
103         boolean shouldCheckLastRcurly = false;
104
105         switch (aAST.getType()) {
106         case TokenTypes.LITERAL_TRY:
107             lcurly = (DetailAST) aAST.getFirstChild();
108             nextToken = (DetailAST) lcurly.getNextSibling();
109             rcurly = lcurly.getLastChild();
110             break;
111         case TokenTypes.LITERAL_CATCH:
112             nextToken = (DetailAST) aAST.getNextSibling();
113             lcurly = aAST.getLastChild();
114             rcurly = lcurly.getLastChild();
115             if (nextToken == null) {
116                 shouldCheckLastRcurly = true;
117                 nextToken = getNextToken(aAST);
118             }
119             break;
120         case TokenTypes.LITERAL_IF:
121             nextToken = aAST.findFirstToken(TokenTypes.LITERAL_ELSE);
122             if (nextToken != null) {
123                 lcurly = nextToken.getPreviousSibling();
124                 rcurly = lcurly.getLastChild();
125             }
126             else {
127                 shouldCheckLastRcurly = true;
128                 nextToken = getNextToken(aAST);
129                 lcurly = aAST.getLastChild();
130                 rcurly = lcurly.getLastChild();
131             }
132             break;
133         case TokenTypes.LITERAL_ELSE:
134             shouldCheckLastRcurly = true;
135             nextToken = getNextToken(aAST);
136             lcurly = (DetailAST) aAST.getFirstChild();
137             rcurly = lcurly.getLastChild();
138             break;
139         case TokenTypes.LITERAL_FINALLY:
140             shouldCheckLastRcurly = true;
141             nextToken = getNextToken(aAST);
142             lcurly = (DetailAST) aAST.getFirstChild();
143             rcurly = lcurly.getLastChild();
144             break;
145         default:
146             throw new RuntimeException JavaDoc("Unexpected token type ("
147                     + TokenTypes.getTokenName(aAST.getType()) + ")");
148         }
149
150         if ((rcurly == null) || (rcurly.getType() != TokenTypes.RCURLY)) {
151             // we need to have both tokens to perform the check
152
return;
153         }
154
155         if (shouldCheckLastRcurly) {
156             if (rcurly.getLineNo() == nextToken.getLineNo()) {
157                 log(rcurly, "line.alone", "}");
158             }
159         }
160         else if ((getAbstractOption() == RightCurlyOption.SAME)
161             && (rcurly.getLineNo() != nextToken.getLineNo()))
162         {
163             log(rcurly, "line.same", "}");
164         }
165         else if ((getAbstractOption() == RightCurlyOption.ALONE)
166                  && (rcurly.getLineNo() == nextToken.getLineNo()))
167         {
168             log(rcurly, "line.alone", "}");
169         }
170
171         if (!mShouldStartLine) {
172             return;
173         }
174         final boolean startsLine =
175             Utils.whitespaceBefore(rcurly.getColumnNo(),
176                                    getLines()[rcurly.getLineNo() - 1]);
177
178         if (!startsLine && (lcurly.getLineNo() != rcurly.getLineNo())) {
179             log(rcurly, "line.new", "}");
180         }
181     }
182
183     /**
184      * Finds next token after the given one.
185      * @param aAST the given node.
186      * @return the token which represents next lexical item.
187      */

188     private DetailAST getNextToken(DetailAST aAST)
189     {
190         DetailAST next = null;
191         DetailAST parent = aAST;
192         while ((parent != null) && (next == null)) {
193             next = (DetailAST) parent.getNextSibling();
194             parent = parent.getParent();
195         }
196         return CheckUtils.getFirstNode(next);
197     }
198 }
199
Popular Tags