Skip to content

8356975: Provide alternative way to generate preview API docs #26267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
Expand Down Expand Up @@ -101,16 +101,20 @@ protected void addContentSelectors(Content target) {
}

@Override
protected void addExtraSection(Content content) {
addSummaryAPI(builder.getForRemoval(), HtmlIds.FOR_REMOVAL,
TERMINALLY_DEPRECATED_KEY, "doclet.Element", content);
protected List<Content> getIndexLinks() {
var list = super.getIndexLinks();
if (!builder.getForRemoval().isEmpty()) {
list.addFirst(getIndexLink(HtmlIds.FOR_REMOVAL, "doclet.Terminally_Deprecated"));
}
return list;
}

@Override
protected void addExtraIndexLink(Content target) {
if (!builder.getForRemoval().isEmpty()) {
addIndexLink(HtmlIds.FOR_REMOVAL, "doclet.Terminally_Deprecated", target);
}
protected void addSummaries(Content content) {
// Add terminally deprecated APIs before other deprecated APIs
addSummaryAPI(builder.getForRemoval(), HtmlIds.FOR_REMOVAL,
TERMINALLY_DEPRECATED_KEY, "doclet.Element", content);
super.addSummaries(content);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import com.sun.source.doctree.RawTextTree;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.doctree.UnknownBlockTagTree;
import com.sun.source.util.DocTreePath;
import com.sun.source.util.SimpleDocTreeVisitor;

Expand Down Expand Up @@ -2493,6 +2494,20 @@ public void addRestrictedSummary(Element forWhat, Content target) {

public void addPreviewInfo(Element forWhat, Content target) {
if (utils.isPreviewAPI(forWhat)) {
// Preview note tag may be used to provide an alternative preview note.
String previewNoteTag = configuration.getOptions().previewNoteTag();
if (previewNoteTag != null) {
List<? extends UnknownBlockTagTree> tags = utils.getBlockTags(forWhat,
t -> t.getTagName().equals(previewNoteTag), UnknownBlockTagTree.class);
if (tags != null && !tags.isEmpty()) {
var previewDiv = HtmlTree.DIV(HtmlStyles.previewBlock);
previewDiv.setId(htmlIds.forPreviewSection(forWhat));
previewDiv.add(HtmlTree.DIV(HtmlStyles.previewComment,
commentTagsToContent(forWhat, tags.getFirst().getContent(), false)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a check to assert there is exactly one occurrence of such a preview note tag?

target.add(previewDiv);
return;
}
}
//in Java platform:
var previewDiv = HtmlTree.DIV(HtmlStyles.previewBlock);
previewDiv.setId(htmlIds.forPreviewSection(forWhat));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
Expand Down Expand Up @@ -32,6 +32,7 @@

import com.sun.source.doctree.DocTree;

import com.sun.source.doctree.UnknownBlockTagTree;
import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyles;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
Expand Down Expand Up @@ -86,9 +87,15 @@ protected void addContentSelectors(Content target) {
target.add(HtmlTree.P(contents.getContent("doclet.Preview_API_Checkbox_Label")));
Content list = HtmlTree.UL(HtmlStyles.previewFeatureList).addStyle(HtmlStyles.checkboxes);
for (var jep : jeps) {
String jepUrl = resources.getText("doclet.Preview_JEP_URL", String.valueOf(jep.number()));
Content label = new ContentBuilder(Text.of(jep.number() + ": "))
.add(HtmlTree.A(jepUrl, Text.of(jep.title() + " (" + jep.status() + ")")));
Content label;
if (jep.number() != 0) {
String jepUrl = resources.getText("doclet.Preview_JEP_URL", String.valueOf(jep.number()));
label = new ContentBuilder(Text.of(jep.number() + ": "))
.add(HtmlTree.A(jepUrl, Text.of(jep.title() + " (" + jep.status() + ")")));
} else {
// Pseudo-JEP created from javadoc tag - use description as label
label = Text.of(jep.title());
}
list.add(HtmlTree.LI(getCheckbox(label, String.valueOf(index++), "feature-")));
}
Content label = contents.getContent("doclet.Preview_API_Checkbox_Toggle_All");
Expand All @@ -98,18 +105,23 @@ protected void addContentSelectors(Content target) {
}

@Override
protected void addExtraSection(Content content) {
protected List<Content> getIndexLinks() {
var list = super.getIndexLinks();
var notes = builder.getElementNotes();
if (!notes.isEmpty()) {
addSummaryAPI(notes, HtmlId.of("preview-api-notes"),
"doclet.Preview_Notes_Elements", "doclet.Element", content);
list.add(getIndexLink(HtmlId.of("preview-api-notes"), "doclet.Preview_Notes"));
}
return list;
}

@Override
protected void addExtraIndexLink(Content target) {
if (!builder.getElementNotes().isEmpty()) {
addIndexLink(HtmlId.of("preview-api-notes"), "doclet.Preview_Notes", target);
protected void addSummaries(Content content) {
var notes = builder.getElementNotes();
super.addSummaries(content);
// Add permanent APIs with preview notes below preview API tables
if (!notes.isEmpty()) {
addSummaryAPI(notes, HtmlId.of("preview-api-notes"),
"doclet.Preview_Notes", "doclet.Element", content);
}
}

Expand All @@ -129,7 +141,7 @@ protected void addTableTabs(Table<Element> table, String headingKey) {
.setDefaultTab(getTableCaption(headingKey))
.setRenderTabs(false);
for (PreviewAPIListBuilder.JEP jep : builder.getJEPs()) {
table.addTab(Text.EMPTY, element -> jep == builder.getJEP(element));
table.addTab(Text.EMPTY, element -> jep.equals(builder.getJEP(element)));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
Expand All @@ -25,7 +25,10 @@

package jdk.javadoc.internal.doclets.formats.html;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.function.Function;

import javax.lang.model.element.Element;
import javax.lang.model.element.ModuleElement;
Expand Down Expand Up @@ -146,15 +149,9 @@ public void buildPage() throws DocFileIOException {
addContentSelectors(content);
if (showContentsList()) {
content.add(HtmlTree.HEADING_TITLE(Headings.CONTENT_HEADING, contents.contentsHeading));
content.add(getContentsList());
}
addExtraSection(content);
for (SummaryElementKind kind : SummaryElementKind.values()) {
if (builder.hasDocumentation(kind)) {
addSummaryAPI(builder.getSet(kind), HtmlIds.forSummaryKind(kind),
getHeadingKey(kind), getHeaderKey(kind), content);
}
content.add(HtmlTree.UL(HtmlStyles.contentsList, getIndexLinks(), Function.identity()));
}
addSummaries(content);
bodyContents.addMainContent(content);
// The script below enables checkboxes in the page and invokes their click handler
// to restore any previous state when the page is loaded via back/forward button.
Expand All @@ -177,17 +174,16 @@ public void buildPage() throws DocFileIOException {
}

/**
* Add the index link.
* Returns a list item containing a link for the table of contents.
*
* @param id the id for the link
* @param headingKey the key for the heading content
* @param content the content to which the index link will be added
* @return a list item containing an index link
*/
protected void addIndexLink(HtmlId id, String headingKey, Content content) {
protected Content getIndexLink(HtmlId id, String headingKey) {
// The "contents-" + id value is used in JavaScript code to toggle visibility of the link.
var li = HtmlTree.LI(links.createLink(id,
return HtmlTree.LI(links.createLink(id,
contents.getContent(headingKey))).setId(HtmlId.of("contents-" + id.name()));
content.add(li);
}

/**
Expand All @@ -198,19 +194,16 @@ protected boolean showContentsList() {
}

/**
* Get the contents list.
*
* @return the contents list
* {@return a list of list items containing the links for the table of contents}
*/
public Content getContentsList() {
var ul= HtmlTree.UL(HtmlStyles.contentsList);
addExtraIndexLink(ul);
protected List<Content> getIndexLinks() {
var list = new ArrayList<Content>();
for (SummaryElementKind kind : SummaryElementKind.values()) {
if (builder.hasDocumentation(kind)) {
addIndexLink(HtmlIds.forSummaryKind(kind), getHeadingKey(kind), ul);
list.add(getIndexLink(HtmlIds.forSummaryKind(kind), getHeadingKey(kind)));
}
}
return ul;
return list;
}

/**
Expand All @@ -225,6 +218,20 @@ public HtmlTree getHeader(PageMode pageMode, String titleKey) {
return body;
}

/**
* Add all API summary tables to the main content of the page.
*
* @param content the content to add the API summary tables to
*/
protected void addSummaries(Content content) {
for (SummaryElementKind kind : SummaryElementKind.values()) {
if (builder.hasDocumentation(kind)) {
addSummaryAPI(builder.getSet(kind), HtmlIds.forSummaryKind(kind),
getHeadingKey(kind), getHeaderKey(kind), content);
}
}
}

/**
* Add summary information to the documentation
*
Expand All @@ -237,7 +244,7 @@ public HtmlTree getHeader(PageMode pageMode, String titleKey) {
protected void addSummaryAPI(SortedSet<Element> apiList, HtmlId id,
String headingKey, String headerKey,
Content content) {
if (apiList.size() > 0) {
if (!apiList.isEmpty()) {
TableHeader tableHeader = getTableHeader(headerKey);

var table = new Table<Element>(HtmlStyles.summaryTable)
Expand Down Expand Up @@ -319,22 +326,6 @@ protected Content getCheckbox(Content label, String id, String htmlPrefix) {
.add(HtmlTree.SPAN(label));
}

/**
* Add an extra optional section to the content.
*
* @param target the content to which the section should be added
*/
protected void addExtraSection(Content target) {
}

/**
* Add an extra optional index link.
*
* @param target the content to which the link should be added
*/
protected void addExtraIndexLink(Content target) {
}

/**
* Allow Subclasses to add a content selector UI such as a row of radio buttons
* near the top of the page. This method does not add anything.
Expand All @@ -345,7 +336,7 @@ protected void addContentSelectors(Content target) {}

/**
* Allow subclasses to add an extra table column for an element.
* This methods does not add any content by returning {@code null}.
* Return {@code null} for no extra content.
*
* @param element the element
* @return content for extra content or null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ doclet.Preview_API_Checkbox_Toggle_All=Toggle all
doclet.Preview_JEP_URL=https://openjdk.org/jeps/{0}
doclet.Preview_Label=Preview
doclet.Preview_Mark=PREVIEW
doclet.Preview_Notes=Preview API Notes
doclet.Preview_Notes_Elements=Elements containing Preview Notes
doclet.Preview_Notes=Permanent APIs affected by Preview Features
doclet.Restricted_Methods=Restricted Methods
doclet.Restricted_Mark=RESTRICTED
doclet.searchTag=Search Tag
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
Expand Down Expand Up @@ -239,11 +239,19 @@ public enum ModularityMismatchPolicy {

/**
* Argument for command-line option {@code --preview-note-tag}.
* If set, the JavaDoc inline tag with the given name is considered
* a preview note and added to the preview API page.
* If set, the JavaDoc tag with the given name can be used to add
* preview-related notes to permanent APIs or override the default
* preview note for preview APIs.
*/
private String previewNoteTag = null;

/**
* Argument for command-line option {@code --preview-feature-tag}.
* If set, the JavaDoc inline tag with the given name is used to
* add mark an API element as preview feature in non-JDK contexts.
*/
private String previewFeatureTag = null;

/**
* Argument for command-line option {@code -quiet}.
* Suppress all messages
Expand Down Expand Up @@ -565,6 +573,14 @@ public boolean process(String option, List<String> args) {
}
},

new Hidden(resources, "--preview-feature-tag", 1) {
@Override
public boolean process(String option, List<String> args) {
previewFeatureTag = args.getFirst();
return true;
}
},

new Hidden(resources, "-quiet") {
@Override
public boolean process(String opt, List<String> args) {
Expand Down Expand Up @@ -958,10 +974,16 @@ public boolean noTimestamp() {

/**
* Argument for command-line option {@code --preview-note-tag}.
* Name of inline tag for preview notes.
* Name of inline tag for preview notes on permanent APIs.
*/
public String previewNoteTag() { return previewNoteTag; }

/**
* Argument for command-line option {@code --preview-feature-tag}.
* Name of inline tag for marking APIs as preview feature.
*/
public String previewFeatureTag() { return previewFeatureTag; }

/**
* Argument for command-line option {@code -quiet}.
* Suppress all messages
Expand Down
Loading