src/share/classes/com/sun/tools/javac/tree/Pretty.java

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

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

mercurial