mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8346109: Create JDK taglet for additional preview notes
Reviewed-by: ihse, liach, rriggs
This commit is contained in:
parent
9ead2b75ce
commit
2321722a45
@ -79,6 +79,8 @@ JAVADOC_TAGS := \
|
|||||||
-tag see \
|
-tag see \
|
||||||
-taglet build.tools.taglet.ExtLink \
|
-taglet build.tools.taglet.ExtLink \
|
||||||
-taglet build.tools.taglet.Incubating \
|
-taglet build.tools.taglet.Incubating \
|
||||||
|
-taglet build.tools.taglet.PreviewNote \
|
||||||
|
--preview-note-tag previewNote \
|
||||||
-tagletpath $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
-tagletpath $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||||
$(CUSTOM_JAVADOC_TAGS) \
|
$(CUSTOM_JAVADOC_TAGS) \
|
||||||
#
|
#
|
||||||
|
|||||||
127
make/jdk/src/classes/build/tools/taglet/PreviewNote.java
Normal file
127
make/jdk/src/classes/build/tools/taglet/PreviewNote.java
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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 build.tools.taglet;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
|
||||||
|
import com.sun.source.doctree.DocTree;
|
||||||
|
import com.sun.source.doctree.UnknownInlineTagTree;
|
||||||
|
import jdk.javadoc.doclet.Doclet;
|
||||||
|
import jdk.javadoc.doclet.DocletEnvironment;
|
||||||
|
import jdk.javadoc.doclet.Reporter;
|
||||||
|
import jdk.javadoc.doclet.StandardDoclet;
|
||||||
|
import jdk.javadoc.doclet.Taglet;
|
||||||
|
|
||||||
|
import static com.sun.source.doctree.DocTree.Kind.UNKNOWN_INLINE_TAG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An inline tag to insert a note formatted as preview note.
|
||||||
|
* The tag can be used as follows:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {@previewNote jep-number [Preview note heading]}
|
||||||
|
* Preview note content
|
||||||
|
* {@previewNote}
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PreviewNote implements Taglet {
|
||||||
|
|
||||||
|
static final String TAG_NAME = "previewNote";
|
||||||
|
Reporter reporter = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(DocletEnvironment env, Doclet doclet) {
|
||||||
|
if (doclet instanceof StandardDoclet stdoclet) {
|
||||||
|
reporter = stdoclet.getReporter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of locations in which the tag may be used.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Set<Location> getAllowedLocations() {
|
||||||
|
return EnumSet.allOf(Taglet.Location.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInlineTag() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return TAG_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(List<? extends DocTree> tags, Element elem) {
|
||||||
|
|
||||||
|
for (DocTree tag : tags) {
|
||||||
|
if (tag.getKind() == UNKNOWN_INLINE_TAG) {
|
||||||
|
UnknownInlineTagTree inlineTag = (UnknownInlineTagTree) tag;
|
||||||
|
String[] content = inlineTag.getContent().toString().trim().split("\\s+", 2);
|
||||||
|
if (!content[0].isBlank()) {
|
||||||
|
StringBuilder sb = new StringBuilder("""
|
||||||
|
<div class="preview-block" style="margin-top:10px; display:block; max-width:max-content;">
|
||||||
|
""");
|
||||||
|
if (content.length == 2) {
|
||||||
|
sb.append("""
|
||||||
|
<div class="preview-label">
|
||||||
|
""")
|
||||||
|
.append(content[1])
|
||||||
|
.append("""
|
||||||
|
</div>
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
sb.append("""
|
||||||
|
<div class="preview-comment">
|
||||||
|
""");
|
||||||
|
return sb.toString();
|
||||||
|
} else {
|
||||||
|
return """
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
""";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reporter == null) {
|
||||||
|
throw new IllegalArgumentException("@" + TAG_NAME + " taglet content must be begin or end");
|
||||||
|
}
|
||||||
|
reporter.print(Diagnostic.Kind.ERROR, "@" + TAG_NAME + " taglet content must be begin or end");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -38,6 +38,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
|||||||
import jdk.javadoc.internal.doclets.toolkit.util.PreviewAPIListBuilder;
|
import jdk.javadoc.internal.doclets.toolkit.util.PreviewAPIListBuilder;
|
||||||
import jdk.javadoc.internal.html.Content;
|
import jdk.javadoc.internal.html.Content;
|
||||||
import jdk.javadoc.internal.html.ContentBuilder;
|
import jdk.javadoc.internal.html.ContentBuilder;
|
||||||
|
import jdk.javadoc.internal.html.HtmlId;
|
||||||
import jdk.javadoc.internal.html.HtmlStyle;
|
import jdk.javadoc.internal.html.HtmlStyle;
|
||||||
import jdk.javadoc.internal.html.HtmlTree;
|
import jdk.javadoc.internal.html.HtmlTree;
|
||||||
import jdk.javadoc.internal.html.Text;
|
import jdk.javadoc.internal.html.Text;
|
||||||
@ -96,6 +97,22 @@ public class PreviewListWriter extends SummaryListWriter<PreviewAPIListBuilder>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addExtraSection(Content content) {
|
||||||
|
var notes = builder.getElementNotes();
|
||||||
|
if (!notes.isEmpty()) {
|
||||||
|
addSummaryAPI(notes, HtmlId.of("preview-api-notes"),
|
||||||
|
"doclet.Preview_Notes_Elements", "doclet.Element", content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addExtraIndexLink(Content target) {
|
||||||
|
if (!builder.getElementNotes().isEmpty()) {
|
||||||
|
addIndexLink(HtmlId.of("preview-api-notes"), "doclet.Preview_Notes", target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addComments(Element e, Content desc) {
|
protected void addComments(Element e, Content desc) {
|
||||||
List<? extends DocTree> tags = utils.getFirstSentenceTrees(e);
|
List<? extends DocTree> tags = utils.getFirstSentenceTrees(e);
|
||||||
|
|||||||
@ -136,6 +136,8 @@ doclet.Preview_API_Checkbox_Toggle_All=Toggle all
|
|||||||
doclet.Preview_JEP_URL=https://openjdk.org/jeps/{0}
|
doclet.Preview_JEP_URL=https://openjdk.org/jeps/{0}
|
||||||
doclet.Preview_Label=Preview
|
doclet.Preview_Label=Preview
|
||||||
doclet.Preview_Mark=PREVIEW
|
doclet.Preview_Mark=PREVIEW
|
||||||
|
doclet.Preview_Notes=Preview API Notes
|
||||||
|
doclet.Preview_Notes_Elements=Elements containing Preview Notes
|
||||||
doclet.Restricted_Methods=Restricted Methods
|
doclet.Restricted_Methods=Restricted Methods
|
||||||
doclet.Restricted_Mark=RESTRICTED
|
doclet.Restricted_Mark=RESTRICTED
|
||||||
doclet.searchTag=Search Tag
|
doclet.searchTag=Search Tag
|
||||||
|
|||||||
@ -236,6 +236,14 @@ public abstract class BaseOptions {
|
|||||||
*/
|
*/
|
||||||
private boolean noTimestamp = false;
|
private boolean noTimestamp = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
private String previewNoteTag = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Argument for command-line option {@code -quiet}.
|
* Argument for command-line option {@code -quiet}.
|
||||||
* Suppress all messages
|
* Suppress all messages
|
||||||
@ -549,6 +557,14 @@ public abstract class BaseOptions {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
new Hidden(resources, "--preview-note-tag", 1) {
|
||||||
|
@Override
|
||||||
|
public boolean process(String option, List<String> args) {
|
||||||
|
previewNoteTag = args.getFirst();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
new Hidden(resources, "-quiet") {
|
new Hidden(resources, "-quiet") {
|
||||||
@Override
|
@Override
|
||||||
public boolean process(String opt, List<String> args) {
|
public boolean process(String opt, List<String> args) {
|
||||||
@ -940,6 +956,12 @@ public abstract class BaseOptions {
|
|||||||
return noTimestamp;
|
return noTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Argument for command-line option {@code --preview-note-tag}.
|
||||||
|
* Name of inline tag for preview notes.
|
||||||
|
*/
|
||||||
|
public String previewNoteTag() { return previewNoteTag; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Argument for command-line option {@code -quiet}.
|
* Argument for command-line option {@code -quiet}.
|
||||||
* Suppress all messages
|
* Suppress all messages
|
||||||
|
|||||||
@ -396,34 +396,6 @@ public class WorkArounds {
|
|||||||
return compilerOptions.isSet("accessInternalAPI");
|
return compilerOptions.isSet("accessInternalAPI");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a map containing {@code jdk.internal.javac.PreviewFeature.JEP} element values associated with the
|
|
||||||
* {@code jdk.internal.javac.PreviewFeature.Feature} enum constant identified by {@code feature}.
|
|
||||||
*
|
|
||||||
* This method uses internal javac features (although only reflectively).
|
|
||||||
*
|
|
||||||
* @param feature the name of the PreviewFeature.Feature enum value
|
|
||||||
* @return the map of PreviewFeature.JEP annotation element values, or an empty map
|
|
||||||
*/
|
|
||||||
public Map<String, Object> getJepInfo(String feature) {
|
|
||||||
TypeElement featureType = elementUtils.getTypeElement("jdk.internal.javac.PreviewFeature.Feature");
|
|
||||||
TypeElement jepType = elementUtils.getTypeElement("jdk.internal.javac.PreviewFeature.JEP");
|
|
||||||
var featureVar = featureType.getEnclosedElements().stream()
|
|
||||||
.filter(e -> feature.equals(e.getSimpleName().toString())).findFirst();
|
|
||||||
if (featureVar.isPresent()) {
|
|
||||||
for (AnnotationMirror anno : featureVar.get().getAnnotationMirrors()) {
|
|
||||||
if (anno.getAnnotationType().asElement().equals(jepType)) {
|
|
||||||
return anno.getElementValues().entrySet()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toMap(
|
|
||||||
e -> e.getKey().getSimpleName().toString(),
|
|
||||||
e -> e.getValue().getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Map.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a similar query is ever added to javax.lang.model, use that instead.
|
* If a similar query is ever added to javax.lang.model, use that instead.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -25,15 +25,22 @@
|
|||||||
|
|
||||||
package jdk.javadoc.internal.doclets.toolkit.util;
|
package jdk.javadoc.internal.doclets.toolkit.util;
|
||||||
|
|
||||||
|
import com.sun.source.doctree.DocTree;
|
||||||
|
import com.sun.source.doctree.UnknownInlineTagTree;
|
||||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||||
|
|
||||||
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
|
import javax.lang.model.element.AnnotationValue;
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build list of all the preview packages, classes, constructors, fields and methods.
|
* Build list of all the preview packages, classes, constructors, fields and methods.
|
||||||
@ -41,8 +48,9 @@ import java.util.stream.Collectors;
|
|||||||
public class PreviewAPIListBuilder extends SummaryAPIListBuilder {
|
public class PreviewAPIListBuilder extends SummaryAPIListBuilder {
|
||||||
|
|
||||||
private final Map<Element, JEP> elementJeps = new HashMap<>();
|
private final Map<Element, JEP> elementJeps = new HashMap<>();
|
||||||
|
private final SortedSet<Element> elementNotes = createSummarySet();
|
||||||
private final Map<String, JEP> jeps = new HashMap<>();
|
private final Map<String, JEP> jeps = new HashMap<>();
|
||||||
private static final JEP NULL_SENTINEL = new JEP(0, "", "");
|
private final String previewNoteTag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JEP for a preview feature in this release.
|
* The JEP for a preview feature in this release.
|
||||||
@ -61,39 +69,78 @@ public class PreviewAPIListBuilder extends SummaryAPIListBuilder {
|
|||||||
*/
|
*/
|
||||||
public PreviewAPIListBuilder(BaseConfiguration configuration) {
|
public PreviewAPIListBuilder(BaseConfiguration configuration) {
|
||||||
super(configuration);
|
super(configuration);
|
||||||
buildSummaryAPIInfo();
|
this.previewNoteTag = configuration.getOptions().previewNoteTag();
|
||||||
|
// retrieve preview JEPs
|
||||||
|
buildPreviewFeatureInfo();
|
||||||
|
if (!jeps.isEmpty()) {
|
||||||
|
// map elements to preview JEPs and preview tags
|
||||||
|
buildSummaryAPIInfo();
|
||||||
|
// remove unused preview JEPs
|
||||||
|
jeps.entrySet().removeIf(e -> !elementJeps.containsValue(e.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildPreviewFeatureInfo() {
|
||||||
|
TypeElement featureType = utils.elementUtils.getTypeElement("jdk.internal.javac.PreviewFeature.Feature");
|
||||||
|
if (featureType == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TypeElement jepType = utils.elementUtils.getTypeElement("jdk.internal.javac.PreviewFeature.JEP");
|
||||||
|
featureType.getEnclosedElements().forEach(elem -> {
|
||||||
|
for (AnnotationMirror anno : elem.getAnnotationMirrors()) {
|
||||||
|
if (anno.getAnnotationType().asElement().equals(jepType)) {
|
||||||
|
Map<? extends ExecutableElement, ? extends AnnotationValue> values = anno.getElementValues();
|
||||||
|
jeps.put(elem.getSimpleName().toString(), new JEP(
|
||||||
|
getAnnotationElementValue(values, "number", 0),
|
||||||
|
getAnnotationElementValue(values, "title", ""),
|
||||||
|
getAnnotationElementValue(values, "status", "Preview"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract a single annotation element value with the given name and default value
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <R> R getAnnotationElementValue(Map<? extends ExecutableElement, ? extends AnnotationValue> values,
|
||||||
|
String name, R defaultValue) {
|
||||||
|
Optional<R> value = values.entrySet().stream()
|
||||||
|
.filter(e -> Objects.equals(e.getKey().getSimpleName().toString(), name))
|
||||||
|
.map(e -> (R) e.getValue().getValue())
|
||||||
|
.findFirst();
|
||||||
|
return value.orElse(defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean belongsToSummary(Element element) {
|
protected boolean belongsToSummary(Element element) {
|
||||||
if (!utils.isPreviewAPI(element)) {
|
if (utils.isPreviewAPI(element)) {
|
||||||
return false;
|
String feature = Objects.requireNonNull(utils.getPreviewFeature(element),
|
||||||
}
|
"Preview feature not specified").toString();
|
||||||
String feature = Objects.requireNonNull(utils.getPreviewFeature(element),
|
// Preview features without JEP are not included in the list.
|
||||||
"Preview feature not specified").toString();
|
JEP jep = jeps.get(feature);
|
||||||
JEP jep = jeps.computeIfAbsent(feature, featureName -> {
|
if (jep != null) {
|
||||||
Map<String, Object> jepInfo = configuration.workArounds.getJepInfo(featureName);
|
elementJeps.put(element, jep);
|
||||||
if (!jepInfo.isEmpty()) {
|
return true;
|
||||||
int number = 0;
|
}
|
||||||
String title = "";
|
}
|
||||||
String status = "Preview"; // Default value is not returned by the method we used above.
|
// If preview tag is defined map elements to preview tags
|
||||||
for (var entry : jepInfo.entrySet()) {
|
if (previewNoteTag != null) {
|
||||||
switch (entry.getKey()) {
|
CommentHelper ch = utils.getCommentHelper(element);
|
||||||
case "number" -> number = (int) entry.getValue();
|
if (ch.dcTree != null) {
|
||||||
case "title" -> title = (String) entry.getValue();
|
var jep = ch.dcTree.getFullBody().stream()
|
||||||
case "status" -> status = (String) entry.getValue();
|
.filter(dt -> dt.getKind() == DocTree.Kind.UNKNOWN_INLINE_TAG)
|
||||||
default -> throw new IllegalArgumentException(entry.getKey());
|
.map(dt -> (UnknownInlineTagTree) dt)
|
||||||
}
|
.filter(t -> previewNoteTag.equals(t.getTagName()) && !t.getContent().isEmpty())
|
||||||
}
|
.map(this::findJEP)
|
||||||
return new JEP(number, title, status);
|
.filter(Objects::nonNull)
|
||||||
|
.findFirst();
|
||||||
|
if (jep.isPresent()) {
|
||||||
|
elementNotes.add(element);
|
||||||
|
elementJeps.put(element, jep.get());
|
||||||
|
// Don't return true as this is not actual preview API.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NULL_SENTINEL;
|
|
||||||
});
|
|
||||||
if (jep != NULL_SENTINEL) {
|
|
||||||
elementJeps.put(element, jep);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
// Preview features without JEP are not included.
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,10 +148,7 @@ public class PreviewAPIListBuilder extends SummaryAPIListBuilder {
|
|||||||
* {@return a sorted set of preview feature JEPs in this release}
|
* {@return a sorted set of preview feature JEPs in this release}
|
||||||
*/
|
*/
|
||||||
public Set<JEP> getJEPs() {
|
public Set<JEP> getJEPs() {
|
||||||
return jeps.values()
|
return new TreeSet<>(jeps.values());
|
||||||
.stream()
|
|
||||||
.filter(jep -> jep != NULL_SENTINEL)
|
|
||||||
.collect(Collectors.toCollection(TreeSet::new));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,4 +157,26 @@ public class PreviewAPIListBuilder extends SummaryAPIListBuilder {
|
|||||||
public JEP getJEP(Element e) {
|
public JEP getJEP(Element e) {
|
||||||
return elementJeps.get(e);
|
return elementJeps.get(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return a sorted set containing elements tagged with preview notes}
|
||||||
|
*/
|
||||||
|
public SortedSet<Element> getElementNotes() {
|
||||||
|
return elementNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JEP findJEP(UnknownInlineTagTree tag) {
|
||||||
|
var content = tag.getContent().toString().trim().split("\\s+", 2);
|
||||||
|
try {
|
||||||
|
var jnum = Integer.parseInt(content[0]);
|
||||||
|
for (var jep : jeps.values()) {
|
||||||
|
if (jep.number == jnum) {
|
||||||
|
return jep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
// print warning?
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8250768 8261976 8277300 8282452 8287597 8325325 8325874 8297879
|
* @bug 8250768 8261976 8277300 8282452 8287597 8325325 8325874 8297879
|
||||||
* 8331947 8281533 8343239 8318416
|
* 8331947 8281533 8343239 8318416 8346109
|
||||||
* @summary test generated docs for items declared using preview
|
* @summary test generated docs for items declared using preview
|
||||||
* @library /tools/lib ../../lib
|
* @library /tools/lib ../../lib
|
||||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||||
@ -296,4 +296,54 @@ public class TestPreview extends JavadocTester {
|
|||||||
checkOutput("m/module-summary.html", true,
|
checkOutput("m/module-summary.html", true,
|
||||||
"Indirect exports from the <code>java.base</code> module are");
|
"Indirect exports from the <code>java.base</code> module are");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test for JDK hidden option to add an entry for a non-preview element
|
||||||
|
// in the preview page based on the presence of a javadoc tag.
|
||||||
|
@Test
|
||||||
|
public void testPreviewNoteTag(Path base) throws IOException {
|
||||||
|
Path src = base.resolve("src");
|
||||||
|
tb.writeJavaFiles(src, """
|
||||||
|
package p;
|
||||||
|
import jdk.internal.javac.PreviewFeature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preview feature
|
||||||
|
*/
|
||||||
|
@PreviewFeature(feature= PreviewFeature.Feature.TEST)
|
||||||
|
public interface CoreInterface {
|
||||||
|
}
|
||||||
|
""", """
|
||||||
|
package p;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non preview feature.
|
||||||
|
* {@previewNote 2147483647 Preview API Note}
|
||||||
|
*/
|
||||||
|
public interface NonPrevieFeature {
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
javadoc("-d", "out-preview-note-tag",
|
||||||
|
"--add-exports", "java.base/jdk.internal.javac=ALL-UNNAMED",
|
||||||
|
"-tag", "previewNote:a:Preview Note:",
|
||||||
|
"--preview-note-tag", "previewNote",
|
||||||
|
"--source-path",
|
||||||
|
src.toString(),
|
||||||
|
"p");
|
||||||
|
checkExit(Exit.OK);
|
||||||
|
|
||||||
|
checkOutput("preview-list.html", true,
|
||||||
|
"""
|
||||||
|
<h2 title="Contents">Contents</h2>
|
||||||
|
<ul class="contents-list">
|
||||||
|
<li id="contents-preview-api-notes"><a href="#preview-api-notes">Preview API Notes</a></li>
|
||||||
|
<li id="contents-interface"><a href="#interface">Interfaces</a></li>""",
|
||||||
|
"""
|
||||||
|
<div class="caption"><span>Elements containing Preview Notes</span></div>""",
|
||||||
|
"""
|
||||||
|
<div class="col-summary-item-name even-row-color preview-api-notes preview-api-notes-tab1\
|
||||||
|
"><a href="p/NonPrevieFeature.html" title="interface in p">p.NonPrevieFeature</a></div>
|
||||||
|
<div class="col-second even-row-color preview-api-notes preview-api-notes-tab1">Test Feature</div>
|
||||||
|
<div class="col-last even-row-color preview-api-notes preview-api-notes-tab1">
|
||||||
|
<div class="block">Non preview feature.</div>""");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user