1 | /* |
2 | * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Sun designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Sun in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
22 | * CA 95054 USA or visit www.sun.com if you need additional information or |
23 | * have any questions. |
24 | */ |
25 | |
26 | package com.sun.tools.javac.tree; |
27 | |
28 | import com.sun.tools.javac.util.*; |
29 | import com.sun.tools.javac.tree.JCTree.*; |
30 | |
31 | /** A subclass of Tree.Visitor, this class defines |
32 | * a general tree translator pattern. Translation proceeds recursively in |
33 | * left-to-right order down a tree, constructing translated nodes by |
34 | * overwriting existing ones. There is one visitor method in this class |
35 | * for every possible kind of tree node. To obtain a specific |
36 | * translator, it suffices to override those visitor methods which |
37 | * do some interesting work. The translator class itself takes care of all |
38 | * navigational aspects. |
39 | * |
40 | * <p><b>This is NOT part of any API supported by Sun Microsystems. If |
41 | * you write code that depends on this, you do so at your own risk. |
42 | * This code and its internal interfaces are subject to change or |
43 | * deletion without notice.</b> |
44 | */ |
45 | public class TreeTranslator extends JCTree.Visitor { |
46 | |
47 | /** Visitor result field: a tree |
48 | */ |
49 | protected JCTree result; |
50 | |
51 | /** Visitor method: Translate a single node. |
52 | */ |
53 | @SuppressWarnings("unchecked") |
54 | public <T extends JCTree> T translate(T tree) { |
55 | if (tree == null) { |
56 | return null; |
57 | } else { |
58 | tree.accept(this); |
59 | JCTree result = this.result; |
60 | this.result = null; |
61 | return (T)result; // XXX cast |
62 | } |
63 | } |
64 | |
65 | /** Visitor method: translate a list of nodes. |
66 | */ |
67 | public <T extends JCTree> List<T> translate(List<T> trees) { |
68 | if (trees == null) return null; |
69 | for (List<T> l = trees; l.nonEmpty(); l = l.tail) |
70 | l.head = translate(l.head); |
71 | return trees; |
72 | } |
73 | |
74 | /** Visitor method: translate a list of variable definitions. |
75 | */ |
76 | public List<JCVariableDecl> translateVarDefs(List<JCVariableDecl> trees) { |
77 | for (List<JCVariableDecl> l = trees; l.nonEmpty(); l = l.tail) |
78 | l.head = translate(l.head); |
79 | return trees; |
80 | } |
81 | |
82 | /** Visitor method: translate a list of type parameters. |
83 | */ |
84 | public List<JCTypeParameter> translateTypeParams(List<JCTypeParameter> trees) { |
85 | for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail) |
86 | l.head = translate(l.head); |
87 | return trees; |
88 | } |
89 | |
90 | /** Visitor method: translate a list of case parts of switch statements. |
91 | */ |
92 | public List<JCCase> translateCases(List<JCCase> trees) { |
93 | for (List<JCCase> l = trees; l.nonEmpty(); l = l.tail) |
94 | l.head = translate(l.head); |
95 | return trees; |
96 | } |
97 | |
98 | /** Visitor method: translate a list of catch clauses in try statements. |
99 | */ |
100 | public List<JCCatch> translateCatchers(List<JCCatch> trees) { |
101 | for (List<JCCatch> l = trees; l.nonEmpty(); l = l.tail) |
102 | l.head = translate(l.head); |
103 | return trees; |
104 | } |
105 | |
106 | /** Visitor method: translate a list of catch clauses in try statements. |
107 | */ |
108 | public List<JCAnnotation> translateAnnotations(List<JCAnnotation> trees) { |
109 | for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) |
110 | l.head = translate(l.head); |
111 | return trees; |
112 | } |
113 | |
114 | /* *************************************************************************** |
115 | * Visitor methods |
116 | ****************************************************************************/ |
117 | |
118 | public void visitTopLevel(JCCompilationUnit tree) { |
119 | tree.pid = translate(tree.pid); |
120 | tree.defs = translate(tree.defs); |
121 | result = tree; |
122 | } |
123 | |
124 | public void visitImport(JCImport tree) { |
125 | tree.qualid = translate(tree.qualid); |
126 | result = tree; |
127 | } |
128 | |
129 | public void visitClassDef(JCClassDecl tree) { |
130 | tree.mods = translate(tree.mods); |
131 | tree.typarams = translateTypeParams(tree.typarams); |
132 | tree.extending = translate(tree.extending); |
133 | tree.implementing = translate(tree.implementing); |
134 | tree.defs = translate(tree.defs); |
135 | result = tree; |
136 | } |
137 | |
138 | public void visitMethodDef(JCMethodDecl tree) { |
139 | tree.mods = translate(tree.mods); |
140 | tree.restype = translate(tree.restype); |
141 | tree.typarams = translateTypeParams(tree.typarams); |
142 | tree.params = translateVarDefs(tree.params); |
143 | tree.thrown = translate(tree.thrown); |
144 | tree.body = translate(tree.body); |
145 | result = tree; |
146 | } |
147 | |
148 | public void visitVarDef(JCVariableDecl tree) { |
149 | tree.mods = translate(tree.mods); |
150 | tree.vartype = translate(tree.vartype); |
151 | tree.init = translate(tree.init); |
152 | result = tree; |
153 | } |
154 | |
155 | public void visitSkip(JCSkip tree) { |
156 | result = tree; |
157 | } |
158 | |
159 | public void visitBlock(JCBlock tree) { |
160 | tree.stats = translate(tree.stats); |
161 | result = tree; |
162 | } |
163 | |
164 | public void visitDoLoop(JCDoWhileLoop tree) { |
165 | tree.body = translate(tree.body); |
166 | tree.cond = translate(tree.cond); |
167 | result = tree; |
168 | } |
169 | |
170 | public void visitWhileLoop(JCWhileLoop tree) { |
171 | tree.cond = translate(tree.cond); |
172 | tree.body = translate(tree.body); |
173 | result = tree; |
174 | } |
175 | |
176 | public void visitForLoop(JCForLoop tree) { |
177 | tree.init = translate(tree.init); |
178 | tree.cond = translate(tree.cond); |
179 | tree.step = translate(tree.step); |
180 | tree.body = translate(tree.body); |
181 | result = tree; |
182 | } |
183 | |
184 | public void visitForeachLoop(JCEnhancedForLoop tree) { |
185 | tree.var = translate(tree.var); |
186 | tree.expr = translate(tree.expr); |
187 | tree.body = translate(tree.body); |
188 | result = tree; |
189 | } |
190 | |
191 | public void visitLabelled(JCLabeledStatement tree) { |
192 | tree.body = translate(tree.body); |
193 | result = tree; |
194 | } |
195 | |
196 | public void visitSwitch(JCSwitch tree) { |
197 | tree.selector = translate(tree.selector); |
198 | tree.cases = translateCases(tree.cases); |
199 | result = tree; |
200 | } |
201 | |
202 | public void visitCase(JCCase tree) { |
203 | tree.pat = translate(tree.pat); |
204 | tree.stats = translate(tree.stats); |
205 | result = tree; |
206 | } |
207 | |
208 | public void visitSynchronized(JCSynchronized tree) { |
209 | tree.lock = translate(tree.lock); |
210 | tree.body = translate(tree.body); |
211 | result = tree; |
212 | } |
213 | |
214 | public void visitTry(JCTry tree) { |
215 | tree.body = translate(tree.body); |
216 | tree.catchers = translateCatchers(tree.catchers); |
217 | tree.finalizer = translate(tree.finalizer); |
218 | result = tree; |
219 | } |
220 | |
221 | public void visitCatch(JCCatch tree) { |
222 | tree.param = translate(tree.param); |
223 | tree.body = translate(tree.body); |
224 | result = tree; |
225 | } |
226 | |
227 | public void visitConditional(JCConditional tree) { |
228 | tree.cond = translate(tree.cond); |
229 | tree.truepart = translate(tree.truepart); |
230 | tree.falsepart = translate(tree.falsepart); |
231 | result = tree; |
232 | } |
233 | |
234 | public void visitIf(JCIf tree) { |
235 | tree.cond = translate(tree.cond); |
236 | tree.thenpart = translate(tree.thenpart); |
237 | tree.elsepart = translate(tree.elsepart); |
238 | result = tree; |
239 | } |
240 | |
241 | public void visitExec(JCExpressionStatement tree) { |
242 | tree.expr = translate(tree.expr); |
243 | result = tree; |
244 | } |
245 | |
246 | public void visitBreak(JCBreak tree) { |
247 | result = tree; |
248 | } |
249 | |
250 | public void visitContinue(JCContinue tree) { |
251 | result = tree; |
252 | } |
253 | |
254 | public void visitReturn(JCReturn tree) { |
255 | tree.expr = translate(tree.expr); |
256 | result = tree; |
257 | } |
258 | |
259 | public void visitThrow(JCThrow tree) { |
260 | tree.expr = translate(tree.expr); |
261 | result = tree; |
262 | } |
263 | |
264 | public void visitAssert(JCAssert tree) { |
265 | tree.cond = translate(tree.cond); |
266 | tree.detail = translate(tree.detail); |
267 | result = tree; |
268 | } |
269 | |
270 | public void visitApply(JCMethodInvocation tree) { |
271 | tree.meth = translate(tree.meth); |
272 | tree.args = translate(tree.args); |
273 | result = tree; |
274 | } |
275 | |
276 | public void visitNewClass(JCNewClass tree) { |
277 | tree.encl = translate(tree.encl); |
278 | tree.clazz = translate(tree.clazz); |
279 | tree.args = translate(tree.args); |
280 | tree.def = translate(tree.def); |
281 | result = tree; |
282 | } |
283 | |
284 | public void visitNewArray(JCNewArray tree) { |
285 | tree.elemtype = translate(tree.elemtype); |
286 | tree.dims = translate(tree.dims); |
287 | tree.elems = translate(tree.elems); |
288 | result = tree; |
289 | } |
290 | |
291 | public void visitParens(JCParens tree) { |
292 | tree.expr = translate(tree.expr); |
293 | result = tree; |
294 | } |
295 | |
296 | public void visitAssign(JCAssign tree) { |
297 | tree.lhs = translate(tree.lhs); |
298 | tree.rhs = translate(tree.rhs); |
299 | result = tree; |
300 | } |
301 | |
302 | public void visitAssignop(JCAssignOp tree) { |
303 | tree.lhs = translate(tree.lhs); |
304 | tree.rhs = translate(tree.rhs); |
305 | result = tree; |
306 | } |
307 | |
308 | public void visitUnary(JCUnary tree) { |
309 | tree.arg = translate(tree.arg); |
310 | result = tree; |
311 | } |
312 | |
313 | public void visitBinary(JCBinary tree) { |
314 | tree.lhs = translate(tree.lhs); |
315 | tree.rhs = translate(tree.rhs); |
316 | result = tree; |
317 | } |
318 | |
319 | public void visitTypeCast(JCTypeCast tree) { |
320 | tree.clazz = translate(tree.clazz); |
321 | tree.expr = translate(tree.expr); |
322 | result = tree; |
323 | } |
324 | |
325 | public void visitTypeTest(JCInstanceOf tree) { |
326 | tree.expr = translate(tree.expr); |
327 | tree.clazz = translate(tree.clazz); |
328 | result = tree; |
329 | } |
330 | |
331 | public void visitIndexed(JCArrayAccess tree) { |
332 | tree.indexed = translate(tree.indexed); |
333 | tree.index = translate(tree.index); |
334 | result = tree; |
335 | } |
336 | |
337 | public void visitSelect(JCFieldAccess tree) { |
338 | tree.selected = translate(tree.selected); |
339 | result = tree; |
340 | } |
341 | |
342 | public void visitIdent(JCIdent tree) { |
343 | result = tree; |
344 | } |
345 | |
346 | public void visitLiteral(JCLiteral tree) { |
347 | result = tree; |
348 | } |
349 | |
350 | public void visitTypeIdent(JCPrimitiveTypeTree tree) { |
351 | result = tree; |
352 | } |
353 | |
354 | public void visitTypeArray(JCArrayTypeTree tree) { |
355 | tree.elemtype = translate(tree.elemtype); |
356 | result = tree; |
357 | } |
358 | |
359 | public void visitTypeApply(JCTypeApply tree) { |
360 | tree.clazz = translate(tree.clazz); |
361 | tree.arguments = translate(tree.arguments); |
362 | result = tree; |
363 | } |
364 | |
365 | public void visitTypeParameter(JCTypeParameter tree) { |
366 | tree.bounds = translate(tree.bounds); |
367 | result = tree; |
368 | } |
369 | |
370 | @Override |
371 | public void visitWildcard(JCWildcard tree) { |
372 | tree.kind = translate(tree.kind); |
373 | tree.inner = translate(tree.inner); |
374 | result = tree; |
375 | } |
376 | |
377 | @Override |
378 | public void visitTypeBoundKind(TypeBoundKind tree) { |
379 | result = tree; |
380 | } |
381 | |
382 | public void visitErroneous(JCErroneous tree) { |
383 | result = tree; |
384 | } |
385 | |
386 | public void visitLetExpr(LetExpr tree) { |
387 | tree.defs = translateVarDefs(tree.defs); |
388 | tree.expr = translate(tree.expr); |
389 | result = tree; |
390 | } |
391 | |
392 | public void visitModifiers(JCModifiers tree) { |
393 | tree.annotations = translateAnnotations(tree.annotations); |
394 | result = tree; |
395 | } |
396 | |
397 | public void visitAnnotation(JCAnnotation tree) { |
398 | tree.annotationType = translate(tree.annotationType); |
399 | tree.args = translate(tree.args); |
400 | result = tree; |
401 | } |
402 | |
403 | public void visitTree(JCTree tree) { |
404 | throw new AssertionError(tree); |
405 | } |
406 | } |