Thu, 10 Jun 2010 16:08:01 -0700
6944312: Potential rebranding issues in openjdk/langtools repository sources
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1999, 2008, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.tree;
28 import java.io.*;
29 import java.util.*;
31 import com.sun.tools.javac.util.*;
32 import com.sun.tools.javac.util.List;
33 import com.sun.tools.javac.code.*;
35 import com.sun.tools.javac.code.Symbol.*;
36 import com.sun.tools.javac.tree.JCTree.*;
38 import static com.sun.tools.javac.code.Flags.*;
40 /** Prints out a tree as an indented Java source program.
41 *
42 * <p><b>This is NOT part of any supported API.
43 * If you write code that depends on this, you do so at your own risk.
44 * This code and its internal interfaces are subject to change or
45 * deletion without notice.</b>
46 */
47 public class Pretty extends JCTree.Visitor {
49 public Pretty(Writer out, boolean sourceOutput) {
50 this.out = out;
51 this.sourceOutput = sourceOutput;
52 }
54 /** Set when we are producing source output. If we're not
55 * producing source output, we can sometimes give more detail in
56 * the output even though that detail would not be valid java
57 * source.
58 */
59 private final boolean sourceOutput;
61 /** The output stream on which trees are printed.
62 */
63 Writer out;
65 /** Indentation width (can be reassigned from outside).
66 */
67 public int width = 4;
69 /** The current left margin.
70 */
71 int lmargin = 0;
73 /** The enclosing class name.
74 */
75 Name enclClassName;
77 /** A hashtable mapping trees to their documentation comments
78 * (can be null)
79 */
80 Map<JCTree, String> docComments = null;
82 /** Align code to be indented to left margin.
83 */
84 void align() throws IOException {
85 for (int i = 0; i < lmargin; i++) out.write(" ");
86 }
88 /** Increase left margin by indentation width.
89 */
90 void indent() {
91 lmargin = lmargin + width;
92 }
94 /** Decrease left margin by indentation width.
95 */
96 void undent() {
97 lmargin = lmargin - width;
98 }
100 /** Enter a new precedence level. Emit a `(' if new precedence level
101 * is less than precedence level so far.
102 * @param contextPrec The precedence level in force so far.
103 * @param ownPrec The new precedence level.
104 */
105 void open(int contextPrec, int ownPrec) throws IOException {
106 if (ownPrec < contextPrec) out.write("(");
107 }
109 /** Leave precedence level. Emit a `(' if inner precedence level
110 * is less than precedence level we revert to.
111 * @param contextPrec The precedence level we revert to.
112 * @param ownPrec The inner precedence level.
113 */
114 void close(int contextPrec, int ownPrec) throws IOException {
115 if (ownPrec < contextPrec) out.write(")");
116 }
118 /** Print string, replacing all non-ascii character with unicode escapes.
119 */
120 public void print(Object s) throws IOException {
121 out.write(Convert.escapeUnicode(s.toString()));
122 }
124 /** Print new line.
125 */
126 public void println() throws IOException {
127 out.write(lineSep);
128 }
130 String lineSep = System.getProperty("line.separator");
132 /**************************************************************************
133 * Traversal methods
134 *************************************************************************/
136 /** Exception to propogate IOException through visitXXX methods */
137 private static class UncheckedIOException extends Error {
138 static final long serialVersionUID = -4032692679158424751L;
139 UncheckedIOException(IOException e) {
140 super(e.getMessage(), e);
141 }
142 }
144 /** Visitor argument: the current precedence level.
145 */
146 int prec;
148 /** Visitor method: print expression tree.
149 * @param prec The current precedence level.
150 */
151 public void printExpr(JCTree tree, int prec) throws IOException {
152 int prevPrec = this.prec;
153 try {
154 this.prec = prec;
155 if (tree == null) print("/*missing*/");
156 else {
157 tree.accept(this);
158 }
159 } catch (UncheckedIOException ex) {
160 IOException e = new IOException(ex.getMessage());
161 e.initCause(ex);
162 throw e;
163 } finally {
164 this.prec = prevPrec;
165 }
166 }
168 /** Derived visitor method: print expression tree at minimum precedence level
169 * for expression.
170 */
171 public void printExpr(JCTree tree) throws IOException {
172 printExpr(tree, TreeInfo.noPrec);
173 }
175 /** Derived visitor method: print statement tree.
176 */
177 public void printStat(JCTree tree) throws IOException {
178 printExpr(tree, TreeInfo.notExpression);
179 }
181 /** Derived visitor method: print list of expression trees, separated by given string.
182 * @param sep the separator string
183 */
184 public <T extends JCTree> void printExprs(List<T> trees, String sep) throws IOException {
185 if (trees.nonEmpty()) {
186 printExpr(trees.head);
187 for (List<T> l = trees.tail; l.nonEmpty(); l = l.tail) {
188 print(sep);
189 printExpr(l.head);
190 }
191 }
192 }
194 /** Derived visitor method: print list of expression trees, separated by commas.
195 */
196 public <T extends JCTree> void printExprs(List<T> trees) throws IOException {
197 printExprs(trees, ", ");
198 }
200 /** Derived visitor method: print list of statements, each on a separate line.
201 */
202 public void printStats(List<? extends JCTree> trees) throws IOException {
203 for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) {
204 align();
205 printStat(l.head);
206 println();
207 }
208 }
210 /** Print a set of modifiers.
211 */
212 public void printFlags(long flags) throws IOException {
213 if ((flags & SYNTHETIC) != 0) print("/*synthetic*/ ");
214 print(TreeInfo.flagNames(flags));
215 if ((flags & StandardFlags) != 0) print(" ");
216 if ((flags & ANNOTATION) != 0) print("@");
217 }
219 public void printAnnotations(List<JCAnnotation> trees) throws IOException {
220 for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) {
221 printStat(l.head);
222 println();
223 align();
224 }
225 }
227 public void printTypeAnnotations(List<JCTypeAnnotation> trees) throws IOException {
228 if (trees.nonEmpty())
229 print(" ");
230 for (List<JCTypeAnnotation> l = trees; l.nonEmpty(); l = l.tail) {
231 printExpr(l.head);
232 print(" ");
233 }
234 }
236 /** Print documentation comment, if it exists
237 * @param tree The tree for which a documentation comment should be printed.
238 */
239 public void printDocComment(JCTree tree) throws IOException {
240 if (docComments != null) {
241 String dc = docComments.get(tree);
242 if (dc != null) {
243 print("/**"); println();
244 int pos = 0;
245 int endpos = lineEndPos(dc, pos);
246 while (pos < dc.length()) {
247 align();
248 print(" *");
249 if (pos < dc.length() && dc.charAt(pos) > ' ') print(" ");
250 print(dc.substring(pos, endpos)); println();
251 pos = endpos + 1;
252 endpos = lineEndPos(dc, pos);
253 }
254 align(); print(" */"); println();
255 align();
256 }
257 }
258 }
259 //where
260 static int lineEndPos(String s, int start) {
261 int pos = s.indexOf('\n', start);
262 if (pos < 0) pos = s.length();
263 return pos;
264 }
266 /** If type parameter list is non-empty, print it enclosed in "<...>" brackets.
267 */
268 public void printTypeParameters(List<JCTypeParameter> trees) throws IOException {
269 if (trees.nonEmpty()) {
270 print("<");
271 printExprs(trees);
272 print(">");
273 }
274 }
276 /** Print a block.
277 */
278 public void printBlock(List<? extends JCTree> stats) throws IOException {
279 print("{");
280 println();
281 indent();
282 printStats(stats);
283 undent();
284 align();
285 print("}");
286 }
288 /** Print a block.
289 */
290 public void printEnumBody(List<JCTree> stats) throws IOException {
291 print("{");
292 println();
293 indent();
294 boolean first = true;
295 for (List<JCTree> l = stats; l.nonEmpty(); l = l.tail) {
296 if (isEnumerator(l.head)) {
297 if (!first) {
298 print(",");
299 println();
300 }
301 align();
302 printStat(l.head);
303 first = false;
304 }
305 }
306 print(";");
307 println();
308 for (List<JCTree> l = stats; l.nonEmpty(); l = l.tail) {
309 if (!isEnumerator(l.head)) {
310 align();
311 printStat(l.head);
312 println();
313 }
314 }
315 undent();
316 align();
317 print("}");
318 }
320 /** Is the given tree an enumerator definition? */
321 boolean isEnumerator(JCTree t) {
322 return t.getTag() == JCTree.VARDEF && (((JCVariableDecl) t).mods.flags & ENUM) != 0;
323 }
325 /** Print unit consisting of package clause and import statements in toplevel,
326 * followed by class definition. if class definition == null,
327 * print all definitions in toplevel.
328 * @param tree The toplevel tree
329 * @param cdef The class definition, which is assumed to be part of the
330 * toplevel tree.
331 */
332 public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException {
333 docComments = tree.docComments;
334 printDocComment(tree);
335 if (tree.pid != null) {
336 print("package ");
337 printExpr(tree.pid);
338 print(";");
339 println();
340 }
341 boolean firstImport = true;
342 for (List<JCTree> l = tree.defs;
343 l.nonEmpty() && (cdef == null || l.head.getTag() == JCTree.IMPORT);
344 l = l.tail) {
345 if (l.head.getTag() == JCTree.IMPORT) {
346 JCImport imp = (JCImport)l.head;
347 Name name = TreeInfo.name(imp.qualid);
348 if (name == name.table.names.asterisk ||
349 cdef == null ||
350 isUsed(TreeInfo.symbol(imp.qualid), cdef)) {
351 if (firstImport) {
352 firstImport = false;
353 println();
354 }
355 printStat(imp);
356 }
357 } else {
358 printStat(l.head);
359 }
360 }
361 if (cdef != null) {
362 printStat(cdef);
363 println();
364 }
365 }
366 // where
367 boolean isUsed(final Symbol t, JCTree cdef) {
368 class UsedVisitor extends TreeScanner {
369 public void scan(JCTree tree) {
370 if (tree!=null && !result) tree.accept(this);
371 }
372 boolean result = false;
373 public void visitIdent(JCIdent tree) {
374 if (tree.sym == t) result = true;
375 }
376 }
377 UsedVisitor v = new UsedVisitor();
378 v.scan(cdef);
379 return v.result;
380 }
382 /**************************************************************************
383 * Visitor methods
384 *************************************************************************/
386 public void visitTopLevel(JCCompilationUnit tree) {
387 try {
388 printUnit(tree, null);
389 } catch (IOException e) {
390 throw new UncheckedIOException(e);
391 }
392 }
394 public void visitImport(JCImport tree) {
395 try {
396 print("import ");
397 if (tree.staticImport) print("static ");
398 printExpr(tree.qualid);
399 print(";");
400 println();
401 } catch (IOException e) {
402 throw new UncheckedIOException(e);
403 }
404 }
406 public void visitClassDef(JCClassDecl tree) {
407 try {
408 println(); align();
409 printDocComment(tree);
410 printAnnotations(tree.mods.annotations);
411 printFlags(tree.mods.flags & ~INTERFACE);
412 Name enclClassNamePrev = enclClassName;
413 enclClassName = tree.name;
414 if ((tree.mods.flags & INTERFACE) != 0) {
415 print("interface " + tree.name);
416 printTypeParameters(tree.typarams);
417 if (tree.implementing.nonEmpty()) {
418 print(" extends ");
419 printExprs(tree.implementing);
420 }
421 } else {
422 if ((tree.mods.flags & ENUM) != 0)
423 print("enum " + tree.name);
424 else
425 print("class " + tree.name);
426 printTypeParameters(tree.typarams);
427 if (tree.extending != null) {
428 print(" extends ");
429 printExpr(tree.extending);
430 }
431 if (tree.implementing.nonEmpty()) {
432 print(" implements ");
433 printExprs(tree.implementing);
434 }
435 }
436 print(" ");
437 if ((tree.mods.flags & ENUM) != 0) {
438 printEnumBody(tree.defs);
439 } else {
440 printBlock(tree.defs);
441 }
442 enclClassName = enclClassNamePrev;
443 } catch (IOException e) {
444 throw new UncheckedIOException(e);
445 }
446 }
448 public void visitMethodDef(JCMethodDecl tree) {
449 try {
450 // when producing source output, omit anonymous constructors
451 if (tree.name == tree.name.table.names.init &&
452 enclClassName == null &&
453 sourceOutput) return;
454 println(); align();
455 printDocComment(tree);
456 printExpr(tree.mods);
457 printTypeParameters(tree.typarams);
458 if (tree.name == tree.name.table.names.init) {
459 print(enclClassName != null ? enclClassName : tree.name);
460 } else {
461 printExpr(tree.restype);
462 print(" " + tree.name);
463 }
464 print("(");
465 printExprs(tree.params);
466 print(")");
467 if (tree.thrown.nonEmpty()) {
468 print(" throws ");
469 printExprs(tree.thrown);
470 }
471 if (tree.defaultValue != null) {
472 print(" default ");
473 printExpr(tree.defaultValue);
474 }
475 if (tree.body != null) {
476 print(" ");
477 printStat(tree.body);
478 } else {
479 print(";");
480 }
481 } catch (IOException e) {
482 throw new UncheckedIOException(e);
483 }
484 }
486 public void visitVarDef(JCVariableDecl tree) {
487 try {
488 if (docComments != null && docComments.get(tree) != null) {
489 println(); align();
490 }
491 printDocComment(tree);
492 if ((tree.mods.flags & ENUM) != 0) {
493 print("/*public static final*/ ");
494 print(tree.name);
495 if (tree.init != null) {
496 if (sourceOutput && tree.init.getTag() == JCTree.NEWCLASS) {
497 print(" /*enum*/ ");
498 JCNewClass init = (JCNewClass) tree.init;
499 if (init.args != null && init.args.nonEmpty()) {
500 print("(");
501 print(init.args);
502 print(")");
503 }
504 if (init.def != null && init.def.defs != null) {
505 print(" ");
506 printBlock(init.def.defs);
507 }
508 return;
509 }
510 print(" /* = ");
511 printExpr(tree.init);
512 print(" */");
513 }
514 } else {
515 printExpr(tree.mods);
516 if ((tree.mods.flags & VARARGS) != 0) {
517 printExpr(((JCArrayTypeTree) tree.vartype).elemtype);
518 print("... " + tree.name);
519 } else {
520 printExpr(tree.vartype);
521 print(" " + tree.name);
522 }
523 if (tree.init != null) {
524 print(" = ");
525 printExpr(tree.init);
526 }
527 if (prec == TreeInfo.notExpression) print(";");
528 }
529 } catch (IOException e) {
530 throw new UncheckedIOException(e);
531 }
532 }
534 public void visitSkip(JCSkip tree) {
535 try {
536 print(";");
537 } catch (IOException e) {
538 throw new UncheckedIOException(e);
539 }
540 }
542 public void visitBlock(JCBlock tree) {
543 try {
544 printFlags(tree.flags);
545 printBlock(tree.stats);
546 } catch (IOException e) {
547 throw new UncheckedIOException(e);
548 }
549 }
551 public void visitDoLoop(JCDoWhileLoop tree) {
552 try {
553 print("do ");
554 printStat(tree.body);
555 align();
556 print(" while ");
557 if (tree.cond.getTag() == JCTree.PARENS) {
558 printExpr(tree.cond);
559 } else {
560 print("(");
561 printExpr(tree.cond);
562 print(")");
563 }
564 print(";");
565 } catch (IOException e) {
566 throw new UncheckedIOException(e);
567 }
568 }
570 public void visitWhileLoop(JCWhileLoop tree) {
571 try {
572 print("while ");
573 if (tree.cond.getTag() == JCTree.PARENS) {
574 printExpr(tree.cond);
575 } else {
576 print("(");
577 printExpr(tree.cond);
578 print(")");
579 }
580 print(" ");
581 printStat(tree.body);
582 } catch (IOException e) {
583 throw new UncheckedIOException(e);
584 }
585 }
587 public void visitForLoop(JCForLoop tree) {
588 try {
589 print("for (");
590 if (tree.init.nonEmpty()) {
591 if (tree.init.head.getTag() == JCTree.VARDEF) {
592 printExpr(tree.init.head);
593 for (List<JCStatement> l = tree.init.tail; l.nonEmpty(); l = l.tail) {
594 JCVariableDecl vdef = (JCVariableDecl)l.head;
595 print(", " + vdef.name + " = ");
596 printExpr(vdef.init);
597 }
598 } else {
599 printExprs(tree.init);
600 }
601 }
602 print("; ");
603 if (tree.cond != null) printExpr(tree.cond);
604 print("; ");
605 printExprs(tree.step);
606 print(") ");
607 printStat(tree.body);
608 } catch (IOException e) {
609 throw new UncheckedIOException(e);
610 }
611 }
613 public void visitForeachLoop(JCEnhancedForLoop tree) {
614 try {
615 print("for (");
616 printExpr(tree.var);
617 print(" : ");
618 printExpr(tree.expr);
619 print(") ");
620 printStat(tree.body);
621 } catch (IOException e) {
622 throw new UncheckedIOException(e);
623 }
624 }
626 public void visitLabelled(JCLabeledStatement tree) {
627 try {
628 print(tree.label + ": ");
629 printStat(tree.body);
630 } catch (IOException e) {
631 throw new UncheckedIOException(e);
632 }
633 }
635 public void visitSwitch(JCSwitch tree) {
636 try {
637 print("switch ");
638 if (tree.selector.getTag() == JCTree.PARENS) {
639 printExpr(tree.selector);
640 } else {
641 print("(");
642 printExpr(tree.selector);
643 print(")");
644 }
645 print(" {");
646 println();
647 printStats(tree.cases);
648 align();
649 print("}");
650 } catch (IOException e) {
651 throw new UncheckedIOException(e);
652 }
653 }
655 public void visitCase(JCCase tree) {
656 try {
657 if (tree.pat == null) {
658 print("default");
659 } else {
660 print("case ");
661 printExpr(tree.pat);
662 }
663 print(": ");
664 println();
665 indent();
666 printStats(tree.stats);
667 undent();
668 align();
669 } catch (IOException e) {
670 throw new UncheckedIOException(e);
671 }
672 }
674 public void visitSynchronized(JCSynchronized tree) {
675 try {
676 print("synchronized ");
677 if (tree.lock.getTag() == JCTree.PARENS) {
678 printExpr(tree.lock);
679 } else {
680 print("(");
681 printExpr(tree.lock);
682 print(")");
683 }
684 print(" ");
685 printStat(tree.body);
686 } catch (IOException e) {
687 throw new UncheckedIOException(e);
688 }
689 }
691 public void visitTry(JCTry tree) {
692 try {
693 print("try ");
694 printStat(tree.body);
695 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
696 printStat(l.head);
697 }
698 if (tree.finalizer != null) {
699 print(" finally ");
700 printStat(tree.finalizer);
701 }
702 } catch (IOException e) {
703 throw new UncheckedIOException(e);
704 }
705 }
707 public void visitCatch(JCCatch tree) {
708 try {
709 print(" catch (");
710 printExpr(tree.param);
711 print(") ");
712 printStat(tree.body);
713 } catch (IOException e) {
714 throw new UncheckedIOException(e);
715 }
716 }
718 public void visitConditional(JCConditional tree) {
719 try {
720 open(prec, TreeInfo.condPrec);
721 printExpr(tree.cond, TreeInfo.condPrec);
722 print(" ? ");
723 printExpr(tree.truepart, TreeInfo.condPrec);
724 print(" : ");
725 printExpr(tree.falsepart, TreeInfo.condPrec);
726 close(prec, TreeInfo.condPrec);
727 } catch (IOException e) {
728 throw new UncheckedIOException(e);
729 }
730 }
732 public void visitIf(JCIf tree) {
733 try {
734 print("if ");
735 if (tree.cond.getTag() == JCTree.PARENS) {
736 printExpr(tree.cond);
737 } else {
738 print("(");
739 printExpr(tree.cond);
740 print(")");
741 }
742 print(" ");
743 printStat(tree.thenpart);
744 if (tree.elsepart != null) {
745 print(" else ");
746 printStat(tree.elsepart);
747 }
748 } catch (IOException e) {
749 throw new UncheckedIOException(e);
750 }
751 }
753 public void visitExec(JCExpressionStatement tree) {
754 try {
755 printExpr(tree.expr);
756 if (prec == TreeInfo.notExpression) print(";");
757 } catch (IOException e) {
758 throw new UncheckedIOException(e);
759 }
760 }
762 public void visitBreak(JCBreak tree) {
763 try {
764 print("break");
765 if (tree.label != null) print(" " + tree.label);
766 print(";");
767 } catch (IOException e) {
768 throw new UncheckedIOException(e);
769 }
770 }
772 public void visitContinue(JCContinue tree) {
773 try {
774 print("continue");
775 if (tree.label != null) print(" " + tree.label);
776 print(";");
777 } catch (IOException e) {
778 throw new UncheckedIOException(e);
779 }
780 }
782 public void visitReturn(JCReturn tree) {
783 try {
784 print("return");
785 if (tree.expr != null) {
786 print(" ");
787 printExpr(tree.expr);
788 }
789 print(";");
790 } catch (IOException e) {
791 throw new UncheckedIOException(e);
792 }
793 }
795 public void visitThrow(JCThrow tree) {
796 try {
797 print("throw ");
798 printExpr(tree.expr);
799 print(";");
800 } catch (IOException e) {
801 throw new UncheckedIOException(e);
802 }
803 }
805 public void visitAssert(JCAssert tree) {
806 try {
807 print("assert ");
808 printExpr(tree.cond);
809 if (tree.detail != null) {
810 print(" : ");
811 printExpr(tree.detail);
812 }
813 print(";");
814 } catch (IOException e) {
815 throw new UncheckedIOException(e);
816 }
817 }
819 public void visitApply(JCMethodInvocation tree) {
820 try {
821 if (!tree.typeargs.isEmpty()) {
822 if (tree.meth.getTag() == JCTree.SELECT) {
823 JCFieldAccess left = (JCFieldAccess)tree.meth;
824 printExpr(left.selected);
825 print(".<");
826 printExprs(tree.typeargs);
827 print(">" + left.name);
828 } else {
829 print("<");
830 printExprs(tree.typeargs);
831 print(">");
832 printExpr(tree.meth);
833 }
834 } else {
835 printExpr(tree.meth);
836 }
837 print("(");
838 printExprs(tree.args);
839 print(")");
840 } catch (IOException e) {
841 throw new UncheckedIOException(e);
842 }
843 }
845 public void visitNewClass(JCNewClass tree) {
846 try {
847 if (tree.encl != null) {
848 printExpr(tree.encl);
849 print(".");
850 }
851 print("new ");
852 if (!tree.typeargs.isEmpty()) {
853 print("<");
854 printExprs(tree.typeargs);
855 print(">");
856 }
857 printExpr(tree.clazz);
858 print("(");
859 printExprs(tree.args);
860 print(")");
861 if (tree.def != null) {
862 Name enclClassNamePrev = enclClassName;
863 enclClassName =
864 tree.def.name != null ? tree.def.name :
865 tree.type != null && tree.type.tsym.name != tree.type.tsym.name.table.names.empty
866 ? tree.type.tsym.name : null;
867 if ((tree.def.mods.flags & Flags.ENUM) != 0) print("/*enum*/");
868 printBlock(tree.def.defs);
869 enclClassName = enclClassNamePrev;
870 }
871 } catch (IOException e) {
872 throw new UncheckedIOException(e);
873 }
874 }
876 public void visitNewArray(JCNewArray tree) {
877 try {
878 if (tree.elemtype != null) {
879 print("new ");
880 printTypeAnnotations(tree.annotations);
881 JCTree elem = tree.elemtype;
882 printBaseElementType(elem);
883 boolean isElemAnnoType = elem instanceof JCAnnotatedType;
884 int i = 0;
885 List<List<JCTypeAnnotation>> da = tree.dimAnnotations;
886 for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
887 if (da.size() > i) {
888 printTypeAnnotations(da.get(i));
889 }
890 print("[");
891 i++;
892 printExpr(l.head);
893 print("]");
894 }
895 if (tree.elems != null) {
896 if (isElemAnnoType) {
897 printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
898 }
899 print("[]");
900 }
901 if (isElemAnnoType)
902 elem = ((JCAnnotatedType)elem).underlyingType;
903 if (elem instanceof JCArrayTypeTree)
904 printBrackets((JCArrayTypeTree) elem);
905 }
906 if (tree.elems != null) {
907 print("{");
908 printExprs(tree.elems);
909 print("}");
910 }
911 } catch (IOException e) {
912 throw new UncheckedIOException(e);
913 }
914 }
916 public void visitParens(JCParens tree) {
917 try {
918 print("(");
919 printExpr(tree.expr);
920 print(")");
921 } catch (IOException e) {
922 throw new UncheckedIOException(e);
923 }
924 }
926 public void visitAssign(JCAssign tree) {
927 try {
928 open(prec, TreeInfo.assignPrec);
929 printExpr(tree.lhs, TreeInfo.assignPrec + 1);
930 print(" = ");
931 printExpr(tree.rhs, TreeInfo.assignPrec);
932 close(prec, TreeInfo.assignPrec);
933 } catch (IOException e) {
934 throw new UncheckedIOException(e);
935 }
936 }
938 public String operatorName(int tag) {
939 switch(tag) {
940 case JCTree.POS: return "+";
941 case JCTree.NEG: return "-";
942 case JCTree.NOT: return "!";
943 case JCTree.COMPL: return "~";
944 case JCTree.PREINC: return "++";
945 case JCTree.PREDEC: return "--";
946 case JCTree.POSTINC: return "++";
947 case JCTree.POSTDEC: return "--";
948 case JCTree.NULLCHK: return "<*nullchk*>";
949 case JCTree.OR: return "||";
950 case JCTree.AND: return "&&";
951 case JCTree.EQ: return "==";
952 case JCTree.NE: return "!=";
953 case JCTree.LT: return "<";
954 case JCTree.GT: return ">";
955 case JCTree.LE: return "<=";
956 case JCTree.GE: return ">=";
957 case JCTree.BITOR: return "|";
958 case JCTree.BITXOR: return "^";
959 case JCTree.BITAND: return "&";
960 case JCTree.SL: return "<<";
961 case JCTree.SR: return ">>";
962 case JCTree.USR: return ">>>";
963 case JCTree.PLUS: return "+";
964 case JCTree.MINUS: return "-";
965 case JCTree.MUL: return "*";
966 case JCTree.DIV: return "/";
967 case JCTree.MOD: return "%";
968 default: throw new Error();
969 }
970 }
972 public void visitAssignop(JCAssignOp tree) {
973 try {
974 open(prec, TreeInfo.assignopPrec);
975 printExpr(tree.lhs, TreeInfo.assignopPrec + 1);
976 print(" " + operatorName(tree.getTag() - JCTree.ASGOffset) + "= ");
977 printExpr(tree.rhs, TreeInfo.assignopPrec);
978 close(prec, TreeInfo.assignopPrec);
979 } catch (IOException e) {
980 throw new UncheckedIOException(e);
981 }
982 }
984 public void visitUnary(JCUnary tree) {
985 try {
986 int ownprec = TreeInfo.opPrec(tree.getTag());
987 String opname = operatorName(tree.getTag());
988 open(prec, ownprec);
989 if (tree.getTag() <= JCTree.PREDEC) {
990 print(opname);
991 printExpr(tree.arg, ownprec);
992 } else {
993 printExpr(tree.arg, ownprec);
994 print(opname);
995 }
996 close(prec, ownprec);
997 } catch (IOException e) {
998 throw new UncheckedIOException(e);
999 }
1000 }
1002 public void visitBinary(JCBinary tree) {
1003 try {
1004 int ownprec = TreeInfo.opPrec(tree.getTag());
1005 String opname = operatorName(tree.getTag());
1006 open(prec, ownprec);
1007 printExpr(tree.lhs, ownprec);
1008 print(" " + opname + " ");
1009 printExpr(tree.rhs, ownprec + 1);
1010 close(prec, ownprec);
1011 } catch (IOException e) {
1012 throw new UncheckedIOException(e);
1013 }
1014 }
1016 public void visitTypeCast(JCTypeCast tree) {
1017 try {
1018 open(prec, TreeInfo.prefixPrec);
1019 print("(");
1020 printExpr(tree.clazz);
1021 print(")");
1022 printExpr(tree.expr, TreeInfo.prefixPrec);
1023 close(prec, TreeInfo.prefixPrec);
1024 } catch (IOException e) {
1025 throw new UncheckedIOException(e);
1026 }
1027 }
1029 public void visitTypeTest(JCInstanceOf tree) {
1030 try {
1031 open(prec, TreeInfo.ordPrec);
1032 printExpr(tree.expr, TreeInfo.ordPrec);
1033 print(" instanceof ");
1034 printExpr(tree.clazz, TreeInfo.ordPrec + 1);
1035 close(prec, TreeInfo.ordPrec);
1036 } catch (IOException e) {
1037 throw new UncheckedIOException(e);
1038 }
1039 }
1041 public void visitIndexed(JCArrayAccess tree) {
1042 try {
1043 printExpr(tree.indexed, TreeInfo.postfixPrec);
1044 print("[");
1045 printExpr(tree.index);
1046 print("]");
1047 } catch (IOException e) {
1048 throw new UncheckedIOException(e);
1049 }
1050 }
1052 public void visitSelect(JCFieldAccess tree) {
1053 try {
1054 printExpr(tree.selected, TreeInfo.postfixPrec);
1055 print("." + tree.name);
1056 } catch (IOException e) {
1057 throw new UncheckedIOException(e);
1058 }
1059 }
1061 public void visitIdent(JCIdent tree) {
1062 try {
1063 print(tree.name);
1064 } catch (IOException e) {
1065 throw new UncheckedIOException(e);
1066 }
1067 }
1069 public void visitLiteral(JCLiteral tree) {
1070 try {
1071 switch (tree.typetag) {
1072 case TypeTags.INT:
1073 print(tree.value.toString());
1074 break;
1075 case TypeTags.LONG:
1076 print(tree.value + "L");
1077 break;
1078 case TypeTags.FLOAT:
1079 print(tree.value + "F");
1080 break;
1081 case TypeTags.DOUBLE:
1082 print(tree.value.toString());
1083 break;
1084 case TypeTags.CHAR:
1085 print("\'" +
1086 Convert.quote(
1087 String.valueOf((char)((Number)tree.value).intValue())) +
1088 "\'");
1089 break;
1090 case TypeTags.BOOLEAN:
1091 print(((Number)tree.value).intValue() == 1 ? "true" : "false");
1092 break;
1093 case TypeTags.BOT:
1094 print("null");
1095 break;
1096 default:
1097 print("\"" + Convert.quote(tree.value.toString()) + "\"");
1098 break;
1099 }
1100 } catch (IOException e) {
1101 throw new UncheckedIOException(e);
1102 }
1103 }
1105 public void visitTypeIdent(JCPrimitiveTypeTree tree) {
1106 try {
1107 switch(tree.typetag) {
1108 case TypeTags.BYTE:
1109 print("byte");
1110 break;
1111 case TypeTags.CHAR:
1112 print("char");
1113 break;
1114 case TypeTags.SHORT:
1115 print("short");
1116 break;
1117 case TypeTags.INT:
1118 print("int");
1119 break;
1120 case TypeTags.LONG:
1121 print("long");
1122 break;
1123 case TypeTags.FLOAT:
1124 print("float");
1125 break;
1126 case TypeTags.DOUBLE:
1127 print("double");
1128 break;
1129 case TypeTags.BOOLEAN:
1130 print("boolean");
1131 break;
1132 case TypeTags.VOID:
1133 print("void");
1134 break;
1135 default:
1136 print("error");
1137 break;
1138 }
1139 } catch (IOException e) {
1140 throw new UncheckedIOException(e);
1141 }
1142 }
1144 public void visitTypeArray(JCArrayTypeTree tree) {
1145 try {
1146 printBaseElementType(tree);
1147 printBrackets(tree);
1148 } catch (IOException e) {
1149 throw new UncheckedIOException(e);
1150 }
1151 }
1153 // Prints the inner element type of a nested array
1154 private void printBaseElementType(JCTree tree) throws IOException {
1155 printExpr(TreeInfo.innermostType(tree));
1156 }
1158 // prints the brackets of a nested array in reverse order
1159 private void printBrackets(JCArrayTypeTree tree) throws IOException {
1160 JCTree elem;
1161 while (true) {
1162 elem = tree.elemtype;
1163 if (elem.getTag() == JCTree.ANNOTATED_TYPE) {
1164 JCAnnotatedType atype = (JCAnnotatedType) elem;
1165 printTypeAnnotations(atype.annotations);
1166 elem = atype.underlyingType;
1167 }
1168 print("[]");
1169 if (elem.getTag() != JCTree.TYPEARRAY) break;
1170 tree = (JCArrayTypeTree) elem;
1171 }
1172 }
1174 public void visitTypeApply(JCTypeApply tree) {
1175 try {
1176 printExpr(tree.clazz);
1177 print("<");
1178 printExprs(tree.arguments);
1179 print(">");
1180 } catch (IOException e) {
1181 throw new UncheckedIOException(e);
1182 }
1183 }
1185 public void visitTypeDisjoint(JCTypeDisjoint tree) {
1186 try {
1187 printExprs(tree.components, " | ");
1188 } catch (IOException e) {
1189 throw new UncheckedIOException(e);
1190 }
1191 }
1193 public void visitTypeParameter(JCTypeParameter tree) {
1194 try {
1195 print(tree.name);
1196 if (tree.bounds.nonEmpty()) {
1197 print(" extends ");
1198 printExprs(tree.bounds, " & ");
1199 }
1200 } catch (IOException e) {
1201 throw new UncheckedIOException(e);
1202 }
1203 }
1205 @Override
1206 public void visitWildcard(JCWildcard tree) {
1207 try {
1208 print(tree.kind);
1209 if (tree.kind.kind != BoundKind.UNBOUND)
1210 printExpr(tree.inner);
1211 } catch (IOException e) {
1212 throw new UncheckedIOException(e);
1213 }
1214 }
1216 @Override
1217 public void visitTypeBoundKind(TypeBoundKind tree) {
1218 try {
1219 print(String.valueOf(tree.kind));
1220 } catch (IOException e) {
1221 throw new UncheckedIOException(e);
1222 }
1223 }
1225 public void visitErroneous(JCErroneous tree) {
1226 try {
1227 print("(ERROR)");
1228 } catch (IOException e) {
1229 throw new UncheckedIOException(e);
1230 }
1231 }
1233 public void visitLetExpr(LetExpr tree) {
1234 try {
1235 print("(let " + tree.defs + " in " + tree.expr + ")");
1236 } catch (IOException e) {
1237 throw new UncheckedIOException(e);
1238 }
1239 }
1241 public void visitModifiers(JCModifiers mods) {
1242 try {
1243 printAnnotations(mods.annotations);
1244 printFlags(mods.flags);
1245 } catch (IOException e) {
1246 throw new UncheckedIOException(e);
1247 }
1248 }
1250 public void visitAnnotation(JCAnnotation tree) {
1251 try {
1252 print("@");
1253 printExpr(tree.annotationType);
1254 print("(");
1255 printExprs(tree.args);
1256 print(")");
1257 } catch (IOException e) {
1258 throw new UncheckedIOException(e);
1259 }
1260 }
1262 public void visitAnnotatedType(JCAnnotatedType tree) {
1263 try {
1264 printTypeAnnotations(tree.annotations);
1265 printExpr(tree.underlyingType);
1266 } catch (IOException e) {
1267 throw new UncheckedIOException(e);
1268 }
1269 }
1271 public void visitTree(JCTree tree) {
1272 try {
1273 print("(UNKNOWN: " + tree + ")");
1274 println();
1275 } catch (IOException e) {
1276 throw new UncheckedIOException(e);
1277 }
1278 }
1280 }