Skip to content
Permalink
Browse files

8254721: Improve support for conditionally generated files

Reviewed-by: hannesw
  • Loading branch information
jonathan-gibbons committed Oct 19, 2020
1 parent 0001435 commit cb5cdd77057a13cabe94a1714e3147fd903ed594
Showing with 257 additions and 60 deletions.
  1. +1 −0 ...k.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java
  2. +11 −10 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java
  3. +39 −24 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java
  4. +33 −1 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java
  5. +17 −1 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDoclet.java
  6. +2 −2 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java
  7. +3 −3 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java
  8. +1 −0 ...jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java
  9. +1 −1 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java
  10. +2 −0 ...jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
  11. +1 −2 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/BuilderFactory.java
  12. +10 −9 ....javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/ConstantsSummaryBuilder.java
  13. +1 −1 ...jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java
  14. +2 −0 test/langtools/jdk/javadoc/doclet/WindowTitles/p1/C1.java
  15. +116 −0 test/langtools/jdk/javadoc/doclet/testConditionalPages/TestConditionalPages.java
  16. +1 −0 test/langtools/jdk/javadoc/doclet/testCopyFiles/modules/acme.mdle/p/Foo.java
  17. +2 −0 test/langtools/jdk/javadoc/doclet/testGeneratedBy/pkg/MyClass.java
  18. +2 −0 test/langtools/jdk/javadoc/doclet/testHelpFile/TestHelpFile.java
  19. +2 −2 test/langtools/jdk/javadoc/doclet/testMetadata/TestMetadata.java
  20. +1 −1 test/langtools/jdk/javadoc/doclet/testModuleDirs/TestModuleDirs.java
  21. +1 −1 test/langtools/jdk/javadoc/doclet/testNavigation/TestModuleNavigation.java
  22. +1 −0 test/langtools/jdk/javadoc/doclet/testPackagePage/com/pkg/C.java
  23. +1 −0 test/langtools/jdk/javadoc/doclet/testTopOption/pkg/Cl.java
  24. +2 −1 test/langtools/jdk/javadoc/tool/api/basic/APITest.java
  25. +4 −1 test/langtools/jdk/javadoc/tool/api/basic/pkg/C.java
@@ -89,6 +89,7 @@ public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) {
constantsTableHeader = new TableHeader(
contents.modifierAndTypeLabel, contents.constantFieldLabel, contents.valueLabel);
this.navBar = new Navigation(null, configuration, PageMode.CONSTANT_VALUES, path);
configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.CONSTANT_VALUES);
}

@Override
@@ -263,32 +263,33 @@ public DeprecatedListWriter(HtmlConfiguration configuration, DocPath filename) {
* @throws DocFileIOException if there is a problem writing the deprecated list
*/
public static void generate(HtmlConfiguration configuration) throws DocFileIOException {
DocPath filename = DocPaths.DEPRECATED_LIST;
DeprecatedListWriter depr = new DeprecatedListWriter(configuration, filename);
depr.generateDeprecatedListFile(
new DeprecatedAPIListBuilder(configuration));
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.DEPRECATED)) {
DocPath filename = DocPaths.DEPRECATED_LIST;
DeprecatedListWriter depr = new DeprecatedListWriter(configuration, filename);
depr.generateDeprecatedListFile(configuration.deprecatedAPIListBuilder);
}
}

