Source code: com/puppycrawl/tools/checkstyle/api/ScopeUtils.java
1 ////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code for adherence to a set of rules.
3 // Copyright (C) 2001-2003 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 antlr.collections.AST;
22
23 /**
24 * Contains utility methods for working on scope.
25 *
26 * @author Oliver Burn
27 * @version 1.0
28 */
29 public final class ScopeUtils
30 {
31 ///CLOVER:OFF
32 /** prevent instantiation */
33 private ScopeUtils()
34 {
35 }
36 ///CLOVER:ON
37
38 /**
39 * Returns the Scope specified by the modifier set.
40 *
41 * @param aMods root node of a modifier set
42 * @return a <code>Scope</code> value
43 */
44 public static Scope getScopeFromMods(DetailAST aMods)
45 {
46 Scope retVal = Scope.PACKAGE; // default scope
47 for (AST token = aMods.getFirstChild();
48 token != null;
49 token = token.getNextSibling())
50 {
51 if ("public".equals(token.getText())) {
52 retVal = Scope.PUBLIC;
53 break;
54 }
55 else if ("protected".equals(token.getText())) {
56 retVal = Scope.PROTECTED;
57 break;
58 }
59 else if ("private".equals(token.getText())) {
60 retVal = Scope.PRIVATE;
61 break;
62 }
63 }
64 return retVal;
65 }
66
67 /**
68 * Returns the scope of the surrounding "block".
69 * @param aAST the node to return the scope for
70 * @return the Scope of the surrounding block
71 */
72 public static Scope getSurroundingScope(DetailAST aAST)
73 {
74 Scope retVal = null;
75 for (DetailAST token = aAST.getParent();
76 token != null;
77 token = token.getParent())
78 {
79 final int type = token.getType();
80 if ((type == TokenTypes.CLASS_DEF)
81 || (type == TokenTypes.INTERFACE_DEF))
82 {
83 final DetailAST mods =
84 token.findFirstToken(TokenTypes.MODIFIERS);
85 final Scope modScope = ScopeUtils.getScopeFromMods(mods);
86 if ((retVal == null) || (retVal.isIn(modScope))) {
87 retVal = modScope;
88 }
89 }
90 else if (type == TokenTypes.LITERAL_NEW) {
91 retVal = Scope.ANONINNER;
92 break; //because Scope.ANONINNER is not in any other Scope
93 }
94 }
95
96 return retVal;
97 }
98
99 /**
100 * Returns whether a node is directly contained within an interface block.
101 *
102 * @param aAST the node to check if directly contained within an interface
103 * block
104 * @return a <code>boolean</code> value
105 */
106 public static boolean inInterfaceBlock(DetailAST aAST)
107 {
108 boolean retVal = false;
109
110 // Loop up looking for a containing interface block
111 for (DetailAST token = aAST.getParent();
112 token != null;
113 token = token.getParent())
114 {
115 final int type = token.getType();
116 if (type == TokenTypes.CLASS_DEF) {
117 break; // in a class
118 }
119 else if (type == TokenTypes.LITERAL_NEW) {
120 break; // inner implementation
121 }
122 else if (type == TokenTypes.INTERFACE_DEF) {
123 retVal = true;
124 break;
125 }
126 }
127
128 return retVal;
129 }
130
131 /**
132 * Returns whether the scope of a node is restricted to a code block.
133 * A code block is a method or constructor body, or a initialiser block.
134 *
135 * @param aAST the node to check
136 * @return a <code>boolean</code> value
137 */
138 public static boolean inCodeBlock(DetailAST aAST)
139 {
140 boolean retVal = false;
141
142 // Loop up looking for a containing code block
143 for (DetailAST token = aAST.getParent();
144 token != null;
145 token = token.getParent())
146 {
147 final int type = token.getType();
148 if ((type == TokenTypes.METHOD_DEF)
149 || (type == TokenTypes.CTOR_DEF)
150 || (type == TokenTypes.INSTANCE_INIT)
151 || (type == TokenTypes.STATIC_INIT))
152 {
153 retVal = true;
154 break;
155 }
156 }
157
158 return retVal;
159 }
160
161 /**
162 * Returns whether a node is contained in the outer most type block.
163 *
164 * @param aAST the node to check
165 * @return a <code>boolean</code> value
166 */
167 public static boolean isOuterMostType(DetailAST aAST)
168 {
169 boolean retVal = true;
170 for (DetailAST parent = aAST.getParent();
171 parent != null;
172 parent = parent.getParent())
173 {
174 if ((parent.getType() == TokenTypes.CLASS_DEF)
175 || (parent.getType() == TokenTypes.INTERFACE_DEF))
176 {
177 retVal = false;
178 break;
179 }
180 }
181
182 return retVal;
183 }
184
185 /**
186 * Determines whether a node is a local variable definition.
187 * I.e. if it is declared in a code block, a for initializer,
188 * or a catch parameter.
189 * @param aAST the node to check.
190 * @return whether aAST is a local variable definition.
191 */
192 public static boolean isLocalVariableDef(DetailAST aAST)
193 {
194 // variable declaration?
195 if (aAST.getType() == TokenTypes.VARIABLE_DEF) {
196 final DetailAST parent = aAST.getParent();
197 if (parent != null) {
198 final int type = parent.getType();
199 return (type == TokenTypes.SLIST)
200 || (type == TokenTypes.FOR_INIT);
201 }
202 }
203 // catch parameter?
204 else if (aAST.getType() == TokenTypes.PARAMETER_DEF) {
205 final DetailAST parent = aAST.getParent();
206 if (parent != null) {
207 return (parent.getType() == TokenTypes.LITERAL_CATCH);
208 }
209 }
210 return false;
211 }
212 }