KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > CheckUtils


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;
20
21 import com.puppycrawl.tools.checkstyle.api.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.FullIdent;
23 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24
25 import java.util.List JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 /**
29  * Contains utility methods for the checks.
30  *
31  * @author Oliver Burn
32  * @author <a HREF="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
33  * @author o_sukhodolsky
34  */

35 public final class CheckUtils
36 {
37     /** prevent instances */
38     private CheckUtils()
39     {
40         throw new UnsupportedOperationException JavaDoc();
41     }
42
43     /**
44      * Tests whether a method definition AST defines an equals covariant.
45      * @param aAST the method definition AST to test.
46      * Precondition: aAST is a TokenTypes.METHOD_DEF node.
47      * @return true if aAST defines an equals covariant.
48      */

49     public static boolean isEqualsMethod(DetailAST aAST)
50     {
51         if (aAST.getType() != TokenTypes.METHOD_DEF) {
52             // A node must be method def
53
return false;
54         }
55
56         // non-static, non-abstract?
57
final DetailAST modifiers = aAST.findFirstToken(TokenTypes.MODIFIERS);
58         if (modifiers.branchContains(TokenTypes.LITERAL_STATIC)
59             || modifiers.branchContains(TokenTypes.ABSTRACT))
60         {
61             return false;
62         }
63
64         // named "equals"?
65
final DetailAST nameNode = aAST.findFirstToken(TokenTypes.IDENT);
66         final String JavaDoc name = nameNode.getText();
67         if (!"equals".equals(name)) {
68             return false;
69         }
70
71         // one parameter?
72
final DetailAST paramsNode = aAST.findFirstToken(TokenTypes.PARAMETERS);
73         return (paramsNode.getChildCount() == 1);
74     }
75
76     /**
77      * Returns whether a token represents an ELSE as part of an ELSE / IF set.
78      * @param aAST the token to check
79      * @return whether it is
80      */

81     public static boolean isElseIf(DetailAST aAST)
82     {
83         final DetailAST parentAST = aAST.getParent();
84
85         return (aAST.getType() == TokenTypes.LITERAL_IF)
86             && (isElse(parentAST) || isElseWithCurlyBraces(parentAST));
87     }
88
89     /**
90      * Returns whether a token represents an ELSE.
91      * @param aAST the token to check
92      * @return whether the token represents an ELSE
93      */

94     private static boolean isElse(DetailAST aAST)
95     {
96         return aAST.getType() == TokenTypes.LITERAL_ELSE;
97     }
98
99     /**
100      * Returns whether a token represents an SLIST as part of an ELSE
101      * statement.
102      * @param aAST the token to check
103      * @return whether the toke does represent an SLIST as part of an ELSE
104      */

105     private static boolean isElseWithCurlyBraces(DetailAST aAST)
106     {
107         return (aAST.getType() == TokenTypes.SLIST)
108             && (aAST.getChildCount() == 2)
109             && isElse(aAST.getParent());
110     }
111
112     /**
113      * Creates <code>FullIdent</code> for given type node.
114      * @param aTypeAST a type node.
115      * @return <code>FullIdent</code> for given type.
116      */

117     public static FullIdent createFullType(DetailAST aTypeAST)
118     {
119         final DetailAST arrayDeclAST =
120             aTypeAST.findFirstToken(TokenTypes.ARRAY_DECLARATOR);
121
122         return createFullTypeNoArrays(arrayDeclAST == null ? aTypeAST
123                                                            : arrayDeclAST);
124     }
125
126     /**
127      * @param aTypeAST a type node (no array)
128      * @return <code>FullIdent</code> for given type.
129      */

130     private static FullIdent createFullTypeNoArrays(DetailAST aTypeAST)
131     {
132         return FullIdent.createFullIdent((DetailAST) aTypeAST.getFirstChild());
133     }
134
135     // constants for parseDouble()
136
/** octal radix */
137     private static final int BASE_8 = 8;
138
139     /** decimal radix */
140     private static final int BASE_10 = 10;
141
142     /** hex radix */
143     private static final int BASE_16 = 16;
144
145     /**
146      * Returns the value represented by the specified string of the specified
147      * type. Returns 0 for types other than float, double, int, and long.
148      * @param aText the string to be parsed.
149      * @param aType the token type of the text. Should be a constant of
150      * {@link com.puppycrawl.tools.checkstyle.api.TokenTypes}.
151      * @return the double value represented by the string argument.
152      */

153     public static double parseDouble(String JavaDoc aText, int aType)
154     {
155         double result = 0;
156         switch (aType) {
157         case TokenTypes.NUM_FLOAT:
158         case TokenTypes.NUM_DOUBLE:
159             result = Double.parseDouble(aText);
160             break;
161         case TokenTypes.NUM_INT:
162         case TokenTypes.NUM_LONG:
163             int radix = BASE_10;
164             if (aText.startsWith("0x") || aText.startsWith("0X")) {
165                 radix = BASE_16;
166                 aText = aText.substring(2);
167             }
168             else if (aText.charAt(0) == '0') {
169                 radix = BASE_8;
170                 aText = aText.substring(1);
171             }
172             if ((aText.endsWith("L")) || (aText.endsWith("l"))) {
173                 aText = aText.substring(0, aText.length() - 1);
174             }
175             if (aText.length() > 0) {
176                 if (aType == TokenTypes.NUM_INT) {
177                     result = parseInt(aText, radix);
178                 }
179                 else {
180                     result = parseLong(aText, radix);
181                 }
182             }
183             break;
184         default:
185             break;
186         }
187         return result;
188     }
189
190     /**
191      * Parses the string argument as a signed integer in the radix specified by
192      * the second argument. The characters in the string must all be digits of
193      * the specified radix. Handles negative values, which method
194      * java.lang.Integer.parseInt(String, int) does not.
195      * @param aText the String containing the integer representation to be
196      * parsed. Precondition: aText contains a parsable int.
197      * @param aRadix the radix to be used while parsing aText.
198      * @return the integer represented by the string argument in the specified
199      * radix.
200      */

201     public static int parseInt(String JavaDoc aText, int aRadix)
202     {
203         int result = 0;
204         final int max = aText.length();
205         for (int i = 0; i < max; i++) {
206             final int digit = Character.digit(aText.charAt(i), aRadix);
207             result *= aRadix;
208             result += digit;
209         }
210         return result;
211     }
212
213     /**
214      * Parses the string argument as a signed long in the radix specified by
215      * the second argument. The characters in the string must all be digits of
216      * the specified radix. Handles negative values, which method
217      * java.lang.Integer.parseInt(String, int) does not.
218      * @param aText the String containing the integer representation to be
219      * parsed. Precondition: aText contains a parsable int.
220      * @param aRadix the radix to be used while parsing aText.
221      * @return the long represented by the string argument in the specified
222      * radix.
223      */

224     public static long parseLong(String JavaDoc aText, int aRadix)
225     {
226         long result = 0;
227         final int max = aText.length();
228         for (int i = 0; i < max; i++) {
229             final int digit = Character.digit(aText.charAt(i), aRadix);
230             result *= aRadix;
231             result += digit;
232         }
233         return result;
234     }
235
236     /**
237      * Returns the value represented by the specified string of the specified
238      * type. Returns 0 for types other than float, double, int, and long.
239      * @param aText the string to be parsed.
240      * @param aType the token type of the text. Should be a constant of
241      * {@link com.puppycrawl.tools.checkstyle.api.TokenTypes}.
242      * @return the float value represented by the string argument.
243      */

244     public static double parseFloat(String JavaDoc aText, int aType)
245     {
246         return (float) parseDouble(aText, aType);
247     }
248
249     /**
250      * Finds sub-node for given node minimal (line, column) pair.
251      * @param aNode the root of tree for search.
252      * @return sub-node with minimal (line, column) pair.
253      */

254     public static DetailAST getFirstNode(final DetailAST aNode)
255     {
256         DetailAST currentNode = aNode;
257         DetailAST child = (DetailAST) aNode.getFirstChild();
258         while (child != null) {
259             final DetailAST newNode = getFirstNode(child);
260             if ((newNode.getLineNo() < currentNode.getLineNo())
261                 || ((newNode.getLineNo() == currentNode.getLineNo())
262                     && (newNode.getColumnNo() < currentNode.getColumnNo())))
263             {
264                 currentNode = newNode;
265             }
266             child = (DetailAST) child.getNextSibling();
267         }
268
269         return currentNode;
270     }
271
272     /**
273      * Retrieves the names of the type parameters to the node.
274      * @param aNode the parameterised AST node
275      * @return a list of type parameter names
276      */

277     public static List JavaDoc getTypeParameterNames(final DetailAST aNode)
278     {
279         final DetailAST typeParameters =
280             aNode.findFirstToken(TokenTypes.TYPE_PARAMETERS);
281
282         final List JavaDoc typeParamNames = new ArrayList JavaDoc();
283         if (typeParameters != null) {
284             final DetailAST typeParam =
285                 typeParameters.findFirstToken(TokenTypes.TYPE_PARAMETER);
286             typeParamNames.add(
287                 typeParam.findFirstToken(TokenTypes.IDENT).getText());
288
289             DetailAST sibling = (DetailAST) typeParam.getNextSibling();
290             while (sibling != null) {
291                 if (sibling.getType() == TokenTypes.TYPE_PARAMETER) {
292                     typeParamNames.add(
293                         sibling.findFirstToken(TokenTypes.IDENT).getText());
294                 }
295                 sibling = (DetailAST) sibling.getNextSibling();
296             }
297         }
298
299         return typeParamNames;
300     }
301
302     /**
303      * Retrieves the type parameters to the node.
304      * @param aNode the parameterised AST node
305      * @return a list of type parameter names
306      */

307     public static List JavaDoc getTypeParameters(final DetailAST aNode)
308     {
309         final DetailAST typeParameters =
310             aNode.findFirstToken(TokenTypes.TYPE_PARAMETERS);
311
312         final List JavaDoc typeParams = new ArrayList JavaDoc();
313         if (typeParameters != null) {
314             final DetailAST typeParam =
315                 typeParameters.findFirstToken(TokenTypes.TYPE_PARAMETER);
316             typeParams.add(typeParam);
317
318             DetailAST sibling = (DetailAST) typeParam.getNextSibling();
319             while (sibling != null) {
320                 if (sibling.getType() == TokenTypes.TYPE_PARAMETER) {
321                     typeParams.add(sibling);
322                 }
323                 sibling = (DetailAST) sibling.getNextSibling();
324             }
325         }
326
327         return typeParams;
328     }
329 }
330
Popular Tags