/**
* Generate the deprecated API list.
*
* @param deprapi list of deprecated API built already.
* @param deprAPI list of deprecated API built already.
* @throws DocFileIOException if there is a problem writing the deprecated list
*/
protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprapi)
protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprAPI)
throws DocFileIOException {
HtmlTree body = getHeader();
bodyContents.addMainContent(getContentsList(deprapi));
bodyContents.addMainContent(getContentsList(deprAPI));
String memberTableSummary;
Content content = new ContentBuilder();
for (DeprElementKind kind : DeprElementKind.values()) {
if (deprapi.hasDocumentation(kind)) {
if (deprAPI.hasDocumentation(kind)) {
memberTableSummary = resources.getText("doclet.Member_Table_Summary",
resources.getText(getHeadingKey(kind)),
resources.getText(getSummaryKey(kind)));
TableHeader memberTableHeader = new TableHeader(
contents.getContent(getHeaderKey(kind)), contents.descriptionLabel);
addDeprecatedAPI(deprapi.getSet(kind), getAnchorName(kind),
addDeprecatedAPI(deprAPI.getSet(kind), getAnchorName(kind),
getHeadingKey(kind), memberTableSummary, memberTableHeader, content);
}
}
@@ -302,7 +303,7 @@ protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprapi)
body.add(bodyContents);
printHtmlDocument(null, description, body);

if (!deprapi.isEmpty() && configuration.mainIndex != null) {
if (!deprAPI.isEmpty() && configuration.mainIndex != null) {
configuration.mainIndex.add(IndexItem.of(IndexItem.Category.TAGS,
resources.getText("doclet.Deprecated_API"), path));
}
@@ -235,7 +235,7 @@ protected void addHelpFileContents(Content contentTree) {
}

// Deprecated
if (!(options.noDeprecatedList() || options.noDeprecated())) {
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.DEPRECATED)) {
section = newHelpSection(contents.deprecatedAPI);
Content deprBody = getContent("doclet.help.deprecated.body",
links.createLink(DocPaths.DEPRECATED_LIST, resources.getText("doclet.Deprecated_API")));
@@ -255,34 +255,49 @@ protected void addHelpFileContents(Content contentTree) {
}

// Serialized Form
section = newHelpSection(contents.serializedForm)
.add(HtmlTree.P(getContent("doclet.help.serial_form.body")));
contentTree.add(section);
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM)) {
section = newHelpSection(contents.serializedForm)
.add(HtmlTree.P(getContent("doclet.help.serial_form.body")));
contentTree.add(section);
}

// Constant Field Values
section = newHelpSection(contents.constantsSummaryTitle);
Content constantsBody = getContent("doclet.help.constants.body",
links.createLink(DocPaths.CONSTANT_VALUES, resources.getText("doclet.Constants_Summary")));
section.add(HtmlTree.P(constantsBody));
contentTree.add(section);
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.CONSTANT_VALUES)) {
section = newHelpSection(contents.constantsSummaryTitle);
Content constantsBody = getContent("doclet.help.constants.body",
links.createLink(DocPaths.CONSTANT_VALUES, resources.getText("doclet.Constants_Summary")));
section.add(HtmlTree.P(constantsBody));
contentTree.add(section);
}

// System Properties
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES)) {
section = newHelpSection(contents.systemPropertiesLabel);
Content sysPropsBody = getContent("doclet.help.systemProperties.body",
links.createLink(DocPaths.SYSTEM_PROPERTIES, resources.getText("doclet.systemProperties")));
section.add(HtmlTree.P(sysPropsBody));
contentTree.add(section);
}

