1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,1409 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.tree; 1.30 + 1.31 +import java.io.*; 1.32 + 1.33 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 1.34 +import com.sun.tools.javac.code.*; 1.35 +import com.sun.tools.javac.tree.JCTree.*; 1.36 +import com.sun.tools.javac.util.*; 1.37 +import com.sun.tools.javac.util.List; 1.38 +import static com.sun.tools.javac.code.Flags.*; 1.39 +import static com.sun.tools.javac.code.Flags.ANNOTATION; 1.40 +import static com.sun.tools.javac.tree.JCTree.Tag.*; 1.41 + 1.42 +/** Prints out a tree as an indented Java source program. 1.43 + * 1.44 + * <p><b>This is NOT part of any supported API. 1.45 + * If you write code that depends on this, you do so at your own risk. 1.46 + * This code and its internal interfaces are subject to change or 1.47 + * deletion without notice.</b> 1.48 + */ 1.49 +public class Pretty extends JCTree.Visitor { 1.50 + 1.51 + public Pretty(Writer out, boolean sourceOutput) { 1.52 + this.out = out; 1.53 + this.sourceOutput = sourceOutput; 1.54 + } 1.55 + 1.56 + /** Set when we are producing source output. If we're not 1.57 + * producing source output, we can sometimes give more detail in 1.58 + * the output even though that detail would not be valid java 1.59 + * source. 1.60 + */ 1.61 + private final boolean sourceOutput; 1.62 + 1.63 + /** The output stream on which trees are printed. 1.64 + */ 1.65 + Writer out; 1.66 + 1.67 + /** Indentation width (can be reassigned from outside). 1.68 + */ 1.69 + public int width = 4; 1.70 + 1.71 + /** The current left margin. 1.72 + */ 1.73 + int lmargin = 0; 1.74 + 1.75 + /** The enclosing class name. 1.76 + */ 1.77 + Name enclClassName; 1.78 + 1.79 + /** A table mapping trees to their documentation comments 1.80 + * (can be null) 1.81 + */ 1.82 + DocCommentTable docComments = null; 1.83 + 1.84 + /** 1.85 + * A string sequence to be used when Pretty output should be constrained 1.86 + * to fit into a given size 1.87 + */ 1.88 + private final static String trimSequence = "[...]"; 1.89 + 1.90 + /** 1.91 + * Max number of chars to be generated when output should fit into a single line 1.92 + */ 1.93 + private final static int PREFERRED_LENGTH = 20; 1.94 + 1.95 + /** Align code to be indented to left margin. 1.96 + */ 1.97 + void align() throws IOException { 1.98 + for (int i = 0; i < lmargin; i++) out.write(" "); 1.99 + } 1.100 + 1.101 + /** Increase left margin by indentation width. 1.102 + */ 1.103 + void indent() { 1.104 + lmargin = lmargin + width; 1.105 + } 1.106 + 1.107 + /** Decrease left margin by indentation width. 1.108 + */ 1.109 + void undent() { 1.110 + lmargin = lmargin - width; 1.111 + } 1.112 + 1.113 + /** Enter a new precedence level. Emit a `(' if new precedence level 1.114 + * is less than precedence level so far. 1.115 + * @param contextPrec The precedence level in force so far. 1.116 + * @param ownPrec The new precedence level. 1.117 + */ 1.118 + void open(int contextPrec, int ownPrec) throws IOException { 1.119 + if (ownPrec < contextPrec) out.write("("); 1.120 + } 1.121 + 1.122 + /** Leave precedence level. Emit a `(' if inner precedence level 1.123 + * is less than precedence level we revert to. 1.124 + * @param contextPrec The precedence level we revert to. 1.125 + * @param ownPrec The inner precedence level. 1.126 + */ 1.127 + void close(int contextPrec, int ownPrec) throws IOException { 1.128 + if (ownPrec < contextPrec) out.write(")"); 1.129 + } 1.130 + 1.131 + /** Print string, replacing all non-ascii character with unicode escapes. 1.132 + */ 1.133 + public void print(Object s) throws IOException { 1.134 + out.write(Convert.escapeUnicode(s.toString())); 1.135 + } 1.136 + 1.137 + /** Print new line. 1.138 + */ 1.139 + public void println() throws IOException { 1.140 + out.write(lineSep); 1.141 + } 1.142 + 1.143 + public static String toSimpleString(JCTree tree) { 1.144 + return toSimpleString(tree, PREFERRED_LENGTH); 1.145 + } 1.146 + 1.147 + public static String toSimpleString(JCTree tree, int maxLength) { 1.148 + StringWriter s = new StringWriter(); 1.149 + try { 1.150 + new Pretty(s, false).printExpr(tree); 1.151 + } 1.152 + catch (IOException e) { 1.153 + // should never happen, because StringWriter is defined 1.154 + // never to throw any IOExceptions 1.155 + throw new AssertionError(e); 1.156 + } 1.157 + //we need to (i) replace all line terminators with a space and (ii) remove 1.158 + //occurrences of 'missing' in the Pretty output (generated when types are missing) 1.159 + String res = s.toString().trim().replaceAll("\\s+", " ").replaceAll("/\\*missing\\*/", ""); 1.160 + if (res.length() < maxLength) { 1.161 + return res; 1.162 + } else { 1.163 + int head = (maxLength - trimSequence.length()) * 2 / 3; 1.164 + int tail = maxLength - trimSequence.length() - head; 1.165 + return res.substring(0, head) + trimSequence + res.substring(res.length() - tail); 1.166 + } 1.167 + } 1.168 + 1.169 + String lineSep = System.getProperty("line.separator"); 1.170 + 1.171 + /************************************************************************** 1.172 + * Traversal methods 1.173 + *************************************************************************/ 1.174 + 1.175 + /** Exception to propogate IOException through visitXXX methods */ 1.176 + private static class UncheckedIOException extends Error { 1.177 + static final long serialVersionUID = -4032692679158424751L; 1.178 + UncheckedIOException(IOException e) { 1.179 + super(e.getMessage(), e); 1.180 + } 1.181 + } 1.182 + 1.183 + /** Visitor argument: the current precedence level. 1.184 + */ 1.185 + int prec; 1.186 + 1.187 + /** Visitor method: print expression tree. 1.188 + * @param prec The current precedence level. 1.189 + */ 1.190 + public void printExpr(JCTree tree, int prec) throws IOException { 1.191 + int prevPrec = this.prec; 1.192 + try { 1.193 + this.prec = prec; 1.194 + if (tree == null) print("/*missing*/"); 1.195 + else { 1.196 + tree.accept(this); 1.197 + } 1.198 + } catch (UncheckedIOException ex) { 1.199 + IOException e = new IOException(ex.getMessage()); 1.200 + e.initCause(ex); 1.201 + throw e; 1.202 + } finally { 1.203 + this.prec = prevPrec; 1.204 + } 1.205 + } 1.206 + 1.207 + /** Derived visitor method: print expression tree at minimum precedence level 1.208 + * for expression. 1.209 + */ 1.210 + public void printExpr(JCTree tree) throws IOException { 1.211 + printExpr(tree, TreeInfo.noPrec); 1.212 + } 1.213 + 1.214 + /** Derived visitor method: print statement tree. 1.215 + */ 1.216 + public void printStat(JCTree tree) throws IOException { 1.217 + printExpr(tree, TreeInfo.notExpression); 1.218 + } 1.219 + 1.220 + /** Derived visitor method: print list of expression trees, separated by given string. 1.221 + * @param sep the separator string 1.222 + */ 1.223 + public <T extends JCTree> void printExprs(List<T> trees, String sep) throws IOException { 1.224 + if (trees.nonEmpty()) { 1.225 + printExpr(trees.head); 1.226 + for (List<T> l = trees.tail; l.nonEmpty(); l = l.tail) { 1.227 + print(sep); 1.228 + printExpr(l.head); 1.229 + } 1.230 + } 1.231 + } 1.232 + 1.233 + /** Derived visitor method: print list of expression trees, separated by commas. 1.234 + */ 1.235 + public <T extends JCTree> void printExprs(List<T> trees) throws IOException { 1.236 + printExprs(trees, ", "); 1.237 + } 1.238 + 1.239 + /** Derived visitor method: print list of statements, each on a separate line. 1.240 + */ 1.241 + public void printStats(List<? extends JCTree> trees) throws IOException { 1.242 + for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail) { 1.243 + align(); 1.244 + printStat(l.head); 1.245 + println(); 1.246 + } 1.247 + } 1.248 + 1.249 + /** Print a set of modifiers. 1.250 + */ 1.251 + public void printFlags(long flags) throws IOException { 1.252 + if ((flags & SYNTHETIC) != 0) print("/*synthetic*/ "); 1.253 + print(TreeInfo.flagNames(flags)); 1.254 + if ((flags & ExtendedStandardFlags) != 0) print(" "); 1.255 + if ((flags & ANNOTATION) != 0) print("@"); 1.256 + } 1.257 + 1.258 + public void printAnnotations(List<JCAnnotation> trees) throws IOException { 1.259 + for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) { 1.260 + printStat(l.head); 1.261 + println(); 1.262 + align(); 1.263 + } 1.264 + } 1.265 + 1.266 + public void printTypeAnnotations(List<JCAnnotation> trees) throws IOException { 1.267 + for (List<JCAnnotation> l = trees; l.nonEmpty(); l = l.tail) { 1.268 + printExpr(l.head); 1.269 + print(" "); 1.270 + } 1.271 + } 1.272 + 1.273 + /** Print documentation comment, if it exists 1.274 + * @param tree The tree for which a documentation comment should be printed. 1.275 + */ 1.276 + public void printDocComment(JCTree tree) throws IOException { 1.277 + if (docComments != null) { 1.278 + String dc = docComments.getCommentText(tree); 1.279 + if (dc != null) { 1.280 + print("/**"); println(); 1.281 + int pos = 0; 1.282 + int endpos = lineEndPos(dc, pos); 1.283 + while (pos < dc.length()) { 1.284 + align(); 1.285 + print(" *"); 1.286 + if (pos < dc.length() && dc.charAt(pos) > ' ') print(" "); 1.287 + print(dc.substring(pos, endpos)); println(); 1.288 + pos = endpos + 1; 1.289 + endpos = lineEndPos(dc, pos); 1.290 + } 1.291 + align(); print(" */"); println(); 1.292 + align(); 1.293 + } 1.294 + } 1.295 + } 1.296 +//where 1.297 + static int lineEndPos(String s, int start) { 1.298 + int pos = s.indexOf('\n', start); 1.299 + if (pos < 0) pos = s.length(); 1.300 + return pos; 1.301 + } 1.302 + 1.303 + /** If type parameter list is non-empty, print it enclosed in 1.304 + * {@literal "<...>"} brackets. 1.305 + */ 1.306 + public void printTypeParameters(List<JCTypeParameter> trees) throws IOException { 1.307 + if (trees.nonEmpty()) { 1.308 + print("<"); 1.309 + printExprs(trees); 1.310 + print(">"); 1.311 + } 1.312 + } 1.313 + 1.314 + /** Print a block. 1.315 + */ 1.316 + public void printBlock(List<? extends JCTree> stats) throws IOException { 1.317 + print("{"); 1.318 + println(); 1.319 + indent(); 1.320 + printStats(stats); 1.321 + undent(); 1.322 + align(); 1.323 + print("}"); 1.324 + } 1.325 + 1.326 + /** Print a block. 1.327 + */ 1.328 + public void printEnumBody(List<JCTree> stats) throws IOException { 1.329 + print("{"); 1.330 + println(); 1.331 + indent(); 1.332 + boolean first = true; 1.333 + for (List<JCTree> l = stats; l.nonEmpty(); l = l.tail) { 1.334 + if (isEnumerator(l.head)) { 1.335 + if (!first) { 1.336 + print(","); 1.337 + println(); 1.338 + } 1.339 + align(); 1.340 + printStat(l.head); 1.341 + first = false; 1.342 + } 1.343 + } 1.344 + print(";"); 1.345 + println(); 1.346 + for (List<JCTree> l = stats; l.nonEmpty(); l = l.tail) { 1.347 + if (!isEnumerator(l.head)) { 1.348 + align(); 1.349 + printStat(l.head); 1.350 + println(); 1.351 + } 1.352 + } 1.353 + undent(); 1.354 + align(); 1.355 + print("}"); 1.356 + } 1.357 + 1.358 + /** Is the given tree an enumerator definition? */ 1.359 + boolean isEnumerator(JCTree t) { 1.360 + return t.hasTag(VARDEF) && (((JCVariableDecl) t).mods.flags & ENUM) != 0; 1.361 + } 1.362 + 1.363 + /** Print unit consisting of package clause and import statements in toplevel, 1.364 + * followed by class definition. if class definition == null, 1.365 + * print all definitions in toplevel. 1.366 + * @param tree The toplevel tree 1.367 + * @param cdef The class definition, which is assumed to be part of the 1.368 + * toplevel tree. 1.369 + */ 1.370 + public void printUnit(JCCompilationUnit tree, JCClassDecl cdef) throws IOException { 1.371 + docComments = tree.docComments; 1.372 + printDocComment(tree); 1.373 + if (tree.pid != null) { 1.374 + print("package "); 1.375 + printExpr(tree.pid); 1.376 + print(";"); 1.377 + println(); 1.378 + } 1.379 + boolean firstImport = true; 1.380 + for (List<JCTree> l = tree.defs; 1.381 + l.nonEmpty() && (cdef == null || l.head.hasTag(IMPORT)); 1.382 + l = l.tail) { 1.383 + if (l.head.hasTag(IMPORT)) { 1.384 + JCImport imp = (JCImport)l.head; 1.385 + Name name = TreeInfo.name(imp.qualid); 1.386 + if (name == name.table.names.asterisk || 1.387 + cdef == null || 1.388 + isUsed(TreeInfo.symbol(imp.qualid), cdef)) { 1.389 + if (firstImport) { 1.390 + firstImport = false; 1.391 + println(); 1.392 + } 1.393 + printStat(imp); 1.394 + } 1.395 + } else { 1.396 + printStat(l.head); 1.397 + } 1.398 + } 1.399 + if (cdef != null) { 1.400 + printStat(cdef); 1.401 + println(); 1.402 + } 1.403 + } 1.404 + // where 1.405 + boolean isUsed(final Symbol t, JCTree cdef) { 1.406 + class UsedVisitor extends TreeScanner { 1.407 + public void scan(JCTree tree) { 1.408 + if (tree!=null && !result) tree.accept(this); 1.409 + } 1.410 + boolean result = false; 1.411 + public void visitIdent(JCIdent tree) { 1.412 + if (tree.sym == t) result = true; 1.413 + } 1.414 + } 1.415 + UsedVisitor v = new UsedVisitor(); 1.416 + v.scan(cdef); 1.417 + return v.result; 1.418 + } 1.419 + 1.420 + /************************************************************************** 1.421 + * Visitor methods 1.422 + *************************************************************************/ 1.423 + 1.424 + public void visitTopLevel(JCCompilationUnit tree) { 1.425 + try { 1.426 + printUnit(tree, null); 1.427 + } catch (IOException e) { 1.428 + throw new UncheckedIOException(e); 1.429 + } 1.430 + } 1.431 + 1.432 + public void visitImport(JCImport tree) { 1.433 + try { 1.434 + print("import "); 1.435 + if (tree.staticImport) print("static "); 1.436 + printExpr(tree.qualid); 1.437 + print(";"); 1.438 + println(); 1.439 + } catch (IOException e) { 1.440 + throw new UncheckedIOException(e); 1.441 + } 1.442 + } 1.443 + 1.444 + public void visitClassDef(JCClassDecl tree) { 1.445 + try { 1.446 + println(); align(); 1.447 + printDocComment(tree); 1.448 + printAnnotations(tree.mods.annotations); 1.449 + printFlags(tree.mods.flags & ~INTERFACE); 1.450 + Name enclClassNamePrev = enclClassName; 1.451 + enclClassName = tree.name; 1.452 + if ((tree.mods.flags & INTERFACE) != 0) { 1.453 + print("interface " + tree.name); 1.454 + printTypeParameters(tree.typarams); 1.455 + if (tree.implementing.nonEmpty()) { 1.456 + print(" extends "); 1.457 + printExprs(tree.implementing); 1.458 + } 1.459 + } else { 1.460 + if ((tree.mods.flags & ENUM) != 0) 1.461 + print("enum " + tree.name); 1.462 + else 1.463 + print("class " + tree.name); 1.464 + printTypeParameters(tree.typarams); 1.465 + if (tree.extending != null) { 1.466 + print(" extends "); 1.467 + printExpr(tree.extending); 1.468 + } 1.469 + if (tree.implementing.nonEmpty()) { 1.470 + print(" implements "); 1.471 + printExprs(tree.implementing); 1.472 + } 1.473 + } 1.474 + print(" "); 1.475 + if ((tree.mods.flags & ENUM) != 0) { 1.476 + printEnumBody(tree.defs); 1.477 + } else { 1.478 + printBlock(tree.defs); 1.479 + } 1.480 + enclClassName = enclClassNamePrev; 1.481 + } catch (IOException e) { 1.482 + throw new UncheckedIOException(e); 1.483 + } 1.484 + } 1.485 + 1.486 + public void visitMethodDef(JCMethodDecl tree) { 1.487 + try { 1.488 + // when producing source output, omit anonymous constructors 1.489 + if (tree.name == tree.name.table.names.init && 1.490 + enclClassName == null && 1.491 + sourceOutput) return; 1.492 + println(); align(); 1.493 + printDocComment(tree); 1.494 + printExpr(tree.mods); 1.495 + printTypeParameters(tree.typarams); 1.496 + if (tree.name == tree.name.table.names.init) { 1.497 + print(enclClassName != null ? enclClassName : tree.name); 1.498 + } else { 1.499 + printExpr(tree.restype); 1.500 + print(" " + tree.name); 1.501 + } 1.502 + print("("); 1.503 + if (tree.recvparam!=null) { 1.504 + printExpr(tree.recvparam); 1.505 + if (tree.params.size() > 0) { 1.506 + print(", "); 1.507 + } 1.508 + } 1.509 + printExprs(tree.params); 1.510 + print(")"); 1.511 + if (tree.thrown.nonEmpty()) { 1.512 + print(" throws "); 1.513 + printExprs(tree.thrown); 1.514 + } 1.515 + if (tree.defaultValue != null) { 1.516 + print(" default "); 1.517 + printExpr(tree.defaultValue); 1.518 + } 1.519 + if (tree.body != null) { 1.520 + print(" "); 1.521 + printStat(tree.body); 1.522 + } else { 1.523 + print(";"); 1.524 + } 1.525 + } catch (IOException e) { 1.526 + throw new UncheckedIOException(e); 1.527 + } 1.528 + } 1.529 + 1.530 + public void visitVarDef(JCVariableDecl tree) { 1.531 + try { 1.532 + if (docComments != null && docComments.hasComment(tree)) { 1.533 + println(); align(); 1.534 + } 1.535 + printDocComment(tree); 1.536 + if ((tree.mods.flags & ENUM) != 0) { 1.537 + print("/*public static final*/ "); 1.538 + print(tree.name); 1.539 + if (tree.init != null) { 1.540 + if (sourceOutput && tree.init.hasTag(NEWCLASS)) { 1.541 + print(" /*enum*/ "); 1.542 + JCNewClass init = (JCNewClass) tree.init; 1.543 + if (init.args != null && init.args.nonEmpty()) { 1.544 + print("("); 1.545 + print(init.args); 1.546 + print(")"); 1.547 + } 1.548 + if (init.def != null && init.def.defs != null) { 1.549 + print(" "); 1.550 + printBlock(init.def.defs); 1.551 + } 1.552 + return; 1.553 + } 1.554 + print(" /* = "); 1.555 + printExpr(tree.init); 1.556 + print(" */"); 1.557 + } 1.558 + } else { 1.559 + printExpr(tree.mods); 1.560 + if ((tree.mods.flags & VARARGS) != 0) { 1.561 + JCTree vartype = tree.vartype; 1.562 + List<JCAnnotation> tas = null; 1.563 + if (vartype instanceof JCAnnotatedType) { 1.564 + tas = ((JCAnnotatedType)vartype).annotations; 1.565 + vartype = ((JCAnnotatedType)vartype).underlyingType; 1.566 + } 1.567 + printExpr(((JCArrayTypeTree) vartype).elemtype); 1.568 + if (tas != null) { 1.569 + print(' '); 1.570 + printTypeAnnotations(tas); 1.571 + } 1.572 + print("... " + tree.name); 1.573 + } else { 1.574 + printExpr(tree.vartype); 1.575 + print(" " + tree.name); 1.576 + } 1.577 + if (tree.init != null) { 1.578 + print(" = "); 1.579 + printExpr(tree.init); 1.580 + } 1.581 + if (prec == TreeInfo.notExpression) print(";"); 1.582 + } 1.583 + } catch (IOException e) { 1.584 + throw new UncheckedIOException(e); 1.585 + } 1.586 + } 1.587 + 1.588 + public void visitSkip(JCSkip tree) { 1.589 + try { 1.590 + print(";"); 1.591 + } catch (IOException e) { 1.592 + throw new UncheckedIOException(e); 1.593 + } 1.594 + } 1.595 + 1.596 + public void visitBlock(JCBlock tree) { 1.597 + try { 1.598 + printFlags(tree.flags); 1.599 + printBlock(tree.stats); 1.600 + } catch (IOException e) { 1.601 + throw new UncheckedIOException(e); 1.602 + } 1.603 + } 1.604 + 1.605 + public void visitDoLoop(JCDoWhileLoop tree) { 1.606 + try { 1.607 + print("do "); 1.608 + printStat(tree.body); 1.609 + align(); 1.610 + print(" while "); 1.611 + if (tree.cond.hasTag(PARENS)) { 1.612 + printExpr(tree.cond); 1.613 + } else { 1.614 + print("("); 1.615 + printExpr(tree.cond); 1.616 + print(")"); 1.617 + } 1.618 + print(";"); 1.619 + } catch (IOException e) { 1.620 + throw new UncheckedIOException(e); 1.621 + } 1.622 + } 1.623 + 1.624 + public void visitWhileLoop(JCWhileLoop tree) { 1.625 + try { 1.626 + print("while "); 1.627 + if (tree.cond.hasTag(PARENS)) { 1.628 + printExpr(tree.cond); 1.629 + } else { 1.630 + print("("); 1.631 + printExpr(tree.cond); 1.632 + print(")"); 1.633 + } 1.634 + print(" "); 1.635 + printStat(tree.body); 1.636 + } catch (IOException e) { 1.637 + throw new UncheckedIOException(e); 1.638 + } 1.639 + } 1.640 + 1.641 + public void visitForLoop(JCForLoop tree) { 1.642 + try { 1.643 + print("for ("); 1.644 + if (tree.init.nonEmpty()) { 1.645 + if (tree.init.head.hasTag(VARDEF)) { 1.646 + printExpr(tree.init.head); 1.647 + for (List<JCStatement> l = tree.init.tail; l.nonEmpty(); l = l.tail) { 1.648 + JCVariableDecl vdef = (JCVariableDecl)l.head; 1.649 + print(", " + vdef.name + " = "); 1.650 + printExpr(vdef.init); 1.651 + } 1.652 + } else { 1.653 + printExprs(tree.init); 1.654 + } 1.655 + } 1.656 + print("; "); 1.657 + if (tree.cond != null) printExpr(tree.cond); 1.658 + print("; "); 1.659 + printExprs(tree.step); 1.660 + print(") "); 1.661 + printStat(tree.body); 1.662 + } catch (IOException e) { 1.663 + throw new UncheckedIOException(e); 1.664 + } 1.665 + } 1.666 + 1.667 + public void visitForeachLoop(JCEnhancedForLoop tree) { 1.668 + try { 1.669 + print("for ("); 1.670 + printExpr(tree.var); 1.671 + print(" : "); 1.672 + printExpr(tree.expr); 1.673 + print(") "); 1.674 + printStat(tree.body); 1.675 + } catch (IOException e) { 1.676 + throw new UncheckedIOException(e); 1.677 + } 1.678 + } 1.679 + 1.680 + public void visitLabelled(JCLabeledStatement tree) { 1.681 + try { 1.682 + print(tree.label + ": "); 1.683 + printStat(tree.body); 1.684 + } catch (IOException e) { 1.685 + throw new UncheckedIOException(e); 1.686 + } 1.687 + } 1.688 + 1.689 + public void visitSwitch(JCSwitch tree) { 1.690 + try { 1.691 + print("switch "); 1.692 + if (tree.selector.hasTag(PARENS)) { 1.693 + printExpr(tree.selector); 1.694 + } else { 1.695 + print("("); 1.696 + printExpr(tree.selector); 1.697 + print(")"); 1.698 + } 1.699 + print(" {"); 1.700 + println(); 1.701 + printStats(tree.cases); 1.702 + align(); 1.703 + print("}"); 1.704 + } catch (IOException e) { 1.705 + throw new UncheckedIOException(e); 1.706 + } 1.707 + } 1.708 + 1.709 + public void visitCase(JCCase tree) { 1.710 + try { 1.711 + if (tree.pat == null) { 1.712 + print("default"); 1.713 + } else { 1.714 + print("case "); 1.715 + printExpr(tree.pat); 1.716 + } 1.717 + print(": "); 1.718 + println(); 1.719 + indent(); 1.720 + printStats(tree.stats); 1.721 + undent(); 1.722 + align(); 1.723 + } catch (IOException e) { 1.724 + throw new UncheckedIOException(e); 1.725 + } 1.726 + } 1.727 + 1.728 + public void visitSynchronized(JCSynchronized tree) { 1.729 + try { 1.730 + print("synchronized "); 1.731 + if (tree.lock.hasTag(PARENS)) { 1.732 + printExpr(tree.lock); 1.733 + } else { 1.734 + print("("); 1.735 + printExpr(tree.lock); 1.736 + print(")"); 1.737 + } 1.738 + print(" "); 1.739 + printStat(tree.body); 1.740 + } catch (IOException e) { 1.741 + throw new UncheckedIOException(e); 1.742 + } 1.743 + } 1.744 + 1.745 + public void visitTry(JCTry tree) { 1.746 + try { 1.747 + print("try "); 1.748 + if (tree.resources.nonEmpty()) { 1.749 + print("("); 1.750 + boolean first = true; 1.751 + for (JCTree var : tree.resources) { 1.752 + if (!first) { 1.753 + println(); 1.754 + indent(); 1.755 + } 1.756 + printStat(var); 1.757 + first = false; 1.758 + } 1.759 + print(") "); 1.760 + } 1.761 + printStat(tree.body); 1.762 + for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { 1.763 + printStat(l.head); 1.764 + } 1.765 + if (tree.finalizer != null) { 1.766 + print(" finally "); 1.767 + printStat(tree.finalizer); 1.768 + } 1.769 + } catch (IOException e) { 1.770 + throw new UncheckedIOException(e); 1.771 + } 1.772 + } 1.773 + 1.774 + public void visitCatch(JCCatch tree) { 1.775 + try { 1.776 + print(" catch ("); 1.777 + printExpr(tree.param); 1.778 + print(") "); 1.779 + printStat(tree.body); 1.780 + } catch (IOException e) { 1.781 + throw new UncheckedIOException(e); 1.782 + } 1.783 + } 1.784 + 1.785 + public void visitConditional(JCConditional tree) { 1.786 + try { 1.787 + open(prec, TreeInfo.condPrec); 1.788 + printExpr(tree.cond, TreeInfo.condPrec + 1); 1.789 + print(" ? "); 1.790 + printExpr(tree.truepart); 1.791 + print(" : "); 1.792 + printExpr(tree.falsepart, TreeInfo.condPrec); 1.793 + close(prec, TreeInfo.condPrec); 1.794 + } catch (IOException e) { 1.795 + throw new UncheckedIOException(e); 1.796 + } 1.797 + } 1.798 + 1.799 + public void visitIf(JCIf tree) { 1.800 + try { 1.801 + print("if "); 1.802 + if (tree.cond.hasTag(PARENS)) { 1.803 + printExpr(tree.cond); 1.804 + } else { 1.805 + print("("); 1.806 + printExpr(tree.cond); 1.807 + print(")"); 1.808 + } 1.809 + print(" "); 1.810 + printStat(tree.thenpart); 1.811 + if (tree.elsepart != null) { 1.812 + print(" else "); 1.813 + printStat(tree.elsepart); 1.814 + } 1.815 + } catch (IOException e) { 1.816 + throw new UncheckedIOException(e); 1.817 + } 1.818 + } 1.819 + 1.820 + public void visitExec(JCExpressionStatement tree) { 1.821 + try { 1.822 + printExpr(tree.expr); 1.823 + if (prec == TreeInfo.notExpression) print(";"); 1.824 + } catch (IOException e) { 1.825 + throw new UncheckedIOException(e); 1.826 + } 1.827 + } 1.828 + 1.829 + public void visitBreak(JCBreak tree) { 1.830 + try { 1.831 + print("break"); 1.832 + if (tree.label != null) print(" " + tree.label); 1.833 + print(";"); 1.834 + } catch (IOException e) { 1.835 + throw new UncheckedIOException(e); 1.836 + } 1.837 + } 1.838 + 1.839 + public void visitContinue(JCContinue tree) { 1.840 + try { 1.841 + print("continue"); 1.842 + if (tree.label != null) print(" " + tree.label); 1.843 + print(";"); 1.844 + } catch (IOException e) { 1.845 + throw new UncheckedIOException(e); 1.846 + } 1.847 + } 1.848 + 1.849 + public void visitReturn(JCReturn tree) { 1.850 + try { 1.851 + print("return"); 1.852 + if (tree.expr != null) { 1.853 + print(" "); 1.854 + printExpr(tree.expr); 1.855 + } 1.856 + print(";"); 1.857 + } catch (IOException e) { 1.858 + throw new UncheckedIOException(e); 1.859 + } 1.860 + } 1.861 + 1.862 + public void visitThrow(JCThrow tree) { 1.863 + try { 1.864 + print("throw "); 1.865 + printExpr(tree.expr); 1.866 + print(";"); 1.867 + } catch (IOException e) { 1.868 + throw new UncheckedIOException(e); 1.869 + } 1.870 + } 1.871 + 1.872 + public void visitAssert(JCAssert tree) { 1.873 + try { 1.874 + print("assert "); 1.875 + printExpr(tree.cond); 1.876 + if (tree.detail != null) { 1.877 + print(" : "); 1.878 + printExpr(tree.detail); 1.879 + } 1.880 + print(";"); 1.881 + } catch (IOException e) { 1.882 + throw new UncheckedIOException(e); 1.883 + } 1.884 + } 1.885 + 1.886 + public void visitApply(JCMethodInvocation tree) { 1.887 + try { 1.888 + if (!tree.typeargs.isEmpty()) { 1.889 + if (tree.meth.hasTag(SELECT)) { 1.890 + JCFieldAccess left = (JCFieldAccess)tree.meth; 1.891 + printExpr(left.selected); 1.892 + print(".<"); 1.893 + printExprs(tree.typeargs); 1.894 + print(">" + left.name); 1.895 + } else { 1.896 + print("<"); 1.897 + printExprs(tree.typeargs); 1.898 + print(">"); 1.899 + printExpr(tree.meth); 1.900 + } 1.901 + } else { 1.902 + printExpr(tree.meth); 1.903 + } 1.904 + print("("); 1.905 + printExprs(tree.args); 1.906 + print(")"); 1.907 + } catch (IOException e) { 1.908 + throw new UncheckedIOException(e); 1.909 + } 1.910 + } 1.911 + 1.912 + public void visitNewClass(JCNewClass tree) { 1.913 + try { 1.914 + if (tree.encl != null) { 1.915 + printExpr(tree.encl); 1.916 + print("."); 1.917 + } 1.918 + print("new "); 1.919 + if (!tree.typeargs.isEmpty()) { 1.920 + print("<"); 1.921 + printExprs(tree.typeargs); 1.922 + print(">"); 1.923 + } 1.924 + if (tree.def != null && tree.def.mods.annotations.nonEmpty()) { 1.925 + printTypeAnnotations(tree.def.mods.annotations); 1.926 + } 1.927 + printExpr(tree.clazz); 1.928 + print("("); 1.929 + printExprs(tree.args); 1.930 + print(")"); 1.931 + if (tree.def != null) { 1.932 + Name enclClassNamePrev = enclClassName; 1.933 + enclClassName = 1.934 + tree.def.name != null ? tree.def.name : 1.935 + tree.type != null && tree.type.tsym.name != tree.type.tsym.name.table.names.empty 1.936 + ? tree.type.tsym.name : null; 1.937 + if ((tree.def.mods.flags & Flags.ENUM) != 0) print("/*enum*/"); 1.938 + printBlock(tree.def.defs); 1.939 + enclClassName = enclClassNamePrev; 1.940 + } 1.941 + } catch (IOException e) { 1.942 + throw new UncheckedIOException(e); 1.943 + } 1.944 + } 1.945 + 1.946 + public void visitNewArray(JCNewArray tree) { 1.947 + try { 1.948 + if (tree.elemtype != null) { 1.949 + print("new "); 1.950 + JCTree elem = tree.elemtype; 1.951 + printBaseElementType(elem); 1.952 + 1.953 + if (!tree.annotations.isEmpty()) { 1.954 + print(' '); 1.955 + printTypeAnnotations(tree.annotations); 1.956 + } 1.957 + if (tree.elems != null) { 1.958 + print("[]"); 1.959 + } 1.960 + 1.961 + int i = 0; 1.962 + List<List<JCAnnotation>> da = tree.dimAnnotations; 1.963 + for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) { 1.964 + if (da.size() > i && !da.get(i).isEmpty()) { 1.965 + print(' '); 1.966 + printTypeAnnotations(da.get(i)); 1.967 + } 1.968 + print("["); 1.969 + i++; 1.970 + printExpr(l.head); 1.971 + print("]"); 1.972 + } 1.973 + printBrackets(elem); 1.974 + } 1.975 + if (tree.elems != null) { 1.976 + print("{"); 1.977 + printExprs(tree.elems); 1.978 + print("}"); 1.979 + } 1.980 + } catch (IOException e) { 1.981 + throw new UncheckedIOException(e); 1.982 + } 1.983 + } 1.984 + 1.985 + public void visitLambda(JCLambda tree) { 1.986 + try { 1.987 + print("("); 1.988 + if (tree.paramKind == JCLambda.ParameterKind.EXPLICIT) { 1.989 + printExprs(tree.params); 1.990 + } else { 1.991 + String sep = ""; 1.992 + for (JCVariableDecl param : tree.params) { 1.993 + print(sep); 1.994 + print(param.name); 1.995 + sep = ","; 1.996 + } 1.997 + } 1.998 + print(")->"); 1.999 + printExpr(tree.body); 1.1000 + } catch (IOException e) { 1.1001 + throw new UncheckedIOException(e); 1.1002 + } 1.1003 + } 1.1004 + 1.1005 + public void visitParens(JCParens tree) { 1.1006 + try { 1.1007 + print("("); 1.1008 + printExpr(tree.expr); 1.1009 + print(")"); 1.1010 + } catch (IOException e) { 1.1011 + throw new UncheckedIOException(e); 1.1012 + } 1.1013 + } 1.1014 + 1.1015 + public void visitAssign(JCAssign tree) { 1.1016 + try { 1.1017 + open(prec, TreeInfo.assignPrec); 1.1018 + printExpr(tree.lhs, TreeInfo.assignPrec + 1); 1.1019 + print(" = "); 1.1020 + printExpr(tree.rhs, TreeInfo.assignPrec); 1.1021 + close(prec, TreeInfo.assignPrec); 1.1022 + } catch (IOException e) { 1.1023 + throw new UncheckedIOException(e); 1.1024 + } 1.1025 + } 1.1026 + 1.1027 + public String operatorName(JCTree.Tag tag) { 1.1028 + switch(tag) { 1.1029 + case POS: return "+"; 1.1030 + case NEG: return "-"; 1.1031 + case NOT: return "!"; 1.1032 + case COMPL: return "~"; 1.1033 + case PREINC: return "++"; 1.1034 + case PREDEC: return "--"; 1.1035 + case POSTINC: return "++"; 1.1036 + case POSTDEC: return "--"; 1.1037 + case NULLCHK: return "<*nullchk*>"; 1.1038 + case OR: return "||"; 1.1039 + case AND: return "&&"; 1.1040 + case EQ: return "=="; 1.1041 + case NE: return "!="; 1.1042 + case LT: return "<"; 1.1043 + case GT: return ">"; 1.1044 + case LE: return "<="; 1.1045 + case GE: return ">="; 1.1046 + case BITOR: return "|"; 1.1047 + case BITXOR: return "^"; 1.1048 + case BITAND: return "&"; 1.1049 + case SL: return "<<"; 1.1050 + case SR: return ">>"; 1.1051 + case USR: return ">>>"; 1.1052 + case PLUS: return "+"; 1.1053 + case MINUS: return "-"; 1.1054 + case MUL: return "*"; 1.1055 + case DIV: return "/"; 1.1056 + case MOD: return "%"; 1.1057 + default: throw new Error(); 1.1058 + } 1.1059 + } 1.1060 + 1.1061 + public void visitAssignop(JCAssignOp tree) { 1.1062 + try { 1.1063 + open(prec, TreeInfo.assignopPrec); 1.1064 + printExpr(tree.lhs, TreeInfo.assignopPrec + 1); 1.1065 + print(" " + operatorName(tree.getTag().noAssignOp()) + "= "); 1.1066 + printExpr(tree.rhs, TreeInfo.assignopPrec); 1.1067 + close(prec, TreeInfo.assignopPrec); 1.1068 + } catch (IOException e) { 1.1069 + throw new UncheckedIOException(e); 1.1070 + } 1.1071 + } 1.1072 + 1.1073 + public void visitUnary(JCUnary tree) { 1.1074 + try { 1.1075 + int ownprec = TreeInfo.opPrec(tree.getTag()); 1.1076 + String opname = operatorName(tree.getTag()); 1.1077 + open(prec, ownprec); 1.1078 + if (!tree.getTag().isPostUnaryOp()) { 1.1079 + print(opname); 1.1080 + printExpr(tree.arg, ownprec); 1.1081 + } else { 1.1082 + printExpr(tree.arg, ownprec); 1.1083 + print(opname); 1.1084 + } 1.1085 + close(prec, ownprec); 1.1086 + } catch (IOException e) { 1.1087 + throw new UncheckedIOException(e); 1.1088 + } 1.1089 + } 1.1090 + 1.1091 + public void visitBinary(JCBinary tree) { 1.1092 + try { 1.1093 + int ownprec = TreeInfo.opPrec(tree.getTag()); 1.1094 + String opname = operatorName(tree.getTag()); 1.1095 + open(prec, ownprec); 1.1096 + printExpr(tree.lhs, ownprec); 1.1097 + print(" " + opname + " "); 1.1098 + printExpr(tree.rhs, ownprec + 1); 1.1099 + close(prec, ownprec); 1.1100 + } catch (IOException e) { 1.1101 + throw new UncheckedIOException(e); 1.1102 + } 1.1103 + } 1.1104 + 1.1105 + public void visitTypeCast(JCTypeCast tree) { 1.1106 + try { 1.1107 + open(prec, TreeInfo.prefixPrec); 1.1108 + print("("); 1.1109 + printExpr(tree.clazz); 1.1110 + print(")"); 1.1111 + printExpr(tree.expr, TreeInfo.prefixPrec); 1.1112 + close(prec, TreeInfo.prefixPrec); 1.1113 + } catch (IOException e) { 1.1114 + throw new UncheckedIOException(e); 1.1115 + } 1.1116 + } 1.1117 + 1.1118 + public void visitTypeTest(JCInstanceOf tree) { 1.1119 + try { 1.1120 + open(prec, TreeInfo.ordPrec); 1.1121 + printExpr(tree.expr, TreeInfo.ordPrec); 1.1122 + print(" instanceof "); 1.1123 + printExpr(tree.clazz, TreeInfo.ordPrec + 1); 1.1124 + close(prec, TreeInfo.ordPrec); 1.1125 + } catch (IOException e) { 1.1126 + throw new UncheckedIOException(e); 1.1127 + } 1.1128 + } 1.1129 + 1.1130 + public void visitIndexed(JCArrayAccess tree) { 1.1131 + try { 1.1132 + printExpr(tree.indexed, TreeInfo.postfixPrec); 1.1133 + print("["); 1.1134 + printExpr(tree.index); 1.1135 + print("]"); 1.1136 + } catch (IOException e) { 1.1137 + throw new UncheckedIOException(e); 1.1138 + } 1.1139 + } 1.1140 + 1.1141 + public void visitSelect(JCFieldAccess tree) { 1.1142 + try { 1.1143 + printExpr(tree.selected, TreeInfo.postfixPrec); 1.1144 + print("." + tree.name); 1.1145 + } catch (IOException e) { 1.1146 + throw new UncheckedIOException(e); 1.1147 + } 1.1148 + } 1.1149 + 1.1150 + public void visitReference(JCMemberReference tree) { 1.1151 + try { 1.1152 + printExpr(tree.expr); 1.1153 + print("::"); 1.1154 + if (tree.typeargs != null) { 1.1155 + print("<"); 1.1156 + printExprs(tree.typeargs); 1.1157 + print(">"); 1.1158 + } 1.1159 + print(tree.getMode() == ReferenceMode.INVOKE ? tree.name : "new"); 1.1160 + } catch (IOException e) { 1.1161 + throw new UncheckedIOException(e); 1.1162 + } 1.1163 + } 1.1164 + 1.1165 + public void visitIdent(JCIdent tree) { 1.1166 + try { 1.1167 + print(tree.name); 1.1168 + } catch (IOException e) { 1.1169 + throw new UncheckedIOException(e); 1.1170 + } 1.1171 + } 1.1172 + 1.1173 + public void visitLiteral(JCLiteral tree) { 1.1174 + try { 1.1175 + switch (tree.typetag) { 1.1176 + case INT: 1.1177 + print(tree.value.toString()); 1.1178 + break; 1.1179 + case LONG: 1.1180 + print(tree.value + "L"); 1.1181 + break; 1.1182 + case FLOAT: 1.1183 + print(tree.value + "F"); 1.1184 + break; 1.1185 + case DOUBLE: 1.1186 + print(tree.value.toString()); 1.1187 + break; 1.1188 + case CHAR: 1.1189 + print("\'" + 1.1190 + Convert.quote( 1.1191 + String.valueOf((char)((Number)tree.value).intValue())) + 1.1192 + "\'"); 1.1193 + break; 1.1194 + case BOOLEAN: 1.1195 + print(((Number)tree.value).intValue() == 1 ? "true" : "false"); 1.1196 + break; 1.1197 + case BOT: 1.1198 + print("null"); 1.1199 + break; 1.1200 + default: 1.1201 + print("\"" + Convert.quote(tree.value.toString()) + "\""); 1.1202 + break; 1.1203 + } 1.1204 + } catch (IOException e) { 1.1205 + throw new UncheckedIOException(e); 1.1206 + } 1.1207 + } 1.1208 + 1.1209 + public void visitTypeIdent(JCPrimitiveTypeTree tree) { 1.1210 + try { 1.1211 + switch(tree.typetag) { 1.1212 + case BYTE: 1.1213 + print("byte"); 1.1214 + break; 1.1215 + case CHAR: 1.1216 + print("char"); 1.1217 + break; 1.1218 + case SHORT: 1.1219 + print("short"); 1.1220 + break; 1.1221 + case INT: 1.1222 + print("int"); 1.1223 + break; 1.1224 + case LONG: 1.1225 + print("long"); 1.1226 + break; 1.1227 + case FLOAT: 1.1228 + print("float"); 1.1229 + break; 1.1230 + case DOUBLE: 1.1231 + print("double"); 1.1232 + break; 1.1233 + case BOOLEAN: 1.1234 + print("boolean"); 1.1235 + break; 1.1236 + case VOID: 1.1237 + print("void"); 1.1238 + break; 1.1239 + default: 1.1240 + print("error"); 1.1241 + break; 1.1242 + } 1.1243 + } catch (IOException e) { 1.1244 + throw new UncheckedIOException(e); 1.1245 + } 1.1246 + } 1.1247 + 1.1248 + public void visitTypeArray(JCArrayTypeTree tree) { 1.1249 + try { 1.1250 + printBaseElementType(tree); 1.1251 + printBrackets(tree); 1.1252 + } catch (IOException e) { 1.1253 + throw new UncheckedIOException(e); 1.1254 + } 1.1255 + } 1.1256 + 1.1257 + // Prints the inner element type of a nested array 1.1258 + private void printBaseElementType(JCTree tree) throws IOException { 1.1259 + printExpr(TreeInfo.innermostType(tree)); 1.1260 + } 1.1261 + 1.1262 + // prints the brackets of a nested array in reverse order 1.1263 + // tree is either JCArrayTypeTree or JCAnnotatedTypeTree 1.1264 + private void printBrackets(JCTree tree) throws IOException { 1.1265 + JCTree elem = tree; 1.1266 + while (true) { 1.1267 + if (elem.hasTag(ANNOTATED_TYPE)) { 1.1268 + JCAnnotatedType atype = (JCAnnotatedType) elem; 1.1269 + elem = atype.underlyingType; 1.1270 + if (elem.hasTag(TYPEARRAY)) { 1.1271 + print(' '); 1.1272 + printTypeAnnotations(atype.annotations); 1.1273 + } 1.1274 + } 1.1275 + if (elem.hasTag(TYPEARRAY)) { 1.1276 + print("[]"); 1.1277 + elem = ((JCArrayTypeTree)elem).elemtype; 1.1278 + } else { 1.1279 + break; 1.1280 + } 1.1281 + } 1.1282 + } 1.1283 + 1.1284 + public void visitTypeApply(JCTypeApply tree) { 1.1285 + try { 1.1286 + printExpr(tree.clazz); 1.1287 + print("<"); 1.1288 + printExprs(tree.arguments); 1.1289 + print(">"); 1.1290 + } catch (IOException e) { 1.1291 + throw new UncheckedIOException(e); 1.1292 + } 1.1293 + } 1.1294 + 1.1295 + public void visitTypeUnion(JCTypeUnion tree) { 1.1296 + try { 1.1297 + printExprs(tree.alternatives, " | "); 1.1298 + } catch (IOException e) { 1.1299 + throw new UncheckedIOException(e); 1.1300 + } 1.1301 + } 1.1302 + 1.1303 + public void visitTypeIntersection(JCTypeIntersection tree) { 1.1304 + try { 1.1305 + printExprs(tree.bounds, " & "); 1.1306 + } catch (IOException e) { 1.1307 + throw new UncheckedIOException(e); 1.1308 + } 1.1309 + } 1.1310 + 1.1311 + public void visitTypeParameter(JCTypeParameter tree) { 1.1312 + try { 1.1313 + if (tree.annotations.nonEmpty()) { 1.1314 + this.printTypeAnnotations(tree.annotations); 1.1315 + } 1.1316 + print(tree.name); 1.1317 + if (tree.bounds.nonEmpty()) { 1.1318 + print(" extends "); 1.1319 + printExprs(tree.bounds, " & "); 1.1320 + } 1.1321 + } catch (IOException e) { 1.1322 + throw new UncheckedIOException(e); 1.1323 + } 1.1324 + } 1.1325 + 1.1326 + @Override 1.1327 + public void visitWildcard(JCWildcard tree) { 1.1328 + try { 1.1329 + print(tree.kind); 1.1330 + if (tree.kind.kind != BoundKind.UNBOUND) 1.1331 + printExpr(tree.inner); 1.1332 + } catch (IOException e) { 1.1333 + throw new UncheckedIOException(e); 1.1334 + } 1.1335 + } 1.1336 + 1.1337 + @Override 1.1338 + public void visitTypeBoundKind(TypeBoundKind tree) { 1.1339 + try { 1.1340 + print(String.valueOf(tree.kind)); 1.1341 + } catch (IOException e) { 1.1342 + throw new UncheckedIOException(e); 1.1343 + } 1.1344 + } 1.1345 + 1.1346 + public void visitErroneous(JCErroneous tree) { 1.1347 + try { 1.1348 + print("(ERROR)"); 1.1349 + } catch (IOException e) { 1.1350 + throw new UncheckedIOException(e); 1.1351 + } 1.1352 + } 1.1353 + 1.1354 + public void visitLetExpr(LetExpr tree) { 1.1355 + try { 1.1356 + print("(let " + tree.defs + " in " + tree.expr + ")"); 1.1357 + } catch (IOException e) { 1.1358 + throw new UncheckedIOException(e); 1.1359 + } 1.1360 + } 1.1361 + 1.1362 + public void visitModifiers(JCModifiers mods) { 1.1363 + try { 1.1364 + printAnnotations(mods.annotations); 1.1365 + printFlags(mods.flags); 1.1366 + } catch (IOException e) { 1.1367 + throw new UncheckedIOException(e); 1.1368 + } 1.1369 + } 1.1370 + 1.1371 + public void visitAnnotation(JCAnnotation tree) { 1.1372 + try { 1.1373 + print("@"); 1.1374 + printExpr(tree.annotationType); 1.1375 + print("("); 1.1376 + printExprs(tree.args); 1.1377 + print(")"); 1.1378 + } catch (IOException e) { 1.1379 + throw new UncheckedIOException(e); 1.1380 + } 1.1381 + } 1.1382 + 1.1383 + public void visitAnnotatedType(JCAnnotatedType tree) { 1.1384 + try { 1.1385 + if (tree.underlyingType.hasTag(SELECT)) { 1.1386 + JCFieldAccess access = (JCFieldAccess) tree.underlyingType; 1.1387 + printExpr(access.selected, TreeInfo.postfixPrec); 1.1388 + print("."); 1.1389 + printTypeAnnotations(tree.annotations); 1.1390 + print(access.name); 1.1391 + } else if (tree.underlyingType.hasTag(TYPEARRAY)) { 1.1392 + printBaseElementType(tree); 1.1393 + printBrackets(tree); 1.1394 + } else { 1.1395 + printTypeAnnotations(tree.annotations); 1.1396 + printExpr(tree.underlyingType); 1.1397 + } 1.1398 + } catch (IOException e) { 1.1399 + throw new UncheckedIOException(e); 1.1400 + } 1.1401 + } 1.1402 + 1.1403 + public void visitTree(JCTree tree) { 1.1404 + try { 1.1405 + print("(UNKNOWN: " + tree + ")"); 1.1406 + println(); 1.1407 + } catch (IOException e) { 1.1408 + throw new UncheckedIOException(e); 1.1409 + } 1.1410 + } 1.1411 + 1.1412 +}