8259216: javadoc omits method receiver for any nested type annotation

Reviewed-by: hannesw
This commit is contained in:
liach 2021-01-15 15:12:34 +00:00 committed by Hannes Wallnöfer
parent bcf20a0dcc
commit eb7fa00690
3 changed files with 78 additions and 34 deletions

View File

@ -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.
*
* <p>Note: receivers can only have type-use annotations.</p>
*
* @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<? extends AnnotationMirror> 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<Boolean, Void>() {
@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<? extends VariableElement> parameters = member.getParameters();
TypeMirror rcvrType = member.getReceiverType();
if (includeAnnotations && rcvrType != null && utils.isAnnotated(rcvrType)) {
List<? extends AnnotationMirror> annotationMirrors = rcvrType.getAnnotationMirrors();
addReceiverAnnotations(member, rcvrType, annotationMirrors, paramTree);
if (includeAnnotations && rcvrType != null && isAnnotatedReceiver(rcvrType)) {
addReceiver(member, rcvrType, paramTree);
sep = "," + DocletConstants.NL + " ";
}
int paramstart;

View File

@ -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<Boolean, Void>() {
return new SimpleTypeVisitor14<Boolean, Void>() {
@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<StringBuilder, Void>() {
return new SimpleTypeVisitor14<StringBuilder, Void>() {
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<TypeElement, Void>() {
return new SimpleTypeVisitor14<TypeElement, Void>() {
@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<String, Void>() {
return new SimpleTypeVisitor14<String, Void>() {
StringBuilder dimension = new StringBuilder();
@Override
public String visitArray(ArrayType t, Void p) {
@ -1379,7 +1379,7 @@ public class Utils {
private final Map<String, String> kindNameMap = new HashMap<>();
public String getTypeName(TypeMirror t, boolean fullyQualified) {
return new SimpleTypeVisitor9<String, Void>() {
return new SimpleTypeVisitor14<String, Void>() {
@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<String, Void>() {
return new SimpleTypeVisitor14<String, Void>() {
@Override
public String visitDeclared(DeclaredType t, Void p) {
return getFullyQualifiedName(t.asElement());

View File

@ -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 {
"""
<div class="member-signature"><span class="return-type">void</span>&nbsp;<span c\
lass="element-name">withException</span>&#8203;<span class="parameters">(<a href\
="RcvrA.html" title="annotation in typeannos">@RcvrA</a>&nbsp;DefaultUnmodified&\
="RcvrA.html" title="annotation in typeannos">@RcvrA</a> DefaultUnmodified&\
nbsp;this)</span>
throws <span class="exceptions">java.lang.Exception</span></div>""",
@ -379,14 +379,14 @@ public class TestTypeAnnotations extends JavadocTester {
<div class="member-signature"><span class="return-type">java.lang.String</span>&\
nbsp;<span class="element-name">nonVoid</span>&#8203;<span class="parameters">(<a href="\
RcvrA.html" title="annotation in typeannos">@RcvrA</a> <a href="RcvrB.html" titl\
e="annotation in typeannos">@RcvrB</a>("m")&nbsp;DefaultUnmodified&nbsp;this)</s\
e="annotation in typeannos">@RcvrB</a>("m") DefaultUnmodified&nbsp;this)</s\
pan></div>""",
"""
<div class="member-signature"><span class="type-parameters">&lt;T extends java.l\
ang.Runnable&gt;</span>&nbsp;<span class="return-type">void</span>&nbsp;<span cl\
ass="element-name">accept</span>&#8203;<span class="parameters">(<a href="RcvrA.\
html" title="annotation in typeannos">@RcvrA</a>&nbsp;DefaultUnmodified&nbsp;thi\
html" title="annotation in typeannos">@RcvrA</a> DefaultUnmodified&nbsp;thi\
s,
T&nbsp;r)</span>
throws <span class="exceptions">java.lang.Exception</span></div>""");
@ -396,14 +396,14 @@ public class TestTypeAnnotations extends JavadocTester {
<div class="member-signature"><span class="modifiers">public final</span>&nbsp;<\
span class="return-type">java.lang.String</span>&nbsp;<span class="element-name">nonVoid\
</span>&#8203;<span class="parameters">(<a href="RcvrA.html" title="annotation i\
n typeannos">@RcvrA</a>&nbsp;PublicModified&nbsp;this)</span></div>""",
n typeannos">@RcvrA</a> PublicModified&nbsp;this)</span></div>""",
"""
<div class="member-signature"><span class="modifiers">public final</span>&nbsp;<\
span class="type-parameters">&lt;T extends java.lang.Runnable&gt;</span>&nbsp;<s\
pan class="return-type">void</span>&nbsp;<span class="element-name">accept</span>&#8203;\
<span class="parameters">(<a href="RcvrA.html" title="annotation in typea\
nnos">@RcvrA</a>&nbsp;PublicModified&nbsp;this,
nnos">@RcvrA</a> PublicModified&nbsp;this,
T&nbsp;r)</span>
throws <span class="exceptions">java.lang.Exception</span></div>""");
@ -412,7 +412,7 @@ public class TestTypeAnnotations extends JavadocTester {
<div class="member-signature"><span class="type-parameters">&lt;T extends java.l\
ang.Runnable&gt;</span>&nbsp;<span class="return-type">void</span>&nbsp;<span cl\
ass="element-name">accept</span>&#8203;<span class="parameters">(<a href="RcvrB.\
html" title="annotation in typeannos">@RcvrB</a>("m")&nbsp;WithValue&nbsp;this,
html" title="annotation in typeannos">@RcvrB</a>("m") WithValue&nbsp;this,
T&nbsp;r)</span>
throws <span class="exceptions">java.lang.Exception</span></div>""");
@ -427,15 +427,28 @@ public class TestTypeAnnotations extends JavadocTester {
"""
<div class="member-signature"><span class="return-type">void</span>&nbsp;<span c\
lass="element-name">field</span>&#8203;<span class="parameters">(<a href="RcvrA.\
html" title="annotation in typeannos">@RcvrA</a>&nbsp;WithBody&nbsp;this)</span>\
html" title="annotation in typeannos">@RcvrA</a> WithBody&nbsp;this)</span>\
</div>""");
checkOutput("typeannos/Generic2.html", true,
"""
<div class="member-signature"><span class="return-type">void</span>&nbsp;<span c\
lass="element-name">test1</span>()</div>""",
"""
<div class="member-signature"><span class="return-type">void</span>&nbsp;<span c\
lass="element-name">test2</span>&#8203;<span class="parameters">(<a href="RcvrA.\
html" title="annotation in typeannos">@RcvrA</a>&nbsp;Generic2&lt;X&gt;&nbsp;thi\
s)</span></div>""");
html" title="annotation in typeannos">@RcvrA</a> Generic2&lt;X&gt;&nbsp;thi\
s)</span></div>""",
"""
<div class="member-signature"><span class="return-type">void</span>&nbsp;<span c\
lass="element-name">test3</span>&#8203;<span class="parameters">(Generic2&lt;<a \
href="RcvrA.html" title="annotation in typeannos">@RcvrA</a> X&gt;&nbsp;this)</s\
pan></div>""",
"""
<div class="member-signature"><span class="return-type">void</span>&nbsp;<span cl\
ass="element-name">test4</span>&#8203;<span class="parameters">(<a href="RcvrA.ht\
ml" title="annotation in typeannos">@RcvrA</a> Generic2&lt;<a href="RcvrA.html" t\
itle="annotation in typeannos">@RcvrA</a> X&gt;&nbsp;this)</span></div>""");
// Test for repeated type annotations (RepeatedAnnotations.java).
@ -535,7 +548,8 @@ public class TestTypeAnnotations extends JavadocTester {
nnotation in typeannos">@RepTypeUseA</a> <a href="RepTypeUseA.html" title="annot\
ation in typeannos">@RepTypeUseA</a> <a href="RepTypeUseB.html" title="annotatio\
n in typeannos">@RepTypeUseB</a> <a href="RepTypeUseB.html" title="annotation in\
typeannos">@RepTypeUseB</a>&nbsp;RepeatingOnConstructor&nbsp;this,
typeannos">@RepTypeUseB</a> <a href="RepeatingOnConstructor.html" title="class \
in typeannos">RepeatingOnConstructor</a>&nbsp;RepeatingOnConstructor.this,
<a href="RepParameterA.html" title="annotation in typeannos">@RepParameterA</a> \
<a href="RepParameterA.html" title="annotation in typeannos">@RepParameterA</a> \
<a href="RepParameterB.html" title="annotation in typeannos">@RepParameterB</a> \
@ -743,7 +757,7 @@ public class TestTypeAnnotations extends JavadocTester {
RepTypeUseA</a> <a href="RepTypeUseA.html" title="annotation in typeannos">@RepT\
ypeUseA</a> <a href="RepTypeUseB.html" title="annotation in typeannos">@RepTypeU\
seB</a> <a href="RepTypeUseB.html" title="annotation in typeannos">@RepTypeUseB<\
/a>&nbsp;RepeatingOnMethod&nbsp;this,
/a> RepeatingOnMethod&nbsp;this,
<a href="RepParameterA.html" title="annotation in typeannos">@RepParameterA</a> \
<a href="RepParameterA.html" title="annotation in typeannos">@RepParameterA</a> \
<a href="RepParameterB.html" title="annotation in typeannos">@RepParameterB</a> \
@ -781,7 +795,7 @@ public class TestTypeAnnotations extends JavadocTester {
on in typeannos">@RepTypeUseA</a> <a href="RepTypeUseA.html" title="annotation i\
n typeannos">@RepTypeUseA</a> <a href="RepTypeUseB.html" title="annotation in ty\
peannos">@RepTypeUseB</a> <a href="RepTypeUseB.html" title="annotation in typean\
nos">@RepTypeUseB</a>&nbsp;RepeatingOnTypeParametersBoundsTypeArgumentsOnMethod&\
nos">@RepTypeUseB</a> RepeatingOnTypeParametersBoundsTypeArgumentsOnMethod&\
lt;<a href="RepTypeUseA.html" title="annotation in typeannos">@RepTypeUseA</a> <\
a href="RepTypeUseA.html" title="annotation in typeannos">@RepTypeUseA</a> <a hr\
ef="RepTypeUseB.html" title="annotation in typeannos">@RepTypeUseB</a> <a href="\