8340565: Create separate index page for terms defined by the index tag

Reviewed-by: prappo
This commit is contained in:
Hannes Wallnöfer 2024-11-12 09:25:34 +00:00
parent baabfbba3e
commit cfe719fbde
13 changed files with 370 additions and 168 deletions

View File

@ -172,6 +172,7 @@ public class Contents {
public final Content relatedPackages;
public final Content returns;
public final Content searchLabel;
public final Content searchTagsLabel;
public final Content seeAlso;
public final Content serializedForm;
public final Content servicesLabel;
@ -325,6 +326,7 @@ public class Contents {
relatedPackages = getContent("doclet.Related_Packages");
returns = getContent("doclet.Returns");
searchLabel = getContent("doclet.search");
searchTagsLabel = getContent("doclet.searchTags");
seeAlso = getContent("doclet.See_Also");
serializedForm = getContent("doclet.Serialized_Form");
servicesLabel = getContent("doclet.Services");

View File

@ -183,7 +183,7 @@ public class HelpWriter extends HtmlDocletWriter {
* <li>Declaration pages: module, package, classes
* <li>Derived info for declarations: use and tree
* <li>General summary info: deprecated, preview
* <li>Detailed summary info: constant values, serialized form, system properties
* <li>Detailed summary info: constant values, search tags, serialized form, system properties
* <li>Index info: all packages, all classes, full index
* </ul>
*
@ -346,6 +346,15 @@ public class HelpWriter extends HtmlDocletWriter {
pageKindsSection.add(section);
}
// Search Tags
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SEARCH_TAGS)) {
section = newHelpSection(contents.searchTagsLabel, PageMode.SEARCH_TAGS);
Content searchTagsBody = getContent("doclet.help.searchTags.body",
links.createLink(DocPaths.SEARCH_TAGS, resources.getText("doclet.searchTags")));
section.add(HtmlTree.P(searchTagsBody));
pageKindsSection.add(section);
}
// Serialized Form
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM)) {
section = newHelpSection(contents.serializedForm, PageMode.SERIALIZED_FORM)

View File

@ -177,7 +177,7 @@ public class HtmlConfiguration extends BaseConfiguration {
// which performs a somewhat similar role
public enum ConditionalPage {
CONSTANT_VALUES, DEPRECATED, EXTERNAL_SPECS, PREVIEW, RESTRICTED,
SERIALIZED_FORM, SYSTEM_PROPERTIES, NEW
SEARCH_TAGS, SERIALIZED_FORM, SYSTEM_PROPERTIES, NEW
}
/**

View File

@ -283,6 +283,7 @@ public class HtmlDoclet extends AbstractDoclet {
if (!options.noExternalSpecsPage()){
writerFactory.newExternalSpecsWriter().buildPage();
}
writerFactory.newSearchTagsWriter().buildPage();
writerFactory.newSystemPropertiesWriter().buildPage();
configuration.indexBuilder.addElements();

View File

@ -0,0 +1,286 @@
/*
* Copyright (c) 2019, 2024, 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.
*/
package jdk.javadoc.internal.doclets.formats.html;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.WeakHashMap;
import java.util.stream.Collectors;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode;
import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyles;
import jdk.javadoc.internal.doclets.toolkit.DocFileElement;
import jdk.javadoc.internal.doclets.toolkit.OverviewElement;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
import jdk.javadoc.internal.html.Content;
import jdk.javadoc.internal.html.ContentBuilder;
import jdk.javadoc.internal.html.HtmlTree;
import jdk.javadoc.internal.html.Text;
import static java.util.stream.Collectors.groupingBy;
/**
* Generates summary files for tags represented by {@code IndexItem}.
* Supported items are search tags and system properties.
*/
public abstract class IndexItemListWriter extends HtmlDocletWriter {
/**
* Cached contents of {@code <title>...</title>} tags of the HTML pages.
*/
final Map<DocFileElement, String> titles = new WeakHashMap<>();
/**
* Constructs a IndexItemListWriter object.
*
* @param configuration The current configuration
* @param path the doc path of the file to write
*/
protected IndexItemListWriter(HtmlConfiguration configuration, DocPath path) {
super(configuration, path, false);
}
@Override
public void buildPage() throws DocFileIOException {
boolean hasTags = configuration.indexBuilder != null
&& !configuration.indexBuilder.getItems(getKind()).isEmpty();
if (!hasTags) {
return;
}
writeGenerating();
configuration.conditionalPages.add(getConditionalPage());
String title = getPageLabel().toString();
HtmlTree body = getBody(getWindowTitle(title));
Content mainContent = new ContentBuilder();
addIndexItems(mainContent);
body.add(new BodyContents()
.setHeader(getHeader(getPageMode()))
.addMainContent(HtmlTree.DIV(HtmlStyles.header,
HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, getPageLabel())))
.addMainContent(mainContent)
.setFooter(getFooter()));
printHtmlDocument(null, title.toLowerCase(Locale.ROOT), body);
if (configuration.indexBuilder != null) {
configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
}
}
protected Map<String, List<IndexItem>> groupTags() {
return configuration.indexBuilder.getItems(getKind()).stream()
.collect(groupingBy(IndexItem::getLabel, TreeMap::new, Collectors.toCollection(ArrayList::new)));
}
protected Content createLink(IndexItem i) {
assert i.getDocTree().getKind() == getKind() : i;
var element = i.getElement();
if (element instanceof OverviewElement) {
return links.createLink(pathToRoot.resolve(i.getUrl()),
resources.getText("doclet.Overview"));
} else if (element instanceof DocFileElement e) {
var fo = e.getFileObject();
var t = titles.computeIfAbsent(e, this::getFileTitle);
if (t.isBlank()) {
// The user should probably be notified (a warning?) that this
// file does not have a title
var p = Path.of(fo.toUri());
t = p.getFileName().toString();
}
var b = new ContentBuilder()
.add(HtmlTree.CODE(Text.of(i.getHolder() + ": ")))
.add(t);
return links.createLink(pathToRoot.resolve(i.getUrl()), b);
} else {
// program elements should be displayed using a code font
var link = links.createLink(pathToRoot.resolve(i.getUrl()), i.getHolder());
return HtmlTree.CODE(link);
}
}
/**
* Adds a table with the included index items to the content.
*
* @param target the content to which the table will be added
*/
protected abstract void addIndexItems(Content target);
/**
* {@return the kind of index item to list in this page}
*/
protected abstract DocTree.Kind getKind();
/**
* {@return the conditional page value}
*/
protected abstract HtmlConfiguration.ConditionalPage getConditionalPage();
/**
* {@return the label for the page heading}
*/
protected abstract Content getPageLabel();
/**
* {@return the Navigation.PageMode value}
*/
protected abstract Navigation.PageMode getPageMode();
// Note: The reason we can't use anonymous classes below is that HtmlDocletWriter.getBodyStyle()
// uses the writer's class name to deduce the CSS body style name.
public static IndexItemListWriter createSystemPropertiesWriter(HtmlConfiguration configuration) {
return new SystemPropertiesWriter(configuration);
}
public static IndexItemListWriter createSearchTagsWriter(HtmlConfiguration configuration) {
return new SearchTagsWriter(configuration);
}
static class SystemPropertiesWriter extends IndexItemListWriter {
SystemPropertiesWriter(HtmlConfiguration configuration) {
super(configuration, DocPaths.SYSTEM_PROPERTIES);
}
@Override
protected DocTree.Kind getKind() {
return DocTree.Kind.SYSTEM_PROPERTY;
}
@Override
protected HtmlConfiguration.ConditionalPage getConditionalPage() {
return HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES;
}
@Override
protected Content getPageLabel() {
return contents.systemPropertiesLabel;
}
@Override
protected Navigation.PageMode getPageMode() {
return PageMode.SYSTEM_PROPERTIES;
}
/**
* Creates a 2-column table containing system properties.
*
* @param target the content to which the links will be added
*/
@Override
protected void addIndexItems(Content target) {
Map<String, List<IndexItem>> searchIndexMap = groupTags();
Content separator = Text.of(", ");
var table = new Table<Void>(HtmlStyles.summaryTable)
.setCaption(contents.systemPropertiesSummaryLabel)
.setHeader(new TableHeader(contents.propertyLabel, contents.referencedIn))
.setColumnStyles(HtmlStyles.colFirst, HtmlStyles.colLast);
searchIndexMap.forEach((key, searchIndexItems) -> {
Content propertyName = Text.of(key);
Content referenceLinks = new ContentBuilder();
for (IndexItem searchIndexItem : searchIndexItems) {
if (!referenceLinks.isEmpty()) {
referenceLinks.add(separator);
}
referenceLinks.add(createLink(searchIndexItem));
}
table.addRow(propertyName, HtmlTree.DIV(HtmlStyles.block, referenceLinks));
});
target.add(table);
}
}
static class SearchTagsWriter extends IndexItemListWriter {
SearchTagsWriter(HtmlConfiguration configuration) {
super(configuration, DocPaths.SEARCH_TAGS);
}
@Override
protected DocTree.Kind getKind() {
return DocTree.Kind.INDEX;
}
@Override
protected HtmlConfiguration.ConditionalPage getConditionalPage() {
return HtmlConfiguration.ConditionalPage.SEARCH_TAGS;
}
@Override
protected Content getPageLabel() {
return contents.searchTagsLabel;
}
@Override
protected Navigation.PageMode getPageMode() {
return PageMode.SEARCH_TAGS;
}
/**
* Creates a 3-column table containing search tags.
*
* @param target the content to which the links will be added
*/
@Override
protected void addIndexItems(Content target) {
Map<String, List<IndexItem>> searchIndexMap = groupTags();
Content separator = Text.of(", ");
var table = new Table<Void>(HtmlStyles.summaryTable)
.setCaption(contents.getContent("doclet.searchTagsSummary"))
.setHeader(new TableHeader(contents.getContent("doclet.searchTag"),
contents.descriptionLabel,
contents.getContent("doclet.DefinedIn")))
.setColumnStyles(HtmlStyles.colFirst, HtmlStyles.colSecond, HtmlStyles.colLast);
searchIndexMap.forEach((key, searchIndexItems) -> {
Content propertyName = Text.of(key);
Content referenceLinks = new ContentBuilder();
String description = "";
for (IndexItem searchIndexItem : searchIndexItems) {
if (!referenceLinks.isEmpty()) {
referenceLinks.add(separator);
}
referenceLinks.add(createLink(searchIndexItem));
if (description.isEmpty()) {
description = searchIndexItem.getDescription();
Objects.requireNonNull(description);
}
}
table.addRow(propertyName, Text.of(description), HtmlTree.DIV(HtmlStyles.block, referenceLinks));
});
target.add(table);
}
}
}

View File

@ -87,8 +87,9 @@ public class Navigation {
PACKAGE,
PREVIEW,
RESTRICTED,
SERIALIZED_FORM,
SEARCH,
SEARCH_TAGS,
SERIALIZED_FORM,
SYSTEM_PROPERTIES,
TREE,
USE
@ -274,6 +275,7 @@ public class Navigation {
case CONSTANT_VALUES:
case EXTERNAL_SPECS:
case RESTRICTED:
case SEARCH_TAGS:
case SERIALIZED_FORM:
case SYSTEM_PROPERTIES:
addOverviewLink(target);

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) 2019, 2024, 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.
*/
package jdk.javadoc.internal.doclets.formats.html;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.WeakHashMap;
import java.util.stream.Collectors;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode;
import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyles;
import jdk.javadoc.internal.doclets.toolkit.DocFileElement;
import jdk.javadoc.internal.doclets.toolkit.OverviewElement;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
import jdk.javadoc.internal.html.Content;
import jdk.javadoc.internal.html.ContentBuilder;
import jdk.javadoc.internal.html.HtmlTree;
import jdk.javadoc.internal.html.Text;
import static java.util.stream.Collectors.groupingBy;
/**
* Generates the file with the summary of all the system properties.
*/
public class SystemPropertiesWriter extends HtmlDocletWriter {
/**
* Cached contents of {@code <title>...</title>} tags of the HTML pages.
*/
final Map<DocFileElement, String> titles = new WeakHashMap<>();
/**
* Constructs SystemPropertiesWriter object.
*
* @param configuration The current configuration
*/
public SystemPropertiesWriter(HtmlConfiguration configuration) {
super(configuration, DocPaths.SYSTEM_PROPERTIES, false);
}
@Override
public void buildPage() throws DocFileIOException {
boolean hasSystemProperties = configuration.indexBuilder != null
&& !configuration.indexBuilder.getItems(DocTree.Kind.SYSTEM_PROPERTY).isEmpty();
if (!hasSystemProperties) {
return;
}
writeGenerating();
configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES);
String title = resources.getText("doclet.systemProperties");
HtmlTree body = getBody(getWindowTitle(title));
Content mainContent = new ContentBuilder();
addSystemProperties(mainContent);
body.add(new BodyContents()
.setHeader(getHeader(PageMode.SYSTEM_PROPERTIES))
.addMainContent(HtmlTree.DIV(HtmlStyles.header,
HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING,
contents.getContent("doclet.systemProperties"))))
.addMainContent(mainContent)
.setFooter(getFooter()));
printHtmlDocument(null, "system properties", body);
if (configuration.indexBuilder != null) {
configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
}
}
/**
* Adds all the system properties to the content.
*
* @param target the content to which the links will be added
*/
protected void addSystemProperties(Content target) {
Map<String, List<IndexItem>> searchIndexMap = groupSystemProperties();
Content separator = Text.of(", ");
var table = new Table<Void>(HtmlStyles.summaryTable)
.setCaption(contents.systemPropertiesSummaryLabel)
.setHeader(new TableHeader(contents.propertyLabel, contents.referencedIn))
.setColumnStyles(HtmlStyles.colFirst, HtmlStyles.colLast);
for (Entry<String, List<IndexItem>> entry : searchIndexMap.entrySet()) {
Content propertyName = Text.of(entry.getKey());
List<IndexItem> searchIndexItems = entry.getValue();
Content separatedReferenceLinks = new ContentBuilder();
separatedReferenceLinks.add(createLink(searchIndexItems.get(0)));
for (int i = 1; i < searchIndexItems.size(); i++) {
separatedReferenceLinks.add(separator);
separatedReferenceLinks.add(createLink(searchIndexItems.get(i)));
}
table.addRow(propertyName, HtmlTree.DIV(HtmlStyles.block, separatedReferenceLinks));
}
target.add(table);
}
private Map<String, List<IndexItem>> groupSystemProperties() {
return configuration.indexBuilder.getItems(DocTree.Kind.SYSTEM_PROPERTY).stream()
.collect(groupingBy(IndexItem::getLabel, TreeMap::new, Collectors.toCollection(ArrayList::new)));
}
private Content createLink(IndexItem i) {
assert i.getDocTree().getKind() == DocTree.Kind.SYSTEM_PROPERTY : i;
var element = i.getElement();
if (element instanceof OverviewElement) {
return links.createLink(pathToRoot.resolve(i.getUrl()),
resources.getText("doclet.Overview"));
} else if (element instanceof DocFileElement e) {
var fo = e.getFileObject();
var t = titles.computeIfAbsent(e, this::getFileTitle);
if (t.isBlank()) {
// The user should probably be notified (a warning?) that this
// file does not have a title
var p = Path.of(fo.toUri());
t = p.getFileName().toString();
}
var b = new ContentBuilder()
.add(HtmlTree.CODE(Text.of(i.getHolder() + ": ")))
.add(t);
return links.createLink(pathToRoot.resolve(i.getUrl()), b);
} else {
// program elements should be displayed using a code font
var link = links.createLink(pathToRoot.resolve(i.getUrl()), i.getHolder());
return HtmlTree.CODE(link);
}
}
}

