From eb7fa006909cb044a3fd55ba87a6237401898033 Mon Sep 17 00:00:00 2001 From: liach Date: Fri, 15 Jan 2021 15:12:34 +0000 Subject: [PATCH] 8259216: javadoc omits method receiver for any nested type annotation Reviewed-by: hannesw --- .../html/AbstractExecutableMemberWriter.java | 58 ++++++++++++++----- .../internal/doclets/toolkit/util/Utils.java | 14 ++--- .../TestTypeAnnotations.java | 40 ++++++++----- 3 files changed, 78 insertions(+), 34 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java index 0e28323216a..472f54955ba 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java @@ -27,7 +27,6 @@ package jdk.javadoc.internal.doclets.formats.html; import java.util.List; -import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; @@ -38,7 +37,7 @@ import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; -import javax.lang.model.util.SimpleTypeVisitor9; +import javax.lang.model.util.SimpleTypeVisitor14; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.Entity; @@ -152,24 +151,56 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite } /** - * Add the receiver annotations information. + * Add the receiver information. + * + *

Note: receivers can only have type-use annotations.

* * @param member the member to write receiver annotations for. * @param rcvrType the receiver type. - * @param annotationMirrors list of annotation descriptions. * @param tree the content tree to which the information will be added. */ - protected void addReceiverAnnotations(ExecutableElement member, TypeMirror rcvrType, - List annotationMirrors, Content tree) { - tree.add(writer.getAnnotationInfo(member.getReceiverType().getAnnotationMirrors(), false)); - tree.add(Entity.NO_BREAK_SPACE); - tree.add(utils.getTypeName(rcvrType, false)); - LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, RECEIVER_TYPE, rcvrType); - tree.add(writer.getTypeParameterLinks(linkInfo)); + protected void addReceiver(ExecutableElement member, TypeMirror rcvrType, Content tree) { + var info = new LinkInfoImpl(configuration, RECEIVER_TYPE, rcvrType); + info.linkToSelf = false; + tree.add(writer.getLink(info)); tree.add(Entity.NO_BREAK_SPACE); + if (member.getKind() == ElementKind.CONSTRUCTOR) { + tree.add(utils.getTypeName(rcvrType, false)); + tree.add("."); + } tree.add("this"); } + /** + * Returns {@code true} if a receiver type is annotated anywhere in its type for + * inclusion in member details. + * + * @param receiverType the receiver type. + * @return {@code true} if the receiver is annotated + */ + protected boolean isAnnotatedReceiver(TypeMirror receiverType) { + return new SimpleTypeVisitor14() { + @Override + protected Boolean defaultAction(TypeMirror e, Void unused) { + return utils.isAnnotated(e); + } + + @Override + public Boolean visitDeclared(DeclaredType t, Void unused) { + if (super.visitDeclared(t, unused) || visit(t.getEnclosingType())) { + return true; + } + + for (var e : t.getTypeArguments()) { + if (visit(e)) { + return true; + } + } + + return false; + } + }.visit(receiverType); + } /** * Add all the parameters for the executable member. @@ -199,9 +230,8 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite String sep = ""; List parameters = member.getParameters(); TypeMirror rcvrType = member.getReceiverType(); - if (includeAnnotations && rcvrType != null && utils.isAnnotated(rcvrType)) { - List annotationMirrors = rcvrType.getAnnotationMirrors(); - addReceiverAnnotations(member, rcvrType, annotationMirrors, paramTree); + if (includeAnnotations && rcvrType != null && isAnnotatedReceiver(rcvrType)) { + addReceiver(member, rcvrType, paramTree); sep = "," + DocletConstants.NL + " "; } int paramstart; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java index 54d20413c83..bf70e39496a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java @@ -85,7 +85,7 @@ import javax.lang.model.util.ElementKindVisitor14; import javax.lang.model.util.Elements; import javax.lang.model.util.SimpleAnnotationValueVisitor14; import javax.lang.model.util.SimpleElementVisitor14; -import javax.lang.model.util.SimpleTypeVisitor9; +import javax.lang.model.util.SimpleTypeVisitor14; import javax.lang.model.util.TypeKindVisitor9; import javax.lang.model.util.Types; import javax.tools.FileObject; @@ -628,7 +628,7 @@ public class Utils { } public boolean isPrimitive(TypeMirror t) { - return new SimpleTypeVisitor9() { + return new SimpleTypeVisitor14() { @Override public Boolean visitNoType(NoType t, Void p) { @@ -733,7 +733,7 @@ public class Utils { } public String getTypeSignature(TypeMirror t, boolean qualifiedName, boolean noTypeParameters) { - return new SimpleTypeVisitor9() { + return new SimpleTypeVisitor14() { final StringBuilder sb = new StringBuilder(); @Override @@ -1211,7 +1211,7 @@ public class Utils { * or null if it is a primitive type. */ public TypeElement asTypeElement(TypeMirror t) { - return new SimpleTypeVisitor9() { + return new SimpleTypeVisitor14() { @Override public TypeElement visitDeclared(DeclaredType t, Void p) { @@ -1267,7 +1267,7 @@ public class Utils { * @return the type's dimension information as a string. */ public String getDimension(TypeMirror t) { - return new SimpleTypeVisitor9() { + return new SimpleTypeVisitor14() { StringBuilder dimension = new StringBuilder(); @Override public String visitArray(ArrayType t, Void p) { @@ -1379,7 +1379,7 @@ public class Utils { private final Map kindNameMap = new HashMap<>(); public String getTypeName(TypeMirror t, boolean fullyQualified) { - return new SimpleTypeVisitor9() { + return new SimpleTypeVisitor14() { @Override public String visitArray(ArrayType t, Void p) { @@ -1764,7 +1764,7 @@ public class Utils { * @return the fully qualified name of Reference type or the primitive name */ public String getQualifiedTypeName(TypeMirror t) { - return new SimpleTypeVisitor9() { + return new SimpleTypeVisitor14() { @Override public String visitDeclared(DeclaredType t, Void p) { return getFullyQualifiedName(t.asElement()); diff --git a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java index 14bdce240ae..2471323e76e 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java @@ -24,7 +24,7 @@ /* * @test * @bug 8005091 8009686 8025633 8026567 6469562 8071982 8071984 8162363 8175200 8186332 8182765 - * 8187288 8241969 + * 8187288 8241969 8259216 * @summary Make sure that type annotations are displayed correctly * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -371,7 +371,7 @@ public class TestTypeAnnotations extends JavadocTester { """
void withException(@RcvrA DefaultUnmodified&\ + ="RcvrA.html" title="annotation in typeannos">@RcvrA DefaultUnmodified&\ nbsp;this) throws java.lang.Exception
""", @@ -379,14 +379,14 @@ public class TestTypeAnnotations extends JavadocTester {
java.lang.String&\ nbsp;nonVoid(@RcvrA @RcvrB("m") DefaultUnmodified this)@RcvrB("m") DefaultUnmodified this)
""", """
<T extends java.l\ ang.Runnable> void accept(@RcvrA DefaultUnmodified thi\ + html" title="annotation in typeannos">@RcvrA DefaultUnmodified thi\ s, T r) throws java.lang.Exception
"""); @@ -396,14 +396,14 @@ public class TestTypeAnnotations extends JavadocTester {
public final <\ span class="return-type">java.lang.String nonVoid\ (@RcvrA PublicModified this)
""", + n typeannos">@RcvrA PublicModified this)""", """
public final <\ span class="type-parameters"><T extends java.lang.Runnable> void accept​\ (@RcvrA PublicModified this, + nnos">@RcvrA PublicModified this, T r) throws java.lang.Exception
"""); @@ -412,7 +412,7 @@ public class TestTypeAnnotations extends JavadocTester {
<T extends java.l\ ang.Runnable> void accept(@RcvrB("m") WithValue this, + html" title="annotation in typeannos">@RcvrB("m") WithValue this, T r) throws java.lang.Exception
"""); @@ -427,15 +427,28 @@ public class TestTypeAnnotations extends JavadocTester { """
void field(@RcvrA WithBody this)\ + html" title="annotation in typeannos">@RcvrA WithBody this)\
"""); checkOutput("typeannos/Generic2.html", true, + """ +
void test1()
""", """
void test2(@RcvrA Generic2<X> thi\ - s)
"""); + html" title="annotation in typeannos">@RcvrA Generic2<X> thi\ + s)""", + """ +
void test3(Generic2<@RcvrA X> this)
""", + """ +
void test4(@RcvrA Generic2<@RcvrA X> this)
"""); // Test for repeated type annotations (RepeatedAnnotations.java). @@ -535,7 +548,8 @@ public class TestTypeAnnotations extends JavadocTester { nnotation in typeannos">@RepTypeUseA @RepTypeUseA @RepTypeUseB @RepTypeUseB RepeatingOnConstructor this, + typeannos">@RepTypeUseB RepeatingOnConstructor RepeatingOnConstructor.this, @RepParameterA \ @RepParameterA \ @RepParameterB \ @@ -743,7 +757,7 @@ public class TestTypeAnnotations extends JavadocTester { RepTypeUseA @RepT\ ypeUseA @RepTypeU\ seB @RepTypeUseB<\ - /a> RepeatingOnMethod this, + /a> RepeatingOnMethod this, @RepParameterA \ @RepParameterA \ @RepParameterB \ @@ -781,7 +795,7 @@ public class TestTypeAnnotations extends JavadocTester { on in typeannos">@RepTypeUseA @RepTypeUseA @RepTypeUseB @RepTypeUseB RepeatingOnTypeParametersBoundsTypeArgumentsOnMethod&\ + nos">@RepTypeUseB RepeatingOnTypeParametersBoundsTypeArgumentsOnMethod&\ lt;@RepTypeUseA <\ a href="RepTypeUseA.html" title="annotation in typeannos">@RepTypeUseA @RepTypeUseB