diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index 8e0c010dd1a..494d5e22d6e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -52,6 +52,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils.ElementFlag; import jdk.javadoc.internal.html.Content; import jdk.javadoc.internal.html.ContentBuilder; import jdk.javadoc.internal.html.Entity; +import jdk.javadoc.internal.html.HtmlId; import jdk.javadoc.internal.html.HtmlTag; import jdk.javadoc.internal.html.HtmlTree; import jdk.javadoc.internal.html.Text; @@ -296,26 +297,12 @@ public class HtmlLinkFactory { Content link = new ContentBuilder(); if (utils.isIncluded(typeElement)) { if (configuration.isGeneratedDoc(typeElement) && !utils.hasHiddenTag(typeElement)) { - DocPath filename = getPath(linkInfo); + DocPath fileName = getPath(linkInfo); if (linkInfo.linkToSelf() || typeElement != m_writer.getCurrentPageElement()) { link.add(m_writer.links.createLink( - filename.fragment(linkInfo.getFragment()), - label, - linkInfo.getStyle(), - title)); - Content spacer = Text.EMPTY; - if (flags.contains(ElementFlag.PREVIEW)) { - link.add(HtmlTree.SUP(m_writer.links.createLink( - filename.fragment(m_writer.htmlIds.forPreviewSection(previewTarget).name()), - m_writer.contents.previewMark))); - spacer = Entity.NO_BREAK_SPACE; - } - if (flags.contains(ElementFlag.RESTRICTED)) { - link.add(spacer); - link.add(HtmlTree.SUP(m_writer.links.createLink( - filename.fragment(m_writer.htmlIds.forRestrictedSection(restrictedTarget).name()), - m_writer.contents.restrictedMark))); - } + fileName.fragment(linkInfo.getFragment()), + label, linkInfo.getStyle(), title)); + addSuperscript(link, flags, fileName, null, previewTarget, restrictedTarget); return link; } } @@ -325,38 +312,61 @@ public class HtmlLinkFactory { label, linkInfo.getStyle(), true); if (crossLink != null) { link.add(crossLink); - Content spacer = Text.EMPTY; - if (flags.contains(ElementFlag.PREVIEW)) { - link.add(HtmlTree.SUP(m_writer.getCrossClassLink( - typeElement, - m_writer.htmlIds.forPreviewSection(previewTarget).name(), - m_writer.contents.previewMark, - null, false))); - spacer = Entity.NO_BREAK_SPACE; - } - if (flags.contains(ElementFlag.RESTRICTED)) { - link.add(spacer); - link.add(HtmlTree.SUP(m_writer.getCrossClassLink( - typeElement, - m_writer.htmlIds.forRestrictedSection(restrictedTarget).name(), - m_writer.contents.restrictedMark, - null, false))); - } + addSuperscript(link, flags, null, typeElement, previewTarget, restrictedTarget); return link; } } // Can't link so just write label. link.add(label); + addSuperscript(link, flags, null, null, previewTarget, restrictedTarget); + return link; + } + + /** + * Adds PREVIEW and RESTRICTED superscript labels. Depending on the parameter values, + * labels will be formatted as local or external links or plain text. + * + * @param content the content to add to + * @param flags the flags + * @param fileName file name to link to, or null if no local link target + * @param typeElement external type to link to, or null if no external link + * @param previewTarget preview link target element + * @param restrictedTarget restricted link target element + */ + private void addSuperscript(Content content, Set flags, DocPath fileName, TypeElement typeElement, + Element previewTarget, ExecutableElement restrictedTarget) { Content spacer = Text.EMPTY; if (flags.contains(ElementFlag.PREVIEW)) { - link.add(HtmlTree.SUP(m_writer.contents.previewMark)); + content.add(HtmlTree.SUP(getSuperscript(fileName, typeElement, + m_writer.htmlIds.forPreviewSection(previewTarget), + m_writer.contents.previewMark))); spacer = Entity.NO_BREAK_SPACE; } if (flags.contains(ElementFlag.RESTRICTED)) { - link.add(spacer); - link.add(HtmlTree.SUP(m_writer.contents.restrictedMark)); + content.add(spacer); + content.add(HtmlTree.SUP(getSuperscript(fileName, typeElement, + m_writer.htmlIds.forRestrictedSection(restrictedTarget), + m_writer.contents.restrictedMark))); + } + } + + /** + * Returns PREVIEW or RESTRICTED superscript as either local or external link or as plain text. + * + * @param fileName local file name to link to, or null if no local link target + * @param typeElement external type to link to, or null if no external link + * @param id the id fragment to link to + * @param label the label content + * @return superscript content + */ + private Content getSuperscript(DocPath fileName, TypeElement typeElement, HtmlId id, Content label) { + if (fileName != null) { + return m_writer.links.createLink(fileName.fragment(id.name()), label); + } else if (typeElement != null) { + return (m_writer.getCrossClassLink(typeElement, id.name(), label, null, false)); + } else { + return label; } - return link; } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java index b16a1490b63..15e88da5bae 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java @@ -224,6 +224,7 @@ public class LinkTaglet extends BaseTaglet { labelContent = plainOrCode(isPlain, Text.of(utils.getSimpleName(refClass))); } return htmlWriter.getLink(new HtmlLinkInfo(config, HtmlLinkInfo.Kind.PLAIN, refClass) + .skipPreview(isPlain) .label(labelContent)); } else if (refMem == null) { // This is a fragment reference since refClass and refFragment are not null but refMem is null. diff --git a/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java b/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java index a59e68d25a0..369312d690a 100644 --- a/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java +++ b/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java @@ -24,7 +24,7 @@ /* * @test * @bug 8250768 8261976 8277300 8282452 8287597 8325325 8325874 8297879 - * 8331947 + * 8331947 8281533 * @summary test generated docs for items declared using preview * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -156,7 +156,20 @@ public class TestPreview extends JavadocTester {
  • java.base
  • preview
  • Core
  • - """); + """, + """ +
    Preview feature. Links: CoreRecordPREVIEW, core recordPREVIEW, + CoreRecord, core record.
    """, + """ +
  • CoreRecord<\ + /a>PREVIEW<\ + /li> +
  • core record
  • """); // 8331947: Support preview features without JEP should not be included in Preview API page checkOutput("preview-list.html", false, "supportMethod"); diff --git a/test/langtools/jdk/javadoc/doclet/testPreview/api/preview/Core.java b/test/langtools/jdk/javadoc/doclet/testPreview/api/preview/Core.java index d2cf31c2e89..1b23d202285 100644 --- a/test/langtools/jdk/javadoc/doclet/testPreview/api/preview/Core.java +++ b/test/langtools/jdk/javadoc/doclet/testPreview/api/preview/Core.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -25,6 +25,13 @@ package preview; import jdk.internal.javac.PreviewFeature; import jdk.internal.javac.PreviewFeature.Feature; +/** + * Preview feature. Links: {@link CoreRecord}, {@link CoreRecord core record}, + * {@linkplain CoreRecord}, {@linkplain CoreRecord core record}. + * + * @see CoreRecord + * @see CoreRecord core record + */ @PreviewFeature(feature=Feature.TEST) public class Core { }