1 19 package org.netbeans.modules.java.source.pretty; 20 21 import com.sun.source.tree.ClassTree; 22 import com.sun.source.tree.MethodTree; 23 import static com.sun.source.tree.Tree.*; 24 import com.sun.source.tree.VariableTree; 25 import org.netbeans.api.java.source.UiUtils; 26 import org.netbeans.modules.java.source.builder.CommentHandlerService; 27 import org.netbeans.api.java.source.Comment; 28 import org.netbeans.api.java.source.query.CommentHandler; 29 import org.netbeans.api.java.source.query.CommentSet; 30 import org.netbeans.api.java.source.query.Query; 31 32 import com.sun.tools.javac.util.*; 33 import com.sun.tools.javac.code.*; 34 import com.sun.tools.javac.code.Symbol.*; 35 import com.sun.tools.javac.tree.JCTree; 36 import com.sun.tools.javac.tree.JCTree.*; 37 import com.sun.tools.javac.tree.TreeInfo; 38 39 import java.io.*; 40 import java.util.Set ; 41 42 import static com.sun.tools.javac.code.Flags.*; 43 import static com.sun.tools.javac.code.TypeTags.*; 44 import org.netbeans.modules.java.source.engine.JavaFormatOptions; 45 46 48 public class VeryPretty extends JCTree.Visitor { 49 public JavaFormatOptions options; 50 private CharBuffer out; 51 boolean cuddleElse; 52 53 private final Name.Table names; 54 private CommentHandler commentHandler; 55 private final Symtab symbols; 56 private final Types types; 57 private final TreeInfo treeinfo; 58 private boolean packagePrinted; 59 private boolean importsPrinted; 60 61 private JCTree selection; 63 private int selectionPos; private int selectionEndPos; 66 public VeryPretty(Context context) { 67 this(context, JavaFormatOptions.getDefault()); 68 } 69 70 public VeryPretty(Context context, JavaFormatOptions options) { 71 this.options = options; 72 out = new CharBuffer(options.rightMargin); 73 cuddleElse = options.cuddleElse && !options.cuddleCloseBrace; 74 names = Name.Table.instance(context); 75 enclClassName = names.empty; 76 commentHandler = CommentHandlerService.instance(context); 77 symbols = Symtab.instance(context); 78 types = Types.instance(context); 79 treeinfo = TreeInfo.instance(context); 80 prec = TreeInfo.notExpression; 81 widthEstimator = new WidthEstimator(context); 82 selectionPos = Position.NOPOS; 83 selectionEndPos = Position.NOPOS; 84 } 85 86 88 public Name enclClassName; 89 90 public String toString() { 91 return out.toString(); 92 } 93 public void writeTo(Writer w) 94 throws IOException 95 { 96 out.writeTo(w); 97 } 98 protected void toLeftMargin() { 99 out.toLeftMargin(); 100 } 101 public void reset(int margin) { 102 out.setLength(0); 103 out.leftMargin = margin; 104 } 106 107 109 public int indent() { 110 int old = out.leftMargin; 111 out.leftMargin = old + options.indentSize; 112 return old; 113 } 114 public void undent(int old) { 115 out.leftMargin = old; 116 } 117 118 public void setPrec(int prec) { 119 this.prec = prec; 120 } 121 122 public void setSelection(JCTree tree) { 123 selection = tree; 124 } 125 public int getSelectionPos() { 126 return selectionPos; 127 } 128 public int getSelectionEndPos() { 129 return selectionEndPos; 130 } 131 132 137 void open(int contextPrec, int ownPrec) { 138 if (options.excessParensAroundConditionals 139 && (ownPrec==treeinfo.ordPrec || ownPrec==treeinfo.eqPrec) 140 && contextPrec>treeinfo.condPrec 141 || ownPrec < contextPrec) 142 print('('); 143 } 144 145 150 void close(int contextPrec, int ownPrec) { 151 if (options.excessParensAroundConditionals 153 && (ownPrec==treeinfo.ordPrec || ownPrec==treeinfo.eqPrec) 154 && contextPrec>treeinfo.condPrec 155 || ownPrec < contextPrec) 156 print(')'); 157 } 158 159 private static char[] hex = "0123456789ABCDEF".toCharArray(); 160 162 public void print(String s) { 163 if (s == null) 164 return; 165 int limit = s.length(); 166 for (int i = 0; i < limit; i++) { 167 char c = s.charAt(i); 168 if (c <= 255) 169 out.append(c); 170 else { 171 out.append("\\u"); 172 out.append(hex[(c >> (3 * 4)) & 0xF]); 173 out.append(hex[(c >> (2 * 4)) & 0xF]); 174 out.append(hex[(c >> (1 * 4)) & 0xF]); 175 out.append(hex[(c >> (0 * 4)) & 0xF]); 176 } 177 } 178 } 179 public final void print(char c) { 180 out.append(c); 181 } 182 public final void needSpace() { 183 out.needSpace(); 184 } 185 public final void print(Name n) { 186 out.appendUtf8(n.table.names, n.index, n.len); 187 } 188 189 public void printQualified(Symbol t) { 190 if (t.owner != null && t.owner.name.len > 0 191 && !(t.type instanceof Type.TypeVar) 192 && (imports == null || !imports.imported(t)) && !(t.owner instanceof MethodSymbol)) { 193 if (t.owner instanceof Symbol.PackageSymbol) 194 printAllQualified(t.owner); 195 else 196 printQualified(t.owner); 197 print('.'); 198 } 199 print(t.name); 200 } 201 public void printAllQualified(Symbol t) { 202 if (t.owner != null && t.owner.name.len > 0) { 203 printAllQualified(t.owner); 204 print('.'); 205 } 206 print(t.name); 207 } 208 public void printImports() { 209 printImports(true); 210 } 211 public void printImports(boolean printPackageStatement) { 212 if (imports == null) 213 return; 214 imports.decideImports(); 215 int nout = 0; 216 if (printPackageStatement && imports.containingPackage != null && 217 imports.containingPackage != symbols.unnamedPackage) { 218 print("package "); 219 printAllQualified(imports.containingPackage); 220 print(";\n\n"); 221 packagePrinted = true; 222 } 223 for (ImportAnalysis.SymRefStats p = imports.usedClassOwners; p != null; p = p.next) 224 if (p.imported && !p.implicitlyImported()) { 225 printImport(p.clazz, true); 226 nout++; 227 } 228 for (ImportAnalysis.SymRefStats p = imports.usedClasses; p != null; p = p.next) 229 if (p.imported && !p.implicitlyImported() && !imports.starred(p.clazz.owner)) { 230 printImport(p.clazz, false); 231 nout++; 232 } 233 if (nout > 0 || printPackageStatement) 234 blankline(); 235 importsPrinted = true; 236 } 237 public void printImports(Set<Symbol> clazzes) { 238 for (Symbol clazz : clazzes) 239 printImport(clazz, false); 240 } 241 private void printImport(Symbol clazz, boolean wildcard) { 242 print("import "); 243 printAllQualified(clazz); 244 if (wildcard) 245 print(".*"); 246 print(";\n"); 247 } 248 private ImportAnalysis imports; 249 public void setImports(ImportAnalysis i) { 250 imports = i; 251 widthEstimator.setImports(i); 252 } 253 public ImportAnalysis getImports() { return imports; } 254 public void print(JCTree t, Type ty) { 255 if (ty == null || ty == Type.noType) { 256 print(t); 257 } else { 258 int arrCnt = 0; 259 while (ty instanceof Type.ArrayType) { 260 ty = ((Type.ArrayType) ty).elemtype; 261 arrCnt++; 262 } 263 printQualified(ty.tsym); 264 if (ty instanceof Type.ClassType) { 265 List < Type > typarams = ((Type.ClassType) ty).typarams_field; 266 if (typarams != null && typarams.nonEmpty()) { 267 char prec = '<'; 268 for (; typarams.nonEmpty(); typarams = typarams.tail) { 269 print(prec); 270 prec = ','; 271 print(null, typarams.head); 272 } 273 print('>'); 274 } 275 } 276 while (--arrCnt >= 0) 277 print("[]"); 278 } 279 } 280 public void print(JCTree t) { 281 CommentSet comment = commentHandler.getComments(t); 282 printPrecedingComments(comment); 283 if (t == selection) 284 selectionPos = out.used; 285 t.accept(this); 286 if (t == selection) 287 selectionEndPos = out.used; 288 printTrailingComments(comment); 289 } 290 291 294 295 297 int prec; 298 299 302 public void printExpr(JCTree tree, int prec) { 303 if (tree == null) { 304 print("/*missing*/"); 305 } else { 306 int prevPrec = this.prec; 307 this.prec = prec; 308 if (tree == selection) 309 selectionPos = out.used; 310 tree.accept(this); 311 if (tree == selection) 312 selectionEndPos = out.used; 313 this.prec = prevPrec; 314 } 315 } 316 317 320 public void printExpr(JCTree tree) { 321 printExpr(tree, treeinfo.noPrec); 322 } 323 public void printNoParenExpr(JCTree tree) { 324 while (tree instanceof JCParens) 325 tree = ((JCParens) tree).expr; 326 printExpr(tree, treeinfo.noPrec); 327 } 328 329 331 public void printStat(JCTree tree) { 332 if(tree==null) print(';'); 333 else { 334 CommentSet comment = commentHandler.getComments(tree); 335 printPrecedingComments(comment); 336 printExpr(tree, treeinfo.notExpression); 337 int tag = tree.tag; 338 if(JCTree.APPLY<=tag && tag<=JCTree.MOD_ASG) print(';'); 339 printTrailingComments(comment); 340 } 341 } 342 343 345 public void printIndentedStat(JCTree tree) { 346 switch(options.redundantBraces.value) { 347 case 0: break; 349 case 1: while(tree instanceof JCBlock) { 351 List<JCStatement> t = ((JCBlock) tree).stats; 352 if(t.isEmpty() || !t.tail.isEmpty()) break; 353 if (t.head instanceof JCVariableDecl) 354 break; 356 printPrecedingComments(tree); 357 tree = t.head; 358 } 359 break; 360 case 2: case 3: 362 printBlock(tree); 363 return; 364 } 365 int old = out.leftMargin; 366 if (!(tree instanceof JCBlock)) 367 indent(); 368 if (options.sameLineIfFit) { 369 int oldhm = out.harden(); 370 int oldc = out.col; 371 int oldu = out.used; 372 int oldm = out.leftMargin; 373 try { 374 needSpace(); 375 printStat(tree); 376 undent(old); 377 out.restore(oldhm); 378 return; 379 } catch(Throwable t) { 380 out.restore(oldhm); 381 out.col = oldc; 382 out.used = oldu; 383 out.leftMargin = oldm; 384 } 385 } 386 if (out.hasMargin() || tree instanceof JCBlock && options.cuddleOpenBrace) 387 needSpace(); 388 else { 389 if (out.col > 0) 390 newline(); 391 out.toLeftMargin(); 392 } 393 printStat(tree); 394 undent(old); 395 } 396 397 399 public <T extends JCTree >void printExprs(List < T > trees, String sep) { 400 if (trees.nonEmpty()) { 401 printNoParenExpr(trees.head); 402 for (List < T > l = trees.tail; l.nonEmpty(); l = l.tail) { 403 print(sep); 404 printNoParenExpr(l.head); 405 } 406 } 407 } 408 public <T extends JCTree >void printExprs(List < T > trees) { 409 printExprs(trees, ", "); 410 } 411 412 private final WidthEstimator widthEstimator; 413 414 418 public <T extends JCTree >void wrapExprs(List < T > trees, String sep, int wrapIndent) { 419 if (trees.nonEmpty()) { 420 boolean first = true; 421 int oldleft = out.leftMargin; 422 out.leftMargin = wrapIndent; 423 int rm = options.rightMargin; 424 for (List < T > l = trees; l.nonEmpty(); l = l.tail) { 425 if (!first) { 426 print(sep); 427 int col = out.col; 428 if (col + widthEstimator.estimateWidth(l.head, rm - col + 1) > rm) 429 toColExactly(wrapIndent); 430 } 431 first = false; 432 printNoParenExpr(l.head); 433 } 434 out.leftMargin = oldleft; 435 } 436 } 437 public <T extends JCTree >void wrapExprs(List < T > trees, String sep) { 438 wrapExprs(trees, sep, out.leftMargin + options.continuationIndent); 439 } 440 public <T extends JCTree >void wrapExprs(List < T > trees) { 441 wrapExprs(trees, ", "); 442 } 443 public <T extends JCTree >void wrapExprs(List < T > trees, int indent) { 444 wrapExprs(trees, ", ", indent); 445 } 446 447 449 public <T extends JCTree >void printStats(List < T > trees) { 450 printStats(trees, Query.NOPOS); 451 } 452 453 459 public <T extends JCTree >void printStats(List < T > trees, int parentPos) { 460 boolean prevDecl = false; 461 boolean first = true; 462 for (List < T > l = trees; l.nonEmpty(); l = l.tail) { 463 T t = l.head; 464 if (isSynthetic(t, parentPos)) 465 continue; 466 boolean isDecl = t instanceof JCVariableDecl || t instanceof JCMethodDecl || t instanceof JCClassDecl; 467 if (!first) 468 if (options.blankLineBeforeInlineDeclarations && isDecl && !prevDecl 469 || options.blankLineAfterDeclarations && !isDecl && prevDecl) 470 blankline(); 471 toColExactly(out.leftMargin); 472 printStat(t); 473 first = false; 474 prevDecl = isDecl; 475 } 476 } 477 478 private static boolean isSynthetic(JCTree tree, int parentPos) { 482 if (Kind.METHOD == tree.getKind() && (((JCMethodDecl) tree).mods.flags & Flags.GENERATEDCONSTR) != 0) 484 return true; 485 return false; 488 } 489 490 492 public void printAnnotations(List<JCAnnotation> annotations) { 493 while (!annotations.isEmpty()) { 494 printNoParenExpr(annotations.head); 495 if (annotations.tail != null) { 496 newline(); 497 toColExactly(out.leftMargin); 498 } 499 else 500 needSpace(); 501 annotations = annotations.tail; 502 } 503 } 504 505 507 public void printFlags(long flags) { 508 print(treeinfo.flagNames(flags)); 509 if ((flags & StandardFlags) != 0) 510 needSpace(); 511 } 512 513 private Comment pendingAppendComment = null; 514 private JCTree lastCommentCheck = null; 515 516 protected void printPrecedingComments(CommentSet commentSet) { 517 if (!commentSet.hasComments()) 518 return; 519 for (Comment c : commentSet.getPrecedingComments()) 520 printComment(c, false, options.moveAppendedComments); 521 } 522 523 protected void printTrailingComments(CommentSet commentSet) { 524 if (!commentSet.hasComments()) 525 return; 526 for (Comment c : commentSet.getTrailingComments()) 527 printComment(c, true, false); 528 } 529 530 533 public void printPrecedingComments(JCTree tree) { 534 if(tree==lastCommentCheck) return; 535 lastCommentCheck = tree; 536 if(pendingAppendComment!=null) { 537 printComment(pendingAppendComment, true, false); 538 pendingAppendComment = null; 539 } 540 if (commentHandler != null) { 541 CommentSet pc = commentHandler.getComments(tree); 542 printPrecedingComments(pc); 543 } 544 } 545 546 public void newline() { 547 if(pendingAppendComment != null) { 548 printComment(pendingAppendComment, true, false); 549 pendingAppendComment = null; 550 } 551 out.nlTerm(); 552 } 553 public void blankline() { 554 newline(); 555 out.blankline(); 556 } 557 public void toColExactly(int n) { 558 if(n<out.col) newline(); 559 out.toCol(n); 560 } 561 562 private String body; 563 class CommentLine { 564 int startColumn; 565 int startPos; 566 int length; 567 CommentLine next; 568 CommentLine(int sc, int sp, int l) { 569 if((length = l)==0) { 570 startColumn = 0; 571 startPos = 0; 572 } else { 573 startColumn = sc; 574 startPos = sp; 575 } 576 } 577 public void print(int col) { 578 if(length>0) { 579 out.toCol(col); 580 int limit = startPos+length; 581 for(int i = startPos; i<limit; i++) 582 out.append(body.charAt(i)); 583 } 584 } 585 } 586 public void printComment(Comment comment, boolean appendOnly, boolean makePrepend) { 587 body = comment.getText(); 588 int col = comment.indent(); 589 int stpos = -1; 590 int endpos = 0; 591 CommentLine root = null; 592 CommentLine tail = null; 593 int limit = body.length(); 594 for(int i = 0; i<limit; i++) { 595 char c = body.charAt(i); 596 switch(c) { 597 default: 598 if(stpos<0) stpos = i; 599 endpos = i + 1; 600 break; 601 case '\t': 602 if(stpos<0) col = (col+8)&~7; 603 break; 604 case ' ': 605 case '*': 606 case '/': 607 if(stpos<0) col++; 608 break; 609 case '\n': 610 int tlen = stpos<0 ? 0 : i-stpos; 611 if(tlen>0||root!=null) { 612 CommentLine cl = new CommentLine(col,stpos,tlen); 613 if(tail==null) root = cl; 614 else tail.next = cl; 615 tail = cl; 616 } 617 stpos = -1; 618 col = 0; 619 break; 620 } 621 } 622 if(stpos>=0 && stpos<limit) { 623 CommentLine cl = new CommentLine(col,stpos,endpos-stpos); 624 if(tail==null) root = cl; 625 else tail.next = cl; 626 } 627 if(root==null) return; 628 int minStartColumn = 99999; 629 for(CommentLine cl = root; cl!=null; cl = cl.next) 630 if(cl.length>0 && cl.startColumn<minStartColumn) minStartColumn = cl.startColumn; 631 for(CommentLine cl = root; cl!=null; cl = cl.next) 632 if(cl.length>0) cl.startColumn -= minStartColumn; 633 634 boolean docComment = comment.isDocComment(); 635 636 int style = (docComment ? options.docCommentStyle 637 : root.next==null ? options.smallCommentStyle 638 : options.blockCommentStyle).value; 639 int col0 = out.col; 640 boolean start = true; 641 int leftMargin = out.leftMargin; 642 if (false && !makePrepend) { 643 if(!appendOnly) { 644 if(pendingAppendComment==null) 645 pendingAppendComment = comment; 646 return; 647 } 648 if (style != 3) 649 style = 0; 650 leftMargin += options.appendCommentCol; 651 if (leftMargin < col0 + 1) 652 leftMargin = col0 + 1; 653 } else if(appendOnly) return; 654 else { 655 if (options.blankLineBeforeAllComments || 656 options.blankLineBeforeDocComments && docComment) 657 out.blankline(); 658 if(!docComment) leftMargin -= options.unindentDisplace; 659 } 660 switch (style) { 661 case 0: for (CommentLine cl = root; cl!=null; cl = cl.next) { 663 out.toColExactly(leftMargin); 664 out.append(start ? docComment ? "/**" : "/*" : " *"); 665 start = false; 666 cl.print(leftMargin+3); 667 if (cl.next==null) 668 out.append(" */"); 669 out.nlTerm(); 670 } 671 break; 672 case 1: out.toColExactly(leftMargin); 674 out.append(docComment ? "/**" : "/*"); 675 for (CommentLine cl = root; cl!=null; cl = cl.next) { 676 out.toColExactly(leftMargin+1); 677 out.append("*"); 678 cl.print(leftMargin+3); 679 out.nlTerm(); 680 } 681 out.toColExactly(leftMargin+1); 682 out.append("*/"); 683 out.nlTerm(); 684 break; 685 case 2: int w = 0; 687 for (CommentLine cl = root; cl!=null; cl = cl.next) { 688 int tw = cl.length+cl.startColumn; 689 if (tw > w) 690 w = tw; 691 } 692 out.toColExactly(leftMargin); 693 out.append(docComment ? "/**" : "/* "); 694 for (int i = w + 2; --i >= 0;) 695 out.append('*'); 696 out.nlTerm(); 697 for (CommentLine cl = root; cl!=null; cl = cl.next) { 698 out.toColExactly(leftMargin); 699 out.append(" *"); 700 cl.print(leftMargin+3); 701 out.toCol(leftMargin + w + 4); 702 out.append('*'); 703 out.nlTerm(); 704 } 705 out.toColExactly(leftMargin + 1); 706 for (int i = w + 4; --i >= 0;) 707 out.append('*'); 708 out.append('/'); 709 out.nlTerm(); 710 break; 711 case 3: for (CommentLine cl = root; cl!=null; cl = cl.next) { 713 out.toColExactly(leftMargin); 714 out.append(start && docComment ? "//*" : "//"); 715 start = false; 716 cl.print(leftMargin+3); 717 out.nlTerm(); 718 } 719 break; 720 } 721 out.nlTerm(); 722 out.toLeftMargin(); 723 } 724 725 727 public void printTypeParameters(List < JCTypeParameter > trees) { 728 729 if (trees.nonEmpty()) { 730 print('<'); 731 printExprs(trees); 732 print('>'); 733 } 734 } 735 736 738 public void printBlock(List<? extends JCTree>stats) { 739 printBlock(stats, Query.NOPOS); 740 } 741 742 748 public void printBlock(List<? extends JCTree> stats, int parentPos) { 749 int old = indent(); 750 int bcol = old; 751 if (options.indBracesHalfway) 752 bcol += (options.indentSize >> 1); 753 else if (options.indBracesInner) 754 bcol = out.leftMargin; 755 out.toCol(bcol); 756 needSpace(); 757 print('{'); 758 if (!stats.isEmpty()) 759 newline(); 760 printStats(stats, parentPos); 761 undent(old); 762 if (options.cuddleCloseBrace) 763 print(" }"); 764 else { 765 toColExactly(bcol); 766 print('}'); 767 } 768 } 769 public void printBlock(JCTree t) { 770 List<? extends JCTree> stats; 771 if (t instanceof JCBlock) 772 stats = ((JCBlock) t).stats; 773 else 774 stats = List.of(t); 775 printBlock(stats); 776 } 777 782 public void printUnit(JCCompilationUnit tree) { 783 if (!packagePrinted) { 784 printPrecedingComments(tree); 785 if (tree.pid != null) { 786 print("package "); 787 printExpr(tree.pid); 788 print(';'); 789 newline(); 790 } 791 packagePrinted = true; 792 } 793 List<JCTree> l = tree.defs; 794 while (l.nonEmpty() && l.head.tag == JCTree.IMPORT){ 795 if (!importsPrinted) { 796 printStat(l.head); 797 newline(); 798 } 799 l = l.tail; 800 } 801 importsPrinted = true; 802 while (l.nonEmpty()) { 803 printStat(l.head); 804 newline(); 805 l = l.tail; 806 } 807 } 808 809 private Name fullName(JCTree tree) { 810 switch (tree.tag) { 811 case JCTree.IDENT: 812 return ((JCIdent) tree).name; 813 case JCTree.SELECT: 814 JCFieldAccess sel = (JCFieldAccess)tree; 815 Name sname = fullName(sel.selected); 816 return sname != null && sname.len > 0 ? sname.append('.', sel.name) : sel.name; 817 default: 818 return null; 819 } 820 } 821 822 825 826 public void visitTopLevel(JCCompilationUnit tree) { 827 printUnit(tree); 828 } 829 830 public void visitImport(JCImport tree) { 831 if (!importsPrinted) { 832 print("import "); 833 if (tree.staticImport) 834 print("static "); 835 print(fullName(tree.qualid)); 836 print(';'); 837 } 838 } 839 840 public void visitClassDef(JCClassDecl tree) { 841 out.toLeftMargin(); 842 Name enclClassNamePrev = enclClassName; 843 enclClassName = tree.name; 844 printClassHeader(tree); 845 needSpace(); 846 printClassBody(tree); 847 enclClassName = enclClassNamePrev; 848 } 849 850 protected void printClassHeader(JCClassDecl tree) { 851 printAnnotations(tree.mods.annotations); 852 long flags = tree.sym != null ? tree.sym.flags() : tree.mods.flags; 853 if ((flags & ENUM) != 0) 854 printFlags(flags & ~(INTERFACE | STATIC | FINAL)); 855 else 856 printFlags(flags & ~(INTERFACE | ABSTRACT)); 857 if ((flags & INTERFACE) != 0 || (flags & ANNOTATION) != 0) { 858 if ((flags & ANNOTATION) != 0) print('@'); 859 print("interface "); 860 print(tree.name); 861 printTypeParameters(tree.typarams); 862 if (tree.implementing.nonEmpty()) { 863 print(" extends "); 864 wrapExprs(tree.implementing); 865 } 866 } else { 867 if ((flags & ENUM) != 0) 868 print("enum "); 869 else { 870 if ((flags & ABSTRACT) != 0) 871 print("abstract "); 872 print("class "); 873 } 874 print(tree.name); 875 printTypeParameters(tree.typarams); 876 if (tree.extending != null) { 877 print(" extends "); 878 print(tree.extending, tree.sym != null 879 ? types.supertype(tree.sym.type) : null); 880 } 881 if (tree.implementing.nonEmpty()) { 882 print(" implements "); 883 wrapExprs(tree.implementing, out.col); 884 } 885 } 886 } 887 888 protected void printClassBody(JCClassDecl tree) { 889 if ((tree.mods.flags & ENUM) != 0) 890 printEnumBody(tree.defs, tree.pos); 891 else 892 printBlock(tree.defs, tree.pos); 893 } 894 895 public void printEnumBody(List<JCTree> stats, int parentPos) { 896 int old = indent(); 897 int bcol = old; 898 if (options.indBracesHalfway) 899 bcol += (options.indentSize >> 1); 900 else if (options.indBracesInner) 901 bcol = out.leftMargin; 902 out.toCol(bcol); 903 needSpace(); 904 print("{"); 905 if (!stats.isEmpty()) 906 newline(); 907 boolean first = true; 908 boolean hasNonEnumerator = false; 909 for (List<JCTree> l = stats; l.nonEmpty(); l = l.tail) { 910 if (isEnumerator(l.head)) { 911 if (!first) { 912 print(", "); 913 if (options.blankLineBeforeInlineDeclarations 914 || options.blankLineAfterDeclarations) 915 blankline(); 916 } 917 toColExactly(out.leftMargin); 918 printStat(l.head); 919 first = false; 920 } 921 else if (!isSynthetic(l.head, parentPos)) 922 hasNonEnumerator = true; 923 } 924 if (hasNonEnumerator) { 925 print(";"); 926 newline(); 927 } 928 for (List<JCTree> l = stats; l.nonEmpty(); l = l.tail) { 929 JCTree t = l.head; 930 if (!isEnumerator(t)) { 931 if (isSynthetic(t, parentPos)) 932 continue; 933 toColExactly(out.leftMargin); 934 printStat(t); 935 newline(); 936 } 937 } 938 undent(old); 939 if (options.cuddleCloseBrace) 940 print(" }"); 941 else { 942 toColExactly(bcol); 943 print('}'); 944 } 945 } 946 947 948 protected boolean isEnumerator(JCTree t) { 949 return t.tag == JCTree.VARDEF && (((JCVariableDecl) t).mods.flags & ENUM) != 0; 950 } 951 952 protected final boolean isMethodPrintable(JCMethodDecl tree) { 953 return ((tree.mods.flags & Flags.SYNTHETIC)==0 && 956 tree.name != names.init || 957 enclClassName != null); 958 } 959 960 public void visitMethodDef(JCMethodDecl tree) { 961 if (isMethodPrintable(tree)) { 962 if (options.blankLineBeforeMethods) 963 blankline(); 964 out.toLeftMargin(); 965 printMethodHeader(tree); 966 needSpace(); 967 printMethodBody(tree); 968 } 969 } 970 971 private String replace(String a,String b) { 972 a = a.replace(b, out.toString()); 973 out.clear(); 974 return a; 975 } 976 977 private static final String REPLACEMENT = "%[a-z]*%"; 978 979 public String getMethodHeader(MethodTree t, String s) { 980 JCMethodDecl tree = (JCMethodDecl) t; 981 printAnnotations(tree.mods.annotations); 982 s = replace(s, UiUtils.PrintPart.ANNOTATIONS); 983 printFlags(tree.mods.flags); 984 s = replace(s, UiUtils.PrintPart.FLAGS); 985 if (tree.name == names.init) { 986 print(enclClassName); 987 s = replace(s, UiUtils.PrintPart.NAME); 988 } else { 989 if (tree.typarams != null) { 990 printTypeParameters(tree.typarams); 991 needSpace(); 992 s = replace(s, UiUtils.PrintPart.TYPEPARAMETERS); 993 } 994 print(tree.restype, tree.sym != null && tree.sym.type!=null ? tree.sym.type.getReturnType() : null); 995 s = replace(s, UiUtils.PrintPart.TYPE); 996 if(options.methodNamesStartLine) { newline(); out.toLeftMargin(); } else needSpace(); 997 out.clear(); 998 print(tree.name); 999 s = replace(s, UiUtils.PrintPart.NAME); 1000 } 1001 print('('); 1002 wrapExprs(tree.params, out.col); 1003 print(')'); 1004 s = replace(s, UiUtils.PrintPart.PARAMETERS); 1005 if (tree.thrown.nonEmpty()) { 1006 print(" throws "); 1007 wrapExprs(tree.thrown, out.col); 1008 s = replace(s, UiUtils.PrintPart.THROWS); 1009 } 1010 return s.replaceAll(REPLACEMENT,""); 1011 } 1012 1013 public String getClassHeader(ClassTree t, String s) { 1014 JCClassDecl tree = (JCClassDecl) t; 1015 printAnnotations(tree.mods.annotations); 1016 s = replace(s, UiUtils.PrintPart.ANNOTATIONS); 1017 long flags = tree.sym != null ? tree.sym.flags() : tree.mods.flags; 1018 if ((flags & ENUM) != 0) 1019 printFlags(flags & ~(INTERFACE | STATIC | FINAL)); 1020 else 1021 printFlags(flags & ~(INTERFACE | ABSTRACT)); 1022 s = replace(s, UiUtils.PrintPart.FLAGS); 1023 if ((flags & INTERFACE) != 0) { 1024 print("interface "); 1025 print(tree.name); 1026 s = replace(s, UiUtils.PrintPart.NAME); 1027 printTypeParameters(tree.typarams); 1028 s = replace(s, UiUtils.PrintPart.TYPEPARAMETERS); 1029 if (tree.implementing.nonEmpty()) { 1030 print(" extends "); 1031 wrapExprs(tree.implementing); 1032 s = replace(s, UiUtils.PrintPart.EXTENDS); 1033 } 1034 } else { 1035 if ((flags & ENUM) != 0) 1036 print("enum "); 1037 else { 1038 if ((flags & ABSTRACT) != 0) 1039 print("abstract "); 1040 print("class "); 1041 } 1042 print(tree.name); 1043 s = replace(s, UiUtils.PrintPart.NAME); 1044 printTypeParameters(tree.typarams); 1045 s = replace(s, UiUtils.PrintPart.TYPEPARAMETERS); 1046 if (tree.extending != null) { 1047 print(" extends "); 1048 print(tree.extending, tree.sym != null 1049 ? types.supertype(tree.sym.type) : null); 1050 s = replace(s, UiUtils.PrintPart.EXTENDS); 1051 } 1052 if (tree.implementing.nonEmpty()) { 1053 print(" implements "); 1054 wrapExprs(tree.implementing, out.col); 1055 s = replace(s, UiUtils.PrintPart.IMPLEMENTS); 1056 } 1057 } 1058 return s.replaceAll(REPLACEMENT,""); 1059 } 1060 1061 public String getVariableHeader(VariableTree t, String s) { 1062 JCVariableDecl tree = (JCVariableDecl) t; 1063 printAnnotations(tree.mods.annotations); 1064 s = replace(s, UiUtils.PrintPart.ANNOTATIONS); 1065 printFlags(tree.mods.flags); 1066 s = replace(s, UiUtils.PrintPart.FLAGS); 1067 Type type = tree.type != null ? tree.type : tree.vartype.type; 1068 print(tree.vartype, type); 1069 s = replace(s, UiUtils.PrintPart.TYPE); 1070 needSpace(); 1071 print(tree.name); 1072 s = replace(s, UiUtils.PrintPart.NAME); 1073 return s.replaceAll(REPLACEMENT,""); 1074 } 1075 1076 protected void printMethodHeader(JCMethodDecl tree) { 1077 printAnnotations(tree.mods.annotations); 1078 printFlags(tree.mods.flags); 1079 if (tree.name == names.init) { 1080 print(enclClassName); 1081 } else { 1082 if (tree.typarams != null) { 1083 printTypeParameters(tree.typarams); 1084 needSpace(); 1085 } 1086 print(tree.restype, tree.sym != null && tree.sym.type!=null ? tree.sym.type.getReturnType() : null); 1087 if(options.methodNamesStartLine) { newline(); out.toLeftMargin(); } 1088 else needSpace(); 1089 print(tree.name); 1090 } 1091 print('('); 1092 wrapExprs(tree.params, out.col); 1093 print(')'); 1094 if (tree.thrown.nonEmpty()) { 1095 print(" throws "); 1096 wrapExprs(tree.thrown, out.col); 1097 } 1098 } 1099 1100 protected void printMethodBody(JCMethodDecl tree) { 1101 if (tree.body != null) { 1102 boolean constructor = (tree.name == names.init); 1103 List<JCStatement> stats = tree.body.stats; 1104 JCTree head = stats.head; 1105 if(head instanceof JCExpressionStatement) head = ((JCExpressionStatement)head).expr; 1106 if(constructor && head instanceof JCMethodInvocation) { 1107 JCMethodInvocation ap = (JCMethodInvocation) head; 1108 if(ap.args.isEmpty() && ap.meth instanceof JCIdent) { 1109 JCIdent id = (JCIdent) ap.meth; 1110 Name n = id.sym==null ? id.name : id.sym.name; 1111 if(n == names.init) { 1112 1114 stats = stats.tail; 1115 } 1116 } 1117 } 1118 printBlock(stats); 1119 } else { 1120 print(';'); 1121 } 1122 } 1123 1124 public void visitVarDef(JCVariableDecl tree) { 1125 if (commentHandler != null && commentHandler.hasComments(tree)) { 1126 if (prec == TreeInfo.notExpression) { newline(); 1128 out.toLeftMargin(); 1129 } 1130 } 1131 if ((tree.mods.flags & ENUM) != 0) 1132 print(tree.name); 1133 else { 1134 printVarHeader(tree); 1135 printVarBody(tree); 1136 } 1137 } 1138 1139 protected void printVarHeader(JCVariableDecl tree) { 1140 printAnnotations(tree.mods.annotations); 1141 printFlags(tree.mods.flags); 1142 Type type = tree.type != null ? tree.type : tree.vartype.type; 1143 if ((tree.mods.flags & VARARGS) != 0) { 1144 printExpr(((JCArrayTypeTree) tree.vartype).elemtype); 1147 print("..."); 1148 } else { 1149 print(tree.vartype, type); 1150 } 1151 needSpace(); 1152 print(tree.name); 1153 } 1154 1155 protected void printVarBody(JCVariableDecl tree) { 1156 if (tree.init != null) { 1157 print(" = "); 1158 printNoParenExpr(tree.init); 1159 } 1160 if (prec == treeinfo.notExpression) 1161 print(';'); 1162 } 1163 1164 public void visitSkip(JCSkip tree) { 1165 print(';'); 1166 } 1167 1168 public void visitBlock(JCBlock tree) { 1169 printFlags(tree.flags); 1170 printBlock(tree.stats); 1171 } 1172 1173 public void visitDoLoop(JCDoWhileLoop tree) { 1174 print("do "); 1175 printIndentedStat(tree.body); 1176 out.toLeftMargin(); 1177 needSpace(); 1178 print("while ("); 1179 printNoParenExpr(tree.cond); 1180 print(");"); 1181 } 1182 1183 public void visitWhileLoop(JCWhileLoop tree) { 1184 print("while ("); 1185 printNoParenExpr(tree.cond); 1186 print(") "); 1187 printIndentedStat(tree.body); 1188 } 1189 1190 public void visitForLoop(JCForLoop tree) { 1191 print("for ("); 1192 if (tree.init.nonEmpty()) { 1193 if (tree.init.head.tag == JCTree.VARDEF) { 1194 printNoParenExpr(tree.init.head); 1195 for (List<? extends JCTree> l = tree.init.tail; l.nonEmpty(); l = l.tail) { 1196 JCVariableDecl vdef = (JCVariableDecl) l.head; 1197 print(", " + vdef.name + " = "); 1198 printNoParenExpr(vdef.init); 1199 } 1200 } else { 1201 printExprs(tree.init); 1202 } 1203 } 1204 print(';'); 1205 if (tree.cond != null) { 1206 print(' '); 1207 printNoParenExpr(tree.cond); 1208 } 1209 print(';'); 1210 if (tree.step.nonEmpty()) { 1211 print(' '); 1212 printExprs(tree.step); 1213 } 1214 print(") "); 1215 printIndentedStat(tree.body); 1216 } 1217 1218 public void visitLabelled(JCLabeledStatement tree) { 1219 print(tree.label); 1220 print(": "); 1221 printIndentedStat(tree.body); 1222 } 1223 1224 public void visitSwitch(JCSwitch tree) { 1225 print("switch ("); 1226 printNoParenExpr(tree.selector); 1227 print(") {\n"); 1228 printStats(tree.cases); 1229 toColExactly(out.leftMargin); 1230 print('}'); 1231 } 1232 1233 public void visitCase(JCCase tree) { 1234 toColExactly(out.leftMargin + options.caseInd); 1235 if (tree.pat == null) { 1236 print("default"); 1237 } else { 1238 print("case "); 1239 printNoParenExpr(tree.pat); 1240 } 1241 print(':'); 1242 newline(); 1243 int old = indent(); 1244 printStats(tree.stats); 1245 undent(old); 1246 } 1247 1248 public void visitSynchronized(JCSynchronized tree) { 1249 print("synchronized ("); 1250 printNoParenExpr(tree.lock); 1251 print(") "); 1252 printBlock(tree.body); 1253 } 1254 1255 public void visitTry(JCTry tree) { 1256 print("try "); 1257 printBlock(tree.body); 1258 for (List < JCCatch > l = tree.catchers; l.nonEmpty(); l = l.tail) 1259 printStat(l.head); 1260 if (tree.finalizer != null) { 1261 toColExactly(out.leftMargin); 1262 print("finally "); 1263 printBlock(tree.finalizer); 1264 } 1265 } 1266 1267 public void visitCatch(JCCatch tree) { 1268 toColExactly(out.leftMargin); 1269 print("catch ("); 1270 printNoParenExpr(tree.param); 1271 print(") "); 1272 printBlock(tree.body); 1273 } 1274 1275 public void visitConditional(JCConditional tree) { 1276 int condWidth = 0; 1277 final int maxCondWidth = 40; 1278 if (options.forceCondExprWrap) { 1279 JCConditional t = tree; 1280 while (true) { 1281 int thisWidth = widthEstimator.estimateWidth(t.cond, maxCondWidth); 1282 if (thisWidth > condWidth) 1283 condWidth = thisWidth; 1284 if (!(t.falsepart instanceof JCConditional)) 1285 break; 1286 t = (JCConditional) t.falsepart; 1287 } 1288 if (condWidth >= maxCondWidth) 1289 condWidth = options.continuationIndent; 1290 } 1291 open(prec, treeinfo.condPrec); 1292 int col0 = out.col; 1293 while (true) { 1294 printExpr(tree.cond, treeinfo.condPrec - 1); 1295 out.toColExactly(col0 + condWidth + 1); 1296 print("? "); 1297 printExpr(tree.truepart, treeinfo.condPrec); 1298 if (options.forceCondExprWrap) 1299 if (tree.falsepart instanceof JCConditional) { 1300 tree = (JCConditional) tree.falsepart; 1301 toColExactly(col0 - 3); 1302 print(" : "); 1303 continue; 1304 } else 1305 toColExactly(col0 + condWidth+1); 1306 else needSpace(); 1307 print(": "); 1308 printExpr(tree.falsepart, treeinfo.condPrec); 1309 break; 1310 } 1311 close(prec, treeinfo.condPrec); 1312 } 1313 1314 private final DanglingElseChecker danglingElseChecker = new DanglingElseChecker(); 1315 public void visitIf(JCIf tree) { 1316 print("if ("); 1317 printNoParenExpr(tree.cond); 1318 print(")"); 1319 boolean prevblock = tree.thenpart instanceof JCBlock || options.redundantBraces.value>=2; 1320 if (tree.elsepart != null && danglingElseChecker.hasDanglingElse(tree.thenpart)) { 1321 printBlock(tree.thenpart); 1322 prevblock = true; 1323 } else 1324 printIndentedStat(tree.thenpart); 1325 if (tree.elsepart != null) { 1326 if (prevblock && cuddleElse) 1327 needSpace(); 1328 else 1329 toColExactly(out.leftMargin); 1330 needSpace(); 1331 print("else"); 1332 if (tree.elsepart instanceof JCIf && options.cuddleElseIf) { 1333 needSpace(); 1334 printStat(tree.elsepart); 1335 } else 1336 printIndentedStat(tree.elsepart); 1337 } 1338 } 1339 1340 public void visitExec(JCExpressionStatement tree) { 1341 printNoParenExpr(tree.expr); 1342 if (prec == treeinfo.notExpression) 1343 print(';'); 1344 } 1345 1346 public void visitBreak(JCBreak tree) { 1347 print("break"); 1348 if (tree.label != null) { 1349 needSpace(); 1350 print(tree.label); 1351 } 1352 print(';'); 1353 } 1354 1355 public void visitContinue(JCContinue tree) { 1356 print("continue"); 1357 if (tree.label != null) { 1358 needSpace(); 1359 print(tree.label); 1360 } 1361 print(';'); 1362 } 1363 1364 public void visitReturn(JCReturn tree) { 1365 print("return"); 1366 if (tree.expr != null) { 1367 needSpace(); 1368 printNoParenExpr(tree.expr); 1369 } 1370 print(';'); 1371 } 1372 1373 public void visitThrow(JCThrow tree) { 1374 print("throw "); 1375 printNoParenExpr(tree.expr); 1376 print(';'); 1377 } 1378 1379 public void visitAssert(JCAssert tree) { 1380 print("assert "); 1381 printExpr(tree.cond); 1382 if (tree.detail != null) { 1383 print(" : "); 1384 printExpr(tree.detail); 1385 } 1386 print(';'); 1387 } 1388 1389 private void printTypeArguments(List<? extends JCExpression> typeargs) { 1390 if (typeargs.size() > 0) { 1391 print('<'); 1392 printExprs(typeargs); 1393 print('>'); 1394 } 1395 } 1396 1397 public void visitApply(JCMethodInvocation tree) { 1398 if (!tree.typeargs.isEmpty()) { 1399 int prevPrec = prec; 1400 this.prec = treeinfo.postfixPrec; 1401 if (tree.meth.tag == JCTree.SELECT) { 1402 JCFieldAccess left = (JCFieldAccess)tree.meth; 1403 printExpr(left.selected); 1404 print('.'); 1405 printTypeArguments(tree.typeargs); 1406 print(left.name.toString()); 1407 } else { 1408 printTypeArguments(tree.typeargs); 1409 printExpr(tree.meth); 1410 } 1411 this.prec = prevPrec; 1412 } else { 1413 printExpr(tree.meth, treeinfo.postfixPrec); 1414 } 1415 print('('); 1416 wrapExprs(tree.args, out.col); 1417 print(')'); 1418 } 1419 1420 public void visitNewClass(JCNewClass tree) { 1421 if (tree.encl != null) { 1422 printExpr(tree.encl); 1423 print('.'); 1424 } 1425 print("new "); 1426 if (!tree.typeargs.isEmpty()) { 1427 print("<"); 1428 printExprs(tree.typeargs); 1429 print(">"); 1430 } 1431 if (tree.encl == null) 1432 print(tree.clazz, tree.clazz.type); 1433 else if (tree.clazz.type != null) 1434 print(tree.clazz.type.tsym.name); 1435 else 1436 print(tree.clazz); 1437 print('('); 1438 wrapExprs(tree.args, out.col); 1439 print(')'); 1440 if (tree.def != null) { 1441 Name enclClassNamePrev = enclClassName; 1442 enclClassName = null; 1443 printBlock(((JCClassDecl) tree.def).defs); 1444 enclClassName = enclClassNamePrev; 1445 } 1446 } 1447 1448 public void visitNewArray(JCNewArray tree) { 1449 if (tree.elemtype != null) { 1450 print("new "); 1451 int n = tree.elems != null ? 1 : 0; 1452 JCTree elemtype = tree.elemtype; 1453 while (elemtype.tag == JCTree.TYPEARRAY) { 1454 n++; 1455 elemtype = ((JCArrayTypeTree) elemtype).elemtype; 1456 } 1457 printExpr(elemtype); 1458 for (List<? extends JCTree> l = tree.dims; l.nonEmpty(); l = l.tail) { 1459 print('['); 1460 printNoParenExpr(l.head); 1461 print(']'); 1462 n--; 1463 } 1464 while(--n >= 0) 1465 print("[]"); 1466 } 1467 if (tree.elems != null) { 1468 print("{"); 1469 wrapExprs(tree.elems); 1470 print('}'); 1471 } 1472 } 1473 1474 public void visitParens(JCParens tree) { 1475 print('('); 1476 printExpr(tree.expr); 1477 print(')'); 1478 } 1479 1480 public void visitAssign(JCAssign tree) { 1481 open(prec, treeinfo.assignPrec); 1482 printExpr(tree.lhs, treeinfo.assignPrec + 1); 1483 print(" = "); 1484 printExpr(tree.rhs, treeinfo.assignPrec); 1485 close(prec, treeinfo.assignPrec); 1486 } 1487 1488 public void visitAssignop(JCAssignOp tree) { 1489 open(prec, treeinfo.assignopPrec); 1490 printExpr(tree.lhs, treeinfo.assignopPrec + 1); 1491 print(" "); 1492 print(treeinfo.operatorName(tree.tag - JCTree.ASGOffset)); 1493 print("= "); 1494 printExpr(tree.rhs, treeinfo.assignopPrec); 1495 close(prec, treeinfo.assignopPrec); 1496 } 1497 1498 public void visitUnary(JCUnary tree) { 1499 int ownprec = treeinfo.opPrec(tree.tag); 1500 Name opname = treeinfo.operatorName(tree.tag); 1501 open(prec, ownprec); 1502 if (tree.tag <= JCTree.PREDEC) { 1503 print(opname); 1504 printExpr(tree.arg, ownprec); 1505 } else { 1506 printExpr(tree.arg, ownprec); 1507 print(opname); 1508 } 1509 close(prec, ownprec); 1510 } 1511 1512 public void visitBinary(JCBinary tree) { 1513 int ownprec = treeinfo.opPrec(tree.tag); 1514 Name opname = treeinfo.operatorName(tree.tag); 1515 open(prec, ownprec); 1516 int stcol = out.col; 1517 printExpr(tree.lhs, ownprec); 1518 int spLimit = options.spaceOperatorsBelow.value; 1519 if(ownprec<=spLimit) needSpace(); 1520 print(opname); 1521 if(ownprec<=spLimit) needSpace(); 1522 int rm = options.rightMargin; 1523 if(out.col+widthEstimator.estimateWidth(tree.rhs,rm-out.col)>rm) 1524 out.toColExactly(stcol); 1525 printExpr(tree.rhs, ownprec + 1); 1526 close(prec, ownprec); 1527 } 1528 1529 public void visitTypeCast(JCTypeCast tree) { 1530 open(prec, treeinfo.prefixPrec); 1531 print('('); 1532 print(tree.clazz, tree.clazz.type); 1533 print(") "); 1534 printExpr(tree.expr, treeinfo.prefixPrec); 1535 close(prec, treeinfo.prefixPrec); 1536 } 1537 1538 public void visitTypeTest(JCInstanceOf tree) { 1539 open(prec, treeinfo.ordPrec); 1540 printExpr(tree.expr, treeinfo.ordPrec); 1541 print(" instanceof "); 1542 print(tree.clazz, tree.clazz.type); 1543 close(prec, treeinfo.ordPrec); 1544 } 1545 1546 public void visitIndexed(JCArrayAccess tree) { 1547 printExpr(tree.indexed, treeinfo.postfixPrec); 1548 print('['); 1549 printExpr(tree.index); 1550 print(']'); 1551 } 1552 1553 public void visitSelect(JCFieldAccess tree) { 1554 if (tree.sym instanceof Symbol.ClassSymbol) { 1555 print(null, tree.type); 1556 } else { 1557 printExpr(tree.selected, treeinfo.postfixPrec); 1558 print('.'); 1559 print(tree.sym==null ? tree.name : tree.sym.name); 1560 } 1561 } 1562 1563 public void visitIdent(JCIdent tree) { 1564 if (tree.sym instanceof Symbol.ClassSymbol) 1565 print(null, tree.type); 1566 else { 1567 Name n = tree.sym==null ? tree.name : tree.sym.name; 1568 if(n==names.init) print(tree.name); 1569 else print(n); 1570 } 1571 } 1572 1573 public void visitLiteral(JCLiteral tree) { 1574 switch (tree.typetag) { 1575 case INT: 1576 print(tree.value.toString()); 1577 break; 1578 case LONG: 1579 print(tree.value.toString() + "L"); 1580 break; 1581 case FLOAT: 1582 print(tree.value.toString() + "F"); 1583 break; 1584 case DOUBLE: 1585 print(tree.value.toString()); 1586 break; 1587 case CHAR: 1588 print("\'" + 1589 Convert.quote( 1590 String.valueOf((char) ((Number ) tree.value).intValue())) + 1591 "\'"); 1592 break; 1593 case CLASS: 1594 print("\"" + Convert.quote((String ) tree.value) + "\""); 1595 break; 1596 case BOOLEAN: 1597 print(tree.getValue().toString()); 1598 break; 1599 case BOT: 1600 print("null"); 1601 break; 1602 default: 1603 print(tree.value.toString()); 1604 } 1605 } 1606 1607 public void visitTypeIdent(JCPrimitiveTypeTree tree) { 1608 print(symbols.typeOfTag[tree.typetag].tsym.name); 1609 } 1610 1611 public void visitTypeArray(JCArrayTypeTree tree) { 1612 printExpr(tree.elemtype); 1613 print("[]"); 1614 } 1615 1616 public void visitTypeApply(JCTypeApply tree) { 1617 printExpr(tree.clazz); 1618 print('<'); 1619 printExprs(tree.arguments); 1620 print('>'); 1621 } 1622 1623 public void visitTypeParameter(JCTypeParameter tree) { 1624 print(tree.name); 1625 if (tree.bounds.nonEmpty()) { 1626 print(" extends "); 1627 printExprs(tree.bounds, " & "); 1628 } 1629 } 1630 1631 public void visitWildcard(JCWildcard tree) { 1632 print("" + tree.kind); 1633 if (tree.kind != BoundKind.UNBOUND) 1634 printExpr(tree.inner); 1635 } 1636 1637 public void visitModifiers(JCModifiers tree) { 1638 printAnnotations(tree.annotations); 1639 printFlags(tree.flags); 1640 } 1641 1642 public void visitAnnotation(JCAnnotation tree) { 1643 print("@"); 1644 printExpr(tree.annotationType); 1645 if (tree.args.nonEmpty()) { 1646 print("("); 1647 printExprs(tree.args); 1648 print(")"); 1649 } 1650 } 1651 1652 public void visitForeachLoop(JCEnhancedForLoop tree) { 1653 print("for ("); 1654 printExpr(tree.getVariable()); 1655 print(" : "); 1656 printExpr(tree.getExpression()); 1657 print(") "); 1658 printIndentedStat(tree.getStatement()); 1659 } 1660 1661 public void visitLetExpr(LetExpr tree) { 1662 print("(let " + tree.defs + " in " + tree.expr + ")"); 1663 } 1664 1665 public void visitErroneous(JCErroneous tree) { 1666 print("(ERROR)"); 1667 } 1668 1669 public void visitTree(JCTree tree) { 1670 print("(UNKNOWN: " + tree + ")"); 1671 newline(); 1672 } 1673} 1674 | Popular Tags |