Source code: com/puppycrawl/tools/checkstyle/checks/usage/transmogrify/ASTUtil.java
1 // Transmogrify License
2 //
3 // Copyright (c) 2001, ThoughtWorks, Inc.
4 // All rights reserved.
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // - Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // Neither the name of the ThoughtWorks, Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from this
15 // software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 package com.puppycrawl.tools.checkstyle.checks.usage.transmogrify;
29
30 import java.io.File;
31
32 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
33
34
35
36 /**
37 * <code>ASTUtil</code> is a <code>Utility Class</code> that contains utility code
38 * for managing our SymTabAST.
39 *
40 * @see Definition
41 * @see TypedDef
42 */
43
44 public class ASTUtil {
45
46 /**
47 * gets a line number for the tree; if the current SymTabAST node does not have one associated
48 * with it, traverse its children until a line number is found. Failure results in line
49 * number value of 0.
50 *
51 * @param tree the SymTabAST to process
52 *
53 * @return int the resulting line number (0 if none is found)
54 */
55 public static int getLine(SymTabAST tree) {
56 SymTabAST indexedNode = (SymTabAST) tree;
57
58 // find a node that actually has line number info
59 if (indexedNode.getLineNo() == 0) {
60 indexedNode = (SymTabAST) indexedNode.getFirstChild();
61
62 while (indexedNode != null && indexedNode.getLineNo() == 0) {
63 indexedNode = (SymTabAST) indexedNode.getNextSibling();
64 }
65
66 if (indexedNode == null) {
67 // we're screwed
68 indexedNode = (SymTabAST) tree;
69 }
70 }
71
72 return indexedNode.getLineNo();
73 }
74
75 /**
76 * gets a column number for the tree; if the current SymTabAST node does not have one associated
77 * with it, traverse its children until a column number is found. Failure results in column
78 * number value of 0.
79 *
80 * @param tree the SymTabAST to process
81 *
82 * @return int the resulting line number (0 if none is found)
83 */
84 public static int getColumn(SymTabAST tree) {
85 SymTabAST indexedNode = (SymTabAST) tree;
86
87 // find a node that actually has line number info
88 // REDTAG -- a label's ':' is a real token and has (the wrong) column info
89 // because it is the parent of the ident node that people will want
90 if (indexedNode.getColumnNo() == 0
91 || indexedNode.getType() == TokenTypes.LABELED_STAT) {
92 indexedNode = (SymTabAST) indexedNode.getFirstChild();
93
94 while (indexedNode != null && indexedNode.getColumnNo() == 0) {
95 indexedNode = (SymTabAST) indexedNode.getNextSibling();
96 }
97
98 if (indexedNode == null) {
99 // we're screwed
100 indexedNode = (SymTabAST) tree;
101 }
102 }
103
104 return indexedNode.getColumnNo();
105 }
106
107 /**
108 * Builds a ClassDef based on the the Node of tpye JavaTokenType.TYPE in the
109 * SymTabAST and returns this.
110 *
111 * @see JavaTokenType
112 *
113 * @return ClassDef
114 * @param tree the SymTabAST contaning all Definitions
115 * @param symboloTable contains the info for the defintion being returned
116 */
117 private static ClassDef getType(SymTabAST tree, SymbolTable symbolTable) {
118 // is this referenced correctly?
119
120 ClassDef result = null;
121
122 SymTabAST typeNode = tree.findFirstToken(TokenTypes.TYPE);
123
124 if (typeNode != null) {
125 //result = new DummyClass((SymTabAST)tree,
126 // ASTUtil.constructDottedName(typeNode.getFirstChild()),
127 // ASTUtil.getOccurrence(typeNode, symbolTable));
128 }
129
130 return result;
131 }
132
133 /**
134 * Builds the dotted name String representation of the object contained within
135 * the SymTabAST.
136 *
137 * @return String
138 * @param tree the SymTabAST contaning the entire hierarcy of the object
139 */
140 public static String constructDottedName(SymTabAST tree) {
141 String result;
142
143 if (tree.getType() == TokenTypes.DOT) {
144 SymTabAST left = (SymTabAST) tree.getFirstChild();
145 SymTabAST right = (SymTabAST) left.getNextSibling();
146
147 result =
148 constructDottedName(left) + "." + constructDottedName(right);
149 }
150 else if (tree.getType() == TokenTypes.ARRAY_DECLARATOR) {
151 StringBuffer buf = new StringBuffer();
152 SymTabAST left = (SymTabAST) tree.getFirstChild();
153 SymTabAST right = (SymTabAST) left.getNextSibling();
154
155 buf.append(constructDottedName(left));
156
157 if (right != null) {
158 buf.append(".");
159 buf.append(constructDottedName(right));
160 }
161
162 buf.append(" []");
163
164 result = buf.toString();
165 }
166 else if (tree.getType() == TokenTypes.METHOD_CALL) {
167 result =
168 constructDottedName((SymTabAST) tree.getFirstChild()) + "()";
169 }
170 else {
171 result = tree.getText();
172 }
173
174 return result;
175 }
176
177 /**
178 * Returns the Package name in the hierarchy represented by the SymTabAST.
179 *
180 * @return String
181 * @param tree the SymTabAST contaning the entire hierarcy of the object
182 */
183 public static String constructPackage(SymTabAST tree) {
184 String fullName = constructDottedName(tree);
185
186 return fullName.substring(0, fullName.lastIndexOf("."));
187 }
188
189 /**
190 * Returns the top Class name in the hierarchy represented by the SymTabAST.
191 *
192 * @return String
193 * @param tree the SymTabAST contaning the entire hierarcy of the object
194 */
195 public static String constructClass(SymTabAST tree) {
196 String fullName = constructDottedName(tree);
197
198 return fullName.substring(
199 fullName.lastIndexOf(".") + 1,
200 fullName.length());
201 }
202
203 public static boolean treesBelowFilesAreEqual(
204 SymTabAST firstRoot,
205 File[] firstFiles,
206 SymTabAST secondRoot,
207 File[] secondFiles) {
208 boolean result = true;
209
210 if (firstFiles.length == secondFiles.length) {
211 for (int i = 0; i < firstFiles.length; i++) {
212 SymTabAST firstTree =
213 (SymTabAST) getFileNode(firstRoot, firstFiles[i])
214 .getFirstChild();
215 SymTabAST secondTree =
216 (SymTabAST) getFileNode(secondRoot, secondFiles[i])
217 .getFirstChild();
218
219 if (!firstTree.equalsList(secondTree)) {
220 result = false;
221 break;
222 }
223 }
224 }
225 else {
226 result = false;
227 }
228
229 return result;
230 }
231
232 public static SymTabAST getFileNode(SymTabAST root, File file)
233 {
234 SymTabAST result = null;
235
236 SymTabAST fileNode = (SymTabAST) root.getFirstChild();
237 while (fileNode != null && result == null) {
238 if (file.equals(fileNode.getFile())) {
239 result = fileNode;
240 }
241 fileNode = (SymTabAST) fileNode.getNextSibling();
242 }
243
244 return result;
245 }
246 }