View File

@ -37,7 +37,6 @@ import jdk.javadoc.internal.doclets.toolkit.DocFileElement;
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
import jdk.javadoc.internal.doclets.toolkit.util.ClassUseMapper;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable;
/**
@ -184,6 +183,13 @@ public class WriterFactory {
return new SearchWriter(configuration);
}
/**
* {@return a new writer for the page listing search tags defined in the API}
*/
public HtmlDocletWriter newSearchTagsWriter() {
return IndexItemListWriter.createSearchTagsWriter(configuration);
}
/**
* {@return a new writer for the page giving the serialized forms of classes and other type elements}
*/
@ -195,7 +201,7 @@ public class WriterFactory {
* {@return a new writer for the page listing system properties referenced in the API}
*/
public HtmlDocletWriter newSystemPropertiesWriter() {
return new SystemPropertiesWriter(configuration);
return IndexItemListWriter.createSystemPropertiesWriter(configuration);
}
/**

View File

@ -857,6 +857,11 @@ public enum HtmlStyles implements HtmlStyle {
*/
searchPage,
/**
* The class of the {@code body} element for the search tags page.
*/
searchTagsPage,
/**
* The class of the {@code body} element for the serialized-forms page.
*/

View File

@ -135,6 +135,9 @@ doclet.Preview_Label=Preview
doclet.Preview_Mark=PREVIEW
doclet.Restricted_Methods=Restricted Methods
doclet.Restricted_Mark=RESTRICTED
doclet.searchTag=Search Tag
doclet.searchTags=Search Tags
doclet.searchTagsSummary=Search Tags Summary
doclet.Terminally_Deprecated=Terminally Deprecated
doclet.Terminally_Deprecated_Elements=Terminally Deprecated Elements
doclet.Terminally_Deprecated_In_Release=Terminally Deprecated in {0}
@ -171,6 +174,7 @@ doclet.Interfaces=Interfaces
doclet.Enclosing_Class=Enclosing class:
doclet.Enclosing_Interface=Enclosing interface:
doclet.Inheritance_Tree=Inheritance Tree
doclet.DefinedIn=Defined In
doclet.ReferencedIn=Referenced In
doclet.Section=Section
doclet.External_Specification=External Specification
@ -340,6 +344,9 @@ doclet.help.serial_form.body=\
# 0: link to Constant Values page
doclet.help.constants.body=\
The {0} page lists the static final fields and their values.
# 0: link to Search Tags page
doclet.help.searchTags.body=\
The {0} page lists search tags defined in the documentation.
# 0: link to System Properties page
doclet.help.systemProperties.body=\
The {0} page lists references to system properties.

View File

@ -175,6 +175,9 @@ public class DocPaths {
/** The name of the file for search page. */
public static final DocPath SEARCH_PAGE = DocPath.create("search.html");
/** The name of the file for search tags index page. */
public static final DocPath SEARCH_TAGS = DocPath.create("search-tags.html");
/** The name of the file for all system properties. */
public static final DocPath SYSTEM_PROPERTIES = DocPath.create("system-properties.html");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@ -23,7 +23,7 @@
/*
* @test
* @bug 8213957 8213958
* @bug 8213957 8213958 8340565
* @summary Test use of at-index in package-iinfo and doc-files
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@ -121,6 +121,23 @@ public class TestIndexInPackageFiles extends JavadocTester {
<a href="p/q/package-summary.html#test.property.1" class="search-tag-link">test.property.1</a>""",
"""
<a href="p/q/doc-files/extra.html#test.property.2" class="search-tag-link">test.property.2</a>""");
checkOrder("search-tags.html",
"""
<div class="col-first even-row-color">test.name.1</div>
<div class="col-second even-row-color">additional info</div>
<div class="col-last even-row-color">
<div class="block"><code><a href="p/q/package-summary.html#test.name.1">package p.q</a></code></div>""",
"""
<div class="col-first odd-row-color">test.name.2</div>
<div class="col-second odd-row-color">additional info</div>
<div class="col-last odd-row-color">
<div class="block"><a href="p/q/doc-files/extra.html#test.name.2"><code>package p.q: </code>Extra</a></div>""",
"""
<div class="col-first even-row-color">test.name.3</div>
<div class="col-second even-row-color">additional info</div>
<div class="col-last even-row-color">
<div class="block"><a href="index.html#test.name.3">Overview</a></div>""");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, 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
@ -23,7 +23,7 @@
/*
* @test
* @bug 8202462
* @bug 8202462 8340565
* @summary {@index} may cause duplicate labels
* @library /tools/lib ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@ -33,7 +33,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import builder.ClassBuilder;
import builder.ClassBuilder.MethodBuilder;
@ -84,6 +83,21 @@ public class TestIndexTaglet extends JavadocTester {
"<h2>Method Summary</h2>\n",
"""
<div class="block">test description with search_phrase_a</div>""");
checkOrder("search-tags.html",
"""
<h1>Search Tags</h1>""",
"""
<div class="caption"><span>Search Tags Summary</span></div>
<div class="summary-table three-column-summary">
<div class="table-header col-first">Search Tag</div>
<div class="table-header col-second">Description</div>
<div class="table-header col-last">Defined In</div>""",
"""
<div class="col-first even-row-color">search_phrase_a</div>
<div class="col-second even-row-color">class a</div>
<div class="col-last even-row-color">
<div class="block"><code><a href="pkg/A.html#search_phrase_a">pkg.A.func(A)</a></code></div>""");
}
@Test
@ -130,5 +144,13 @@ public class TestIndexTaglet extends JavadocTester {
This is a class. Here is <span id="foo" class="search-tag-result">foo</span>.""",
"""
This is a method. Here is <span id="foo-1" class="search-tag-result">foo</span>.""");
checkOrder("search-tags.html",
"""
<div class="col-first even-row-color">foo</div>
<div class="col-second even-row-color">first</div>
<div class="col-last even-row-color">
<div class="block"><code><a href="pkg/A.html#foo">class pkg.A</a></code>, <code\
><a href="pkg/A.html#foo-1">pkg.A.m()</a></code></div>""");
}
}