8192007: javadoc @uses and @provides tags in the modules documentation appears before the first-sentence summary of the service type.
Reviewed-by: jjg, ksrini
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Wed Jan 03 18:21:10 2018 -0800
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java Thu Jan 04 09:22:17 2018 -0800
@@ -820,11 +820,14 @@
Content summary = new ContentBuilder();
if (display(usesTrees)) {
description = usesTrees.get(t);
- if (description != null) {
- summary.addContent(description);
+ if (description != null && !description.isEmpty()) {
+ summary.addContent(HtmlTree.DIV(HtmlStyle.block, description));
+ } else {
+ addSummaryComment(t, summary);
}
+ } else {
+ summary.addContent(Contents.SPACE);
}
- addSummaryComment(t, summary);
table.addRow(typeLinkContent, summary);
}
}
@@ -847,11 +850,12 @@
Content desc = new ContentBuilder();
if (display(providesTrees)) {
description = providesTrees.get(srv);
- if (description != null) {
- desc.addContent(description);
+ desc.addContent((description != null && !description.isEmpty())
+ ? HtmlTree.DIV(HtmlStyle.block, description)
+ : Contents.SPACE);
+ } else {
+ desc.addContent(Contents.SPACE);
}
- }
- addSummaryComment(srv, desc);
// Only display the implementation details in the "all" mode.
if (moduleMode == ModuleMode.ALL && !implSet.isEmpty()) {
desc.addContent(new HtmlTree(HtmlTag.BR));
--- a/test/langtools/jdk/javadoc/doclet/testModules/TestModuleServices.java Wed Jan 03 18:21:10 2018 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModuleServices.java Thu Jan 04 09:22:17 2018 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8178067
+ * @bug 8178067 8192007
* @summary tests the module's services, such as provides and uses
* @modules jdk.javadoc/jdk.javadoc.internal.api
* jdk.javadoc/jdk.javadoc.internal.tool
@@ -34,6 +34,7 @@
* @run main TestModuleServices
*/
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -52,6 +53,106 @@
}
@Test
+ public void checkModuleServicesDescription(Path base) throws Exception {
+ Path src = Files.createDirectories(base.resolve("src"));
+ ModuleBuilder mb = new ModuleBuilder(tb, "moduleService")
+ .comment("This module exports a package containing the declaration of a service type.")
+ .exports("pkgService")
+ .classes("/**A Package that has a service.*/ package pkgService;")
+ .classes("package pkgService; /**A service Interface for service providers.*/ "
+ + "public interface Service {\n"
+ + " /**\n"
+ + " * A test method for the service.\n"
+ + " */\n"
+ + " void testMethod1();\n"
+ + " /**\n"
+ + " * Another test method for the service.\n"
+ + " */\n"
+ + " void testMethod2();\n"
+ + "}");
+ mb.write(src);
+ mb = new ModuleBuilder(tb, "moduleServiceProvider")
+ .comment("This module provides an implementation of a service.\n" +
+ "@provides pkgService.Service Provides a service whose name is ServiceProvider.")
+ .requires("moduleService")
+ .provides("pkgService.Service", "pkgServiceProvider.ServiceProvider")
+ .classes("/**A Package that has a service provider.*/ package pkgServiceProvider;")
+ .classes("package pkgServiceProvider;\n"
+ + "public class ServiceProvider implements pkgService.Service {\n"
+ + " /**\n"
+ + " * {@inheritDoc}\n"
+ + " */\n"
+ + " public void testMethod1() {}\n"
+ + " /**\n"
+ + " * This is an internal implementation so the documentation will not be seen.\n"
+ + " */\n"
+ + " public void testMethod2() {}\n"
+ + "}");
+ mb.write(src);
+ mb = new ModuleBuilder(tb, "moduleServiceUser")
+ .comment("This module uses a service defined in another module.\n"
+ + "@uses pkgService.Service If no other provider is found, a default internal implementation will be used.")
+ .requires("moduleService")
+ .uses("pkgService.Service")
+ .classes("/**A Package that has a service user.*/ package pkgServiceUser;")
+ .classes("package pkgServiceUser;\n"
+ + "/**\n"
+ + " * A service user class.\n"
+ + " */\n"
+ + "public class ServiceUser {\n"
+ + "}");
+ mb.write(src);
+ mb = new ModuleBuilder(tb, "moduleServiceUserNoDescription")
+ .comment("This is another module that uses a service defined in another module.\n"
+ + "@uses pkgService.Service")
+ .requires("moduleService")
+ .uses("pkgService.Service")
+ .classes("/**A Package that has a service user with no description.*/ package pkgServiceUserNoDescription;")
+ .classes("package pkgServiceUserNoDescription;\n"
+ + "/**\n"
+ + " * A service user class.\n"
+ + " */\n"
+ + "public class ServiceUserNoDescription {\n"
+ + "}");
+ mb.write(src);
+
+ javadoc("-d", base.resolve("out").toString(),
+ "-quiet", "-noindex",
+ "--module-source-path", src.toString(),
+ "--module", "moduleService,moduleServiceProvider,moduleServiceUser,moduleServiceUserNoDescription",
+ "pkgService", "moduleServiceProvider/pkgServiceProvider", "moduleServiceUser/pkgServiceUser",
+ "moduleServiceUserNoDescription/pkgServiceUserNoDescription");
+ checkExit(Exit.OK);
+
+ checkOutput("moduleServiceProvider-summary.html", true,
+ "<tr class=\"altColor\">\n"
+ + "<th class=\"colFirst\" scope=\"row\"><a href=\"pkgService/Service.html\" "
+ + "title=\"interface in pkgService\">Service</a></th>\n"
+ + "<td class=\"colLast\">\n"
+ + "<div class=\"block\">Provides a service whose name is ServiceProvider.</div>\n"
+ + "</td>\n"
+ + "</tr>");
+ checkOutput("moduleServiceUser-summary.html", true,
+ "<tr class=\"altColor\">\n"
+ + "<th class=\"colFirst\" scope=\"row\"><a href=\"pkgService/Service.html\" title=\"interface in pkgService\">Service</a></th>\n"
+ + "<td class=\"colLast\">\n"
+ + "<div class=\"block\">If no other provider is found, a default internal implementation will be used.</div>\n"
+ + "</td>\n"
+ + "</tr>");
+ checkOutput("moduleServiceUserNoDescription-summary.html", true,
+ "<tr class=\"altColor\">\n"
+ + "<th class=\"colFirst\" scope=\"row\"><a href=\"pkgService/Service.html\" title=\"interface in pkgService\">Service</a></th>\n"
+ + "<td class=\"colLast\">\n"
+ + "<div class=\"block\">A service Interface for service providers.</div>\n"
+ + "</td>\n"
+ + "</tr>");
+ checkOutput("moduleServiceProvider-summary.html", false,
+ "A service Interface for service providers.");
+ checkOutput("moduleServiceUser-summary.html", false,
+ "A service Interface for service providers.");
+ }
+
+ @Test
public void checkUsesNoApiTagModuleModeDefault(Path base) throws Exception {
ModuleBuilder mb = new ModuleBuilder(tb, "m")
.comment("module m.\n@provides p1.A abc") // bogus tag
@@ -251,7 +352,8 @@
"<tbody>\n" +
"<tr class=\"altColor\">\n" +
"<th class=\"colFirst\" scope=\"row\"><a href=\"p1/A.html\" title=\"interface in p1\">A</a></th>\n" +
- "<td class=\"colLast\">abc </td>\n" +
+ "<td class=\"colLast\">\n" +
+ "<div class=\"block\">abc</div>\n</td>\n" +
"</tr>\n" +
"</tbody>\n" +
"</table>\n");
@@ -292,7 +394,8 @@
"<tbody>\n" +
"<tr class=\"altColor\">\n" +
"<th class=\"colFirst\" scope=\"row\"><a href=\"p1/A.html\" title=\"interface in p1\">A</a></th>\n" +
- "<td class=\"colLast\">abc </td>\n" +
+ "<td class=\"colLast\">\n" +
+ "<div class=\"block\">abc</div>\n</td>\n" +
"</tr>\n" +
"</tbody>\n" +
"</table>",
@@ -305,7 +408,8 @@
"<tbody>\n" +
"<tr class=\"altColor\">\n" +
"<th class=\"colFirst\" scope=\"row\"><a href=\"p2/B.html\" title=\"class in p2\">B</a></th>\n" +
- "<td class=\"colLast\">def </td>\n" +
+ "<td class=\"colLast\">\n" +
+ "<div class=\"block\">def</div>\n</td>\n" +
"</tr>\n" +
"</tbody>\n" +
"</table>\n");
--- a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java Wed Jan 03 18:21:10 2018 -0800
+++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java Thu Jan 04 09:22:17 2018 -0800
@@ -26,7 +26,7 @@
* @bug 8154119 8154262 8156077 8157987 8154261 8154817 8135291 8155995 8162363
* 8168766 8168688 8162674 8160196 8175799 8174974 8176778 8177562 8175218
* 8175823 8166306 8178043 8181622 8183511 8169819 8074407 8183037 8191464
- 8164407
+ 8164407 8192007
* @summary Test modules support in javadoc.
* @author bpatel
* @library ../lib
@@ -764,7 +764,8 @@
+ "</a>",
"<tr class=\"altColor\">\n"
+ "<th class=\"colFirst\" scope=\"row\"><a href=\"testpkgmdlB/TestClassInModuleB.html\" title=\"class in testpkgmdlB\">TestClassInModuleB</a></th>\n"
- + "<td class=\"colLast\">With a test description for uses. </td>\n"
+ + "<td class=\"colLast\">\n"
+ + "<div class=\"block\">With a test description for uses.</div>\n</td>\n"
+ "</tr>",
"<caption><span>Opens</span><span class=\"tabEnd\"> </span></caption>\n"
+ "<tr>\n"
@@ -931,7 +932,8 @@
+ "<td class=\"colLast\"><a href=\"testpkgmdlB/package-summary.html\">testpkgmdlB</a></td>\n");
checkOutput("moduleB-summary.html", true,
"<th class=\"colFirst\" scope=\"row\"><a href=\"testpkgmdlB/TestClassInModuleB.html\" title=\"class in testpkgmdlB\">TestClassInModuleB</a></th>\n"
- + "<td class=\"colLast\">With a test description for uses. </td>");
+ + "<td class=\"colLast\">\n"
+ + "<div class=\"block\">With a test description for uses.</div>\n</td>\n");
checkOutput("moduletags-summary.html", true,
"<li><a href=\"#module.description\">Description</a> | <a href=\"#modules.summary\">Modules"
+ "</a> | <a href=\"#packages.summary\">Packages</a> | Services</li>",