KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > source > transform > ImmutableTreeTranslator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.java.source.transform;
21
22 import org.netbeans.modules.java.source.engine.EngineEnvironment;
23 import org.netbeans.api.java.source.query.CommentHandler;
24 import org.netbeans.modules.java.source.engine.RootTree;
25 import org.netbeans.api.java.source.query.QueryEnvironment;
26 import org.netbeans.modules.java.source.engine.EngineEnvironment;
27 import org.netbeans.modules.java.source.engine.ASTModel;
28 import org.netbeans.modules.java.source.engine.TreeMakerInt;
29 import org.netbeans.api.java.source.query.Query;
30
31 import com.sun.source.tree.*;
32 import com.sun.source.tree.Tree.Kind;
33 import javax.lang.model.element.Element;
34 import javax.lang.model.element.TypeElement;
35
36 import java.util.ArrayList JavaDoc;
37 import java.util.List JavaDoc;
38 import org.netbeans.api.java.source.SourceUtils;
39 import org.netbeans.modules.java.source.builder.QualIdentTree;
40 import org.netbeans.modules.java.source.pretty.ImportAnalysis2;
41
42 /** A subclass of Tree.Visitor, this class defines
43  * a general tree translator pattern. Translation proceeds recursively in
44  * left-to-right order down a tree. If a node needs to be translated, a
45  * replacement is constructed. There is one visitor method in this class
46  * for every possible kind of tree node. To obtain a specific
47  * translator, it suffices to override those visitor methods which
48  * do some interesting work. The translator class itself takes care of all
49  * navigational aspects.
50  *
51  * All visitor methods must follow the following Pattern:
52  * <br>public Tree visitT(T tree) {
53  * <br>&nbsp;&nbsp;rewriteChildren(tree);
54  * <br>&nbsp;&nbsp;// fetch field values as tree.X
55  * <br>&nbsp;&nbsp;// <i>Do not assign to any fields of tree</i>
56  * <br>&nbsp;&nbsp;return new_tree_to_replace_old
57  * <br>&nbsp;&nbsp;// (returning the original tree leaves it unchanged)
58  * <br>}
59  */

