DocPretty.java revision 2571:10fc81ac75b4
125603Skjc/* 225603Skjc * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 3139823Simp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 425603Skjc * 525603Skjc * This code is free software; you can redistribute it and/or modify it 625603Skjc * under the terms of the GNU General Public License version 2 only, as 725603Skjc * published by the Free Software Foundation. Oracle designates this 825603Skjc * particular file as subject to the "Classpath" exception as provided 925603Skjc * by Oracle in the LICENSE file that accompanied this code. 1025603Skjc * 1125603Skjc * This code is distributed in the hope that it will be useful, but WITHOUT 1225603Skjc * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1325603Skjc * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1425603Skjc * version 2 for more details (a copy is included in the LICENSE file that 1525603Skjc * accompanied this code). 1625603Skjc * 1725603Skjc * You should have received a copy of the GNU General Public License version 1825603Skjc * 2 along with this work; if not, write to the Free Software Foundation, 1925603Skjc * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2025603Skjc * 2125603Skjc * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2225603Skjc * or visit www.oracle.com if you need additional information or have any 2325603Skjc * questions. 2425603Skjc */ 2525603Skjc 2625603Skjcpackage com.sun.tools.javac.tree; 2725603Skjc 2825603Skjcimport java.io.Writer; 2925603Skjc 3025603Skjcimport com.sun.source.doctree.*; 3125603Skjcimport com.sun.source.doctree.AttributeTree.ValueKind; 3225603Skjcimport com.sun.tools.javac.util.Convert; 3354263Sshinimport java.io.IOException; 3425603Skjcimport java.util.List; 3525603Skjc 3625603Skjc/** 37116720Sharti * Prints out a doc comment tree. 38116720Sharti * 39116720Sharti * <p><b>This is NOT part of any supported API. 4032350Seivind * If you write code that depends on this, you do so at your own risk. 4154263Sshin * This code and its internal interfaces are subject to change or 4232925Seivind * deletion without notice.</b> 4332350Seivind */ 4425603Skjcpublic class DocPretty implements DocTreeVisitor<Void,Void> { 4525603Skjc 46114201Sharti /** 47114201Sharti * The output stream on which trees are printed. 4825603Skjc */ 4925603Skjc final Writer out; 5037939Skjc 5137939Skjc /** 52114201Sharti * The left margin. 53117630Sharti */ 5425603Skjc int lmargin = 0; 5525603Skjc 5625603Skjc public DocPretty(Writer out) { 5725603Skjc this.out = out; 5825603Skjc } 5925603Skjc 6025603Skjc /** Visitor method: print expression tree. 6125603Skjc */ 6225603Skjc public void print(DocTree tree) throws IOException { 6325603Skjc try { 6425603Skjc if (tree == null) 6537939Skjc print("/*missing*/"); 6625603Skjc else { 6725603Skjc tree.accept(this, null); 6825603Skjc } 6925603Skjc } catch (UncheckedIOException ex) { 7025603Skjc throw new IOException(ex.getMessage(), ex); 7125603Skjc } 72163606Srwatson } 73163606Srwatson 74116741Sharti /** 75116741Sharti * Print string, replacing all non-ascii character with unicode escapes. 76116741Sharti */ 77116741Sharti protected void print(Object s) throws IOException { 78116741Sharti out.write(Convert.escapeUnicode(s.toString())); 79116741Sharti } 80116741Sharti 81116741Sharti /** 82116741Sharti * Print list. 83116741Sharti */ 84116741Sharti public void print(List<? extends DocTree> list) throws IOException { 85116741Sharti for (DocTree t: list) { 86116741Sharti print(t); 87116741Sharti } 88118157Sharti } 89116741Sharti 90116741Sharti /** 91116741Sharti * Print list., with separators 92116741Sharti */ 93116741Sharti protected void print(List<? extends DocTree> list, String sep) throws IOException { 94116741Sharti if (list.isEmpty()) 95116741Sharti return; 96116741Sharti boolean first = true; 97118157Sharti for (DocTree t: list) { 98116741Sharti if (!first) 99114201Sharti print(sep); 100114201Sharti print(t); 101249132Smav first = false; 102147256Sbrooks } 10337939Skjc } 104116720Sharti 10537939Skjc /** Print new line. 10625603Skjc */ 107116720Sharti protected void println() throws IOException { 10825603Skjc out.write(lineSep); 10925603Skjc } 11025603Skjc 11125603Skjc protected void printTagName(DocTree node) throws IOException { 11225603Skjc out.write("@"); 11325603Skjc out.write(node.getKind().tagName); 11425603Skjc } 115191148Skmacy 11625603Skjc final String lineSep = System.getProperty("line.separator"); 11725603Skjc 11825603Skjc /************************************************************************** 11925603Skjc * Traversal methods 12025603Skjc *************************************************************************/ 121191148Skmacy 12225603Skjc /** Exception to propagate IOException through visitXXX methods */ 12325603Skjc private static class UncheckedIOException extends Error { 124116720Sharti static final long serialVersionUID = -4032692679158424751L; 125191148Skmacy UncheckedIOException(IOException e) { 12625603Skjc super(e.getMessage(), e); 12725603Skjc } 12878249Speter } 12925603Skjc 13059633Skjc 13125603Skjc public Void visitAttribute(AttributeTree node, Void p) { 13237939Skjc try { 13325603Skjc print(node.getName()); 13425603Skjc String quote; 135105576Srwatson switch (node.getValueKind()) { 136172930Srwatson case EMPTY: 137105576Srwatson quote = null; 138105576Srwatson break; 139105576Srwatson case UNQUOTED: 140105576Srwatson quote = ""; 141148887Srwatson break; 142148887Srwatson case SINGLE: 14325603Skjc quote = "'"; 14425603Skjc break; 14525603Skjc case DOUBLE: 14625603Skjc quote = "\""; 14725603Skjc break; 14825603Skjc default: 14925603Skjc throw new AssertionError(); 150116720Sharti } 15137939Skjc if (quote != null) { 15225603Skjc print("=" + quote); 15337939Skjc print(node.getValue()); 154128636Sluigi print(quote); 15546695Skjc } 156112193Sharti } catch (IOException e) { 15746695Skjc throw new UncheckedIOException(e); 158112193Sharti } 159191148Skmacy return null; 16025603Skjc } 16125603Skjc 16225603Skjc public Void visitAuthor(AuthorTree node, Void p) { 16325603Skjc try { 16425603Skjc printTagName(node); 16525603Skjc print(" "); 166128636Sluigi print(node.getName()); 16725603Skjc } catch (IOException e) { 16837939Skjc throw new UncheckedIOException(e); 16925603Skjc } 17037939Skjc return null; 17137939Skjc } 17246695Skjc 17346695Skjc public Void visitComment(CommentTree node, Void p) { 17437939Skjc try { 17537939Skjc print(node.getBody()); 176116720Sharti } catch (IOException e) { 177116720Sharti throw new UncheckedIOException(e); 17837939Skjc } 17937939Skjc return null; 18025603Skjc } 18125603Skjc 18225603Skjc public Void visitDeprecated(DeprecatedTree node, Void p) { 18325603Skjc try { 18425603Skjc printTagName(node); 18525603Skjc if (!node.getBody().isEmpty()) { 18625603Skjc print(" "); 18725603Skjc print(node.getBody()); 18825603Skjc } 18925603Skjc } catch (IOException e) { 19025603Skjc throw new UncheckedIOException(e); 191116720Sharti } 192116720Sharti return null; 193111119Simp } 19425603Skjc 19525603Skjc public Void visitDocComment(DocCommentTree node, Void p) { 19625603Skjc try { 19725603Skjc List<? extends DocTree> fs = node.getFirstSentence(); 19825603Skjc List<? extends DocTree> b = node.getBody(); 19925603Skjc List<? extends DocTree> t = node.getBlockTags(); 20037939Skjc print(fs); 20137939Skjc if (!fs.isEmpty() && !b.isEmpty()) 20237939Skjc print(" "); 203116720Sharti print(b); 20437939Skjc if ((!fs.isEmpty() || !b.isEmpty()) && !t.isEmpty()) 20537939Skjc print("\n"); 20637939Skjc print(t, "\n"); 20737939Skjc } catch (IOException e) { 20825603Skjc throw new UncheckedIOException(e); 20925603Skjc } 21025603Skjc return null; 211116741Sharti } 212116741Sharti 213116741Sharti public Void visitDocRoot(DocRootTree node, Void p) { 214116741Sharti try { 215116741Sharti print("{"); 216116741Sharti printTagName(node); 217116741Sharti print("}"); 218116741Sharti } catch (IOException e) { 219116741Sharti throw new UncheckedIOException(e); 220116741Sharti } 22125603Skjc return null; 22225603Skjc } 22325603Skjc 22425603Skjc public Void visitEndElement(EndElementTree node, Void p) { 225117629Sharti try { 226117629Sharti print("</"); 22769152Sjlemon print(node.getName()); 22825603Skjc print(">"); 22925603Skjc } catch (IOException e) { 23025603Skjc throw new UncheckedIOException(e); 23125603Skjc } 23225603Skjc return null; 23325603Skjc } 23425603Skjc 23525603Skjc public Void visitEntity(EntityTree node, Void p) { 23625603Skjc try { 23725603Skjc print("&"); 23825603Skjc print(node.getName()); 23925603Skjc print(";"); 24025603Skjc } catch (IOException e) { 241116720Sharti throw new UncheckedIOException(e); 242116720Sharti } 24325603Skjc return null; 244111888Sjlemon } 245116720Sharti 24625603Skjc public Void visitErroneous(ErroneousTree node, Void p) { 24725603Skjc try { 24825603Skjc print(node.getBody()); 24925603Skjc } catch (IOException e) { 25025603Skjc throw new UncheckedIOException(e); 251105576Srwatson } 252172930Srwatson return null; 253105576Srwatson } 25425603Skjc 25525603Skjc public Void visitIdentifier(IdentifierTree node, Void p) { 256116741Sharti try { 257116741Sharti print(node.getName()); 258116741Sharti } catch (IOException e) { 259116741Sharti throw new UncheckedIOException(e); 260116741Sharti } 261116741Sharti return null; 262116741Sharti } 263116741Sharti 264116741Sharti public Void visitInheritDoc(InheritDocTree node, Void p) { 265116741Sharti try { 266116741Sharti print("{"); 267116741Sharti printTagName(node); 268116741Sharti print("}"); 26925603Skjc } catch (IOException e) { 27025603Skjc throw new UncheckedIOException(e); 271148125Srwatson } 272116720Sharti return null; 273148125Srwatson } 274148125Srwatson 275148125Srwatson public Void visitLink(LinkTree node, Void p) { 276148125Srwatson try { 277148125Srwatson print("{"); 278148125Srwatson printTagName(node); 279148125Srwatson print(" "); 28037939Skjc print(node.getReference()); 281111888Sjlemon if (!node.getLabel().isEmpty()) { 28237939Skjc print(" "); 283148125Srwatson print(node.getLabel()); 28425603Skjc } 285116720Sharti print("}"); 286116720Sharti } catch (IOException e) { 287116741Sharti throw new UncheckedIOException(e); 28825603Skjc } 28925603Skjc return null; 29037939Skjc } 29137939Skjc 29237939Skjc public Void visitLiteral(LiteralTree node, Void p) { 29337939Skjc try { 29437939Skjc print("{"); 295116720Sharti printTagName(node); 29637939Skjc print(" "); 29737939Skjc print(node.getBody()); 29837939Skjc print("}"); 29937939Skjc } catch (IOException e) { 30037939Skjc throw new UncheckedIOException(e); 301116720Sharti } 302116720Sharti return null; 303116720Sharti } 30437939Skjc 30537939Skjc public Void visitParam(ParamTree node, Void p) { 30637939Skjc try { 30737939Skjc printTagName(node); 30837939Skjc print(" "); 30937939Skjc if (node.isTypeParameter()) print("<"); 31025603Skjc print(node.getName()); 31137939Skjc if (node.isTypeParameter()) print(">"); 312116720Sharti if (!node.getDescription().isEmpty()) { 31325603Skjc print(" "); 31437939Skjc print(node.getDescription()); 315111888Sjlemon } 31637939Skjc } catch (IOException e) { 31725603Skjc throw new UncheckedIOException(e); 318116720Sharti } 31937939Skjc return null; 32037939Skjc } 321111888Sjlemon 32237939Skjc public Void visitReference(ReferenceTree node, Void p) { 32337939Skjc try { 32437939Skjc print(node.getSignature()); 325116741Sharti } catch (IOException e) { 326116741Sharti throw new UncheckedIOException(e); 327116741Sharti } 328116741Sharti return null; 329116741Sharti } 330116741Sharti 331116741Sharti public Void visitReturn(ReturnTree node, Void p) { 33237939Skjc try { 33337939Skjc printTagName(node); 33425603Skjc print(" "); 335223741Sbz print(node.getDescription()); 336111888Sjlemon } catch (IOException e) { 33725603Skjc throw new UncheckedIOException(e); 33825603Skjc } 33925603Skjc return null; 340114201Sharti } 34125603Skjc 34225603Skjc public Void visitSee(SeeTree node, Void p) { 343116720Sharti try { 34425603Skjc printTagName(node); 345111774Smdodd boolean first = true; 346111774Smdodd boolean needSep = true; 347147256Sbrooks for (DocTree t: node.getReference()) { 34825603Skjc if (needSep) print(" "); 34925603Skjc needSep = (first && (t instanceof ReferenceTree)); 35025603Skjc first = false; 351114201Sharti print(t); 35225603Skjc } 35325603Skjc } catch (IOException e) { 354106939Ssam throw new UncheckedIOException(e); 355106939Ssam } 356106939Ssam return null; 35746695Skjc } 35825603Skjc 359160035Syar public Void visitSerial(SerialTree node, Void p) { 360160038Syar try { 361160038Syar printTagName(node); 36225603Skjc if (!node.getDescription().isEmpty()) { 36325603Skjc print(" "); 36425603Skjc print(node.getDescription()); 36525603Skjc } 36625603Skjc } catch (IOException e) { 36725603Skjc throw new UncheckedIOException(e); 36825603Skjc } 36937939Skjc return null; 370114739Sharti } 371114739Sharti 372116741Sharti public Void visitSerialData(SerialDataTree node, Void p) { 373116741Sharti try { 374116741Sharti printTagName(node); 375116741Sharti if (!node.getDescription().isEmpty()) { 376116741Sharti print(" "); 37737939Skjc print(node.getDescription()); 378114201Sharti } 379114201Sharti } catch (IOException e) { 380114201Sharti throw new UncheckedIOException(e); 381114201Sharti } 382114201Sharti return null; 383114201Sharti } 384114201Sharti 385116741Sharti public Void visitSerialField(SerialFieldTree node, Void p) { 386116741Sharti try { 387116741Sharti printTagName(node); 388116741Sharti print(" "); 389114201Sharti print(node.getName()); 390114201Sharti print(" "); 391114201Sharti print(node.getType()); 392117630Sharti if (!node.getDescription().isEmpty()) { 393117630Sharti print(" "); 394117630Sharti print(node.getDescription()); 395117630Sharti } 396117630Sharti } catch (IOException e) { 397117630Sharti throw new UncheckedIOException(e); 398117630Sharti } 399117630Sharti return null; 400117630Sharti } 401117630Sharti 402117630Sharti public Void visitSince(SinceTree node, Void p) { 403117630Sharti try { 404117630Sharti printTagName(node); 405117630Sharti print(" "); 406117630Sharti print(node.getBody()); 407117630Sharti } catch (IOException e) { 408117630Sharti throw new UncheckedIOException(e); 409117630Sharti } 410117630Sharti return null; 411117630Sharti } 412117630Sharti 413117630Sharti public Void visitStartElement(StartElementTree node, Void p) { 414117630Sharti try { 415117630Sharti print("<"); 416117630Sharti print(node.getName()); 417117630Sharti List<? extends DocTree> attrs = node.getAttributes(); 418117630Sharti if (!attrs.isEmpty()) { 419117630Sharti print(" "); 420117630Sharti print(attrs); 421117630Sharti DocTree last = node.getAttributes().get(attrs.size() - 1); 422117630Sharti if (node.isSelfClosing() && last instanceof AttributeTree 423117630Sharti && ((AttributeTree) last).getValueKind() == ValueKind.UNQUOTED) 424117630Sharti print(" "); 425117630Sharti } 426117630Sharti if (node.isSelfClosing()) 427117630Sharti print("/"); 428117630Sharti print(">"); 429117630Sharti } catch (IOException e) { 430117630Sharti throw new UncheckedIOException(e); 431117630Sharti } 432117630Sharti return null; 433117630Sharti } 434117630Sharti 435117630Sharti public Void visitText(TextTree node, Void p) { 436117630Sharti try { 437117630Sharti print(node.getBody()); 438117630Sharti } catch (IOException e) { 439117630Sharti throw new UncheckedIOException(e); 440117630Sharti } 441117630Sharti return null; 442117630Sharti } 443117630Sharti 444117630Sharti public Void visitThrows(ThrowsTree node, Void p) { 445117630Sharti try { 446117630Sharti printTagName(node); 447117630Sharti print(" "); 448118157Sharti print(node.getExceptionName()); 449118157Sharti if (!node.getDescription().isEmpty()) { 450118157Sharti print(" "); 451118157Sharti print(node.getDescription()); 452118157Sharti } 453118157Sharti } catch (IOException e) { 454118157Sharti throw new UncheckedIOException(e); 455118157Sharti } 456118157Sharti return null; 457118157Sharti } 458118157Sharti 459118157Sharti public Void visitUnknownBlockTag(UnknownBlockTagTree node, Void p) { 460118157Sharti try { 461147256Sbrooks print("@"); 462147256Sbrooks print(node.getTagName()); 463147256Sbrooks print(" "); 464147256Sbrooks print(node.getContent()); 465147256Sbrooks } catch (IOException e) { 466147256Sbrooks throw new UncheckedIOException(e); 467147256Sbrooks } 468147256Sbrooks return null; 469147256Sbrooks } 470147256Sbrooks 471147256Sbrooks public Void visitUnknownInlineTag(UnknownInlineTagTree node, Void p) { 472147256Sbrooks try { 473147256Sbrooks print("{"); 474147256Sbrooks print("@"); 475147256Sbrooks print(node.getTagName()); 476147256Sbrooks print(" "); 477147256Sbrooks print(node.getContent()); 478147256Sbrooks print("}"); 479147256Sbrooks } catch (IOException e) { 480147256Sbrooks throw new UncheckedIOException(e); 481147256Sbrooks } 482147256Sbrooks return null; 483147256Sbrooks } 484147256Sbrooks 485147256Sbrooks public Void visitValue(ValueTree node, Void p) { 486147256Sbrooks try { 487147256Sbrooks print("{"); 488147256Sbrooks printTagName(node); 489147256Sbrooks if (node.getReference() != null) { 490147256Sbrooks print(" "); 491147256Sbrooks print(node.getReference()); 492147256Sbrooks } 493147256Sbrooks print("}"); 494147256Sbrooks } catch (IOException e) { 495147256Sbrooks throw new UncheckedIOException(e); 496114201Sharti } 497114201Sharti return null; 498147256Sbrooks } 499114201Sharti 500114201Sharti public Void visitVersion(VersionTree node, Void p) { 501114201Sharti try { 502147256Sbrooks printTagName(node); 503114201Sharti print(" "); 504 print(node.getBody()); 505 } catch (IOException e) { 506 throw new UncheckedIOException(e); 507 } 508 return null; 509 } 510 511 public Void visitOther(DocTree node, Void p) { 512 try { 513 print("(UNKNOWN: " + node + ")"); 514 println(); 515 } catch (IOException e) { 516 throw new UncheckedIOException(e); 517 } 518 return null; 519 } 520} 521