src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -21,23 +21,41 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
-package com.sun.tools.doclets.formats.html;
+package jdk.javadoc.internal.doclets.formats.html;
 
-import com.sun.javadoc.*;
-import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
-import com.sun.tools.doclets.formats.html.markup.HtmlStyle;
-import com.sun.tools.doclets.formats.html.markup.HtmlTree;
-import com.sun.tools.doclets.formats.html.markup.RawHtml;
-import com.sun.tools.doclets.formats.html.markup.StringContent;
-import com.sun.tools.doclets.internal.toolkit.*;
-import com.sun.tools.doclets.internal.toolkit.builders.SerializedFormBuilder;
-import com.sun.tools.doclets.internal.toolkit.taglets.*;
-import com.sun.tools.doclets.internal.toolkit.util.*;
+import java.util.List;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleElementVisitor9;
 
+import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.IndexTree;
+import com.sun.tools.javac.util.DefinedBy;
+
+import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
+import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
+import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
+import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
+import jdk.javadoc.internal.doclets.toolkit.Configuration;
+import jdk.javadoc.internal.doclets.toolkit.Content;
+import jdk.javadoc.internal.doclets.toolkit.builders.SerializedFormBuilder;
+import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter;
+import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
+import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
+import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
+import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
+import jdk.javadoc.internal.doclets.toolkit.util.MessageRetriever;
+import jdk.javadoc.internal.doclets.toolkit.util.Utils;
+
 /**
  * The taglet writer that writes HTML.
  *
  *  <p><b>This is NOT part of any supported API.
  *  If you write code that depends on this, you do so at your own risk.

@@ -70,90 +88,66 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    protected Content codeTagOutput(Tag tag) {
-        Content result = HtmlTree.CODE(new StringContent(utils.normalizeNewlines(tag.text())));
+    protected Content codeTagOutput(Element element, DocTree tag) {
+        CommentHelper ch = utils.getCommentHelper(element);
+        String str = utils.normalizeNewlines(ch.getText(tag));
+        StringContent content = new StringContent(str);
+        Content result = HtmlTree.CODE(content);
         return result;
     }
 
-    protected Content indexTagOutput(Tag tag) {
-        String text = tag.text();
-        String tagText = "";
-        String desc = "";
-        if (text.isEmpty() || text.trim().isEmpty()) {
-            configuration.message.warning(tag.position(), "doclet.invalid_usage_of_tag", tag.name());
-        } else {
-            int len = text.length();
-            int tagTextEnd = 0;
-            int descstart = 0;
-            int start = 0;
-            Character term = ' ';
-            int cp = text.codePointAt(0);
-            if (cp == '"') {
-                term = '"';
-                start++;
+    protected Content indexTagOutput(Element element, DocTree tag) {
+        CommentHelper ch = utils.getCommentHelper(element);
+        IndexTree itt = (IndexTree)tag;
+
+        String tagText =  ch.getText(itt.getSearchTerm());
+        if (tagText.charAt(0) == '"' && tagText.charAt(tagText.length() - 1) == '"') {
+            tagText = tagText.substring(1, tagText.length() - 1);
             }
-            for (int i = start; i < len; i += Character.charCount(cp)) {
-                cp = text.codePointAt(i);
-                if (cp == term) {
-                    tagTextEnd = i;
-                    break;
-                }
-            }
-            if (tagTextEnd < len - 1 && tagTextEnd != 0) {
-                descstart = tagTextEnd + 1;
-            }
-            String desctext = "";
-            if (descstart > 0) {
-                tagText = text.substring(start, tagTextEnd).trim();
-                desctext = text.substring(descstart, len).trim();
-                // strip off the white space which can be between tag description and the
-                // actual label.
-                for (int i = 0; i < desctext.length(); i++) {
-                    char ch2 = desctext.charAt(i);
-                    if (!(ch2 == ' ' || ch2 == '\t' || ch2 == '\n')) {
-                        desc = desctext.substring(i);
-                        break;
-                    }
-                }
-            } else {
-                if (term == '"') {
-                    if (tagTextEnd == 0) {
-                        // If unclosed quote, print out a warning and ignore the invalid tag text.
-                        configuration.message.warning(tag.position(), "doclet.invalid_usage_of_tag", tag.name());
-                        tagText = "";
-                    } else {
-                        tagText = text.substring(start, tagTextEnd).trim();
-                    }
-                } else {
-                    tagText = text.trim();
-                }
-                desc = "";
-            }
-        }
+        String desc = ch.getText(itt.getDescription());
+
         String anchorName = htmlWriter.getName(tagText);
         Content result = HtmlTree.A_ID(anchorName, new StringContent(tagText));
         if (configuration.createindex && !tagText.isEmpty()) {
             SearchIndexItem si = new SearchIndexItem();
             si.setLabel(tagText);
             si.setDescription(desc);
-            if (tag.holder() instanceof ProgramElementDoc) {
-                if (tag.holder() instanceof MemberDoc) {
-                    si.setUrl(DocPath.forClass(((MemberDoc) tag.holder()).containingClass()).getPath()
-                            + "#" + anchorName);
-                    si.setHolder(((MemberDoc) tag.holder()).qualifiedName());
-                } else {
-                    si.setUrl(DocPath.forClass((ClassDoc) tag.holder()).getPath() + "#" + anchorName);
-                    si.setHolder(((ClassDoc) tag.holder()).qualifiedName());
-                }
-            } else if (tag.holder() instanceof PackageDoc) {
-                si.setUrl(DocPath.forPackage((PackageDoc) tag.holder()).getPath()
+            new SimpleElementVisitor9<Void, Void>() {
+                @Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
+                public Void visitPackage(PackageElement e, Void p) {
+                    si.setUrl(DocPath.forPackage(e).getPath()
                         + "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName);
-                si.setHolder(((PackageDoc) tag.holder()).name());
+                    si.setHolder(utils.getSimpleName(element));
+                    return null;
             }
+
+                @Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
+                public Void visitType(TypeElement e, Void p) {
+                    si.setUrl(DocPath.forClass(utils, e).getPath() + "#" + anchorName);
+                    si.setHolder(utils.getFullyQualifiedName(e));
+                    return null;
+                }
+
+                @Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
+                public Void visitVariable(VariableElement e, Void p) {
+                    TypeElement te = utils.getEnclosingTypeElement(e);
+                    si.setUrl(DocPath.forClass(utils, te).getPath() + "#" + anchorName);
+                    si.setHolder(utils.getFullyQualifiedName(e) + "." + utils.getSimpleName(e));
+                    return null;
+                }
+
+                @Override @DefinedBy(DefinedBy.Api.LANGUAGE_MODEL)
+                protected Void defaultAction(Element e, Void p) {
+                    TypeElement te = utils.getEnclosingTypeElement(e);
+                    si.setUrl(DocPath.forClass(utils, te).getPath() + "#" + anchorName);
+                    si.setHolder(utils.getFullyQualifiedName(e));
+                    return null;
+                }
+            }.visit(element);
             si.setCategory(configuration.getResource("doclet.SearchTags").toString());
             configuration.tagSearchIndex.add(si);
         }
         return result;
     }

@@ -171,41 +165,39 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content deprecatedTagOutput(Doc doc) {
+    public Content deprecatedTagOutput(Element element) {
         ContentBuilder result = new ContentBuilder();
-        Tag[] deprs = doc.tags("deprecated");
-        if (doc instanceof ClassDoc) {
-            if (utils.isDeprecated((ProgramElementDoc) doc)) {
+        CommentHelper ch = utils.getCommentHelper(element);
+        List<? extends DocTree> deprs = utils.getBlockTags(element, DocTree.Kind.DEPRECATED);
+        if (utils.isTypeElement(element)) {
+            if (utils.isDeprecated(element)) {
                 result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
                         new StringContent(configuration.getText("doclet.Deprecated"))));
                 result.addContent(RawHtml.nbsp);
-                if (deprs.length > 0) {
-                    Tag[] commentTags = deprs[0].inlineTags();
-                    if (commentTags.length > 0) {
-                        result.addContent(commentTagsToOutput(null, doc,
-                            deprs[0].inlineTags(), false)
-                        );
+                if (!deprs.isEmpty()) {
+                    List<? extends DocTree> commentTags = ch.getDescription(configuration, deprs.get(0));
+                    if (!commentTags.isEmpty()) {
+                        result.addContent(commentTagsToOutput(null, element, commentTags, false));
                     }
                 }
             }
         } else {
-            MemberDoc member = (MemberDoc) doc;
-            if (utils.isDeprecated((ProgramElementDoc) doc)) {
+            if (utils.isDeprecated(element)) {
                 result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
                         new StringContent(configuration.getText("doclet.Deprecated"))));
                 result.addContent(RawHtml.nbsp);
-                if (deprs.length > 0) {
-                    Content body = commentTagsToOutput(null, doc,
-                        deprs[0].inlineTags(), false);
+                if (!deprs.isEmpty()) {
+                    List<? extends DocTree> bodyTags = ch.getBody(configuration, deprs.get(0));
+                    Content body = commentTagsToOutput(null, element, bodyTags, false);
                     if (!body.isEmpty())
                         result.addContent(HtmlTree.SPAN(HtmlStyle.deprecationComment, body));
                 }
             } else {
-                if (utils.isDeprecated(member.containingClass())) {
+                if (utils.isDeprecated(utils.getEnclosingTypeElement(element))) {
                     result.addContent(HtmlTree.SPAN(HtmlStyle.deprecatedLabel,
                             new StringContent(configuration.getText("doclet.Deprecated"))));
                     result.addContent(RawHtml.nbsp);
                 }
             }

@@ -214,12 +206,13 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    protected Content literalTagOutput(Tag tag) {
-        Content result = new StringContent(utils.normalizeNewlines(tag.text()));
+    protected Content literalTagOutput(Element element, DocTree tag) {
+        CommentHelper ch = utils.getCommentHelper(element);
+        Content result = new StringContent(utils.normalizeNewlines(ch.getText(tag)));
         return result;
     }
 
     /**
      * {@inheritDoc}

@@ -238,74 +231,79 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content paramTagOutput(ParamTag paramTag, String paramName) {
+    public Content paramTagOutput(Element element, DocTree paramTag, String paramName) {
         ContentBuilder body = new ContentBuilder();
+        CommentHelper ch = utils.getCommentHelper(element);
         body.addContent(HtmlTree.CODE(new RawHtml(paramName)));
         body.addContent(" - ");
-        body.addContent(htmlWriter.commentTagsToContent(paramTag, null, paramTag.inlineTags(), false));
+        List<? extends DocTree> description = ch.getDescription(configuration, paramTag);
+        body.addContent(htmlWriter.commentTagsToContent(paramTag, element, description, false));
         HtmlTree result = HtmlTree.DD(body);
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content propertyTagOutput(Tag tag, String prefix) {
+    public Content propertyTagOutput(Element element, DocTree tag, String prefix) {
         Content body = new ContentBuilder();
+        CommentHelper ch = utils.getCommentHelper(element);
         body.addContent(new RawHtml(prefix));
         body.addContent(" ");
-        body.addContent(HtmlTree.CODE(new RawHtml(tag.text())));
+        body.addContent(HtmlTree.CODE(new RawHtml(ch.getText(tag))));
         body.addContent(".");
         Content result = HtmlTree.P(body);
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content returnTagOutput(Tag returnTag) {
+    public Content returnTagOutput(Element element, DocTree returnTag) {
         ContentBuilder result = new ContentBuilder();
+        CommentHelper ch = utils.getCommentHelper(element);
         result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.returnLabel,
                 new StringContent(configuration.getText("doclet.Returns")))));
         result.addContent(HtmlTree.DD(htmlWriter.commentTagsToContent(
-                returnTag, null, returnTag.inlineTags(), false)));
+                returnTag, element, ch.getDescription(configuration, returnTag), false)));
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content seeTagOutput(Doc holder, SeeTag[] seeTags) {
+    public Content seeTagOutput(Element holder, List<? extends DocTree> seeTags) {
         ContentBuilder body = new ContentBuilder();
-        if (seeTags.length > 0) {
-            for (SeeTag seeTag : seeTags) {
+        if (!seeTags.isEmpty()) {
+            for (DocTree dt : seeTags) {
                 appendSeparatorIfNotEmpty(body);
-                body.addContent(htmlWriter.seeTagToContent(seeTag));
+                body.addContent(htmlWriter.seeTagToContent(holder, dt));
             }
         }
-        if (holder.isField() && ((FieldDoc)holder).constantValue() != null &&
+        if (utils.isVariableElement(holder) && ((VariableElement)holder).getConstantValue() != null &&
                 htmlWriter instanceof ClassWriterImpl) {
             //Automatically add link to constant values page for constant fields.
             appendSeparatorIfNotEmpty(body);
             DocPath constantsPath =
                     htmlWriter.pathToRoot.resolve(DocPaths.CONSTANT_VALUES);
             String whichConstant =
-                    ((ClassWriterImpl) htmlWriter).getClassDoc().qualifiedName() + "." + ((FieldDoc) holder).name();
+                    ((ClassWriterImpl) htmlWriter).getTypeElement().getQualifiedName() + "." +
+                    utils.getSimpleName(holder);
             DocLink link = constantsPath.fragment(whichConstant);
             body.addContent(htmlWriter.getHyperLink(link,
                     new StringContent(configuration.getText("doclet.Constants_Summary"))));
         }
-        if (holder.isClass() && ((ClassDoc)holder).isSerializable()) {
+        if (utils.isClass(holder) && utils.isSerializable((TypeElement)holder)) {
             //Automatically add link to serialized form page for serializable classes.
-            if ((SerializedFormBuilder.serialInclude(holder) &&
-                      SerializedFormBuilder.serialInclude(((ClassDoc)holder).containingPackage()))) {
+            if (SerializedFormBuilder.serialInclude(utils, holder) &&
+                      SerializedFormBuilder.serialInclude(utils, utils.containingPackage(holder))) {
                 appendSeparatorIfNotEmpty(body);
                 DocPath serialPath = htmlWriter.pathToRoot.resolve(DocPaths.SERIALIZED_FORM);
-                DocLink link = serialPath.fragment(((ClassDoc)holder).qualifiedName());
+                DocLink link = serialPath.fragment(utils.getFullyQualifiedName(holder));
                 body.addContent(htmlWriter.getHyperLink(link,
                         new StringContent(configuration.getText("doclet.Serialized_Form"))));
             }
         }
         if (body.isEmpty())

@@ -327,33 +325,37 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content simpleTagOutput(Tag[] simpleTags, String header) {
+    public Content simpleTagOutput(Element element, List<? extends DocTree> simpleTags, String header) {
+        CommentHelper ch = utils.getCommentHelper(element);
         ContentBuilder result = new ContentBuilder();
         result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.simpleTagLabel, new RawHtml(header))));
         ContentBuilder body = new ContentBuilder();
-        for (int i = 0; i < simpleTags.length; i++) {
-            if (i > 0) {
+        boolean many = false;
+        for (DocTree simpleTag : simpleTags) {
+            if (many) {
                 body.addContent(", ");
             }
-            body.addContent(htmlWriter.commentTagsToContent(
-                    simpleTags[i], null, simpleTags[i].inlineTags(), false));
+            List<? extends DocTree> bodyTags = ch.getBody(configuration, simpleTag);
+            body.addContent(htmlWriter.commentTagsToContent(simpleTag, element, bodyTags, false));
+            many = true;
         }
         result.addContent(HtmlTree.DD(body));
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content simpleTagOutput(Tag simpleTag, String header) {
+    public Content simpleTagOutput(Element element, DocTree simpleTag, String header) {
         ContentBuilder result = new ContentBuilder();
         result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.simpleTagLabel, new RawHtml(header))));
-        Content body = htmlWriter.commentTagsToContent(
-                simpleTag, null, simpleTag.inlineTags(), false);
+        CommentHelper ch = utils.getCommentHelper(element);
+        List<? extends DocTree> description = ch.getDescription(configuration, simpleTag);
+        Content body = htmlWriter.commentTagsToContent(simpleTag, element, description, false);
         result.addContent(HtmlTree.DD(body));
         return result;
     }
 
     /**

@@ -366,19 +368,28 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content throwsTagOutput(ThrowsTag throwsTag) {
+    public Content throwsTagOutput(Element element, DocTree throwsTag) {
         ContentBuilder body = new ContentBuilder();
-        Content excName = (throwsTag.exceptionType() == null) ?
-                new RawHtml(throwsTag.exceptionName()) :
-                htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
-                throwsTag.exceptionType()));
+        CommentHelper ch = utils.getCommentHelper(element);
+        Element exception = ch.getException(configuration, throwsTag);
+        Content excName;
+        if (exception == null) {
+            excName = new RawHtml(ch.getExceptionName(throwsTag).toString());
+        } else if (exception.asType() == null) {
+            excName = new RawHtml(utils.getFullyQualifiedName(exception));
+        } else {
+            LinkInfoImpl link = new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER,
+                                                 exception.asType());
+            link.excludeTypeBounds = true;
+            excName = htmlWriter.getLink(link);
+        }
         body.addContent(HtmlTree.CODE(excName));
-        Content desc = htmlWriter.commentTagsToContent(throwsTag, null,
-            throwsTag.inlineTags(), false);
+        List<? extends DocTree> description = ch.getDescription(configuration, throwsTag);
+        Content desc = htmlWriter.commentTagsToContent(throwsTag, element, description, false);
         if (desc != null && !desc.isEmpty()) {
             body.addContent(" - ");
             body.addContent(desc);
         }
         HtmlTree result = HtmlTree.DD(body);

@@ -386,47 +397,46 @@
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content throwsTagOutput(Type throwsType) {
+    public Content throwsTagOutput(TypeMirror throwsType) {
         HtmlTree result = HtmlTree.DD(HtmlTree.CODE(htmlWriter.getLink(
                 new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, throwsType))));
         return result;
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content valueTagOutput(FieldDoc field, String constantVal,
-            boolean includeLink) {
+    public Content valueTagOutput(VariableElement field, String constantVal, boolean includeLink) {
         return includeLink ?
             htmlWriter.getDocLink(LinkInfoImpl.Kind.VALUE_TAG, field,
                 constantVal, false) : new RawHtml(constantVal);
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content commentTagsToOutput(Tag holderTag, Tag[] tags) {
+    public Content commentTagsToOutput(DocTree holderTag, List<? extends DocTree> tags) {
         return commentTagsToOutput(holderTag, null, tags, false);
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content commentTagsToOutput(Doc holderDoc, Tag[] tags) {
-        return commentTagsToOutput(null, holderDoc, tags, false);
+    public Content commentTagsToOutput(Element holder, List<? extends DocTree> tags) {
+        return commentTagsToOutput(null, holder, tags, false);
     }
 
     /**
      * {@inheritDoc}
      */
-    public Content commentTagsToOutput(Tag holderTag,
-        Doc holderDoc, Tag[] tags, boolean isFirstSentence) {
-        return htmlWriter.commentTagsToContent(
-            holderTag, holderDoc, tags, isFirstSentence);
+    public Content commentTagsToOutput(DocTree holderTag,
+        Element holder, List<? extends DocTree> tags, boolean isFirstSentence) {
+        return htmlWriter.commentTagsToContent(holderTag, holder,
+                tags, isFirstSentence);
     }
 
     /**
      * {@inheritDoc}
      */