KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > api > DetailAST


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.api;
20
21 import java.util.BitSet JavaDoc;
22
23 import antlr.CommonAST;
24 import antlr.Token;
25 import antlr.collections.AST;
26
27 /**
28  * An extension of the CommonAST that records the line and column
29  * number. The idea was taken from <a target="_top"
30  * HREF="http://www.jguru.com/jguru/faq/view.jsp?EID=62654">Java Guru
31  * FAQ: How can I include line numbers in automatically generated
32  * ASTs?</a>.
33  * @author Oliver Burn
34  * @author lkuehne
35  * @version 1.0
36  * @see <a HREF="http://www.antlr.org/">ANTLR Website</a>
37  */

38 public final class DetailAST extends CommonAST
39 {
40     /** constant to indicate if not calculated the child count */
41     private static final int NOT_INITIALIZED = Integer.MIN_VALUE;
42
43     /** the line number **/
44     private int mLineNo = NOT_INITIALIZED;
45     /** the column number **/
46     private int mColumnNo = NOT_INITIALIZED;
47
48     /** number of children */
49     private int mChildCount = NOT_INITIALIZED;
50     /** the parent token */
51     private DetailAST mParent;
52     /** previous sibling */
53     private DetailAST mPreviousSibling;
54
55     /**
56      * All token types in this branch.
57      * Token 'x' (where x is an int) is in this branch
58      * if mBranchTokenTypes.get(x) is true.
59      */

60     private BitSet JavaDoc mBranchTokenTypes;
61
62     /** {@inheritDoc} */
63     public void initialize(Token aTok)
64     {
65         super.initialize(aTok);
66         mLineNo = aTok.getLine();
67         mColumnNo = aTok.getColumn() - 1; // expect columns to start @ 0
68
}
69
70     /** {@inheritDoc} */
71     public void initialize(AST aAST)
72     {
73         final DetailAST da = (DetailAST) aAST;
74         setText(da.getText());
75         setType(da.getType());
76         mLineNo = da.getLineNo();
77         mColumnNo = da.getColumnNo();
78     }
79
80     /**
81      * Sets this AST's first Child.
82      * @param aAST the new first child
83      */

84     public void setFirstChild(AST aAST)
85     {
86         mChildCount = NOT_INITIALIZED;
87         super.setFirstChild(aAST);
88         if (aAST != null) {
89             ((DetailAST) aAST).setParent(this);
90         }
91     }
92
93     /**
94      * Sets AST's next sibling.
95      * @param aAST the new next sibling
96      */

97     public void setNextSibling(AST aAST)
98     {
99         super.setNextSibling(aAST);
100         if ((aAST != null) && (mParent != null)) {
101             ((DetailAST) aAST).setParent(mParent);
102         }
103         if (aAST != null) {
104             ((DetailAST) aAST).setPreviousSibling(this);
105         }
106     }
107
108     /**
109      * Sets previous sibling.
110      * @param aAST a previous sibling
111      */

112     void setPreviousSibling(DetailAST aAST)
113     {
114         mPreviousSibling = aAST;
115     }
116
117     /**
118      * Adds new child to AST.
119      * @param aAST the new child
120      */

121     public void addChild(AST aAST)
122     {
123         super.addChild(aAST);
124         if (aAST != null) {
125             ((DetailAST) aAST).setParent(this);
126             ((DetailAST) getFirstChild()).setParent(this);
127         }
128     }
129
130     /**
131      * Returns the number of child nodes one level below this node. That is is
132      * does not recurse down the tree.
133      * @return the number of child nodes
134      */

135     public int getChildCount()
136     {
137         // lazy init
138
if (mChildCount == NOT_INITIALIZED) {
139             mChildCount = 0;
140             AST child = getFirstChild();
141
142             while (child != null) {
143                 mChildCount += 1;
144                 child = child.getNextSibling();
145             }
146         }
147         return mChildCount;
148     }
149
150     /**
151      * Set the parent token.
152      * @param aParent the parent token
153      */

154     // TODO: should be private but that breaks the DetailASTTest
155
// until we manage parent in DetailAST instead of externally
156
void setParent(DetailAST aParent)
157     {
158         // TODO: Check visibility, could be private
159
// if set in setFirstChild() and friends
160
mParent = aParent;
161         final DetailAST nextSibling = (DetailAST) getNextSibling();
162         if (nextSibling != null) {
163             nextSibling.setParent(aParent);
164             nextSibling.setPreviousSibling(this);
165         }
166     }
167
168     /**
169      * Returns the parent token.
170      * @return the parent token
171      */

172     public DetailAST getParent()
173     {
174         return mParent;
175     }
176
177     /** @return the line number **/
178     public int getLineNo()
179     {
180         if (mLineNo == NOT_INITIALIZED) {
181             // an inner AST that has been initialized
182
// with initialize(String text)
183
final DetailAST child = (DetailAST) getFirstChild();
184             final DetailAST sibling = (DetailAST) getNextSibling();
185             if (child != null) {
186                 return child.getLineNo();
187             }
188             else if (sibling != null) {
189                 return sibling.getLineNo();
190             }
191         }
192         return mLineNo;
193     }
194
195     /** @return the column number **/
196     public int getColumnNo()
197     {
198         if (mColumnNo == NOT_INITIALIZED) {
199             // an inner AST that has been initialized
200
// with initialize(String text)
201
final DetailAST child = (DetailAST) getFirstChild();
202             final DetailAST sibling = (DetailAST) getNextSibling();
203             if (child != null) {
204                 return child.getColumnNo();
205             }
206             else if (sibling != null) {
207                 return sibling.getColumnNo();
208             }
209         }
210         return mColumnNo;
211     }
212
213     /** @return the last child node */
214     public DetailAST getLastChild()
215     {
216         AST ast = getFirstChild();
217         while ((ast != null) && (ast.getNextSibling() != null)) {
218             ast = ast.getNextSibling();
219         }
220         return (DetailAST) ast;
221     }
222
223     /**
224      * @return the token types that occur in the branch as a sorted set.
225      */

226     private BitSet JavaDoc getBranchTokenTypes()
227     {
228         // lazy init
229
if (mBranchTokenTypes == null) {
230
231             mBranchTokenTypes = new BitSet JavaDoc();
232             mBranchTokenTypes.set(getType());
233
234             // add union of all childs
235
DetailAST child = (DetailAST) getFirstChild();
236             while (child != null) {
237                 final BitSet JavaDoc childTypes = child.getBranchTokenTypes();
238                 mBranchTokenTypes.or(childTypes);
239
240                 child = (DetailAST) child.getNextSibling();
241             }
242         }
243         return mBranchTokenTypes;
244     }
245
246     /**
247      * Checks if this branch of the parse tree contains a token
248      * of the provided type.
249      * @param aType a TokenType
250      * @return true if and only if this branch (including this node)
251      * contains a token of type <code>aType</code>.
252      */

253     public boolean branchContains(int aType)
254     {
255         return getBranchTokenTypes().get(aType);
256     }
257
258     /**
259      * Returns the number of direct child tokens that have the specified type.
260      * @param aType the token type to match
261      * @return the number of matching token
262      */

263     public int getChildCount(int aType)
264     {
265         int count = 0;
266         for (AST i = getFirstChild(); i != null; i = i.getNextSibling()) {
267             if (i.getType() == aType) {
268                 count++;
269             }
270         }
271         return count;
272     }
273
274     /**
275      * Returns the previous sibling or null if no such sibling exists.
276      * @return the previous sibling or null if no such sibling exists.
277      */

278     public DetailAST getPreviousSibling()
279     {
280         return mPreviousSibling;
281     }
282
283     /**
284      * Returns the first child token that makes a specified type.
285      * @param aType the token type to match
286      * @return the matching token, or null if no match
287      */

288     public DetailAST findFirstToken(int aType)
289     {
290         DetailAST retVal = null;
291         for (AST i = getFirstChild(); i != null; i = i.getNextSibling()) {
292             if (i.getType() == aType) {
293                 retVal = (DetailAST) i;
294                 break;
295             }
296         }
297         return retVal;
298     }
299
300     /** {@inheritDoc} */
301     public String JavaDoc toString()
302     {
303         return super.toString() + "[" + getLineNo() + "x" + getColumnNo() + "]";
304     }
305 }
306
Popular Tags