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    }