--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Sep 25 12:36:45 2018 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Tue Sep 25 13:58:54 2018 +0530
@@ -355,6 +355,7 @@
/**
* Returns a TagletWriter that knows how to write HTML.
*
+ * @param isFirstSentence true if we want to write the first sentence
* @return a TagletWriter that knows how to write HTML.
*/
public TagletWriter getTagletWriterInstance(boolean isFirstSentence) {
@@ -362,6 +363,17 @@
}
/**
+ * Returns a TagletWriter that knows how to write HTML.
+ *
+ * @param isFirstSentence true if we want to write the first sentence
+ * @param inSummary true if tags are to be added in a summary section
+ * @return a TagletWriter
+ */
+ public TagletWriter getTagletWriterInstance(boolean isFirstSentence, boolean inSummary) {
+ return new TagletWriterImpl(this, isFirstSentence, inSummary);
+ }
+
+ /**
* Get Package link, with target frame.
*
* @param pkg The link will be to the "package-summary.html" page for this package
@@ -1127,7 +1139,7 @@
public void addInlineComment(Element element, DocTree tag, Content htmltree) {
CommentHelper ch = utils.getCommentHelper(element);
List<? extends DocTree> description = ch.getDescription(configuration, tag);
- addCommentTags(element, tag, description, false, false, htmltree);
+ addCommentTags(element, tag, description, false, false, false, htmltree);
}
/**
@@ -1151,7 +1163,7 @@
*/
public void addInlineDeprecatedComment(Element e, DocTree tag, Content htmltree) {
CommentHelper ch = utils.getCommentHelper(e);
- addCommentTags(e, ch.getBody(configuration, tag), true, false, htmltree);
+ addCommentTags(e, ch.getBody(configuration, tag), true, false, false, htmltree);
}
/**
@@ -1172,13 +1184,13 @@
* @param htmltree the documentation tree to which the summary will be added
*/
public void addSummaryComment(Element element, List<? extends DocTree> firstSentenceTags, Content htmltree) {
- addCommentTags(element, firstSentenceTags, false, true, htmltree);
+ addCommentTags(element, firstSentenceTags, false, true, true, htmltree);
}
public void addSummaryDeprecatedComment(Element element, DocTree tag, Content htmltree) {
CommentHelper ch = utils.getCommentHelper(element);
List<? extends DocTree> body = ch.getBody(configuration, tag);
- addCommentTags(element, ch.getFirstSentenceTrees(configuration, body), true, true, htmltree);
+ addCommentTags(element, ch.getFirstSentenceTrees(configuration, body), true, true, true, htmltree);
}
/**
@@ -1188,7 +1200,7 @@
* @param htmltree the documentation tree to which the inline comments will be added
*/
public void addInlineComment(Element element, Content htmltree) {
- addCommentTags(element, utils.getFullBody(element), false, false, htmltree);
+ addCommentTags(element, utils.getFullBody(element), false, false, false, htmltree);
}
/**
@@ -1198,11 +1210,12 @@
* @param tags the first sentence tags for the doc
* @param depr true if it is deprecated
* @param first true if the first sentence tags should be added
+ * @param inSummary true if the comment tags are added into the summary section
* @param htmltree the documentation tree to which the comment tags will be added
*/
private void addCommentTags(Element element, List<? extends DocTree> tags, boolean depr,
- boolean first, Content htmltree) {
- addCommentTags(element, null, tags, depr, first, htmltree);
+ boolean first, boolean inSummary, Content htmltree) {
+ addCommentTags(element, null, tags, depr, first, inSummary, htmltree);
}
/**
@@ -1213,15 +1226,16 @@
* @param tags the first sentence tags for the doc
* @param depr true if it is deprecated
* @param first true if the first sentence tags should be added
+ * @param inSummary true if the comment tags are added into the summary section
* @param htmltree the documentation tree to which the comment tags will be added
*/
private void addCommentTags(Element element, DocTree holderTag, List<? extends DocTree> tags, boolean depr,
- boolean first, Content htmltree) {
+ boolean first, boolean inSummary, Content htmltree) {
if(configuration.nocomment){
return;
}
Content div;
- Content result = commentTagsToContent(null, element, tags, first);
+ Content result = commentTagsToContent(null, element, tags, first, inSummary);
if (depr) {
div = HtmlTree.DIV(HtmlStyle.deprecationComment, result);
htmltree.addContent(div);
@@ -1267,10 +1281,10 @@
private boolean commentRemoved = false;
/**
- * Converts inline tags and text to text strings, expanding the
+ * Converts inline tags and text to Content, expanding the
* inline tags along the way. Called wherever text can contain
* an inline tag, such as in comments or in free-form text arguments
- * to non-inline tags.
+ * to block tags.
*
* @param holderTag specific tag where comment resides
* @param element specific element where comment resides
@@ -1281,6 +1295,25 @@
*/
public Content commentTagsToContent(DocTree holderTag, Element element,
List<? extends DocTree> tags, boolean isFirstSentence) {
+ return commentTagsToContent(holderTag, element, tags, isFirstSentence, false);
+ }
+
+ /**
+ * Converts inline tags and text to text strings, expanding the
+ * inline tags along the way. Called wherever text can contain
+ * an inline tag, such as in comments or in free-form text arguments
+ * to block tags.
+ *
+ * @param holderTag specific tag where comment resides
+ * @param element specific element where comment resides
+ * @param tags array of text tags and inline tags (often alternating)
+ present in the text of interest for this element
+ * @param isFirstSentence true if text is first sentence
+ * @param inSummary if the comment tags are added into the summary section
+ * @return a Content object
+ */
+ public Content commentTagsToContent(DocTree holderTag, Element element,
+ List<? extends DocTree> tags, boolean isFirstSentence, boolean inSummary) {
final Content result = new ContentBuilder() {
@Override
@@ -1445,7 +1478,7 @@
public Boolean visitIndex(IndexTree node, Content p) {
Content output = TagletWriter.getInlineTagOutput(element,
configuration.tagletManager, holderTag, tag,
- getTagletWriterInstance(isFirstSentence));
+ getTagletWriterInstance(isFirstSentence, inSummary));
if (output != null) {
result.addContent(output);
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Tue Sep 25 12:36:45 2018 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Tue Sep 25 13:58:54 2018 +0530
@@ -396,14 +396,14 @@
(utils.getBlockTags(mdle, DocTree.Kind.PROVIDES)).forEach((tree) -> {
TypeElement t = ch.getServiceType(configuration, tree);
if (t != null) {
- providesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false));
+ providesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false, true));
}
});
// Generate the map of all services listed using @uses, and the description.
(utils.getBlockTags(mdle, DocTree.Kind.USES)).forEach((tree) -> {
TypeElement t = ch.getServiceType(configuration, tree);
if (t != null) {
- usesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false));
+ usesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(configuration, tree), false, true));
}
});
}
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Tue Sep 25 12:36:45 2018 +0530
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java Tue Sep 25 13:58:54 2018 +0530
@@ -71,12 +71,18 @@
private final HtmlDocletWriter htmlWriter;
private final HtmlConfiguration configuration;
private final Utils utils;
+ private final boolean inSummary;
public TagletWriterImpl(HtmlDocletWriter htmlWriter, boolean isFirstSentence) {
+ this(htmlWriter, isFirstSentence, false);
+ }
+
+ public TagletWriterImpl(HtmlDocletWriter htmlWriter, boolean isFirstSentence, boolean inSummary) {
super(isFirstSentence);
this.htmlWriter = htmlWriter;
configuration = htmlWriter.configuration;
this.utils = configuration.utils;
+ this.inSummary = inSummary;
}
/**
@@ -107,53 +113,58 @@
String desc = ch.getText(itt.getDescription());
String anchorName = htmlWriter.links.getName(tagText);
- Content result = HtmlTree.A_ID(HtmlStyle.searchTagResult, anchorName, new StringContent(tagText));
- if (configuration.createindex && !tagText.isEmpty()) {
- SearchIndexItem si = new SearchIndexItem();
- si.setLabel(tagText);
- si.setDescription(desc);
- DocPaths docPaths = configuration.docPaths;
- new SimpleElementVisitor9<Void, Void>() {
- @Override
- public Void visitModule(ModuleElement e, Void p) {
- si.setUrl(docPaths.moduleSummary(e).getPath() + "#" + anchorName);
- si.setHolder(utils.getFullyQualifiedName(element));
- return null;
- }
+ Content result = null;
+ if (isFirstSentence && inSummary) {
+ result = new StringContent(tagText);
+ } else {
+ result = HtmlTree.A_ID(HtmlStyle.searchTagResult, anchorName, new StringContent(tagText));
+ if (configuration.createindex && !tagText.isEmpty()) {
+ SearchIndexItem si = new SearchIndexItem();
+ si.setLabel(tagText);
+ si.setDescription(desc);
+ DocPaths docPaths = configuration.docPaths;
+ new SimpleElementVisitor9<Void, Void>() {
+ @Override
+ public Void visitModule(ModuleElement e, Void p) {
+ si.setUrl(docPaths.moduleSummary(e).getPath() + "#" + anchorName);
+ si.setHolder(utils.getFullyQualifiedName(element));
+ return null;
+ }
- @Override
- public Void visitPackage(PackageElement e, Void p) {
- si.setUrl(docPaths.forPackage(e).getPath()
- + "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName);
- si.setHolder(utils.getSimpleName(element));
- return null;
- }
+ @Override
+ public Void visitPackage(PackageElement e, Void p) {
+ si.setUrl(docPaths.forPackage(e).getPath()
+ + "/" + DocPaths.PACKAGE_SUMMARY.getPath() + "#" + anchorName);
+ si.setHolder(utils.getSimpleName(element));
+ return null;
+ }
- @Override
- public Void visitType(TypeElement e, Void p) {
- si.setUrl(docPaths.forClass(e).getPath() + "#" + anchorName);
- si.setHolder(utils.getFullyQualifiedName(e));
- return null;
- }
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ si.setUrl(docPaths.forClass(e).getPath() + "#" + anchorName);
+ si.setHolder(utils.getFullyQualifiedName(e));
+ return null;
+ }
- @Override
- public Void visitVariable(VariableElement e, Void p) {
- TypeElement te = utils.getEnclosingTypeElement(e);
- si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
- si.setHolder(utils.getFullyQualifiedName(e) + "." + utils.getSimpleName(e));
- return null;
- }
+ @Override
+ public Void visitVariable(VariableElement e, Void p) {
+ TypeElement te = utils.getEnclosingTypeElement(e);
+ si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
+ si.setHolder(utils.getFullyQualifiedName(e) + "." + utils.getSimpleName(e));
+ return null;
+ }
- @Override
- protected Void defaultAction(Element e, Void p) {
- TypeElement te = utils.getEnclosingTypeElement(e);
- si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
- si.setHolder(utils.getFullyQualifiedName(e));
- return null;
- }
- }.visit(element);
- si.setCategory(configuration.getContent("doclet.SearchTags").toString());
- configuration.tagSearchIndex.add(si);
+ @Override
+ protected Void defaultAction(Element e, Void p) {
+ TypeElement te = utils.getEnclosingTypeElement(e);
+ si.setUrl(docPaths.forClass(te).getPath() + "#" + anchorName);
+ si.setHolder(utils.getFullyQualifiedName(e));
+ return null;
+ }
+ }.visit(element);
+ si.setCategory(configuration.getContent("doclet.SearchTags").toString());
+ configuration.tagSearchIndex.add(si);
+ }
}
return result;
}
@@ -236,7 +247,7 @@
body.addContent(HtmlTree.CODE(new RawHtml(paramName)));
body.addContent(" - ");
List<? extends DocTree> description = ch.getDescription(configuration, paramTag);
- body.addContent(htmlWriter.commentTagsToContent(paramTag, element, description, false));
+ body.addContent(htmlWriter.commentTagsToContent(paramTag, element, description, false, inSummary));
HtmlTree result = HtmlTree.DD(body);
return result;
}
@@ -264,7 +275,7 @@
result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.returnLabel,
new StringContent(configuration.getText("doclet.Returns")))));
result.addContent(HtmlTree.DD(htmlWriter.commentTagsToContent(
- returnTag, element, ch.getDescription(configuration, returnTag), false)));
+ returnTag, element, ch.getDescription(configuration, returnTag), false, inSummary)));
return result;
}
@@ -333,7 +344,7 @@
body.addContent(", ");
}
List<? extends DocTree> bodyTags = ch.getBody(configuration, simpleTag);
- body.addContent(htmlWriter.commentTagsToContent(simpleTag, element, bodyTags, false));
+ body.addContent(htmlWriter.commentTagsToContent(simpleTag, element, bodyTags, false, inSummary));
many = true;
}
result.addContent(HtmlTree.DD(body));
@@ -348,7 +359,7 @@
result.addContent(HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.simpleTagLabel, new RawHtml(header))));
CommentHelper ch = utils.getCommentHelper(element);
List<? extends DocTree> description = ch.getDescription(configuration, simpleTag);
- Content body = htmlWriter.commentTagsToContent(simpleTag, element, description, false);
+ Content body = htmlWriter.commentTagsToContent(simpleTag, element, description, false, inSummary);
result.addContent(HtmlTree.DD(body));
return result;
}
@@ -382,7 +393,7 @@
}
body.addContent(HtmlTree.CODE(excName));
List<? extends DocTree> description = ch.getDescription(configuration, throwsTag);
- Content desc = htmlWriter.commentTagsToContent(throwsTag, element, description, false);
+ Content desc = htmlWriter.commentTagsToContent(throwsTag, element, description, false, inSummary);
if (desc != null && !desc.isEmpty()) {
body.addContent(" - ");
body.addContent(desc);
@@ -429,7 +440,7 @@
public Content commentTagsToOutput(DocTree holderTag,
Element holder, List<? extends DocTree> tags, boolean isFirstSentence) {
return htmlWriter.commentTagsToContent(holderTag, holder,
- tags, isFirstSentence);
+ tags, isFirstSentence, inSummary);
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testIndexTaglet/TestIndexTaglet.java Tue Sep 25 13:58:54 2018 +0530
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018, 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
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8202462
+ * @summary {@index} may cause duplicate labels
+ * @library /tools/lib ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build JavadocTester toolbox.ToolBox builder.ClassBuilder
+ * @run main TestIndexTaglet
+ */
+
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import builder.ClassBuilder;
+import builder.ClassBuilder.MethodBuilder;
+import toolbox.ToolBox;
+
+public class TestIndexTaglet extends JavadocTester {
+
+ final ToolBox tb;
+
+ public static void main(String... args) throws Exception {
+ TestIndexTaglet tester = new TestIndexTaglet();
+ tester.runTests(m -> new Object[]{Paths.get(m.getName())});
+ }
+
+ TestIndexTaglet() {
+ tb = new ToolBox();
+ }
+
+ @Test
+ void test(Path base) throws Exception {
+ Path srcDir = base.resolve("src");
+ createTestClass(srcDir);
+
+ Path outDir = base.resolve("out");
+ javadoc("-d", outDir.toString(),
+ "-sourcepath", srcDir.toString(),
+ "pkg");
+
+ checkExit(Exit.OK);
+
+ checkOrder("pkg/A.html",
+ "<h3>Method Detail</h3>\n",
+ "<div class=\"block\">test description with <a id=\"search_phrase_a\" "
+ + "class=\"searchTagResult\">search_phrase_a</a></div>");
+
+ checkOrder("pkg/A.html",
+ "<h3>Method Summary</h3>\n",
+ "<div class=\"block\">test description with search_phrase_a</div>");
+ }
+
+ void createTestClass(Path srcDir) throws Exception {
+ MethodBuilder method = MethodBuilder
+ .parse("public void func(A a) {}")
+ .setComments("test description with {@index search_phrase_a class a}");
+
+ new ClassBuilder(tb, "pkg.A")
+ .setModifiers("public", "class")
+ .addMembers(method)
+ .write(srcDir);
+
+ }
+}
--- a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java Tue Sep 25 12:36:45 2018 +0530
+++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java Tue Sep 25 13:58:54 2018 +0530
@@ -1071,7 +1071,7 @@
+ "<th class=\"colSecond\" scope=\"row\"><a href=\"../moduleA/module-summary.html\">moduleA</a></th>\n"
+ "<td class=\"colLast\">\n"
+ "<div class=\"block\">This is a test description for the moduleA module with a Search "
- + "phrase <a id=\"searchphrase\" class=\"searchTagResult\">search phrase</a>.</div>\n"
+ + "phrase search phrase.</div>\n"
+ "</td>\n"
+ "</tr>\n"
+ "<tr class=\"rowColor\">\n"
@@ -1164,7 +1164,7 @@
+ "<dt><a href=\"moduleA/module-summary.html\">moduleA</a> - module moduleA</dt>\n"
+ "<dd>\n"
+ "<div class=\"block\">This is a test description for the moduleA module with a Search "
- + "phrase <a id=\"searchphrase\" class=\"searchTagResult\">search phrase</a>.</div>\n"
+ + "phrase search phrase.</div>\n"
+ "</dd>\n"
+ "<dt><a href=\"moduleB/module-summary.html\">moduleB</a> - module moduleB</dt>\n"
+ "<dd>\n"
@@ -1193,7 +1193,7 @@
"<th class=\"colFirst\" scope=\"row\"><a href=\"moduleA/module-summary.html\">moduleA</a></th>\n"
+ "<td class=\"colLast\">\n"
+ "<div class=\"block\">This is a test description for the moduleA module with a Search "
- + "phrase <a id=\"searchphrase\" class=\"searchTagResult\">search phrase</a>.</div>\n"
+ + "phrase search phrase.</div>\n"
+ "</td>",
"<th class=\"colFirst\" scope=\"row\"><a href=\"moduleB/module-summary.html\">moduleB</a></th>\n"
+ "<td class=\"colLast\">\n"
@@ -1235,7 +1235,7 @@
+ "<th class=\"colSecond\" scope=\"row\"><a href=\"../moduleA/module-summary.html\">moduleA</a></th>\n"
+ "<td class=\"colLast\">\n"
+ "<div class=\"block\">This is a test description for the moduleA module with a Search "
- + "phrase <a id=\"searchphrase\" class=\"searchTagResult\">search phrase</a>.</div>\n"
+ + "phrase search phrase.</div>\n"
+ "</td>",
"<table class=\"requiresSummary\">\n"
+ "<caption><span>Requires</span><span class=\"tabEnd\"> </span></caption>\n"