60 public class ImmutableTreeTranslator implements TreeVisitor<Tree,Object JavaDoc> {
61
62     public Element currentSym;
63
64     protected TreeMakerInt make;
65     protected CommentHandler comments;
66     protected ASTModel model;
67     protected QueryEnvironment env;
68     private CompilationUnitTree topLevel;
69     private ImportAnalysis2 importAnalysis;
70
71     public void attach(QueryEnvironment env) {
72     make = env.getTreeMaker();
73     comments = env.getCommentHandler();
74         this.model = ((EngineEnvironment)env).getModel();
75         this.env = env;
76         importAnalysis = new ImportAnalysis2(env);
77     }
78     
79     public void release() {
80         make = null;
81         comments = null;
82         model = null;
83         env = null;
84         topLevel = null;
85     }
86
87     /** Visitor method: Translate a single node.
88      */

89     public Tree translate(Tree tree) {
90     if (tree == null)
91         return null;
92         else if (tree instanceof RootTree)
93             return rewriteChildren((RootTree)tree);
94     else
95         return tree.accept(this, null);
96     }
97
98     public <T extends Tree> T translateClassRef(T tree) {
99     return (T)translate(tree);
100     }
101     
102     public final <T extends Tree> List JavaDoc<T> translateClassRef(List JavaDoc<T> trees) {
103     if (trees == null || trees.isEmpty())
104             return trees;
105         List JavaDoc<T> newTrees = new ArrayList JavaDoc<T>();
106         boolean changed = false;
107         for (T t : trees) {
108             T newT = translateClassRef(t);
109             if (newT != t)
110                 changed = true;
111             if (newT != null)
112                 newTrees.add(newT);
113         }
114         return changed ? newTrees : trees;
115     }
116
117     /** Visitor method: Translate a single node.
118      * return type is guaranteed to be the same as the input type
119      */

120     public <T extends Tree> T translateStable(T tree) {
121     Tree t2 = translate(tree);
122     if(t2!=null && t2.getClass()!=tree.getClass()) {
123         t2 = Transformer.deblock(t2);
124         if(t2.getClass()!=tree.getClass()) {
125                 //possibly import analysis rewrote QualIdentTree->IdentifierTree or QIT->MemberSelectTree:
126
if ( tree.getClass() != QualIdentTree.class
127                     || (t2.getKind() != Kind.IDENTIFIER) && (t2.getKind() != Kind.MEMBER_SELECT)) {
128                     System.err.println("Rewrite stability problem: got "+t2.getClass()
129                         +"\n\t\texpected "+tree.getClass());
130                     return tree;
131                 }
132         }
133     }
134     return (T)t2;
135     }
136
137     /** Visitor method: translate a list of nodes.
138      */

139     public <T extends Tree> List JavaDoc<T> translate(List JavaDoc<T> trees) {
140     if (trees == null || trees.isEmpty())
141             return trees;
142         List JavaDoc<T> newTrees = new ArrayList JavaDoc<T>();
143         boolean changed = false;
144         for (T t : trees) {
145             T newT = (T)translate(t);
146             if (newT != t)
147                 changed = true;
148             if (newT != null)
149                 newTrees.add(newT);
150         }
151         return changed ? newTrees : trees;
152     }
153     
154     /** Visitor method: translate a list of nodes.
155      * List type is guaranteed to be the same as the input type.
156      */

157     public <T extends Tree> List JavaDoc<T> translateStable(List JavaDoc<T> trees) {
158     if (trees == null || trees.isEmpty()) return trees;
159         List JavaDoc<T> newTrees = new ArrayList JavaDoc<T>();
160         boolean changed = false;
161         for (T t : trees) {
162             T newT = translateStable(t);
163             if (newT != t)
164                 changed = true;
165             if (newT != null)
166                 newTrees.add(newT);
167         }
168         return changed ? newTrees : trees;
169     }
170     
171     /**
172      * Remove any empty statements, chop unreachable statements, and
173      * inline block statements (if possible).
174      *
175      * Note: this method should only be called on lists which were
176      * transformed, to avoid adding deltas not in the changes set.
177      */

178     protected <T extends Tree> List JavaDoc<T> optimize(List JavaDoc<T> trees) {
179     if (trees == null || trees.isEmpty())
180             return trees;
181         List JavaDoc<T> newTrees = new ArrayList JavaDoc<T>();
182         for (T t : trees) {
183             if (t == null || Query.isEmpty(t))
184                 continue;
185             switch (t.getKind()) {
186                 case BLOCK: {
187 // #pf: the following code was commented out because it is not always reasonable
188
// to inline functionality. -- Sometimes there is conflict between minimal
189
// changes and this optimization. -- Consider rename refactoring in case --
190
// User expects identifier change, but optimization replaces whole block.
191
// See BodyStatementTest.java:testRenameInCase() for details.
192
// BlockTree bt = (BlockTree)t;
193
// boolean canInline = !bt.isStatic(); // don't inline static initializers
194
// if (canInline)
195
// for (StatementTree st : bt.getStatements())
196
// if (st instanceof VariableTree) {
197
// canInline = false;
198
// break;
199
// }
200
// if (canInline) {
201
// // add statements instead of block
202
// for (StatementTree st : bt.getStatements())
203
// newTrees.add((T)st);
204
// }
205
// else
206
// newTrees.add(t); // just add block
207
// break;
208
}
209                 case RETURN:
210                 case THROW:
211                 case BREAK:
212                 case CONTINUE:
213                     newTrees.add(t);
214                     // any subsequent statements are chopped
215
return equals(trees, newTrees) ? trees : newTrees;
216                 default:
217                     newTrees.add(t);
218                     break;
219             }
220         }
221         return equals(trees, newTrees) ? trees : newTrees;
222     }
223     
224     /**
225      * Implements the equals contract for List, which javac's List doesn't
226      * support. Two Lists are considered equal if they are the same length,
227      * and have the same objects in the same order.
228      */

229     private static <T extends Tree> boolean equals(List JavaDoc<T> list1, List JavaDoc<T> list2) {
230         int n = list1.size();
231         if (n != list2.size())
232             return false;
233         for (int i = 0; i < n; i++)
234             if (list1.get(i) != list2.get(i))
235                 return false;
236         return true;
237     }
238     
239     public final void copyCommentTo(Tree from1, Tree from2, Tree to) {
240     copyCommentTo(from1,to);
241     if(from1 != from2) copyCommentTo(from2,to);
242     }
243     
244     public final void copyCommentTo(Tree from, Tree to) {
245         comments.copyComments(from, to);
246     }
247
248     protected int size(List JavaDoc<?> list) {
249         return list == null ? 0 : list.size();
250     }
251     
252     private void copyPosTo(Tree from, Tree to) {
253         model.setPos(to, model.getPos(from));
254     }
255     
256     private boolean safeEquals(Object JavaDoc o1, Object JavaDoc o2) {
257         if (o1 == null && o2 == null)
258             return true;
259         if (o1 == null || o2 == null)
260             return false;
261         return o1.equals(o2);
262     }
263
264 /* ***************************************************************************
265  * Visitor methods
266  ****************************************************************************/

267
268     public Tree visitCompilationUnit(CompilationUnitTree tree, Object JavaDoc p) {
269     topLevel = (CompilationUnitTree)tree;
270     CompilationUnitTree result = rewriteChildren(topLevel);
271     topLevel = null;
272         return result;
273     }
274     public Tree visitImport(ImportTree tree, Object JavaDoc p) {
275     return rewriteChildren(tree);
276     }
277     public Tree visitClass(ClassTree tree, Object JavaDoc p) {
278         Element oldSym = currentSym;
279         currentSym = model.getElement(tree);
280         importAnalysis.classEntered(tree);
281     ClassTree result = rewriteChildren(tree);
282         importAnalysis.classLeft();
283         currentSym = oldSym;
284         return result;
285     }
286     public Tree visitMethod(MethodTree tree, Object JavaDoc p) {
287         Element oldSym = currentSym;
288         currentSym = model.getElement(tree);
289     MethodTree result = rewriteChildren(tree);
290         currentSym = oldSym;
291         return result;
292     }
293     
294     public Tree visitVariable(VariableTree tree, Object JavaDoc p) {
295         Element oldSym = currentSym;
296         currentSym = model.getElement(tree);
297     VariableTree result = rewriteChildren(tree);
298         currentSym = oldSym;
299         return result;
300     }
301     
302     public Tree visitEmptyStatement(EmptyStatementTree tree, Object JavaDoc p) {
303     return rewriteChildren(tree);
304     }
305     public Tree visitBlock(BlockTree tree, Object JavaDoc p) {
306     return rewriteChildren(tree);
307     }
308     public Tree visitDoWhileLoop(DoWhileLoopTree tree, Object JavaDoc p) {
309     return rewriteChildren(tree);
310     }
311     public Tree visitWhileLoop(WhileLoopTree tree, Object JavaDoc p) {
312     return rewriteChildren(tree);
313     }
314     public Tree visitForLoop(ForLoopTree tree, Object JavaDoc p) {
315     return rewriteChildren(tree);
316     }
317     public Tree visitEnhancedForLoop(EnhancedForLoopTree tree, Object JavaDoc p) {
318     return rewriteChildren(tree);
319     }
320     public Tree visitLabeledStatement(LabeledStatementTree tree, Object JavaDoc p) {
321     return rewriteChildren(tree);
322     }
323     public Tree visitSwitch(SwitchTree tree, Object JavaDoc p) {
324     return rewriteChildren(tree);
325     }
326     public Tree visitCase(CaseTree tree, Object JavaDoc p) {
327     return rewriteChildren(tree);
328     }
329     public Tree visitSynchronized(SynchronizedTree tree, Object JavaDoc p) {
330     return rewriteChildren(tree);
331     }
332     public Tree visitTry(TryTree tree, Object JavaDoc p) {
333     return rewriteChildren(tree);
334     }
335     public Tree visitCatch(CatchTree tree, Object JavaDoc p) {
336     return rewriteChildren(tree);
337     }
338     public Tree visitConditionalExpression(ConditionalExpressionTree tree, Object JavaDoc p) {
339     return rewriteChildren(tree);
340     }
341     public Tree visitIf(IfTree tree, Object JavaDoc p) {
342     return rewriteChildren(tree);
343     }
344     public Tree visitExpressionStatement(ExpressionStatementTree tree, Object JavaDoc p) {
345     return rewriteChildren(tree);
346     }
347     public Tree visitBreak(BreakTree tree, Object JavaDoc p) {
348     return rewriteChildren(tree);
349     }
350     public Tree visitContinue(ContinueTree tree, Object JavaDoc p) {
351     return rewriteChildren(tree);
352     }
353     public Tree visitReturn(ReturnTree tree, Object JavaDoc p) {
354     return rewriteChildren(tree);
355     }
356     public Tree visitThrow(ThrowTree tree, Object JavaDoc p) {
357     return rewriteChildren(tree);
358     }
359     public Tree visitAssert(AssertTree tree, Object JavaDoc p) {
360     return rewriteChildren(tree);
361     }
362     public Tree visitMethodInvocation(MethodInvocationTree tree, Object JavaDoc p) {
363     return rewriteChildren(tree);
364     }
365     public Tree visitNewClass(NewClassTree tree, Object JavaDoc p) {
366     return rewriteChildren(tree);
367     }
368     public Tree visitNewArray(NewArrayTree tree, Object JavaDoc p) {
369     return rewriteChildren(tree);
370     }
371     public Tree visitParenthesized(ParenthesizedTree tree, Object JavaDoc p) {
372     return rewriteChildren(tree);
373     }
374     public Tree visitAssignment(AssignmentTree tree, Object JavaDoc p) {
375     return rewriteChildren(tree);
376     }
377     public Tree visitCompoundAssignment(CompoundAssignmentTree tree, Object JavaDoc p) {
378     return rewriteChildren(tree);
379     }
380     public Tree visitUnary(UnaryTree tree, Object JavaDoc p) {
381     return rewriteChildren(tree);
382     }
383     public Tree visitBinary(BinaryTree tree, Object JavaDoc p) {
384     return rewriteChildren(tree);
385     }
386     public Tree visitTypeCast(TypeCastTree tree, Object JavaDoc p) {
387     return rewriteChildren(tree);
388     }
389     public Tree visitInstanceOf(InstanceOfTree tree, Object JavaDoc p) {
390     return rewriteChildren(tree);
391     }
392     public Tree visitArrayAccess(ArrayAccessTree tree, Object JavaDoc p) {
393     return rewriteChildren(tree);
394     }
395     public Tree visitMemberSelect(MemberSelectTree tree, Object JavaDoc p) {
396         if (tree instanceof QualIdentTree) {
397             Element el = ((QualIdentTree) tree).sym;
398             
399             return importAnalysis.resolveImport(tree, el);
400         } else {
401             return rewriteChildren(tree);
402         }
403     }
404     public Tree visitIdentifier(IdentifierTree tree, Object JavaDoc p) {
405     return rewriteChildren(tree);
406     }
407     public Tree visitLiteral(LiteralTree tree, Object JavaDoc p) {
408     return rewriteChildren(tree);
409     }
410     public Tree visitPrimitiveType(PrimitiveTypeTree tree, Object JavaDoc p) {
411     return rewriteChildren(tree);
412     }
413     public Tree visitArrayType(ArrayTypeTree tree, Object JavaDoc p) {
414     return rewriteChildren(tree);
415     }
416     public Tree visitParameterizedType(ParameterizedTypeTree tree, Object JavaDoc p) {
417     return rewriteChildren(tree);
418     }
419     public Tree visitTypeParameter(TypeParameterTree tree, Object JavaDoc p) {
420     return rewriteChildren(tree);
421     }
422     public Tree visitWildcard(WildcardTree tree, Object JavaDoc p) {
423         return rewriteChildren(tree);
424     }
425     public Tree visitAnnotation(AnnotationTree tree, Object JavaDoc p) {
426         return rewriteChildren(tree);
427     }
428     public Tree visitModifiers(ModifiersTree tree, Object JavaDoc p) {
429         return rewriteChildren(tree);
430     }
431     public Tree visitErroneous(ErroneousTree tree, Object JavaDoc p) {
432     return rewriteChildren(tree);
433     }
434     public Tree visitOther(Tree tree, Object JavaDoc p) {
435     throw new Error JavaDoc("Tree not overloaded: "+tree);
436     }
437
438     /* * * * * * * * * * * * Visitor helpers* * * * * * * * * * * * * */
439     protected final CompilationUnitTree rewriteChildren(CompilationUnitTree tree) {
440     ExpressionTree pid = (ExpressionTree)translate(tree.getPackageName());
441         
442         importAnalysis.setPackage(tree.getPackageName());
443         importAnalysis.setImports(translate(tree.getImports()));
444         
445         List JavaDoc<? extends Tree> types = translate(tree.getTypeDecls());
446         List JavaDoc<? extends ImportTree> imps = importAnalysis.getImports();
447         
448     if (pid!=tree.getPackageName() || !imps.equals(tree.getImports()) ||
449             !types.equals(tree.getTypeDecls())) {
450         CompilationUnitTree n = make.CompilationUnit(pid, imps, types, tree.getSourceFile());
451             model.setElement(n, model.getElement(tree));
452         copyCommentTo(tree,n);
453             model.setPos(n, model.getPos(tree));
454         tree = n;
455     }
456     return tree;
457     }
458
459     protected final RootTree rewriteChildren(RootTree tree) {
460         List JavaDoc<CompilationUnitTree> units = translate(tree.getCompilationUnits());
461     if (!units.equals(tree.getCompilationUnits()))
462         tree = new RootTree(units);
463     return tree;
464     }
465
466     protected final ImportTree rewriteChildren(ImportTree tree) {
467     Tree qualid = translateClassRef(tree.getQualifiedIdentifier());
468         if (qualid == tree.getQualifiedIdentifier())
469             qualid = translate(tree.getQualifiedIdentifier());
470     if (qualid!=tree.getQualifiedIdentifier()) {
471         ImportTree n = make.Import(qualid, tree.isStatic());
472             model.setType(n, model.getType(tree));
473         copyCommentTo(tree,n);
474             copyPosTo(tree,n);
475         tree = n;
476     }
477     return tree;
478     }
479
480     protected final ClassTree rewriteChildren(ClassTree tree) {
481         ModifiersTree mods = (ModifiersTree)translate(tree.getModifiers());
482     List JavaDoc<? extends TypeParameterTree> typarams = translateStable(tree.getTypeParameters());
483     Tree extending = translateClassRef(tree.getExtendsClause());
484     List JavaDoc<? extends ExpressionTree> implementing =
485             translateClassRef((List JavaDoc<? extends ExpressionTree>)tree.getImplementsClause());
486     List JavaDoc<? extends Tree> defs = translate(tree.getMembers());
487         boolean typeChanged = !typarams.equals(tree.getTypeParameters()) ||
488             extending != tree.getExtendsClause() ||
489             !implementing.equals(tree.getImplementsClause());
490     if (typeChanged || mods != tree.getModifiers() ||
491             !defs.equals(tree.getMembers())) {
492         ClassTree n = make.Class(mods, tree.getSimpleName(), typarams,
493                                      extending, implementing, defs);
494             if (!typeChanged) {
495                 model.setElement(n, model.getElement(tree));
496                 model.setType(n, model.getType(tree));
497             }
498         copyCommentTo(tree,n);
499             if (tree.getMembers().size() == defs.size())
500                 model.setPos(n, model.getPos(tree));
501             else
502                 copyPosTo(tree,n);
503         tree = n;
504     }
505     return tree;
506     }
507
508     protected final MethodTree rewriteChildren(MethodTree tree) {
509         ModifiersTree mods = (ModifiersTree)translate(tree.getModifiers());
510     ExpressionTree restype = (ExpressionTree)translateClassRef(tree.getReturnType());
511     List JavaDoc<? extends TypeParameterTree> typarams = translateStable(tree.getTypeParameters());
512     List JavaDoc<? extends VariableTree> params = translateStable(tree.getParameters());
513     List JavaDoc<? extends ExpressionTree> thrown = translateStable(tree.getThrows());
514         ExpressionTree defaultValue = (ExpressionTree)translate(tree.getDefaultValue());
515     BlockTree body = (BlockTree)translate(tree.getBody());
516         
517     if (restype!=tree.getReturnType() || !typarams.equals(tree.getTypeParameters()) ||
518             !params.equals(tree.getParameters()) || !thrown.equals(tree.getThrows()) ||
519             mods!=tree.getModifiers() || defaultValue!=tree.getDefaultValue() ||
520             body!=tree.getBody()) {
521             MethodTree n = make.Method(mods, tree.getName().toString(), restype, typarams,
522                                         params, thrown, body, defaultValue);
523             
524         copyCommentTo(tree,n);
525             copyPosTo(tree,n);
526         tree = n;
527     }
528     return tree;
529     }
530     
531     protected final VariableTree rewriteChildren(VariableTree tree) {
532         ModifiersTree mods = (ModifiersTree)translate(tree.getModifiers());
533     ExpressionTree vartype = (ExpressionTree)translateClassRef(tree.getType());
534     ExpressionTree init = (ExpressionTree)translate(tree.getInitializer());
535     if (vartype!=tree.getType() || mods!=tree.getModifiers() || init!=tree.getInitializer()) {
536         VariableTree n = make.Variable(mods, tree.getName().toString(), vartype, init);
537         copyCommentTo(tree,n);
538             copyPosTo(tree,n);
539         tree = n;
540     }
541     return tree;
542     }
543     
544     protected final EmptyStatementTree rewriteChildren(EmptyStatementTree tree) {
545     return tree;
546     }
547
548     protected final BlockTree rewriteChildren(BlockTree tree) {
549         List JavaDoc<? extends StatementTree> oldStats = tree.getStatements();
550     List JavaDoc<? extends StatementTree> newStats = translate(oldStats);
551     if (!newStats.equals(oldStats)) {
552             //the newStates can contain elements from oldStats, so optimization could introduce new deltas:
553
// newStats = optimize(newStats);
554
BlockTree n = make.Block(newStats, tree.isStatic());
555             model.setType(n, model.getType(tree));
556         copyCommentTo(tree,n);
557             if (newStats.size() != oldStats.size() ||
558                 (oldStats.size() > 0 && newStats.size() > 0 &&
559                  oldStats.get(0) != newStats.get(0) &&
560                  (model.getPos(oldStats.get(0)) < 0 || model.getPos(newStats.get(0)) < 0))) {
561         /* Don't set the block's pos, because if it is a method body
562          * with a synthetic first statement (ie. "super()"), then
563          * pretty printers will print it since its pos is different
564          * from its parent's. Instead, just mark the topLevel so
565          * Commit knows to save it.
566          */

567                 if (topLevel == null)
568                     topLevel = model.getTopLevel(tree);
569                 model.setPos(topLevel, Query.NOPOS);
570             } else
571                 copyPosTo(tree,n);
572         tree = n;
573     }
574     return tree;
575     }
576
577     protected final DoWhileLoopTree rewriteChildren(DoWhileLoopTree tree) {
578     StatementTree body = (StatementTree)translate(tree.getStatement());
579     ExpressionTree cond = (ExpressionTree)translate(tree.getCondition());
580     if (body!=tree.getStatement() || cond!=tree.getCondition()) {
581         DoWhileLoopTree n = make.DoWhileLoop(cond, body);
582             model.setType(n, model.getType(tree));
583         copyCommentTo(tree,n);
584             copyPosTo(tree,n);
585         tree = n;
586     }
587     return tree;
588     }
589
590     protected final WhileLoopTree rewriteChildren(WhileLoopTree tree) {
591     ExpressionTree cond = (ExpressionTree)translate(tree.getCondition());
592     StatementTree body = (StatementTree)translate(tree.getStatement());
593     if (cond!=tree.getCondition() || body!=tree.getStatement()) {
594         WhileLoopTree n = make.WhileLoop(cond, body);
595             model.setType(n, model.getType(tree));
596         copyCommentTo(tree,n);
597             copyPosTo(tree,n);
598         tree = n;
599     }
600     return tree;
601     }
602
603     protected final ForLoopTree rewriteChildren(ForLoopTree tree) {
604     List JavaDoc<? extends StatementTree> init = translate(tree.getInitializer());
605     ExpressionTree cond = (ExpressionTree)translate(tree.getCondition());
606     List JavaDoc<? extends ExpressionStatementTree> step = translate(tree.getUpdate());
607     StatementTree body = (StatementTree)translate(tree.getStatement());
608     if (!init.equals(tree.getInitializer()) || cond!=tree.getCondition() ||
609             !step.equals(tree.getUpdate()) || body!=tree.getStatement()) {
610             if (init != tree.getInitializer())
611                 init = optimize(init);
612             if (step != tree.getUpdate())
613                 step = optimize(step);
614         ForLoopTree n = make.ForLoop(init, cond, step, body);
615             model.setType(n, model.getType(tree));
616         copyCommentTo(tree,n);
617             if (tree.getInitializer().size() != init.size() ||
618                 tree.getUpdate().size() != step.size())
619                 model.setPos(tree, Query.NOPOS);
620             else
621                 copyPosTo(tree,n);
622         tree = n;
623     }
624     return tree;
625     }
626
627     protected final EnhancedForLoopTree rewriteChildren(EnhancedForLoopTree tree) {
628     VariableTree var = (VariableTree)translate(tree.getVariable());
629     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
630     StatementTree body = (StatementTree)translate(tree.getStatement());
631     if (var!=tree.getVariable() || expr!=tree.getExpression() ||
632             body!=tree.getStatement()) {
633         EnhancedForLoopTree n = make.EnhancedForLoop(var, expr, body);
634             model.setType(n, model.getType(tree));
635         copyCommentTo(tree,n);
636             copyPosTo(tree,n);
637         tree = n;
638     }
639     return tree;
640     }
641
642     protected final LabeledStatementTree rewriteChildren(LabeledStatementTree tree) {
643     StatementTree body = (StatementTree)translate(tree.getStatement());
644     if (body!=tree.getStatement()) {
645         LabeledStatementTree n = make.LabeledStatement(tree.getLabel(), body);
646             model.setType(n, model.getType(tree));
647         copyCommentTo(tree,n);
648             copyPosTo(tree,n);
649         tree = n;
650     }
651     return tree;
652     }
653
654     protected final SwitchTree rewriteChildren(SwitchTree tree) {
655     ExpressionTree selector = (ExpressionTree)translate(tree.getExpression());
656     List JavaDoc<? extends CaseTree> cases = translateStable(tree.getCases());
657     if (selector!=tree.getExpression() || !cases.equals(tree.getCases())) {
658         SwitchTree n = make.Switch(selector, cases);
659             model.setType(n, model.getType(tree));
660         copyCommentTo(tree,n);
661             copyPosTo(tree,n);
662         tree = n;
663     }
664     return tree;
665     }
666
667     protected final CaseTree rewriteChildren(CaseTree tree) {
668     ExpressionTree pat = (ExpressionTree)translate(tree.getExpression());
669     List JavaDoc<? extends StatementTree> stats = translate(tree.getStatements());
670     if (pat!=tree.getExpression() || !stats.equals(tree.getStatements())) {
671             if (stats != tree.getStatements())
672                 stats = optimize(stats);
673         CaseTree n = make.Case(pat, stats);
674             model.setType(n, model.getType(tree));
675         copyCommentTo(tree,n);
676             copyPosTo(tree,n);
677         tree = n;
678     }
679     return tree;
680     }
681
682     protected final SynchronizedTree rewriteChildren(SynchronizedTree tree) {
683     ExpressionTree lock = (ExpressionTree)translate(tree.getExpression());
684     BlockTree body = (BlockTree)translate(tree.getBlock());
685     if (lock!=tree.getExpression() || body!=tree.getBlock()) {
686         SynchronizedTree n = make.Synchronized(lock, body);
687             model.setType(n, model.getType(tree));
688         copyCommentTo(tree,n);
689             copyPosTo(tree,n);
690         tree = n;
691     }
692     return tree;
693     }
694
695     protected final TryTree rewriteChildren(TryTree tree) {
696     BlockTree body = (BlockTree)translate(tree.getBlock());
697     List JavaDoc<? extends CatchTree> catches = translateStable(tree.getCatches());
698     BlockTree finalizer = (BlockTree)translate(tree.getFinallyBlock());
699     if (body!=tree.getBlock() || !catches.equals(tree.getCatches()) ||
700             finalizer!=tree.getFinallyBlock()) {
701         TryTree n = make.Try(body, catches, finalizer);
702             model.setType(n, model.getType(tree));
703         copyCommentTo(tree,n);
704             copyPosTo(tree,n);
705         tree = n;
706     }
707     return tree;
708     }
709     
710     protected final CatchTree rewriteChildren(CatchTree tree) {
711     VariableTree param = translateStable(tree.getParameter());
712     BlockTree body = (BlockTree)translate(tree.getBlock());
713     if (param!=tree.getParameter() || body!=tree.getBlock()) {
714         CatchTree n = make.Catch(param, body);
715             model.setType(n, model.getType(tree));
716         copyCommentTo(tree,n);
717             copyPosTo(tree,n);
718         tree = n;
719     }
720     return tree;
721     }
722     
723     protected final ConditionalExpressionTree rewriteChildren(ConditionalExpressionTree tree) {
724     ExpressionTree cond = (ExpressionTree)translate(tree.getCondition());
725     ExpressionTree truepart = (ExpressionTree)translate(tree.getTrueExpression());
726     ExpressionTree falsepart = (ExpressionTree)translate(tree.getFalseExpression());
727     if (cond!=tree.getCondition() || truepart!=tree.getTrueExpression() ||
728             falsepart!=tree.getFalseExpression()) {
729         ConditionalExpressionTree n = make.ConditionalExpression(cond, truepart, falsepart);
730             model.setType(n, model.getType(tree));
731         copyCommentTo(tree,n);
732             copyPosTo(tree,n);
733         tree = n;
734     }
735     return tree;
736     }
737     
738     protected final IfTree rewriteChildren(IfTree tree) {
739     ExpressionTree cond = (ExpressionTree)translate(tree.getCondition());
740     StatementTree thenpart = (StatementTree)translate(tree.getThenStatement());
741     StatementTree elsepart = (StatementTree)translate(tree.getElseStatement());
742     if (cond!=tree.getCondition() || thenpart!=tree.getThenStatement() ||
743             elsepart!=tree.getElseStatement()) {
744         IfTree n = make.If(cond, thenpart, elsepart);
745             model.setType(n, model.getType(tree));
746         copyCommentTo(tree,n);
747             copyPosTo(tree,n);
748         tree = n;
749     }
750     return tree;
751     }
752     
753     protected final ExpressionStatementTree rewriteChildren(ExpressionStatementTree tree) {
754     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
755     if (expr!=tree.getExpression()) {
756         ExpressionStatementTree n = make.ExpressionStatement(expr);
757             model.setType(n, model.getType(tree));
758         copyCommentTo(tree,n);
759             copyPosTo(tree,n);
760         tree = n;
761     }
762     return tree;
763     }
764     
765     protected final BreakTree rewriteChildren(BreakTree tree) {
766     return tree;
767     }
768     
769     protected final ContinueTree rewriteChildren(ContinueTree tree) {
770     return tree;
771     }
772     
773     protected final ReturnTree rewriteChildren(ReturnTree tree) {
774     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
775     if (expr!=tree.getExpression()) {
776         ReturnTree n = make.Return(expr);
777             model.setType(n, model.getType(tree));
778         copyCommentTo(tree,n);
779             copyPosTo(tree,n);
780         tree = n;
781     }
782     return tree;
783     }
784     
785     protected final ThrowTree rewriteChildren(ThrowTree tree) {
786     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
787     if (expr!=tree.getExpression()) {
788         ThrowTree n = make.Throw(expr);
789             model.setType(n, model.getType(tree));
790         copyCommentTo(tree,n);
791             copyPosTo(tree,n);
792         tree = n;
793     }
794     return tree;
795     }
796     
797     protected final AssertTree rewriteChildren(AssertTree tree) {
798     ExpressionTree cond = (ExpressionTree)translate(tree.getCondition());
799     ExpressionTree detail = (ExpressionTree)translate(tree.getDetail());
800     if (cond!=tree.getCondition() || detail!=tree.getDetail()) {
801         AssertTree n = make.Assert(cond, detail);
802             model.setType(n, model.getType(tree));
803         copyCommentTo(tree,n);
804             copyPosTo(tree,n);
805         tree = n;
806     }
807     return tree;
808     }
809     
810     protected final MethodInvocationTree rewriteChildren(MethodInvocationTree tree) {
811         List JavaDoc<? extends ExpressionTree> typeargs =
812             (List JavaDoc<? extends ExpressionTree>)translate(tree.getTypeArguments());
813     ExpressionTree meth = (ExpressionTree)translate(tree.getMethodSelect());
814     List JavaDoc<? extends ExpressionTree> args = translate(tree.getArguments());
815     if (!typeargs.equals(tree.getTypeArguments()) || meth!=tree.getMethodSelect() ||
816                 !args.equals(tree.getArguments())) {
817             if (args != tree.getArguments())
818                 args = optimize(args);
819             if (typeargs != tree.getTypeArguments())
820                 typeargs = optimize(typeargs);
821         MethodInvocationTree n = make.MethodInvocation(typeargs, meth, args);
822             model.setType(n, model.getType(tree));
823         copyCommentTo(tree,n);
824         tree = n;
825             if (size(tree.getTypeArguments()) != size(typeargs) &&
826                     size(tree.getArguments()) != size(args))
827                 model.setPos(tree, Query.NOPOS);
828             else
829                 copyPosTo(tree,n);
830     }
831     return tree;
832     }
833     
834     protected final NewClassTree rewriteChildren(NewClassTree tree) {
835     ExpressionTree encl = (ExpressionTree)translate(tree.getEnclosingExpression());
836         List JavaDoc<? extends ExpressionTree> typeargs =
837             (List JavaDoc<? extends ExpressionTree>)translate(tree.getTypeArguments());
838     ExpressionTree clazz = translateClassRef(tree.getIdentifier());
839     List JavaDoc<? extends ExpressionTree> args = translate(tree.getArguments());
840     ClassTree def = translateStable(tree.getClassBody());
841     if (encl!=tree.getEnclosingExpression() ||
842                 !typeargs.equals(tree.getTypeArguments()) || clazz!=tree.getIdentifier() ||
843                 !args.equals(tree.getArguments()) || def!=tree.getClassBody()) {
844             if (args != tree.getArguments())
845                 args = optimize(args);
846             if (typeargs != tree.getTypeArguments())
847                 typeargs = optimize(typeargs);
848         NewClassTree n = make.NewClass(encl, typeargs, clazz, args, def);
849             model.setElement(n, model.getElement(tree));
850             model.setType(n, model.getType(tree));
851         copyCommentTo(tree,n);
852             if ((size(tree.getTypeArguments()) != size(typeargs) &&
853                     size(tree.getArguments()) != size(args)) ||
854                     def != tree.getClassBody())
855                 model.setPos(n, Query.NOPOS);
856             else
857                 copyPosTo(tree,n);
858         tree = n;
859     }
860     return tree;
861     }
862     
863     protected final NewArrayTree rewriteChildren(NewArrayTree tree) {
864     ExpressionTree elemtype = (ExpressionTree)translateClassRef(tree.getType());
865     List JavaDoc<? extends ExpressionTree> dims = translate(tree.getDimensions());
866     List JavaDoc<? extends ExpressionTree> elems = translate(tree.getInitializers());
867     if (elemtype!=tree.getType() || !safeEquals(dims, tree.getDimensions()) ||
868                 !safeEquals(elems, tree.getInitializers())) {
869             if (elems != tree.getInitializers())
870                 elems = optimize(elems);
871             if (dims != tree.getDimensions())
872                 dims = optimize(dims);
873         NewArrayTree n = make.NewArray(elemtype, dims, elems);
874             model.setType(n, model.getType(tree));
875         copyCommentTo(tree,n);
876         tree = n;
877             if (size(tree.getDimensions()) != size(dims) ||
878                     size(tree.getInitializers()) != size(elems))
879                 model.setPos(tree, Query.NOPOS);
880             else
881                 copyPosTo(tree,n);
882     }
883     return tree;
884     }
885     
886     protected final ParenthesizedTree rewriteChildren(ParenthesizedTree tree) {
887     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
888     if (expr!=tree.getExpression()) {
889         ParenthesizedTree n = make.Parenthesized(expr);
890             model.setType(n, model.getType(tree));
891         copyCommentTo(tree,n);
892             copyPosTo(tree,n);
893         tree = n;
894     }
895     return tree;
896     }
897     
898     protected final AssignmentTree rewriteChildren(AssignmentTree tree) {
899     ExpressionTree lhs = (ExpressionTree)translate(tree.getVariable());
900     ExpressionTree rhs = (ExpressionTree)translate(tree.getExpression());
901     if (lhs!=tree.getVariable() || rhs!=tree.getExpression()) {
902         AssignmentTree n = make.Assignment(lhs, rhs);
903             model.setType(n, model.getType(tree));
904         copyCommentTo(tree,n);
905             copyPosTo(tree,n);
906         tree = n;
907     }
908     return tree;
909     }
910     
911     protected final CompoundAssignmentTree rewriteChildren(CompoundAssignmentTree tree) {
912     ExpressionTree lhs = (ExpressionTree)translate(tree.getVariable());
913     ExpressionTree rhs = (ExpressionTree)translate(tree.getExpression());
914     if (lhs!=tree.getVariable() || rhs!=tree.getExpression()) {
915         CompoundAssignmentTree n = make.CompoundAssignment(tree.getKind(), lhs, rhs);
916             model.setType(n, model.getType(tree));
917         copyCommentTo(tree,n);
918             copyPosTo(tree,n);
919         tree = n;
920     }
921     return tree;
922     }
923     
924     protected final UnaryTree rewriteChildren(UnaryTree tree) {
925     ExpressionTree arg = (ExpressionTree)translate(tree.getExpression());
926     if (arg!=tree.getExpression()) {
927         UnaryTree n = make.Unary(tree.getKind(), arg);
928             model.setType(n, model.getType(tree));
929         copyCommentTo(tree,n);
930             copyPosTo(tree,n);
931         tree = n;
932     }
933     return tree;
934     }
935     
936     protected final BinaryTree rewriteChildren(BinaryTree tree) {
937     ExpressionTree lhs = (ExpressionTree)translate(tree.getLeftOperand());
938     ExpressionTree rhs = (ExpressionTree)translate(tree.getRightOperand());
939     if (lhs!=tree.getLeftOperand() || rhs!=tree.getRightOperand()) {
940         BinaryTree n = make.Binary(tree.getKind(), lhs, rhs);
941             model.setType(n, model.getType(tree));
942         copyCommentTo(tree,n);
943             copyPosTo(tree,n);
944         tree = n;
945     }
946     return tree;
947     }
948     
949     protected final TypeCastTree rewriteChildren(TypeCastTree tree) {
950     Tree clazz = translateClassRef(tree.getType());
951     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
952     if (clazz!=tree.getType() || expr!=tree.getExpression()) {
953         TypeCastTree n = make.TypeCast(clazz, expr);
954             model.setType(n, model.getType(tree));
955         copyCommentTo(tree,n);
956             copyPosTo(tree,n);
957         tree = n;
958     }
959     return tree;
960     }
961     
962     protected final InstanceOfTree rewriteChildren(InstanceOfTree tree) {
963     ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
964     Tree clazz = translateClassRef(tree.getType());
965     if (expr!=tree.getExpression() || clazz!=tree.getType()) {
966         InstanceOfTree n = make.InstanceOf(expr, clazz);
967             model.setType(n, model.getType(tree));
968         copyCommentTo(tree,n);
969             copyPosTo(tree,n);
970         tree = n;
971     }
972     return tree;
973     }
974     
975     protected final ArrayAccessTree rewriteChildren(ArrayAccessTree tree) {
976     ExpressionTree array = (ExpressionTree)translate(tree.getExpression());
977     ExpressionTree index = (ExpressionTree)translate(tree.getIndex());
978     if (array!=tree.getExpression() || index!=tree.getIndex()) {
979         ArrayAccessTree n = make.ArrayAccess(array, index);
980             model.setType(n, model.getType(tree));
981         copyCommentTo(tree,n);
982             copyPosTo(tree,n);
983         tree = n;
984     }
985     return tree;
986     }
987     
988     protected final MemberSelectTree rewriteChildren(MemberSelectTree tree) {
989     ExpressionTree selected = translateClassRef(tree.getExpression());
990     if (selected!=tree.getExpression()) {
991         MemberSelectTree n = make.MemberSelect(selected, tree.getIdentifier());
992             model.setElement(n, model.getElement(tree));
993             model.setType(n, model.getType(tree));
994         copyCommentTo(tree,n);
995             copyPosTo(tree,n);
996         tree = n;
997     }
998     return tree;
999     }
1000    
1001    protected final IdentifierTree rewriteChildren(IdentifierTree tree) {
1002    return tree;
1003    }
1004    
1005    protected final LiteralTree rewriteChildren(LiteralTree tree) {
1006    return tree;
1007    }
1008    
1009    protected final PrimitiveTypeTree rewriteChildren(PrimitiveTypeTree tree) {
1010    return tree;
1011    }
1012    
1013    protected final ArrayTypeTree rewriteChildren(ArrayTypeTree tree) {
1014    ExpressionTree elemtype = (ExpressionTree)translateClassRef(tree.getType());
1015    if (elemtype!=tree.getType()) {
1016        ArrayTypeTree n = make.ArrayType(elemtype);
1017            model.setType(n, model.getType(tree));
1018        copyCommentTo(tree,n);
1019            copyPosTo(tree,n);
1020        tree = n;
1021    }
1022    return tree;
1023    }
1024    
1025    protected final ParameterizedTypeTree rewriteChildren(ParameterizedTypeTree tree) {
1026    ExpressionTree clazz = (ExpressionTree)translateClassRef(tree.getType());
1027    List JavaDoc<? extends ExpressionTree> arguments =
1028                (List JavaDoc<? extends ExpressionTree>)translate(tree.getTypeArguments());
1029    if (clazz!=tree.getType() || !arguments.equals(tree.getTypeArguments())) {
1030            if (arguments != tree.getTypeArguments())
1031                arguments = optimize(arguments);
1032        ParameterizedTypeTree n = make.ParameterizedType(clazz, arguments);
1033            model.setType(n, model.getType(tree));
1034        copyCommentTo(tree,n);
1035        tree = n;
1036            if (tree.getTypeArguments().size() != arguments.size())
1037                model.setPos(tree, Query.NOPOS);
1038            else
1039                copyPosTo(tree,n);
1040    }
1041    return tree;
1042    }
1043    
1044    protected final TypeParameterTree rewriteChildren(TypeParameterTree tree) {
1045    List JavaDoc<? extends ExpressionTree> bounds =
1046                (List JavaDoc<? extends ExpressionTree>)translate(tree.getBounds());
1047    if (!bounds.equals(tree.getBounds())) {
1048            bounds = optimize(bounds);
1049        TypeParameterTree n = make.TypeParameter(tree.getName(), bounds);
1050            model.setType(n, model.getType(tree));
1051        copyCommentTo(tree,n);
1052        tree = n;
1053            if (tree.getBounds().size() != bounds.size())
1054                model.setPos(tree, Query.NOPOS);
1055            else
1056                copyPosTo(tree,n);
1057    }
1058    return tree;
1059    }
1060    
1061    protected final WildcardTree rewriteChildren(WildcardTree tree) {
1062        Tree type = translateClassRef(tree.getBound());
1063    if (type != tree.getBound()) {
1064        WildcardTree n = make.Wildcard(tree.getKind(), type);
1065            model.setType(n, model.getType(tree));
1066        copyCommentTo(tree,n);
1067            copyPosTo(tree,n);
1068        tree = n;
1069    }
1070        return tree;
1071    }
1072    
1073    protected final AnnotationTree rewriteChildren(AnnotationTree tree) {
1074        Tree annotationType = translate(tree.getAnnotationType());
1075    List JavaDoc<? extends ExpressionTree> args = translate(tree.getArguments());
1076    if (annotationType!=tree.getAnnotationType() || !args.equals(tree.getArguments())) {
1077            if (args != tree.getArguments())
1078                args = optimize(args);
1079        AnnotationTree n = make.Annotation(annotationType, args);
1080            model.setType(n, model.getType(tree));
1081        copyCommentTo(tree,n);
1082        tree = n;
1083            if (tree.getArguments().size() != args.size())
1084                model.setPos(tree, Query.NOPOS);
1085            else
1086                copyPosTo(tree,n);
1087    }
1088    return tree;
1089    }
1090    
1091    protected final ModifiersTree rewriteChildren(ModifiersTree tree) {
1092    List JavaDoc<? extends AnnotationTree> annotations = translateStable(tree.getAnnotations());
1093    if (!annotations.equals(tree.getAnnotations())) {
1094        ModifiersTree n = make.Modifiers(tree, annotations);
1095            model.setType(n, model.getType(tree));
1096        copyCommentTo(tree,n);
1097            copyPosTo(tree,n);
1098        tree = n;
1099    }
1100    return tree;
1101    }
1102    
1103    protected final ErroneousTree rewriteChildren(ErroneousTree tree) {
1104        List JavaDoc<? extends Tree> oldErrs = tree.getErrorTrees();
1105    List JavaDoc<? extends Tree> newErrs = translate(oldErrs);
1106    if (!newErrs.equals(oldErrs)) {
1107        ErroneousTree n = make.Erroneous(newErrs);
1108            model.setType(n, model.getType(tree));
1109        copyCommentTo(tree,n);
1110            copyPosTo(tree,n);
1111        tree = n;
1112    }
1113    return tree;
1114    }
1115}
1116
Popular Tags