Skip to content

Commit 834d55c

Browse files
committed
8277300: Issues with javadoc support for preview features
Reviewed-by: prappo, jjg
1 parent 138a171 commit 834d55c

File tree

8 files changed

+239
-30
lines changed

8 files changed

+239
-30
lines changed

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -89,18 +89,29 @@ protected Content getClassLink(LinkInfo linkInfo) {
8989
}
9090
Content label = classLinkInfo.getClassLinkLabel(configuration);
9191
Set<ElementFlag> flags;
92-
Element target;
92+
Element previewTarget;
9393
boolean showPreview = !classLinkInfo.skipPreview;
9494
if (!hasWhere && showPreview) {
9595
flags = utils.elementFlags(typeElement);
96-
target = typeElement;
96+
previewTarget = typeElement;
9797
} else if ((classLinkInfo.context == HtmlLinkInfo.Kind.SEE_TAG || classLinkInfo.context == HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW) &&
9898
classLinkInfo.targetMember != null && showPreview) {
9999
flags = utils.elementFlags(classLinkInfo.targetMember);
100-
target = classLinkInfo.targetMember;
100+
TypeElement enclosing = utils.getEnclosingTypeElement(classLinkInfo.targetMember);
101+
Set<ElementFlag> enclosingFlags = utils.elementFlags(enclosing);
102+
if (flags.contains(ElementFlag.PREVIEW) && enclosingFlags.contains(ElementFlag.PREVIEW)) {
103+
if (enclosing.equals(m_writer.getCurrentPageElement())) {
104+
//skip the PREVIEW tag:
105+
flags = EnumSet.copyOf(flags);
106+
flags.remove(ElementFlag.PREVIEW);
107+
}
108+
previewTarget = enclosing;
109+
} else {
110+
previewTarget = classLinkInfo.targetMember;
111+
}
101112
} else {
102113
flags = EnumSet.noneOf(ElementFlag.class);
103-
target = null;
114+
previewTarget = null;
104115
}
105116