// Search
section = newHelpSection(getContent("doclet.help.search.head"));
Content searchIntro = HtmlTree.P(getContent("doclet.help.search.intro"));
Content searchExamples = new HtmlTree(TagName.UL).setStyle(HtmlStyle.helpSectionList);
for (String[] example : SEARCH_EXAMPLES) {
searchExamples.add(HtmlTree.LI(
getContent("doclet.help.search.example",
HtmlTree.CODE(new StringContent(example[0])), example[1])));
if (options.createIndex()) {
section = newHelpSection(getContent("doclet.help.search.head"));
Content searchIntro = HtmlTree.P(getContent("doclet.help.search.intro"));
Content searchExamples = new HtmlTree(TagName.UL).setStyle(HtmlStyle.helpSectionList);
for (String[] example : SEARCH_EXAMPLES) {
searchExamples.add(HtmlTree.LI(
getContent("doclet.help.search.example",
HtmlTree.CODE(new StringContent(example[0])), example[1])));
}
Content searchSpecLink = HtmlTree.A(
resources.getText("doclet.help.search.spec.url", configuration.getDocletVersion().feature()),
getContent("doclet.help.search.spec.title"));
Content searchRefer = HtmlTree.P(getContent("doclet.help.search.refer", searchSpecLink));
section.add(searchIntro)
.add(searchExamples)
.add(searchRefer);
contentTree.add(section);
}
Content searchSpecLink = HtmlTree.A(
resources.getText("doclet.help.search.spec.url", configuration.getDocletVersion().feature()),
getContent("doclet.help.search.spec.title"));
Content searchRefer = HtmlTree.P(getContent("doclet.help.search.refer", searchSpecLink));
section.add(searchIntro)
.add(searchExamples)
.add(searchRefer);
contentTree.add(section);

contentTree.add(new HtmlTree(TagName.HR))
.add(HtmlTree.SPAN(HtmlStyle.helpFootnote,
@@ -27,10 +27,12 @@

import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.Element;
import javax.lang.model.element.PackageElement;
@@ -47,14 +49,15 @@
import jdk.javadoc.doclet.Taglet;
import jdk.javadoc.internal.Versions;
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.BaseOptions;
import jdk.javadoc.internal.doclets.toolkit.DocletException;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.WriterFactory;
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;

/**
* Configure the output based on the command-line options.
@@ -105,6 +108,16 @@
*/
protected HtmlIndexBuilder mainIndex;

/**
* The collection of deprecated items, if any, to be displayed on the deprecated-list page,
* or null if the page should not be generated.
* The page will not be generated if {@link BaseOptions#noDeprecated() no deprecated items}
* are to be included in the documentation,
* or if the page is {@link HtmlOptions#noDeprecatedList() not wanted},
* or if there are no deprecated elements being documented.
*/
protected DeprecatedAPIListBuilder deprecatedAPIListBuilder;

public final Contents contents;

protected final Messages messages;
@@ -115,6 +128,23 @@

private final HtmlOptions options;

/**
* Kinds of conditional pages.
*/
// Note: this should (eventually) be merged with Navigation.PageMode,
// which performs a somewhat similar role
public enum ConditionalPage {
CONSTANT_VALUES, DEPRECATED, SERIALIZED_FORM, SYSTEM_PROPERTIES
}

/**
* A set of values indicating which conditional pages should be generated.
* The set is computed lazily, although values must (obviously) be set before
* they are required, such as when deciding whether or not to generate links
* to these files in the navigation par, on each page, the help file, and so on.
*/
public final Set<ConditionalPage> conditionalPages;

/**
* Constructs the full configuration needed by the doclet, including
* the format-specific part, defined in this class, and the format-independent
@@ -162,6 +192,8 @@ public HtmlConfiguration(Doclet doclet, Locale locale, Reporter reporter) {
v = Runtime.version(); // arguably, the only sensible default
}
docletVersion = v;

conditionalPages = EnumSet.noneOf(ConditionalPage.class);
}

private final Runtime.Version docletVersion;
@@ -40,6 +40,7 @@
import jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder;
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
@@ -115,6 +116,21 @@ public HtmlConfiguration getConfiguration() {
return configuration;
}

@Override // defined by AbstractDoclet
public void generateClassFiles(DocletEnvironment docEnv, ClassTree classTree) throws DocletException {

if (!(configuration.getOptions().noDeprecated()
|| configuration.getOptions().noDeprecatedList())) {
DeprecatedAPIListBuilder builder = new DeprecatedAPIListBuilder(configuration);
if (!builder.isEmpty()) {
configuration.deprecatedAPIListBuilder = builder;
configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.DEPRECATED);
}
}

super.generateClassFiles(docEnv, classTree);
}

/**
* Start the generation of files. Call generate methods in the individual
* writers, which will in turn generate the documentation files. Call the
@@ -155,7 +171,7 @@ protected void generateOtherFiles(ClassTree classtree)
TreeWriter.generate(configuration, classtree);
}

if (!(options.noDeprecatedList() || nodeprecated)) {
if (configuration.conditionalPages.contains((HtmlConfiguration.ConditionalPage.DEPRECATED))) {
DeprecatedListWriter.generate(configuration);
}

@@ -128,8 +128,8 @@
private String helpFile = "";

/**
* Argument for command-line option {@code -nodeprecated}.
* True if command-line option "-nodeprecated" is used. Default value is
* Argument for command-line option {@code -nodeprecatedlist}.
* True if command-line option "-nodeprecatedlist" is used. Default value is
* false.
*/
private boolean noDeprecatedList = false;
@@ -308,8 +308,8 @@ private void addMainNavLinks(Content tree) {
addPageLabel(tree, contents.useLabel, options.classUse());
addTreeLink(tree);
if (documentedPage == PageMode.DEPRECATED) {
addActivePageLink(tree, contents.deprecatedLabel, !(options.noDeprecated()
|| options.noDeprecatedList()));
addActivePageLink(tree, contents.deprecatedLabel,
configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.DEPRECATED));
} else {
addDeprecatedLink(tree);
}
@@ -863,7 +863,7 @@ private void addTreeLink(Content tree) {
}

private void addDeprecatedLink(Content tree) {
if (!(options.noDeprecated() || options.noDeprecatedList())) {
if (configuration.conditionalPages.contains(HtmlConfiguration.ConditionalPage.DEPRECATED)) {
tree.add(HtmlTree.LI(links.createLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
contents.deprecatedLabel, "", "")));
}
@@ -64,6 +64,7 @@ public SerializedFormWriterImpl(HtmlConfiguration configuration) {
super(configuration, DocPaths.SERIALIZED_FORM);
visibleClasses = configuration.getIncludedTypeElements();
this.navBar = new Navigation(null, configuration, PageMode.SERIALIZED_FORM, path);
configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM);
}

/**
@@ -41,7 +41,6 @@
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.doclets.toolkit.util.IndexItem.Category;

import javax.lang.model.element.Element;
import java.nio.file.Path;
@@ -100,6 +99,7 @@ private static void generate(HtmlConfiguration configuration, DocPath fileName)
}
SystemPropertiesWriter systemPropertiesGen = new SystemPropertiesWriter(configuration, fileName);
systemPropertiesGen.buildSystemPropertiesPage();
configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.SYSTEM_PROPERTIES);
}

/**
@@ -205,6 +205,8 @@ doclet.help.serial_form.body=\
description.
doclet.help.constants.body=\
The {0} page lists the static final fields and their values.
doclet.help.systemProperties.body=\
The {0) page lists references to system properties.
doclet.help.footnote=\
This help file applies to API documentation generated by the standard doclet.
doclet.help.enum.intro=\
@@ -76,8 +76,7 @@ public BuilderFactory (BaseConfiguration configuration) {
* @return the builder that builds the constant summary.
*/
public AbstractBuilder getConstantsSummaryBuilder() {
return ConstantsSummaryBuilder.getInstance(context,
writerFactory.getConstantsSummaryWriter());
return ConstantsSummaryBuilder.getInstance(context);
}

/**
@@ -58,7 +58,7 @@
/**
* The writer used to write the results.
*/
protected final ConstantsSummaryWriter writer;
protected ConstantsSummaryWriter writer;

/**
* The set of TypeElements that have constant fields.
@@ -89,12 +89,9 @@
* Construct a new ConstantsSummaryBuilder.
*
* @param context the build context.
* @param writer the writer for the summary.
*/
private ConstantsSummaryBuilder(Context context,
ConstantsSummaryWriter writer) {
private ConstantsSummaryBuilder(Context context) {
super(context);
this.writer = writer;
this.typeElementsWithConstFields = new HashSet<>();
this.printedPackageHeaders = new TreeSet<>(utils.comparators.makePackageComparator());
}
@@ -103,16 +100,20 @@ private ConstantsSummaryBuilder(Context context,
* Construct a ConstantsSummaryBuilder.
*
* @param context the build context.
* @param writer the writer for the summary.
* @return the new ConstantsSummaryBuilder
*/
public static ConstantsSummaryBuilder getInstance(Context context,
ConstantsSummaryWriter writer) {
return new ConstantsSummaryBuilder(context, writer);
public static ConstantsSummaryBuilder getInstance(Context context) {
return new ConstantsSummaryBuilder(context);
}

@Override
public void build() throws DocletException {
boolean anyConstants = configuration.packages.stream().anyMatch(this::hasConstantField);
if (!anyConstants) {
return;
}

writer = configuration.getWriterFactory().getConstantsSummaryWriter();
if (writer == null) {
//Doclet does not support this output.
return;
@@ -84,7 +84,7 @@ public DeprecatedAPIListBuilder(BaseConfiguration configuration) {
}

public boolean isEmpty() {
return deprecatedMap.values().stream().allMatch(Collection::isEmpty);
return deprecatedMap.values().stream().allMatch(Set::isEmpty);
}

/**
@@ -26,4 +26,6 @@
import java.io.Serializable;

public class C1 implements Serializable {
@Deprecated
public static final int ZERO = 0;
}

1 comment on commit cb5cdd7

@bridgekeeper

This comment has been minimized.

Copy link

@bridgekeeper bridgekeeper bot commented on cb5cdd7 Oct 19, 2020

Please sign in to comment.