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