106117
Content link = new ContentBuilder();
@@ -115,7 +126,7 @@ protected Content getClassLink(LinkInfo linkInfo) {
115126
title));
116127
if (flags.contains(ElementFlag.PREVIEW)) {
117128
link.add(HtmlTree.SUP(m_writer.links.createLink(
118-
filename.fragment(m_writer.htmlIds.forPreviewSection(target).name()),
129+
filename.fragment(m_writer.htmlIds.forPreviewSection(previewTarget).name()),
119130
m_writer.contents.previewMark)));
120131
}
121132
return link;
@@ -130,7 +141,7 @@ protected Content getClassLink(LinkInfo linkInfo) {
130141
if (flags.contains(ElementFlag.PREVIEW)) {
131142
link.add(HtmlTree.SUP(m_writer.getCrossClassLink(
132143
typeElement,
133-
m_writer.htmlIds.forPreviewSection(target).name(),
144+
m_writer.htmlIds.forPreviewSection(previewTarget).name(),
134145
m_writer.contents.previewMark,
135146
null, false)));
136147
}
@@ -192,7 +203,7 @@ protected Content getTypeParameterLinks(LinkInfo linkInfo) {
192203
*/
193204
protected Content getTypeParameterLink(LinkInfo linkInfo, TypeMirror typeParam) {
194205
HtmlLinkInfo typeLinkInfo = new HtmlLinkInfo(m_writer.configuration,
195-
((HtmlLinkInfo) linkInfo).getContext(), typeParam).skipPreview(true);
206+
((HtmlLinkInfo) linkInfo).getContext(), typeParam);
196207
typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds;
197208
typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks;
198209
typeLinkInfo.linkToSelf = linkInfo.linkToSelf;

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
7777
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
7878
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
79+
import jdk.javadoc.internal.doclets.toolkit.util.Utils.PreviewFlagProvider;
7980

8081
/**
8182
* The taglet writer that writes HTML.
@@ -435,12 +436,18 @@ protected Content snippetTagOutput(Element element, SnippetTree tag, StyledText
435436
int idx = line.indexOf(strippedLine);
436437
assert idx >= 0; // because the stripped line is a substring of the line being stripped
437438
Text whitespace = Text.of(utils.normalizeNewlines(line.substring(0, idx)));
438-
// If the leading whitespace is not excluded from the link,
439-
// browsers might exhibit unwanted behavior. For example, a
440-
// browser might display hand-click cursor while user hovers
441-
// over that whitespace portion of the line; or use
442-
// underline decoration.
443-
c = new ContentBuilder(whitespace, htmlWriter.linkToContent(element, e, t, strippedLine));
439+
//disable preview tagging inside the snippets:
440+
PreviewFlagProvider prevPreviewProvider = utils.setPreviewFlagProvider(el -> false);
441+
try {
442+
// If the leading whitespace is not excluded from the link,
443+
// browsers might exhibit unwanted behavior. For example, a
444+
// browser might display hand-click cursor while user hovers
445+
// over that whitespace portion of the line; or use
446+
// underline decoration.
447+
c = new ContentBuilder(whitespace, htmlWriter.linkToContent(element, e, t, strippedLine));
448+
} finally {
449+
utils.setPreviewFlagProvider(prevPreviewProvider);
450+
}
444451
// We don't care about trailing whitespace.
445452
} else {
446453
c = HtmlTree.SPAN(Text.of(text));

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -3053,9 +3053,11 @@ public String toString() {
30533053
*/
30543054
public boolean isPreviewAPI(Element el) {
30553055
boolean parentPreviewAPI = false;
3056-
Element enclosing = el.getEnclosingElement();
3057-
if (enclosing != null && (enclosing.getKind().isClass() || enclosing.getKind().isInterface())) {
3058-
parentPreviewAPI = configuration.workArounds.isPreviewAPI(enclosing);
3056+
if (!isClassOrInterface(el)) {
3057+
Element enclosing = el.getEnclosingElement();
3058+
if (isClassOrInterface(enclosing)) {
3059+
parentPreviewAPI = configuration.workArounds.isPreviewAPI(enclosing);
3060+
}
30593061
}
30603062
boolean previewAPI = configuration.workArounds.isPreviewAPI(el);
30613063
return !parentPreviewAPI && previewAPI;
@@ -3082,18 +3084,12 @@ public boolean isReflectivePreviewAPI(Element el) {
30823084
*/
30833085
public Set<ElementFlag> elementFlags(Element el) {
30843086
Set<ElementFlag> flags = EnumSet.noneOf(ElementFlag.class);
3085-
PreviewSummary previewAPIs = declaredUsingPreviewAPIs(el);
30863087

30873088
if (isDeprecated(el)) {
30883089
flags.add(ElementFlag.DEPRECATED);
30893090
}
30903091

3091-
if ((!previewLanguageFeaturesUsed(el).isEmpty() ||
3092-
configuration.workArounds.isPreviewAPI(el) ||
3093-
!previewAPIs.previewAPI.isEmpty() ||
3094-
!previewAPIs.reflectivePreviewAPI.isEmpty() ||
3095-
!previewAPIs.declaredUsingPreviewFeature.isEmpty()) &&
3096-
!hasNoProviewAnnotation(el)) {
3092+
if (previewFlagProvider.isPreview(el)) {
30973093
flags.add(ElementFlag.PREVIEW);
30983094
}
30993095

@@ -3109,9 +3105,42 @@ public enum ElementFlag {
31093105
PREVIEW
31103106
}
31113107

3112-
private boolean hasNoProviewAnnotation(Element el) {
3108+
private boolean isClassOrInterface(Element el) {
3109+
return el != null && (el.getKind().isClass() || el.getKind().isInterface());
3110+
}
3111+
3112+
private boolean hasNoPreviewAnnotation(Element el) {
31133113
return el.getAnnotationMirrors()
31143114
.stream()
31153115
.anyMatch(am -> "jdk.internal.javac.NoPreview".equals(getQualifiedTypeName(am.getAnnotationType())));
31163116
}
3117+
3118+
private PreviewFlagProvider previewFlagProvider = new PreviewFlagProvider() {
3119+
@Override
3120+
public boolean isPreview(Element el) {
3121+
PreviewSummary previewAPIs = declaredUsingPreviewAPIs(el);
3122+
Element enclosing = el.getEnclosingElement();
3123+
3124+
return ( !previewLanguageFeaturesUsed(el).isEmpty()
3125+
|| configuration.workArounds.isPreviewAPI(el)
3126+
|| ( !isClassOrInterface(el) && isClassOrInterface(enclosing)
3127+
&& configuration.workArounds.isPreviewAPI(enclosing))
3128+
|| !previewAPIs.previewAPI.isEmpty()
3129+
|| !previewAPIs.reflectivePreviewAPI.isEmpty()
3130+
|| !previewAPIs.declaredUsingPreviewFeature.isEmpty())
3131+
&& !hasNoPreviewAnnotation(el);
3132+
}
3133+
};
3134+
3135+
public PreviewFlagProvider setPreviewFlagProvider(PreviewFlagProvider provider) {
3136+
Objects.requireNonNull(provider);
3137+
PreviewFlagProvider old = previewFlagProvider;
3138+
previewFlagProvider = provider;
3139+
return old;
3140+
}
3141+
3142+
public interface PreviewFlagProvider {
3143+
public boolean isPreview(Element el);
3144+
}
3145+
31173146
}

test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8250768 8261976
26+
* @bug 8250768 8261976 8277300
2727
* @summary test generated docs for items declared using preview
2828
* @library ../../lib
2929
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@@ -33,8 +33,6 @@
3333
*/
3434

3535
import java.nio.file.Paths;
36-
import java.text.MessageFormat;
37-
import java.util.ResourceBundle;
3836
import javadoc.tester.JavadocTester;
3937

4038
public class TestPreview extends JavadocTester {
@@ -101,4 +99,25 @@ public void testPreviewAPIJavadoc() {
10199
</div>
102100
""");
103101
}
102+
103+
@Test
104+
public void test8277300() {
105+
javadoc("-d", "out-8277300",
106+
"--add-exports", "java.base/jdk.internal.javac=api2",
107+
"--source-path", Paths.get(testSrc, "api2").toAbsolutePath().toString(),
108+
"--show-packages=all",
109+
"api2/api");
110+
checkExit(Exit.OK);
111+
112+
checkOutput("api2/api/API.html", true,
113+
"<p><a href=\"#test()\"><code>test()</code></a></p>",
114+
"<p><a href=\"#testNoPreviewInSig()\"><code>testNoPreviewInSig()</code></a></p>",
115+
"title=\"class or interface in java.util\" class=\"external-link\">List</a>&lt;<a href=\"API.html\" title=\"class in api\">API</a><sup><a href=\"#preview-api.API\">PREVIEW</a></sup>&gt;");
116+
checkOutput("api2/api/API2.html", true,
117+
"<a href=\"API.html#test()\"><code>API.test()</code></a><sup><a href=\"API.html#preview-api.API\">PREVIEW</a></sup>",
118+
"<a href=\"API.html#testNoPreviewInSig()\"><code>API.testNoPreviewInSig()</code></a><sup><a href=\"API.html#preview-api.API\">PREVIEW</a></sup>",
119+
"<a href=\"API3.html#test()\"><code>API3.test()</code></a><sup><a href=\"API3.html#preview-test()\">PREVIEW</a></sup>");
120+
checkOutput("api2/api/API3.html", true,
121+
"<div class=\"block\"><a href=\"#test()\"><code>test()</code></a><sup><a href=\"#preview-test()\">PREVIEW</a></sup></div>");
122+
}
104123
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package api;
25+
26+
import java.util.List;
27+
import jdk.internal.javac.PreviewFeature;
28+
import jdk.internal.javac.PreviewFeature.Feature;
29+
30+
/**
31+
* <p>{@link API#test()}</p>
32+
* <p>{@link API#testNoPreviewInSig()}</p>
33+
*/
34+
@PreviewFeature(feature=Feature.TEST, reflective=false)
35+
public class API {
36+
37+
public API test() {
38+
return null;
39+
}
40+
41+
public void testNoPreviewInSig() {
42+
}
43+
44+
public void typeArgs(List<API> api) {
45+
}
46+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package api;
25+
26+
/**
27+
* <p>{@link API#test()}
28+
* <p>{@link API#testNoPreviewInSig()}
29+
* <p>{@link API3#test()}
30+
*/
31+
public class API2 {
32+
33+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package api;
25+
26+
import jdk.internal.javac.PreviewFeature;
27+
import jdk.internal.javac.PreviewFeature.Feature;
28+
29+
/**
30+
* {@link API3#test()}
31+
*/
32+
public class API3 {
33+
34+
@PreviewFeature(feature=Feature.TEST, reflective=false)
35+
public void test() {
36+
return null;
37+
}
38+
39+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
module api2 {
24+
exports api;
25+
}

0 commit comments

Comments
 (0)