duke@1: /*
jjg@1486: * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@1: *
duke@1: * This code is free software; you can redistribute it and/or modify it
duke@1: * under the terms of the GNU General Public License version 2 only, as
ohair@554: * published by the Free Software Foundation. Oracle designates this
duke@1: * particular file as subject to the "Classpath" exception as provided
ohair@554: * by Oracle in the LICENSE file that accompanied this code.
duke@1: *
duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT
duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@1: * version 2 for more details (a copy is included in the LICENSE file that
duke@1: * accompanied this code).
duke@1: *
duke@1: * You should have received a copy of the GNU General Public License version
duke@1: * 2 along with this work; if not, write to the Free Software Foundation,
duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@1: *
ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@554: * or visit www.oracle.com if you need additional information or have any
ohair@554: * questions.
duke@1: */
duke@1:
duke@1: package com.sun.tools.javac.tree;
duke@1:
duke@1: import java.io.*;
duke@1:
mcimadamore@1143: import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
jjg@1280: import com.sun.tools.javac.code.*;
jjg@1280: import com.sun.tools.javac.tree.JCTree.*;
duke@1: import com.sun.tools.javac.util.*;
duke@1: import com.sun.tools.javac.util.List;
duke@1: import static com.sun.tools.javac.code.Flags.*;
jjg@1127: import static com.sun.tools.javac.code.Flags.ANNOTATION;
jjg@1127: import static com.sun.tools.javac.tree.JCTree.Tag.*;
duke@1:
duke@1: /** Prints out a tree as an indented Java source program.
duke@1: *
jjg@581: *
This is NOT part of any supported API.
jjg@581: * If you write code that depends on this, you do so at your own risk.
duke@1: * This code and its internal interfaces are subject to change or
duke@1: * deletion without notice.
duke@1: */
duke@1: public class Pretty extends JCTree.Visitor {
duke@1:
duke@1: public Pretty(Writer out, boolean sourceOutput) {
duke@1: this.out = out;
duke@1: this.sourceOutput = sourceOutput;
duke@1: }
duke@1:
duke@1: /** Set when we are producing source output. If we're not
duke@1: * producing source output, we can sometimes give more detail in
duke@1: * the output even though that detail would not be valid java
jjg@439: * source.
duke@1: */
duke@1: private final boolean sourceOutput;
duke@1:
duke@1: /** The output stream on which trees are printed.
duke@1: */
duke@1: Writer out;
duke@1:
duke@1: /** Indentation width (can be reassigned from outside).
duke@1: */
duke@1: public int width = 4;
duke@1:
duke@1: /** The current left margin.
duke@1: */
duke@1: int lmargin = 0;
duke@1:
duke@1: /** The enclosing class name.
duke@1: */
duke@1: Name enclClassName;
duke@1:
jjg@1280: /** A table mapping trees to their documentation comments
duke@1: * (can be null)
duke@1: */
jjg@1280: DocCommentTable docComments = null;
duke@1:
mcimadamore@1347: /**
mcimadamore@1347: * A string sequence to be used when Pretty output should be constrained
mcimadamore@1347: * to fit into a given size
mcimadamore@1347: */
mcimadamore@1347: private final static String trimSequence = "[...]";
mcimadamore@1347:
mcimadamore@1348: /**
mcimadamore@1348: * Max number of chars to be generated when output should fit into a single line
mcimadamore@1348: */
mcimadamore@1348: private final static int PREFERRED_LENGTH = 20;
mcimadamore@1348:
duke@1: /** Align code to be indented to left margin.
duke@1: */
duke@1: void align() throws IOException {
duke@1: for (int i = 0; i < lmargin; i++) out.write(" ");
duke@1: }
duke@1:
duke@1: /** Increase left margin by indentation width.
duke@1: */
duke@1: void indent() {
duke@1: lmargin = lmargin + width;
duke@1: }
duke@1:
duke@1: /** Decrease left margin by indentation width.
duke@1: */
duke@1: void undent() {
duke@1: lmargin = lmargin - width;
duke@1: }
duke@1:
duke@1: /** Enter a new precedence level. Emit a `(' if new precedence level
duke@1: * is less than precedence level so far.
duke@1: * @param contextPrec The precedence level in force so far.
duke@1: * @param ownPrec The new precedence level.
duke@1: */
duke@1: void open(int contextPrec, int ownPrec) throws IOException {
duke@1: if (ownPrec < contextPrec) out.write("(");
duke@1: }
duke@1:
duke@1: /** Leave precedence level. Emit a `(' if inner precedence level
duke@1: * is less than precedence level we revert to.
duke@1: * @param contextPrec The precedence level we revert to.
duke@1: * @param ownPrec The inner precedence level.
duke@1: */
duke@1: void close(int contextPrec, int ownPrec) throws IOException {
duke@1: if (ownPrec < contextPrec) out.write(")");
duke@1: }
duke@1:
duke@1: /** Print string, replacing all non-ascii character with unicode escapes.
duke@1: */
duke@1: public void print(Object s) throws IOException {
duke@1: out.write(Convert.escapeUnicode(s.toString()));
duke@1: }
duke@1:
duke@1: /** Print new line.
duke@1: */
duke@1: public void println() throws IOException {
duke@1: out.write(lineSep);
duke@1: }
duke@1:
mcimadamore@1348: public static String toSimpleString(JCTree tree) {
mcimadamore@1348: return toSimpleString(tree, PREFERRED_LENGTH);
mcimadamore@1348: }
mcimadamore@1348:
mcimadamore@1347: public static String toSimpleString(JCTree tree, int maxLength) {
mcimadamore@1347: StringWriter s = new StringWriter();
mcimadamore@1347: try {
mcimadamore@1347: new Pretty(s, false).printExpr(tree);
mcimadamore@1347: }
mcimadamore@1347: catch (IOException e) {
mcimadamore@1347: // should never happen, because StringWriter is defined
mcimadamore@1347: // never to throw any IOExceptions
mcimadamore@1347: throw new AssertionError(e);
mcimadamore@1347: }
mcimadamore@1347: //we need to (i) replace all line terminators with a space and (ii) remove
mcimadamore@1347: //occurrences of 'missing' in the Pretty output (generated when types are missing)
jjg@1486: String res = s.toString().trim().replaceAll("\\s+", " ").replaceAll("/\\*missing\\*/", "");
mcimadamore@1347: if (res.length() < maxLength) {
mcimadamore@1347: return res;
mcimadamore@1347: } else {
jjg@1486: int head = (maxLength - trimSequence.length()) * 2 / 3;
jjg@1486: int tail = maxLength - trimSequence.length() - head;
jjg@1486: return res.substring(0, head) + trimSequence + res.substring(res.length() - tail);
mcimadamore@1347: }
mcimadamore@1347: }
mcimadamore@1347:
duke@1: String lineSep = System.getProperty("line.separator");
duke@1:
duke@1: /**************************************************************************
duke@1: * Traversal methods
duke@1: *************************************************************************/
duke@1:
duke@1: /** Exception to propogate IOException through visitXXX methods */
duke@1: private static class UncheckedIOException extends Error {
duke@1: static final long serialVersionUID = -4032692679158424751L;
duke@1: UncheckedIOException(IOException e) {
duke@1: super(e.getMessage(), e);
duke@1: }
duke@1: }
duke@1:
duke@1: /** Visitor argument: the current precedence level.
duke@1: */
duke@1: int prec;
duke@1:
duke@1: /** Visitor method: print expression tree.
duke@1: * @param prec The current precedence level.
duke@1: */
duke@1: public void printExpr(JCTree tree, int prec) throws IOException {
duke@1: int prevPrec = this.prec;
duke@1: try {
duke@1: this.prec = prec;
duke@1: if (tree == null) print("/*missing*/");
duke@1: else {
duke@1: tree.accept(this);
duke@1: }
duke@1: } catch (UncheckedIOException ex) {
duke@1: IOException e = new IOException(ex.getMessage());
duke@1: e.initCause(ex);
duke@1: throw e;
duke@1: } finally {
duke@1: this.prec = prevPrec;
duke@1: }
duke@1: }
duke@1:
duke@1: /** Derived visitor method: print expression tree at minimum precedence level
duke@1: * for expression.
duke@1: */
duke@1: public void printExpr(JCTree tree) throws IOException {
duke@1: printExpr(tree, TreeInfo.noPrec);
duke@1: }
duke@1:
duke@1: /** Derived visitor method: print statement tree.
duke@1: */
duke@1: public void printStat(JCTree tree) throws IOException {
duke@1: printExpr(tree, TreeInfo.notExpression);
duke@1: }
duke@1:
duke@1: /** Derived visitor method: print list of expression trees, separated by given string.
duke@1: * @param sep the separator string
duke@1: */
duke@1: public void printExprs(List trees, String sep) throws IOException {
duke@1: if (trees.nonEmpty()) {
duke@1: printExpr(trees.head);
duke@1: for (List l = trees.tail; l.nonEmpty(); l = l.tail) {
duke@1: print(sep);
duke@1: printExpr(l.head);
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: /** Derived visitor method: print list of expression trees, separated by commas.
duke@1: */
duke@1: public void printExprs(List trees) throws IOException {
duke@1: printExprs(trees, ", ");
duke@1: }
duke@1:
duke@1: /** Derived visitor method: print list of statements, each on a separate line.
duke@1: */
duke@1: public void printStats(List extends JCTree> trees) throws IOException {
duke@1: for (List extends JCTree> l = trees; l.nonEmpty(); l = l.tail) {
duke@1: align();
duke@1: printStat(l.head);
duke@1: println();
duke@1: }
duke@1: }
duke@1:
duke@1: /** Print a set of modifiers.
duke@1: */
duke@1: public void printFlags(long flags) throws IOException {
duke@1: if ((flags & SYNTHETIC) != 0) print("/*synthetic*/ ");
duke@1: print(TreeInfo.flagNames(flags));
mcimadamore@1366: if ((flags & ExtendedStandardFlags) != 0) print(" ");
duke@1: if ((flags & ANNOTATION) != 0) print("@");
duke@1: }
duke@1:
duke@1: public void printAnnotations(List trees) throws IOException {
duke@1: for (List l = trees; l.nonEmpty(); l = l.tail) {
duke@1: printStat(l.head);
duke@1: println();
duke@1: align();
duke@1: }
duke@1: }
duke@1:
jjg@1521: public void printTypeAnnotations(List trees) throws IOException {
jjg@1521: for (List l = trees; l.nonEmpty(); l = l.tail) {
jjg@1521: printExpr(l.head);
jjg@1521: print(" ");
jjg@1521: }
jjg@1521: }
jjg@1521:
duke@1: /** Print documentation comment, if it exists
duke@1: * @param tree The tree for which a documentation comment should be printed.
duke@1: */
duke@1: public void printDocComment(JCTree tree) throws IOException {
duke@1: if (docComments != null) {
jjg@1280: String dc = docComments.getCommentText(tree);
duke@1: if (dc != null) {
duke@1: print("/**"); println();
duke@1: int pos = 0;
duke@1: int endpos = lineEndPos(dc, pos);
duke@1: while (pos < dc.length()) {
duke@1: align();
duke@1: print(" *");
duke@1: if (pos < dc.length() && dc.charAt(pos) > ' ') print(" ");
duke@1: print(dc.substring(pos, endpos)); println();
duke@1: pos = endpos + 1;
duke@1: endpos = lineEndPos(dc, pos);
duke@1: }
duke@1: align(); print(" */"); println();
duke@1: align();
duke@1: }
duke@1: }
duke@1: }
duke@1: //where
duke@1: static int lineEndPos(String s, int start) {
duke@1: int pos = s.indexOf('\n', start);
duke@1: if (pos < 0) pos = s.length();
duke@1: return pos;
duke@1: }
duke@1:
jjg@1326: /** If type parameter list is non-empty, print it enclosed in
jjg@1326: * {@literal "<...>"} brackets.
duke@1: */
duke@1: public void printTypeParameters(List trees) throws IOException {
duke@1: if (trees.nonEmpty()) {
duke@1: print("<");
duke@1: printExprs(trees);
duke@1: print(">");
duke@1: }
duke@1: }
duke@1:
duke@1: /** Print a block.
duke@1: */
duke@1: public void printBlock(List extends JCTree> stats) throws IOException {
duke@1: print("{");
duke@1: println();
duke@1: indent();
duke@1: printStats(stats);
duke@1: undent();
duke@1: align();
duke@1: print("}");
duke@1: }
duke@1:
duke@1: /** Print a block.
duke@1: */
duke@1: public void printEnumBody(List stats) throws IOException {
duke@1: print("{");
duke@1: println();
duke@1: indent();
duke@1: boolean first = true;
duke@1: for (List l = stats; l.nonEmpty(); l = l.tail) {
duke@1: if (isEnumerator(l.head)) {
duke@1: if (!first) {
duke@1: print(",");
duke@1: println();
duke@1: }
duke@1: align();
duke@1: printStat(l.head);
duke@1: first = false;
duke@1: }
duke@1: }
duke@1: print(";");
duke@1: println();
duke@1: for (List l = stats; l.nonEmpty(); l = l.tail) {
duke@1: if (!isEnumerator(l.head)) {
duke@1: align();
duke@1: printStat(l.head);
duke@1: println();
duke@1: }
duke@1: }
duke@1: undent();
duke@1: align();
duke@1: print("}");
duke@1: }
duke@1:
duke@1: /** Is the given tree an enumerator definition? */
duke@1: boolean isEnumerator(JCTree t) {
jjg@1127: return t.hasTag(VARDEF) && (((JCVariableDecl) t).mods.flags & ENUM) != 0;
duke@1: }
duke@1:
duke@1: /** Print unit consisting of package clause and import statements in toplevel,
duke@1: * followed by class definition. if class definition == null,
duke@1: * print all definitions in toplevel.
duke@1: * @param tree The toplevel tree
duke@1: * @param cdef The class definition, which is assumed to be part of the
duke@1: * toplevel tree.
duke@1: */
duke@1: public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException {
duke@1: docComments = tree.docComments;
duke@1: printDocComment(tree);
duke@1: if (tree.pid != null) {
duke@1: print("package ");
duke@1: printExpr(tree.pid);
duke@1: print(";");
duke@1: println();
duke@1: }
duke@1: boolean firstImport = true;
duke@1: for (List l = tree.defs;
jjg@1127: l.nonEmpty() && (cdef == null || l.head.hasTag(IMPORT));
duke@1: l = l.tail) {
jjg@1127: if (l.head.hasTag(IMPORT)) {
duke@1: JCImport imp = (JCImport)l.head;
duke@1: Name name = TreeInfo.name(imp.qualid);
jjg@113: if (name == name.table.names.asterisk ||
duke@1: cdef == null ||
duke@1: isUsed(TreeInfo.symbol(imp.qualid), cdef)) {
duke@1: if (firstImport) {
duke@1: firstImport = false;
duke@1: println();
duke@1: }
duke@1: printStat(imp);
duke@1: }
duke@1: } else {
duke@1: printStat(l.head);
duke@1: }
duke@1: }
duke@1: if (cdef != null) {
duke@1: printStat(cdef);
duke@1: println();
duke@1: }
duke@1: }
duke@1: // where
duke@1: boolean isUsed(final Symbol t, JCTree cdef) {
duke@1: class UsedVisitor extends TreeScanner {
duke@1: public void scan(JCTree tree) {
duke@1: if (tree!=null && !result) tree.accept(this);
duke@1: }
duke@1: boolean result = false;
duke@1: public void visitIdent(JCIdent tree) {
duke@1: if (tree.sym == t) result = true;
duke@1: }
duke@1: }
duke@1: UsedVisitor v = new UsedVisitor();
duke@1: v.scan(cdef);
duke@1: return v.result;
duke@1: }
duke@1:
duke@1: /**************************************************************************
duke@1: * Visitor methods
duke@1: *************************************************************************/
duke@1:
duke@1: public void visitTopLevel(JCCompilationUnit tree) {
duke@1: try {
duke@1: printUnit(tree, null);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitImport(JCImport tree) {
duke@1: try {
duke@1: print("import ");
duke@1: if (tree.staticImport) print("static ");
duke@1: printExpr(tree.qualid);
duke@1: print(";");
duke@1: println();
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitClassDef(JCClassDecl tree) {
duke@1: try {
duke@1: println(); align();
duke@1: printDocComment(tree);
duke@1: printAnnotations(tree.mods.annotations);
duke@1: printFlags(tree.mods.flags & ~INTERFACE);
duke@1: Name enclClassNamePrev = enclClassName;
duke@1: enclClassName = tree.name;
duke@1: if ((tree.mods.flags & INTERFACE) != 0) {
duke@1: print("interface " + tree.name);
duke@1: printTypeParameters(tree.typarams);
duke@1: if (tree.implementing.nonEmpty()) {
duke@1: print(" extends ");
duke@1: printExprs(tree.implementing);
duke@1: }
duke@1: } else {
duke@1: if ((tree.mods.flags & ENUM) != 0)
duke@1: print("enum " + tree.name);
duke@1: else
duke@1: print("class " + tree.name);
duke@1: printTypeParameters(tree.typarams);
duke@1: if (tree.extending != null) {
duke@1: print(" extends ");
duke@1: printExpr(tree.extending);
duke@1: }
duke@1: if (tree.implementing.nonEmpty()) {
duke@1: print(" implements ");
duke@1: printExprs(tree.implementing);
duke@1: }
duke@1: }
duke@1: print(" ");
duke@1: if ((tree.mods.flags & ENUM) != 0) {
duke@1: printEnumBody(tree.defs);
duke@1: } else {
duke@1: printBlock(tree.defs);
duke@1: }
duke@1: enclClassName = enclClassNamePrev;
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitMethodDef(JCMethodDecl tree) {
duke@1: try {
duke@1: // when producing source output, omit anonymous constructors
jjg@113: if (tree.name == tree.name.table.names.init &&
duke@1: enclClassName == null &&
duke@1: sourceOutput) return;
duke@1: println(); align();
duke@1: printDocComment(tree);
duke@1: printExpr(tree.mods);
duke@1: printTypeParameters(tree.typarams);
jjg@113: if (tree.name == tree.name.table.names.init) {
duke@1: print(enclClassName != null ? enclClassName : tree.name);
duke@1: } else {
duke@1: printExpr(tree.restype);
duke@1: print(" " + tree.name);
duke@1: }
duke@1: print("(");
jjg@1521: if (tree.recvparam!=null) {
jjg@1521: printExpr(tree.recvparam);
jjg@1521: if (tree.params.size() > 0) {
jjg@1521: print(", ");
jjg@1521: }
jjg@1521: }
duke@1: printExprs(tree.params);
duke@1: print(")");
duke@1: if (tree.thrown.nonEmpty()) {
duke@1: print(" throws ");
duke@1: printExprs(tree.thrown);
duke@1: }
jjg@461: if (tree.defaultValue != null) {
jjg@461: print(" default ");
jjg@461: printExpr(tree.defaultValue);
jjg@461: }
duke@1: if (tree.body != null) {
duke@1: print(" ");
duke@1: printStat(tree.body);
duke@1: } else {
duke@1: print(";");
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitVarDef(JCVariableDecl tree) {
duke@1: try {
jjg@1280: if (docComments != null && docComments.hasComment(tree)) {
duke@1: println(); align();
duke@1: }
duke@1: printDocComment(tree);
duke@1: if ((tree.mods.flags & ENUM) != 0) {
duke@1: print("/*public static final*/ ");
duke@1: print(tree.name);
duke@1: if (tree.init != null) {
jjg@1127: if (sourceOutput && tree.init.hasTag(NEWCLASS)) {
jjg@439: print(" /*enum*/ ");
jjg@439: JCNewClass init = (JCNewClass) tree.init;
jjg@439: if (init.args != null && init.args.nonEmpty()) {
jjg@439: print("(");
jjg@439: print(init.args);
jjg@439: print(")");
jjg@439: }
jjg@439: if (init.def != null && init.def.defs != null) {
jjg@439: print(" ");
jjg@439: printBlock(init.def.defs);
jjg@439: }
jjg@439: return;
jjg@439: }
duke@1: print(" /* = ");
duke@1: printExpr(tree.init);
duke@1: print(" */");
duke@1: }
duke@1: } else {
duke@1: printExpr(tree.mods);
duke@1: if ((tree.mods.flags & VARARGS) != 0) {
jjg@1521: JCTree vartype = tree.vartype;
jjg@1521: List tas = null;
jjg@1521: if (vartype instanceof JCAnnotatedType) {
jjg@1521: tas = ((JCAnnotatedType)vartype).annotations;
jjg@1521: vartype = ((JCAnnotatedType)vartype).underlyingType;
jjg@1521: }
jjg@1521: printExpr(((JCArrayTypeTree) vartype).elemtype);
jjg@1755: if (tas != null) {
jjg@1755: print(' ');
jjg@1521: printTypeAnnotations(tas);
jjg@1755: }
duke@1: print("... " + tree.name);
duke@1: } else {
duke@1: printExpr(tree.vartype);
duke@1: print(" " + tree.name);
duke@1: }
duke@1: if (tree.init != null) {
duke@1: print(" = ");
duke@1: printExpr(tree.init);
duke@1: }
duke@1: if (prec == TreeInfo.notExpression) print(";");
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitSkip(JCSkip tree) {
duke@1: try {
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitBlock(JCBlock tree) {
duke@1: try {
duke@1: printFlags(tree.flags);
duke@1: printBlock(tree.stats);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitDoLoop(JCDoWhileLoop tree) {
duke@1: try {
duke@1: print("do ");
duke@1: printStat(tree.body);
duke@1: align();
duke@1: print(" while ");
jjg@1127: if (tree.cond.hasTag(PARENS)) {
duke@1: printExpr(tree.cond);
duke@1: } else {
duke@1: print("(");
duke@1: printExpr(tree.cond);
duke@1: print(")");
duke@1: }
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitWhileLoop(JCWhileLoop tree) {
duke@1: try {
duke@1: print("while ");
jjg@1127: if (tree.cond.hasTag(PARENS)) {
duke@1: printExpr(tree.cond);
duke@1: } else {
duke@1: print("(");
duke@1: printExpr(tree.cond);
duke@1: print(")");
duke@1: }
duke@1: print(" ");
duke@1: printStat(tree.body);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitForLoop(JCForLoop tree) {
duke@1: try {
duke@1: print("for (");
duke@1: if (tree.init.nonEmpty()) {
jjg@1127: if (tree.init.head.hasTag(VARDEF)) {
duke@1: printExpr(tree.init.head);
duke@1: for (List l = tree.init.tail; l.nonEmpty(); l = l.tail) {
duke@1: JCVariableDecl vdef = (JCVariableDecl)l.head;
duke@1: print(", " + vdef.name + " = ");
duke@1: printExpr(vdef.init);
duke@1: }
duke@1: } else {
duke@1: printExprs(tree.init);
duke@1: }
duke@1: }
duke@1: print("; ");
duke@1: if (tree.cond != null) printExpr(tree.cond);
duke@1: print("; ");
duke@1: printExprs(tree.step);
duke@1: print(") ");
duke@1: printStat(tree.body);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitForeachLoop(JCEnhancedForLoop tree) {
duke@1: try {
duke@1: print("for (");
duke@1: printExpr(tree.var);
duke@1: print(" : ");
duke@1: printExpr(tree.expr);
duke@1: print(") ");
duke@1: printStat(tree.body);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitLabelled(JCLabeledStatement tree) {
duke@1: try {
duke@1: print(tree.label + ": ");
duke@1: printStat(tree.body);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitSwitch(JCSwitch tree) {
duke@1: try {
duke@1: print("switch ");
jjg@1127: if (tree.selector.hasTag(PARENS)) {
duke@1: printExpr(tree.selector);
duke@1: } else {
duke@1: print("(");
duke@1: printExpr(tree.selector);
duke@1: print(")");
duke@1: }
duke@1: print(" {");
duke@1: println();
duke@1: printStats(tree.cases);
duke@1: align();
duke@1: print("}");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitCase(JCCase tree) {
duke@1: try {
duke@1: if (tree.pat == null) {
duke@1: print("default");
duke@1: } else {
duke@1: print("case ");
duke@1: printExpr(tree.pat);
duke@1: }
duke@1: print(": ");
duke@1: println();
duke@1: indent();
duke@1: printStats(tree.stats);
duke@1: undent();
duke@1: align();
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitSynchronized(JCSynchronized tree) {
duke@1: try {
duke@1: print("synchronized ");
jjg@1127: if (tree.lock.hasTag(PARENS)) {
duke@1: printExpr(tree.lock);
duke@1: } else {
duke@1: print("(");
duke@1: printExpr(tree.lock);
duke@1: print(")");
duke@1: }
duke@1: print(" ");
duke@1: printStat(tree.body);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitTry(JCTry tree) {
duke@1: try {
duke@1: print("try ");
darcy@609: if (tree.resources.nonEmpty()) {
darcy@609: print("(");
darcy@609: boolean first = true;
darcy@609: for (JCTree var : tree.resources) {
darcy@609: if (!first) {
darcy@609: println();
darcy@609: indent();
darcy@609: }
darcy@609: printStat(var);
darcy@609: first = false;
darcy@609: }
darcy@609: print(") ");
darcy@609: }
duke@1: printStat(tree.body);
duke@1: for (List l = tree.catchers; l.nonEmpty(); l = l.tail) {
duke@1: printStat(l.head);
duke@1: }
duke@1: if (tree.finalizer != null) {
duke@1: print(" finally ");
duke@1: printStat(tree.finalizer);
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitCatch(JCCatch tree) {
duke@1: try {
duke@1: print(" catch (");
duke@1: printExpr(tree.param);
duke@1: print(") ");
duke@1: printStat(tree.body);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitConditional(JCConditional tree) {
duke@1: try {
duke@1: open(prec, TreeInfo.condPrec);
duke@1: printExpr(tree.cond, TreeInfo.condPrec);
duke@1: print(" ? ");
duke@1: printExpr(tree.truepart, TreeInfo.condPrec);
duke@1: print(" : ");
duke@1: printExpr(tree.falsepart, TreeInfo.condPrec);
duke@1: close(prec, TreeInfo.condPrec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitIf(JCIf tree) {
duke@1: try {
duke@1: print("if ");
jjg@1127: if (tree.cond.hasTag(PARENS)) {
duke@1: printExpr(tree.cond);
duke@1: } else {
duke@1: print("(");
duke@1: printExpr(tree.cond);
duke@1: print(")");
duke@1: }
duke@1: print(" ");
duke@1: printStat(tree.thenpart);
duke@1: if (tree.elsepart != null) {
duke@1: print(" else ");
duke@1: printStat(tree.elsepart);
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitExec(JCExpressionStatement tree) {
duke@1: try {
duke@1: printExpr(tree.expr);
duke@1: if (prec == TreeInfo.notExpression) print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitBreak(JCBreak tree) {
duke@1: try {
duke@1: print("break");
duke@1: if (tree.label != null) print(" " + tree.label);
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitContinue(JCContinue tree) {
duke@1: try {
duke@1: print("continue");
duke@1: if (tree.label != null) print(" " + tree.label);
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitReturn(JCReturn tree) {
duke@1: try {
duke@1: print("return");
duke@1: if (tree.expr != null) {
duke@1: print(" ");
duke@1: printExpr(tree.expr);
duke@1: }
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitThrow(JCThrow tree) {
duke@1: try {
duke@1: print("throw ");
duke@1: printExpr(tree.expr);
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitAssert(JCAssert tree) {
duke@1: try {
duke@1: print("assert ");
duke@1: printExpr(tree.cond);
duke@1: if (tree.detail != null) {
duke@1: print(" : ");
duke@1: printExpr(tree.detail);
duke@1: }
duke@1: print(";");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitApply(JCMethodInvocation tree) {
duke@1: try {
duke@1: if (!tree.typeargs.isEmpty()) {
jjg@1127: if (tree.meth.hasTag(SELECT)) {
duke@1: JCFieldAccess left = (JCFieldAccess)tree.meth;
duke@1: printExpr(left.selected);
duke@1: print(".<");
duke@1: printExprs(tree.typeargs);
duke@1: print(">" + left.name);
duke@1: } else {
duke@1: print("<");
duke@1: printExprs(tree.typeargs);
duke@1: print(">");
duke@1: printExpr(tree.meth);
duke@1: }
duke@1: } else {
duke@1: printExpr(tree.meth);
duke@1: }
duke@1: print("(");
duke@1: printExprs(tree.args);
duke@1: print(")");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitNewClass(JCNewClass tree) {
duke@1: try {
duke@1: if (tree.encl != null) {
duke@1: printExpr(tree.encl);
duke@1: print(".");
duke@1: }
duke@1: print("new ");
duke@1: if (!tree.typeargs.isEmpty()) {
duke@1: print("<");
duke@1: printExprs(tree.typeargs);
duke@1: print(">");
duke@1: }
jjg@1755: if (tree.def != null && tree.def.mods.annotations.nonEmpty()) {
jjg@1755: printTypeAnnotations(tree.def.mods.annotations);
jjg@1755: }
duke@1: printExpr(tree.clazz);
duke@1: print("(");
duke@1: printExprs(tree.args);
duke@1: print(")");
duke@1: if (tree.def != null) {
duke@1: Name enclClassNamePrev = enclClassName;
duke@1: enclClassName =
duke@1: tree.def.name != null ? tree.def.name :
jjg@113: tree.type != null && tree.type.tsym.name != tree.type.tsym.name.table.names.empty
jjg@113: ? tree.type.tsym.name : null;
duke@1: if ((tree.def.mods.flags & Flags.ENUM) != 0) print("/*enum*/");
duke@1: printBlock(tree.def.defs);
duke@1: enclClassName = enclClassNamePrev;
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitNewArray(JCNewArray tree) {
duke@1: try {
duke@1: if (tree.elemtype != null) {
duke@1: print("new ");
jjg@1521: printTypeAnnotations(tree.annotations);
duke@1: JCTree elem = tree.elemtype;
jjg@1521: printBaseElementType(elem);
jjg@1521: boolean isElemAnnoType = elem instanceof JCAnnotatedType;
jjg@1521: int i = 0;
jjg@1521: List> da = tree.dimAnnotations;
duke@1: for (List l = tree.dims; l.nonEmpty(); l = l.tail) {
jjg@1755: if (da.size() > i && !da.get(i).isEmpty()) {
jjg@1755: print(' ');
jjg@1521: printTypeAnnotations(da.get(i));
jjg@1521: }
duke@1: print("[");
jjg@1521: i++;
duke@1: printExpr(l.head);
duke@1: print("]");
duke@1: }
jjg@1521: if (tree.elems != null) {
jjg@1521: if (isElemAnnoType) {
jjg@1755: print(' ');
jjg@1521: printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
jjg@1521: }
jjg@1521: print("[]");
jjg@1521: }
jjg@1521: if (isElemAnnoType)
jjg@1521: elem = ((JCAnnotatedType)elem).underlyingType;
duke@1: if (elem instanceof JCArrayTypeTree)
duke@1: printBrackets((JCArrayTypeTree) elem);
duke@1: }
duke@1: if (tree.elems != null) {
jjg@815: if (tree.elemtype != null) print("[]");
duke@1: print("{");
duke@1: printExprs(tree.elems);
duke@1: print("}");
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
mcimadamore@1142: public void visitLambda(JCLambda tree) {
mcimadamore@1142: try {
mcimadamore@1142: print("(");
mcimadamore@1510: if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT) {
mcimadamore@1348: printExprs(tree.params);
mcimadamore@1348: } else {
mcimadamore@1348: String sep = "";
mcimadamore@1348: for (JCVariableDecl param : tree.params) {
mcimadamore@1348: print(sep);
mcimadamore@1348: print(param.name);
mcimadamore@1348: sep = ",";
mcimadamore@1348: }
mcimadamore@1348: }
mcimadamore@1142: print(")->");
mcimadamore@1142: printExpr(tree.body);
mcimadamore@1142: } catch (IOException e) {
mcimadamore@1142: throw new UncheckedIOException(e);
mcimadamore@1142: }
mcimadamore@1142: }
mcimadamore@1142:
duke@1: public void visitParens(JCParens tree) {
duke@1: try {
duke@1: print("(");
duke@1: printExpr(tree.expr);
duke@1: print(")");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitAssign(JCAssign tree) {
duke@1: try {
duke@1: open(prec, TreeInfo.assignPrec);
duke@1: printExpr(tree.lhs, TreeInfo.assignPrec + 1);
duke@1: print(" = ");
duke@1: printExpr(tree.rhs, TreeInfo.assignPrec);
duke@1: close(prec, TreeInfo.assignPrec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
jjg@1127: public String operatorName(JCTree.Tag tag) {
duke@1: switch(tag) {
jjg@1127: case POS: return "+";
jjg@1127: case NEG: return "-";
jjg@1127: case NOT: return "!";
jjg@1127: case COMPL: return "~";
jjg@1127: case PREINC: return "++";
jjg@1127: case PREDEC: return "--";
jjg@1127: case POSTINC: return "++";
jjg@1127: case POSTDEC: return "--";
jjg@1127: case NULLCHK: return "<*nullchk*>";
jjg@1127: case OR: return "||";
jjg@1127: case AND: return "&&";
jjg@1127: case EQ: return "==";
jjg@1127: case NE: return "!=";
jjg@1127: case LT: return "<";
jjg@1127: case GT: return ">";
jjg@1127: case LE: return "<=";
jjg@1127: case GE: return ">=";
jjg@1127: case BITOR: return "|";
jjg@1127: case BITXOR: return "^";
jjg@1127: case BITAND: return "&";
jjg@1127: case SL: return "<<";
jjg@1127: case SR: return ">>";
jjg@1127: case USR: return ">>>";
jjg@1127: case PLUS: return "+";
jjg@1127: case MINUS: return "-";
jjg@1127: case MUL: return "*";
jjg@1127: case DIV: return "/";
jjg@1127: case MOD: return "%";
duke@1: default: throw new Error();
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitAssignop(JCAssignOp tree) {
duke@1: try {
duke@1: open(prec, TreeInfo.assignopPrec);
duke@1: printExpr(tree.lhs, TreeInfo.assignopPrec + 1);
jjg@1127: print(" " + operatorName(tree.getTag().noAssignOp()) + "= ");
duke@1: printExpr(tree.rhs, TreeInfo.assignopPrec);
duke@1: close(prec, TreeInfo.assignopPrec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitUnary(JCUnary tree) {
duke@1: try {
duke@1: int ownprec = TreeInfo.opPrec(tree.getTag());
duke@1: String opname = operatorName(tree.getTag());
duke@1: open(prec, ownprec);
jjg@1127: if (!tree.getTag().isPostUnaryOp()) {
duke@1: print(opname);
duke@1: printExpr(tree.arg, ownprec);
duke@1: } else {
duke@1: printExpr(tree.arg, ownprec);
duke@1: print(opname);
duke@1: }
duke@1: close(prec, ownprec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitBinary(JCBinary tree) {
duke@1: try {
duke@1: int ownprec = TreeInfo.opPrec(tree.getTag());
duke@1: String opname = operatorName(tree.getTag());
duke@1: open(prec, ownprec);
duke@1: printExpr(tree.lhs, ownprec);
duke@1: print(" " + opname + " ");
duke@1: printExpr(tree.rhs, ownprec + 1);
duke@1: close(prec, ownprec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitTypeCast(JCTypeCast tree) {
duke@1: try {
duke@1: open(prec, TreeInfo.prefixPrec);
duke@1: print("(");
duke@1: printExpr(tree.clazz);
duke@1: print(")");
duke@1: printExpr(tree.expr, TreeInfo.prefixPrec);
duke@1: close(prec, TreeInfo.prefixPrec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitTypeTest(JCInstanceOf tree) {
duke@1: try {
duke@1: open(prec, TreeInfo.ordPrec);
duke@1: printExpr(tree.expr, TreeInfo.ordPrec);
duke@1: print(" instanceof ");
duke@1: printExpr(tree.clazz, TreeInfo.ordPrec + 1);
duke@1: close(prec, TreeInfo.ordPrec);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitIndexed(JCArrayAccess tree) {
duke@1: try {
duke@1: printExpr(tree.indexed, TreeInfo.postfixPrec);
duke@1: print("[");
duke@1: printExpr(tree.index);
duke@1: print("]");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitSelect(JCFieldAccess tree) {
duke@1: try {
duke@1: printExpr(tree.selected, TreeInfo.postfixPrec);
duke@1: print("." + tree.name);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
mcimadamore@1143: public void visitReference(JCMemberReference tree) {
mcimadamore@1143: try {
mcimadamore@1143: printExpr(tree.expr);
mcimadamore@1415: print("::");
mcimadamore@1143: if (tree.typeargs != null) {
mcimadamore@1143: print("<");
mcimadamore@1143: printExprs(tree.typeargs);
mcimadamore@1143: print(">");
mcimadamore@1143: }
mcimadamore@1143: print(tree.getMode() == ReferenceMode.INVOKE ? tree.name : "new");
mcimadamore@1143: } catch (IOException e) {
mcimadamore@1143: throw new UncheckedIOException(e);
mcimadamore@1143: }
mcimadamore@1143: }
mcimadamore@1143:
duke@1: public void visitIdent(JCIdent tree) {
duke@1: try {
duke@1: print(tree.name);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitLiteral(JCLiteral tree) {
duke@1: try {
duke@1: switch (tree.typetag) {
jjg@1374: case INT:
duke@1: print(tree.value.toString());
duke@1: break;
jjg@1374: case LONG:
duke@1: print(tree.value + "L");
duke@1: break;
jjg@1374: case FLOAT:
duke@1: print(tree.value + "F");
duke@1: break;
jjg@1374: case DOUBLE:
duke@1: print(tree.value.toString());
duke@1: break;
jjg@1374: case CHAR:
duke@1: print("\'" +
duke@1: Convert.quote(
duke@1: String.valueOf((char)((Number)tree.value).intValue())) +
duke@1: "\'");
duke@1: break;
jjg@1374: case BOOLEAN:
duke@1: print(((Number)tree.value).intValue() == 1 ? "true" : "false");
duke@1: break;
jjg@1374: case BOT:
duke@1: print("null");
duke@1: break;
duke@1: default:
duke@1: print("\"" + Convert.quote(tree.value.toString()) + "\"");
duke@1: break;
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitTypeIdent(JCPrimitiveTypeTree tree) {
duke@1: try {
duke@1: switch(tree.typetag) {
jjg@1374: case BYTE:
duke@1: print("byte");
duke@1: break;
jjg@1374: case CHAR:
duke@1: print("char");
duke@1: break;
jjg@1374: case SHORT:
duke@1: print("short");
duke@1: break;
jjg@1374: case INT:
duke@1: print("int");
duke@1: break;
jjg@1374: case LONG:
duke@1: print("long");
duke@1: break;
jjg@1374: case FLOAT:
duke@1: print("float");
duke@1: break;
jjg@1374: case DOUBLE:
duke@1: print("double");
duke@1: break;
jjg@1374: case BOOLEAN:
duke@1: print("boolean");
duke@1: break;
jjg@1374: case VOID:
duke@1: print("void");
duke@1: break;
duke@1: default:
duke@1: print("error");
duke@1: break;
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitTypeArray(JCArrayTypeTree tree) {
duke@1: try {
duke@1: printBaseElementType(tree);
duke@1: printBrackets(tree);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: // Prints the inner element type of a nested array
jjg@308: private void printBaseElementType(JCTree tree) throws IOException {
jjg@470: printExpr(TreeInfo.innermostType(tree));
duke@1: }
duke@1:
duke@1: // prints the brackets of a nested array in reverse order
duke@1: private void printBrackets(JCArrayTypeTree tree) throws IOException {
duke@1: JCTree elem;
duke@1: while (true) {
duke@1: elem = tree.elemtype;
jjg@1521: if (elem.hasTag(ANNOTATED_TYPE)) {
jjg@1521: JCAnnotatedType atype = (JCAnnotatedType) elem;
jjg@1521: elem = atype.underlyingType;
jjg@1521: if (!elem.hasTag(TYPEARRAY)) break;
jjg@1755: print(' ');
jjg@1521: printTypeAnnotations(atype.annotations);
jjg@1521: }
duke@1: print("[]");
jjg@1127: if (!elem.hasTag(TYPEARRAY)) break;
duke@1: tree = (JCArrayTypeTree) elem;
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitTypeApply(JCTypeApply tree) {
duke@1: try {
duke@1: printExpr(tree.clazz);
duke@1: print("<");
duke@1: printExprs(tree.arguments);
duke@1: print(">");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
darcy@969: public void visitTypeUnion(JCTypeUnion tree) {
mcimadamore@550: try {
jjg@724: printExprs(tree.alternatives, " | ");
mcimadamore@550: } catch (IOException e) {
mcimadamore@550: throw new UncheckedIOException(e);
mcimadamore@550: }
mcimadamore@550: }
mcimadamore@550:
mcimadamore@1436: public void visitTypeIntersection(JCTypeIntersection tree) {
mcimadamore@1436: try {
mcimadamore@1436: printExprs(tree.bounds, " & ");
mcimadamore@1436: } catch (IOException e) {
mcimadamore@1436: throw new UncheckedIOException(e);
mcimadamore@1436: }
mcimadamore@1436: }
mcimadamore@1436:
duke@1: public void visitTypeParameter(JCTypeParameter tree) {
duke@1: try {
jjg@1755: if (tree.annotations.nonEmpty()) {
jjg@1755: this.printTypeAnnotations(tree.annotations);
jjg@1755: }
duke@1: print(tree.name);
duke@1: if (tree.bounds.nonEmpty()) {
duke@1: print(" extends ");
duke@1: printExprs(tree.bounds, " & ");
duke@1: }
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: @Override
duke@1: public void visitWildcard(JCWildcard tree) {
duke@1: try {
duke@1: print(tree.kind);
duke@1: if (tree.kind.kind != BoundKind.UNBOUND)
duke@1: printExpr(tree.inner);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: @Override
duke@1: public void visitTypeBoundKind(TypeBoundKind tree) {
duke@1: try {
duke@1: print(String.valueOf(tree.kind));
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitErroneous(JCErroneous tree) {
duke@1: try {
duke@1: print("(ERROR)");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitLetExpr(LetExpr tree) {
duke@1: try {
duke@1: print("(let " + tree.defs + " in " + tree.expr + ")");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitModifiers(JCModifiers mods) {
duke@1: try {
duke@1: printAnnotations(mods.annotations);
duke@1: printFlags(mods.flags);
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
duke@1: public void visitAnnotation(JCAnnotation tree) {
duke@1: try {
duke@1: print("@");
duke@1: printExpr(tree.annotationType);
duke@1: print("(");
duke@1: printExprs(tree.args);
duke@1: print(")");
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
duke@1:
jjg@1521: public void visitAnnotatedType(JCAnnotatedType tree) {
jjg@1521: try {
jjg@1521: if (tree.underlyingType.getKind() == JCTree.Kind.MEMBER_SELECT) {
jjg@1521: JCFieldAccess access = (JCFieldAccess) tree.underlyingType;
jjg@1521: printExpr(access.selected, TreeInfo.postfixPrec);
jjg@1521: print(".");
jjg@1521: printTypeAnnotations(tree.annotations);
jjg@1521: print(access.name);
jjg@1521: } else if (tree.underlyingType.getKind() == JCTree.Kind.ARRAY_TYPE) {
jjg@1521: JCArrayTypeTree array = (JCArrayTypeTree) tree.underlyingType;
jjg@1521: printBaseElementType(tree);
jjg@1755: print(' ');
jjg@1521: printTypeAnnotations(tree.annotations);
jjg@1521: print("[]");
jjg@1521: JCExpression elem = array.elemtype;
jjg@1521: if (elem.hasTag(TYPEARRAY)) {
jjg@1521: printBrackets((JCArrayTypeTree) elem);
jjg@1521: }
jjg@1521: } else {
jjg@1521: printTypeAnnotations(tree.annotations);
jjg@1521: printExpr(tree.underlyingType);
jjg@1521: }
jjg@1521: } catch (IOException e) {
jjg@1521: throw new UncheckedIOException(e);
jjg@1521: }
jjg@1521: }
jjg@1521:
duke@1: public void visitTree(JCTree tree) {
duke@1: try {
duke@1: print("(UNKNOWN: " + tree + ")");
duke@1: println();
duke@1: } catch (IOException e) {
duke@1: throw new UncheckedIOException(e);
duke@1: }
duke@1: }
jjg@308:
duke@1: }