001 /*
002 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package com.sun.tools.javac.tree;
027
028 import com.sun.tools.javac.util.*;
029 import com.sun.tools.javac.tree.JCTree.*;
030
031 /** A subclass of Tree.Visitor, this class defines
032 * a general tree translator pattern. Translation proceeds recursively in
033 * left-to-right order down a tree, constructing translated nodes by
034 * overwriting existing ones. There is one visitor method in this class
035 * for every possible kind of tree node. To obtain a specific
036 * translator, it suffices to override those visitor methods which
037 * do some interesting work. The translator class itself takes care of all
038 * navigational aspects.
039 *
040 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
041 * you write code that depends on this, you do so at your own risk.
042 * This code and its internal interfaces are subject to change or
043 * deletion without notice.</b>
044 */
045 public class TreeTranslator extends JCTree.Visitor {
046
047 /** Visitor result field: a tree
048 */
049 protected JCTree result;
050
051 /** Visitor method: Translate a single node.
052 */
053 @SuppressWarnings("unchecked")
054 public <T extends JCTree> T translate(T tree) {
055 if (tree == null) {
056 return null;
057 } else {
058 tree.accept(this);
059 JCTree result = this.result;
060 this.result = null;
061 return (T)result; // XXX cast
062 }
063 }
064
065 /** Visitor method: translate a list of nodes.
066 */
067 public <T extends JCTree> List<T> translate(List<T> trees) {
068 if (trees == null) return null;
069 for (List<T> l = trees; l.nonEmpty(); l = l.tail)
070 l.head = translate(l.head);
071 return trees;
072 }
073
074 /** Visitor method: translate a list of variable definitions.
075 */
076 public List<JCVariableDecl> translateVarDefs(List<JCVariableDecl> trees) {
077 for (List<JCVariableDecl> l = trees; l.nonEmpty(); l = l.tail)
078 l.head = translate(l.head);
079 return trees;
080 }
081
082 /** Visitor method: translate a list of type parameters.
083 */
084 public List<JCTypeParameter> translateTypeParams(List<JCTypeParameter> trees) {
085 for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail)
086 l.head = translate(l.head);
087 return trees;
088 }
089
090 /** Visitor method: translate a list of case parts of switch statements.
091 */
092 public List<JCCase> translateCases(List<JCCase> trees) {
093 for (List<JCCase> l = trees; l.nonEmpty(); l = l.tail)
094 l.head = translate(l.head);
095 return trees;
096 }
097
098 /** Visitor method: translate a list of catch clauses in try statements.
099 */
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 // mgr: staging additions
165 public void visitBracketExpr(JCBracketExpr tree) {
166 result = tree;
167 }
168 public void visitBracketStat(JCBracketStat tree) {
169 result = tree;
170 }
171
172 public void visitDoLoop(JCDoWhileLoop tree) {
173 tree.body = translate(tree.body);
174 tree.cond = translate(tree.cond);
175 result = tree;
176 }
177
178 public void visitWhileLoop(JCWhileLoop tree) {
179 tree.cond = translate(tree.cond);
180 tree.body = translate(tree.body);
181 result = tree;
182 }
183
184 public void visitForLoop(JCForLoop tree) {
185 tree.init = translate(tree.init);
186 tree.cond = translate(tree.cond);
187 tree.step = translate(tree.step);
188 tree.body = translate(tree.body);
189 result = tree;
190 }
191
192 public void visitForeachLoop(JCEnhancedForLoop tree) {
193 tree.var = translate(tree.var);
194 tree.expr = translate(tree.expr);
195 tree.body = translate(tree.body);
196 result = tree;
197 }
198
199 public void visitLabelled(JCLabeledStatement tree) {
200 tree.body = translate(tree.body);
201 result = tree;
202 }
203
204 public void visitSwitch(JCSwitch tree) {
205 tree.selector = translate(tree.selector);
206 tree.cases = translateCases(tree.cases);
207 result = tree;
208 }
209
210 public void visitCase(JCCase tree) {
211 tree.pat = translate(tree.pat);
212 tree.stats = translate(tree.stats);
213 result = tree;
214 }
215
216 public void visitSynchronized(JCSynchronized tree) {
217 tree.lock = translate(tree.lock);
218 tree.body = translate(tree.body);
219 result = tree;
220 }
221
222 public void visitTry(JCTry tree) {
223 tree.body = translate(tree.body);
224 tree.catchers = translateCatchers(tree.catchers);
225 tree.finalizer = translate(tree.finalizer);
226 result = tree;
227 }
228
229 public void visitCatch(JCCatch tree) {
230 tree.param = translate(tree.param);
231 tree.body = translate(tree.body);
232 result = tree;
233 }
234
235 public void visitConditional(JCConditional tree) {
236 tree.cond = translate(tree.cond);
237 tree.truepart = translate(tree.truepart);
238 tree.falsepart = translate(tree.falsepart);
239 result = tree;
240 }
241
242 public void visitIf(JCIf tree) {
243 tree.cond = translate(tree.cond);
244 tree.thenpart = translate(tree.thenpart);
245 tree.elsepart = translate(tree.elsepart);
246 result = tree;
247 }
248
249 public void visitExec(JCExpressionStatement tree) {
250 tree.expr = translate(tree.expr);
251 result = tree;
252 }
253
254 public void visitBreak(JCBreak tree) {
255 result = tree;
256 }
257
258 public void visitContinue(JCContinue tree) {
259 result = tree;
260 }
261
262 public void visitReturn(JCReturn tree) {
263 tree.expr = translate(tree.expr);
264 result = tree;
265 }
266
267 public void visitThrow(JCThrow tree) {
268 tree.expr = translate(tree.expr);
269 result = tree;
270 }
271
272 public void visitAssert(JCAssert tree) {
273 tree.cond = translate(tree.cond);
274 tree.detail = translate(tree.detail);
275 result = tree;
276 }
277
278 public void visitApply(JCMethodInvocation tree) {
279 tree.meth = translate(tree.meth);
280 tree.args = translate(tree.args);
281 result = tree;
282 }
283
284 public void visitNewClass(JCNewClass tree) {
285 tree.encl = translate(tree.encl);
286 tree.clazz = translate(tree.clazz);
287 tree.args = translate(tree.args);
288 tree.def = translate(tree.def);
289 result = tree;
290 }
291
292 public void visitNewArray(JCNewArray tree) {
293 tree.elemtype = translate(tree.elemtype);
294 tree.dims = translate(tree.dims);
295 tree.elems = translate(tree.elems);
296 result = tree;
297 }
298
299 public void visitParens(JCParens tree) {
300 tree.expr = translate(tree.expr);
301 result = tree;
302 }
303
304 public void visitAssign(JCAssign tree) {
305 tree.lhs = translate(tree.lhs);
306 tree.rhs = translate(tree.rhs);
307 result = tree;
308 }
309
310 public void visitAssignop(JCAssignOp tree) {
311 tree.lhs = translate(tree.lhs);
312 tree.rhs = translate(tree.rhs);
313 result = tree;
314 }
315
316 public void visitUnary(JCUnary tree) {
317 tree.arg = translate(tree.arg);
318 result = tree;
319 }
320
321 public void visitBinary(JCBinary tree) {
322 tree.lhs = translate(tree.lhs);
323 tree.rhs = translate(tree.rhs);
324 result = tree;
325 }
326
327 public void visitTypeCast(JCTypeCast tree) {
328 tree.clazz = translate(tree.clazz);
329 tree.expr = translate(tree.expr);
330 result = tree;
331 }
332
333 public void visitTypeTest(JCInstanceOf tree) {
334 tree.expr = translate(tree.expr);
335 tree.clazz = translate(tree.clazz);
336 result = tree;
337 }
338
339 public void visitIndexed(JCArrayAccess tree) {
340 tree.indexed = translate(tree.indexed);
341 tree.index = translate(tree.index);
342 result = tree;
343 }
344
345 public void visitSelect(JCFieldAccess tree) {
346 tree.selected = translate(tree.selected);
347 result = tree;
348 }
349
350 public void visitIdent(JCIdent tree) {
351 result = tree;
352 }
353
354 public void visitLiteral(JCLiteral tree) {
355 result = tree;
356 }
357
358 public void visitTypeIdent(JCPrimitiveTypeTree tree) {
359 result = tree;
360 }
361
362 public void visitTypeArray(JCArrayTypeTree tree) {
363 tree.elemtype = translate(tree.elemtype);
364 result = tree;
365 }
366
367 public void visitTypeApply(JCTypeApply tree) {
368 tree.clazz = translate(tree.clazz);
369 tree.arguments = translate(tree.arguments);
370 result = tree;
371 }
372
373 public void visitTypeParameter(JCTypeParameter tree) {
374 tree.bounds = translate(tree.bounds);
375 result = tree;
376 }
377
378 @Override
379 public void visitWildcard(JCWildcard tree) {
380 tree.kind = translate(tree.kind);
381 tree.inner = translate(tree.inner);
382 result = tree;
383 }
384
385 @Override
386 public void visitTypeBoundKind(TypeBoundKind tree) {
387 result = tree;
388 }
389
390 public void visitErroneous(JCErroneous tree) {
391 result = tree;
392 }
393
394 public void visitLetExpr(LetExpr tree) {
395 tree.defs = translateVarDefs(tree.defs);
396 tree.expr = translate(tree.expr);
397 result = tree;
398 }
399
400 public void visitModifiers(JCModifiers tree) {
401 tree.annotations = translateAnnotations(tree.annotations);
402 result = tree;
403 }
404
405 public void visitAnnotation(JCAnnotation tree) {
406 tree.annotationType = translate(tree.annotationType);
407 tree.args = translate(tree.args);
408 result = tree;
409 }
410
411 public void visitTree(JCTree tree) {
412 throw new AssertionError(tree);
413 }
414 }