8315464: Uncouple AllClassesIndexWriter from IndexBuilder

Reviewed-by: jjg
This commit is contained in:
Hannes Wallnöfer 2023-09-22 19:17:40 +00:00
parent 9b65b7ddbe
commit 6b8261b8d6
13 changed files with 68 additions and 115 deletions

View File

@ -28,6 +28,7 @@ package jdk.javadoc.internal.doclets.formats.html;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.lang.model.element.TypeElement;
@ -39,8 +40,6 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
import jdk.javadoc.internal.doclets.toolkit.util.Utils.ElementFlag;
/**
@ -48,25 +47,19 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils.ElementFlag;
*/
public class AllClassesIndexWriter extends HtmlDocletWriter {
/**
* Index of all the classes.
*/
protected IndexBuilder indexBuilder;
/**
* Construct AllClassesIndexWriter object. Also initializes the indexBuilder variable in this
* class.
*
* @param configuration The current configuration
* @param indexBuilder Unicode based Index from {@link IndexBuilder}
*/
public AllClassesIndexWriter(HtmlConfiguration configuration, IndexBuilder indexBuilder) {
public AllClassesIndexWriter(HtmlConfiguration configuration) {
super(configuration, DocPaths.ALLCLASSES_INDEX);
this.indexBuilder = indexBuilder;
}
@Override
public void buildPage() throws DocFileIOException {
messages.notice("doclet.Building_Index_For_All_Classes");
String label = resources.getText("doclet.All_Classes_And_Interfaces");
Content allClassesContent = new ContentBuilder();
addContents(allClassesContent);
@ -97,13 +90,9 @@ public class AllClassesIndexWriter extends HtmlDocletWriter {
.addTab(contents.records, utils::isRecord)
.addTab(contents.exceptionClasses, utils::isThrowable)
.addTab(contents.annotationTypes, utils::isAnnotationInterface);
for (Character unicode : indexBuilder.getFirstCharacters()) {
for (IndexItem indexItem : indexBuilder.getItems(unicode)) {
TypeElement typeElement = (TypeElement) indexItem.getElement();
if (typeElement != null && utils.isCoreClass(typeElement)) {
addTableRow(table, typeElement);
}
}
Set<TypeElement> typeElements = getTypeElements();
for (TypeElement typeElement : typeElements) {
addTableRow(table, typeElement);
}
Content titleContent = contents.allClassesAndInterfacesLabel;
var pHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING,
@ -115,6 +104,24 @@ public class AllClassesIndexWriter extends HtmlDocletWriter {
}
}
private Set<TypeElement> getTypeElements() {
Set<TypeElement> classes = new TreeSet<>(utils.comparators.allClassesComparator());
boolean noDeprecated = options.noDeprecated();
Set<TypeElement> includedTypes = configuration.getIncludedTypeElements();
for (TypeElement typeElement : includedTypes) {
if (utils.hasHiddenTag(typeElement) || !utils.isCoreClass(typeElement)) {
continue;
}
if (noDeprecated
&& (utils.isDeprecated(typeElement)
|| utils.isDeprecated(utils.containingPackage(typeElement)))) {
continue;
}
classes.add(typeElement);
}
return classes;
}
/**
* Add table row.
*

View File

@ -475,8 +475,8 @@ public class ConstantsSummaryWriter extends HtmlDocletWriter {
content.add(bodyContents);
printHtmlDocument(null, "summary of constants", content);
if (hasConstants && configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
if (hasConstants && configuration.indexBuilder != null) {
configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS,
resources.getText("doclet.Constants_Summary"), path));
}
}

View File

@ -86,8 +86,8 @@ public class ExternalSpecsWriter extends HtmlDocletWriter {
*/
@Override
public void buildPage() throws DocFileIOException {
boolean hasExternalSpecs = configuration.mainIndex != null
&& !configuration.mainIndex.getItems(DocTree.Kind.SPEC).isEmpty();
boolean hasExternalSpecs = configuration.indexBuilder != null
&& !configuration.indexBuilder.getItems(DocTree.Kind.SPEC).isEmpty();
if (!hasExternalSpecs) {
return;
}
@ -110,15 +110,15 @@ public class ExternalSpecsWriter extends HtmlDocletWriter {
.setFooter(getFooter()));
printHtmlDocument(null, "external specifications", body);
if (configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
if (configuration.indexBuilder != null) {
configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
}
}
protected void checkUniqueItems() {
Map<String, Map<String, List<IndexItem>>> itemsByURL = new HashMap<>();
Map<String, Map<String, List<IndexItem>>> itemsByTitle = new HashMap<>();
for (IndexItem ii : configuration.mainIndex.getItems(DocTree.Kind.SPEC)) {
for (IndexItem ii : configuration.indexBuilder.getItems(DocTree.Kind.SPEC)) {
if (ii.getDocTree() instanceof SpecTree st) {
String url = st.getURL().toString();
String title = ii.getLabel(); // normalized form of st.getTitle()
@ -230,7 +230,7 @@ public class ExternalSpecsWriter extends HtmlDocletWriter {
}
private Map<String, List<IndexItem>> groupExternalSpecs() {
return configuration.mainIndex.getItems(DocTree.Kind.SPEC).stream()
return configuration.indexBuilder.getItems(DocTree.Kind.SPEC).stream()
.collect(groupingBy(IndexItem::getLabel, () -> new TreeMap<>(getTitleComparator()), toList()));
}

View File

@ -112,7 +112,7 @@ public class HtmlConfiguration extends BaseConfiguration {
* 2. items for elements are added in bulk before generating the index files
* 3. additional items are added as needed
*/
public HtmlIndexBuilder mainIndex;
public HtmlIndexBuilder indexBuilder;
/**
* The collection of deprecated items, if any, to be displayed on the deprecated-list page,
@ -307,7 +307,7 @@ public class HtmlConfiguration extends BaseConfiguration {
}
}
if (options.createIndex()) {
mainIndex = new HtmlIndexBuilder(this);
indexBuilder = new HtmlIndexBuilder(this);
}
docPaths = new DocPaths(utils);
setCreateOverview();

View File

@ -59,7 +59,6 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
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.IndexBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.NewAPIBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.PreviewAPIListBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.ResourceIOException;
@ -273,16 +272,14 @@ public class HtmlDoclet extends AbstractDoclet {
}
writerFactory.newSystemPropertiesWriter().buildPage();
configuration.mainIndex.addElements();
IndexBuilder allClassesIndex = new IndexBuilder(configuration, nodeprecated, true);
allClassesIndex.addElements();
configuration.indexBuilder.addElements();
writerFactory.newAllClassesIndexWriter(allClassesIndex).buildPage();
writerFactory.newAllClassesIndexWriter().buildPage();
if (!configuration.packages.isEmpty()) {
writerFactory.newAllPackagesIndexWriter().buildPage();
}
configuration.mainIndex.createSearchIndexFiles();
configuration.indexBuilder.createSearchIndexFiles();
IndexWriter.generate(configuration);
writerFactory.newSearchWriter().buildPage();
}

View File

@ -1470,13 +1470,13 @@ public abstract class HtmlDocletWriter {
attrs.add("id=\"").add(htmlId.name()).add("\"");
}
// Generate index item
if (!headingContent.isEmpty() && configuration.mainIndex != null) {
if (!headingContent.isEmpty() && configuration.indexBuilder != null) {
String tagText = headingContent.replaceAll("\\s+", " ");
IndexItem item = IndexItem.of(element, node, tagText,
getTagletWriterInstance(context).getHolderName(element),
resources.getText("doclet.Section"),
new DocLink(path, id));
configuration.mainIndex.add(item);
configuration.indexBuilder.add(item);
}
}

View File

@ -42,7 +42,6 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
/**
* Extensions to {@code IndexBuilder} to fill in remaining fields
@ -51,10 +50,8 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils;
* JavaScript files.
*/
public class HtmlIndexBuilder extends IndexBuilder {
private final HtmlConfiguration configuration;
private final Resources resources;
private final Utils utils;
private final HtmlIds htmlIds;
/**
@ -63,11 +60,9 @@ public class HtmlIndexBuilder extends IndexBuilder {
* @param configuration the current configuration of the doclet
*/
HtmlIndexBuilder(HtmlConfiguration configuration) {
super(configuration, configuration.getOptions().noDeprecated());
this.configuration = configuration;
resources = configuration.docResources;
utils = configuration.utils;
htmlIds = configuration.htmlIds;
super(configuration);
this.resources = configuration.docResources;
this.htmlIds = configuration.htmlIds;
}
/**
@ -79,15 +74,12 @@ public class HtmlIndexBuilder extends IndexBuilder {
@Override
public void addElements() {
super.addElements();
if (classesOnly) {
return;
}
Map<String,Integer> duplicateLabelCheck = new HashMap<>();
for (Character ch : getFirstCharacters()) {
for (IndexItem item : getItems(ch)) {
duplicateLabelCheck.compute(item.getFullyQualifiedLabel(utils),
(k, v) -> v == null ? 1 : v + 1);
(k, v) -> v == null ? 1 : v + 1);
}
}

View File

@ -79,7 +79,7 @@ public class IndexWriter extends HtmlDocletWriter {
*/
public static void generate(HtmlConfiguration configuration) throws DocletException {
var writerFactory = configuration.getWriterFactory();
IndexBuilder mainIndex = configuration.mainIndex;
IndexBuilder mainIndex = configuration.indexBuilder;
List<Character> firstCharacters = mainIndex.getFirstCharacters();
if (configuration.getOptions().splitIndex()) {
ListIterator<Character> iter = firstCharacters.listIterator();
@ -104,7 +104,7 @@ public class IndexWriter extends HtmlDocletWriter {
protected IndexWriter(HtmlConfiguration configuration, DocPath path,
List<Character> allFirstCharacters, List<Character> displayFirstCharacters) {
super(configuration, path);
this.mainIndex = configuration.mainIndex;
this.mainIndex = configuration.indexBuilder;
this.splitIndex = configuration.getOptions().splitIndex();
this.allFirstCharacters = allFirstCharacters;
this.displayFirstCharacters = displayFirstCharacters;

View File

@ -696,8 +696,8 @@ public class SerializedFormWriter extends SubWriterHolderWriter {
source.add(bodyContents);
printHtmlDocument(null, "serialized forms", source);
if (configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
if (configuration.indexBuilder != null) {
configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS,
resources.getText("doclet.Serialized_Form"), path));
}
}

View File

@ -73,8 +73,8 @@ public class SystemPropertiesWriter extends HtmlDocletWriter {
@Override
public void buildPage() throws DocFileIOException {
boolean hasSystemProperties = configuration.mainIndex != null
&& !configuration.mainIndex.getItems(DocTree.Kind.SYSTEM_PROPERTY).isEmpty();
boolean hasSystemProperties = configuration.indexBuilder != null
&& !configuration.indexBuilder.getItems(DocTree.Kind.SYSTEM_PROPERTY).isEmpty();
if (!hasSystemProperties) {
return;
}
@ -95,8 +95,8 @@ public class SystemPropertiesWriter extends HtmlDocletWriter {
.setFooter(getFooter()));
printHtmlDocument(null, "system properties", body);
if (configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
if (configuration.indexBuilder != null) {
configuration.indexBuilder.add(IndexItem.of(IndexItem.Category.TAGS, title, path));
}
}
@ -127,7 +127,7 @@ public class SystemPropertiesWriter extends HtmlDocletWriter {
}
private Map<String, List<IndexItem>> groupSystemProperties() {
return configuration.mainIndex.getItems(DocTree.Kind.SYSTEM_PROPERTY).stream()
return configuration.indexBuilder.getItems(DocTree.Kind.SYSTEM_PROPERTY).stream()
.collect(groupingBy(IndexItem::getLabel, TreeMap::new, Collectors.toCollection(ArrayList::new)));
}

View File

@ -103,8 +103,8 @@ public class WriterFactory {
/**
* {@return a new writer for the list of "all classes"}
*/
public HtmlDocletWriter newAllClassesIndexWriter(IndexBuilder indexBuilder) {
return new AllClassesIndexWriter(configuration, indexBuilder);
public HtmlDocletWriter newAllClassesIndexWriter() {
return new AllClassesIndexWriter(configuration);
}
/**

View File

@ -379,7 +379,7 @@ public class TagletWriter {
String holder = getHolderName(element);
IndexItem item = IndexItem.of(element, tree, tagText, holder, desc,
new DocLink(htmlWriter.path, id.name()));
configuration.mainIndex.add(item);
configuration.indexBuilder.add(item);
}
}
return result;

View File

@ -35,18 +35,17 @@ import javax.lang.model.element.TypeElement;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import static jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable.Kind.*;
/**
* An alphabetical index of elements, search tags, and other items.
* Two tables are maintained:
* one is indexed by the first character of each items name;
* the other is index by the item's category, indicating the JavaScript
* one is indexed by the first character of each item's name;
* the other is indexed by the item's category, indicating the JavaScript
* file in which the item should be written.
*/
public class IndexBuilder {
public abstract class IndexBuilder {
/**
* Sets of items keyed by the first character of the names (labels)
@ -65,73 +64,39 @@ public class IndexBuilder {
*/
private final boolean noDeprecated;
/**
* Build this index only for classes?
*/
protected final boolean classesOnly;
private final BaseConfiguration configuration;
private final Utils utils;
protected final BaseConfiguration configuration;
protected final Utils utils;
/**
* The comparator used for the sets in {@code itemsByFirstChar}.
*/
private final Comparator<IndexItem> mainComparator;
/**
* Creates a new {@code IndexBuilder}.
*
* @param configuration the current configuration of the doclet
* @param noDeprecated true if -nodeprecated option is used,
* false otherwise
*/
public IndexBuilder(BaseConfiguration configuration,
boolean noDeprecated)
{
this(configuration, noDeprecated, false);
}
/**
* Creates a new {@code IndexBuilder}.
*
* @param configuration the current configuration of the doclet
* @param noDeprecated true if -nodeprecated option is used,
* false otherwise
* @param classesOnly include only classes in index
*/
public IndexBuilder(BaseConfiguration configuration,
boolean noDeprecated,
boolean classesOnly)
{
public IndexBuilder(BaseConfiguration configuration) {
this.configuration = configuration;
this.utils = configuration.utils;
Messages messages = configuration.getMessages();
if (classesOnly) {
messages.notice("doclet.Building_Index_For_All_Classes");
} else {
messages.notice("doclet.Building_Index");
}
this.noDeprecated = noDeprecated;
this.classesOnly = classesOnly;
configuration.getMessages().notice("doclet.Building_Index");
noDeprecated = configuration.getOptions().noDeprecated();
itemsByFirstChar = new TreeMap<>();
itemsByCategory = new EnumMap<>(IndexItem.Category.class);
mainComparator = classesOnly ? makeClassComparator() : makeIndexComparator();
mainComparator = makeComparator();
}
/**
* Adds all the selected modules, packages, types and their members to the index,
* or just the type elements if {@code classesOnly} is {@code true}.
* Adds all the selected modules, packages, types and their members to the index.
*/
public void addElements() {
public void addElements() {
Set<TypeElement> classes = configuration.getIncludedTypeElements();
indexTypeElements(classes);
if (classesOnly) {
return;
}
Set<PackageElement> packages = configuration.getSpecifiedPackageElements();
if (packages.isEmpty()) {
packages = classes
@ -310,14 +275,6 @@ public class IndexBuilder {
return '*';
}
/**
* Returns a comparator for the all-classes list.
* @return a comparator for class element items
*/
private Comparator<IndexItem> makeClassComparator() {
return Comparator.comparing(IndexItem::getElement, utils.comparators.allClassesComparator());
}
/**
* Returns a comparator for the {@code IndexItem}s in the index page.
* This is a composite comparator that must be able to compare all kinds of items:
@ -325,7 +282,7 @@ public class IndexBuilder {
*
* @return a comparator for index page items
*/
private Comparator<IndexItem> makeIndexComparator() {
private Comparator<IndexItem> makeComparator() {
// We create comparators specific to element and search tag items, and a
// base comparator used to compare between the two kinds of items.
// In order to produce consistent results, it is important that the base comparator