8223607: --override-methods=summary ignores some signature changes

Reviewed-by: jjg
This commit is contained in:
Hannes Wallnöfer 2020-12-18 15:46:25 +00:00
parent 59ae054873
commit 45bd3b9ec0
7 changed files with 457 additions and 29 deletions

View File

@ -25,13 +25,10 @@
package jdk.javadoc.internal.doclets.toolkit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@ -48,14 +45,10 @@ import javax.lang.model.util.Types;
import javax.tools.FileObject;
import javax.tools.JavaFileManager.Location;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.api.BasicJavacTask;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Source.Feature;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
@ -66,11 +59,9 @@ import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.model.JavacTypes;
import com.sun.tools.javac.util.Names;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
import jdk.javadoc.internal.doclint.DocLint;
import jdk.javadoc.internal.tool.ToolEnvironment;
import jdk.javadoc.internal.tool.DocEnvImpl;

View File

@ -25,20 +25,28 @@
package jdk.javadoc.internal.doclets.toolkit.util;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.WildcardType;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleElementVisitor14;
import javax.lang.model.util.SimpleTypeVisitor14;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -582,14 +590,10 @@ public class VisibleMemberTable {
return false;
}
TypeMirror inheritedMethodReturn = inheritedMethod.getReturnType();
TypeMirror lMethodReturn = lMethod.getReturnType();
boolean covariantReturn =
lMethodReturn.getKind() == TypeKind.DECLARED
&& inheritedMethodReturn.getKind() == TypeKind.DECLARED
&& !utils.typeUtils.isSameType(lMethodReturn, inheritedMethodReturn)
&& utils.typeUtils.isSubtype(lMethodReturn, inheritedMethodReturn);
boolean simpleOverride = covariantReturn ? false : utils.isSimpleOverride(lMethod);
// Even with --override-methods=summary we want to include details of
// overriding method if something noteworthy has been added or changed.
boolean simpleOverride = utils.isSimpleOverride(lMethod)
&& !overridingSignatureChanged(lMethod, inheritedMethod);
overriddenMethodTable.computeIfAbsent(lMethod,
l -> new OverridingMethodInfo(inheritedMethod, simpleOverride));
return simpleOverride;
@ -598,6 +602,90 @@ public class VisibleMemberTable {
return true;
}
// Check whether the signature of an overriding method has any changes worth
// being documented compared to the overridden method.
private boolean overridingSignatureChanged(ExecutableElement method, ExecutableElement overriddenMethod) {
// Covariant return type
TypeMirror overriddenMethodReturn = overriddenMethod.getReturnType();
TypeMirror methodReturn = method.getReturnType();
if (methodReturn.getKind() == TypeKind.DECLARED
&& overriddenMethodReturn.getKind() == TypeKind.DECLARED
&& !utils.typeUtils.isSameType(methodReturn, overriddenMethodReturn)
&& utils.typeUtils.isSubtype(methodReturn, overriddenMethodReturn)) {
return true;
}
// Modifiers changed from protected to public, non-final to final, or change in abstractness
Set<Modifier> modifiers = method.getModifiers();
Set<Modifier> overriddenModifiers = overriddenMethod.getModifiers();
if ((modifiers.contains(Modifier.PUBLIC) && overriddenModifiers.contains(Modifier.PROTECTED))
|| modifiers.contains(Modifier.FINAL)
|| modifiers.contains(Modifier.ABSTRACT) != overriddenModifiers.contains(Modifier.ABSTRACT)) {
return true;
}
// Change in thrown types
if (!method.getThrownTypes().equals(overriddenMethod.getThrownTypes())) {
return true;
}
// Documented annotations added anywhere in the method signature
return !getDocumentedAnnotations(method).equals(getDocumentedAnnotations(overriddenMethod));
}
private Set<AnnotationMirror> getDocumentedAnnotations(ExecutableElement element) {
Set<AnnotationMirror> annotations = new HashSet<>();
addDocumentedAnnotations(annotations, element.getAnnotationMirrors());
new SimpleTypeVisitor14<Void, Void>() {
@Override
protected Void defaultAction(TypeMirror e, Void v) {
addDocumentedAnnotations(annotations, e.getAnnotationMirrors());
return null;
}
@Override
public Void visitArray(ArrayType t, Void unused) {
if (t.getComponentType() != null) {
visit(t.getComponentType());
}
return super.visitArray(t, unused);
}
@Override
public Void visitDeclared(DeclaredType t, Void unused) {
t.getTypeArguments().forEach(this::visit);
return super.visitDeclared(t, unused);
}
@Override
public Void visitWildcard(WildcardType t, Void unused) {
if (t.getExtendsBound() != null) {
visit(t.getExtendsBound());
}
if (t.getSuperBound() != null) {
visit(t.getSuperBound());
}
return super.visitWildcard(t, unused);
}
@Override
public Void visitExecutable(ExecutableType t, Void unused) {
t.getParameterTypes().forEach(this::visit);
t.getTypeVariables().forEach(this::visit);
visit(t.getReturnType());
return super.visitExecutable(t, unused);
}
}.visit(element.asType());
return annotations;
}
private void addDocumentedAnnotations(Set<AnnotationMirror> annotations, List<? extends AnnotationMirror> annotationMirrors) {
annotationMirrors.forEach(annotation -> {
if (utils.isDocumentedAnnotation((TypeElement) annotation.getAnnotationType().asElement())) {
annotations.add(annotation);
}
});
}
/*
* This class encapsulates the details of local members, orderedMembers
* contains the members in the declaration order, additionally a

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8157000 8192850 8182765
* @bug 8157000 8192850 8182765 8223607
* @summary test the behavior of --override-methods option
* @library ../../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
@ -310,8 +310,8 @@ public class TestOverrideMethods extends JavadocTester {
the order they are declared."""
);
// Check methods with covariant return types
// Only m2 should be shown in summary; m1 and m3 should listed as declared in Base
// Check methods with covariant return types, changes in modifiers or thrown exceptions.
// Only those should be shown in summary; m1, m3, m9 should listed as declared in Base
checkOutput("pkg6/Sub.html", true,
"""
<div class="summary-table three-column-summary" aria-labelledby="method-summary-table-tab0">
@ -326,13 +326,224 @@ public class TestOverrideMethods extends JavadocTester {
<div class="col-last even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table">
<div class="block">This is Base::m2.</div>
</div>
<div class="col-first odd-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code>void</code></div>
<div class="col-second odd-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code><span class="member-name-link"><a href="#m4()">m4</a></span>()</code></div>
<div class="col-last odd-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table">
<div class="block">This is Base::m4.</div>
</div>
<div class="col-first even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code>java.lang.Object</code></div>
<div class="col-second even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code><span class="member-name-link"><a href="#m5()">m5</a></span>()</code></div>
<div class="col-last even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table">
<div class="block">This is Base::m5.</div>
</div>
<div class="col-first odd-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code>java.lang.Object</code></div>
<div class="col-second odd-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code><span class="member-name-link"><a href="#m6()">m6</a></span>()</code></div>
<div class="col-last odd-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table">
<div class="block">This is Base::m6.</div>
</div>
<div class="col-first even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code>java.lang.Object</code></div>
<div class="col-second even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table"><code><span class="member-name-link"><a href="#m7()">m7</a></span>()</code></div>
<div class="col-last even-row-color method-summary-table-tab2 method-summary-table-tab4 method-summary-table">
<div class="block">This is Base::m7.</div>
</div>
<div class="col-first odd-row-color method-summary-table-tab2 method-summary-table method-summary-table-tab3"><code>abstract java.lang.Object</code></div>
<div class="col-second odd-row-color method-summary-table-tab2 method-summary-table method-summary-table-tab3"><code><span class="member-name-link"><a href="#m8()">m8</a></span>()</code></div>
<div class="col-last odd-row-color method-summary-table-tab2 method-summary-table method-summary-table-tab3">
<div class="block">This is Base::m8.</div>
</div>
""",
"""
<div class="inherited-list">
<h3 id="methods.inherited.from.class.pkg6.Base">Methods declared in class&nbsp;p\
kg6.<a href="Base.html" title="class in pkg6">Base</a></h3>
<code><a href="Base.html#m1()">m1</a>, <a href="Base.html#m3()">m3</a></code></div>
<code><a href="Base.html#m1()">m1</a>, <a href="Base.html#m3()">m3</a>, <a href="Base.html#m9()">m9</a></code></div>
""");
}
@Test
public void testSummaryAnnotations() {
javadoc("-d", "out-summary-annotations",
"-sourcepath", testSrc,
"--no-platform-links",
"-javafx",
"--disable-javafx-strict-checks",
"--override-methods=summary",
"-private",
"pkg7");
checkExit(Exit.OK);
checkOutput("pkg7/AnnotatedSub1.html", true,
"""
<div class="inherited-list">
<h3 id="methods.inherited.from.class.pkg7.AnnotatedBase">Methods declared in int\
erface&nbsp;pkg7.<a href="AnnotatedBase.html" title="interface in pkg7">Annotate\
dBase</a></h3>
<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></code></div>""");
checkOutput("pkg7/AnnotatedSub2.html", true,
"""
<div class="member-signature"><span class="annotations"><a href="A.html" title="\
annotation in pkg7">@A</a>
</span><span class="return-type"><a href="A.html" title="annotation in pkg7">@A<\
/a> java.lang.Iterable&lt;java.lang.String&gt;</span>&nbsp;<span class="element-\
name">m1</span>&#8203;<span class="parameters">(java.lang.Class&lt;? extends jav\
a.lang.CharSequence&gt;&nbsp;p1,
int[]&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
checkOutput("pkg7/AnnotatedSub3.html", true,
"""
<div class="member-signature"><span class="annotations"><a href="A.html" title="\
annotation in pkg7">@A</a>
</span><span class="return-type"><a href="A.html" title="annotation in pkg7">@A<\
/a> java.lang.Iterable&lt;java.lang.String&gt;</span>&nbsp;<span class="element-\
name">m1</span>&#8203;<span class="parameters">(java.lang.Class&lt;? extends jav\
a.lang.CharSequence&gt;&nbsp;p1,
int[]&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
checkOutput("pkg7/AnnotatedSub4.html", true,
"""
<div class="member-signature"><span class="return-type">java.lang.Iterable&lt;<a\
href="A.html" title="annotation in pkg7">@A</a> java.lang.String&gt;</span>&nbs\
p;<span class="element-name">m1</span>&#8203;<span class="parameters">(java.lang\
.Class&lt;? extends java.lang.CharSequence&gt;&nbsp;p1,
int[]&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
checkOutput("pkg7/AnnotatedSub5.html", true,
"""
<div class="member-signature"><span class="return-type">java.lang.Iterable&lt;ja\
va.lang.String&gt;</span>&nbsp;<span class="element-name">m1</span>&#8203;<span \
class="parameters">(<a href="A.html" title="annotation in pkg7">@A</a>
<a href="A.html" title="annotation in pkg7">@A</a> java.lang.Class&lt;? extends\
java.lang.CharSequence&gt;&nbsp;p1,
int[]&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
checkOutput("pkg7/AnnotatedSub6.html", true,
"""
<div class="member-signature"><span class="return-type">java.lang.Iterable&lt;ja\
va.lang.String&gt;</span>&nbsp;<span class="element-name">m1</span>&#8203;<span \
class="parameters">(java.lang.Class&lt;<a href="A.html" title="annotation in pkg\
7">@A</a> ? extends java.lang.CharSequence&gt;&nbsp;p1,
int[]&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
checkOutput("pkg7/AnnotatedSub7.html", true,
"""
<div class="member-signature"><span class="return-type">java.lang.Iterable&lt;ja\
va.lang.String&gt;</span>&nbsp;<span class="element-name">m1</span>&#8203;<span \
class="parameters">(java.lang.Class&lt;? extends <a href="A.html" title="annotat\
ion in pkg7">@A</a> java.lang.CharSequence&gt;&nbsp;p1,
int[]&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
checkOutput("pkg7/AnnotatedSub8.html", true,
"""
<div class="member-signature"><span class="return-type">java.lang.Iterable&lt;ja\
va.lang.String&gt;</span>&nbsp;<span class="element-name">m1</span>&#8203;<span \
class="parameters">(java.lang.Class&lt;? extends java.lang.CharSequence&gt;&nbsp;p1,
int <a href="A.html" title="annotation in pkg7">@A</a> []&nbsp;p2)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from inte\
rface:&nbsp;<code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">Ann\
otatedBase</a></code></span></div>
<div class="block">This is AnnotatedBase::m1.</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="AnnotatedBase.html#m1(java.lang.Class,int%5B%5D)">m1</a></cod\
e>&nbsp;in interface&nbsp;<code><a href="AnnotatedBase.html" title="interface in\
pkg7">AnnotatedBase</a></code></dd>
<dt>Parameters:</dt>
<dd><code>p1</code> - first parameter</dd>
<dd><code>p2</code> - second parameter</dd>
<dt>Returns:</dt>
<dd>something</dd>
</dl>""");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@ -23,21 +23,55 @@
package pkg6;
import java.io.IOException;
public class Base<T> {
/**
* This is Base::m1.
* @return something
* */
*/
public Object m1() { }
/**
* This is Base::m2.
* @return something
* */
*/
public Object m2() { }
/**
* This is Base::m3.
* @return something
* */
*/
public T m3() { }
/**
* This is Base::m4.
*/
protected void m4() { }
/**
* This is Base::m5.
* @throws IOException an error
*/
public Object m5() throws IOException { }
/**
* This is Base::m6.
*/
public Object m6() { }
/**
* This is Base::m7.
*/
public abstract Object m7();
/**
* This is Base::m8.
*/
public Object m8() { }
/**
* This is Base::m9.
*/
public abstract Object m9();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, 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
@ -33,5 +33,23 @@ public class Sub<T> extends Base<T> {
// not a covariant override
@Override
public T m3() { }
// change visibility to public
@Override
public void m4() { }
// drop checked exception
@Override
public Object m5() { }
// add final modifier
@Override
public final Object m6() { }
// implement abstract method
@Override
public Object m7() { }
// override concrete method as abstract
@Override
public abstract Object m8();
// override abstract method unchanged
@Override
public abstract Object m9();
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2020, 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.
*
* 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 pkg7;
import java.lang.annotation.Documented;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
// Adding documented annotations anywhere in the signature of an overriding
// method should cause it to be included in the details section even with
// --override-methods=summary option.
interface AnnotatedBase {
/**
* This is AnnotatedBase::m1.
* @param p1 first parameter
* @param p2 second parameter
* @return something
*/
public Iterable<String> m1(Class<? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub1 extends AnnotatedBase {
@Override
public Iterable<String> m1(Class<? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub2 extends AnnotatedBase {
@Override
@A
public Iterable<String> m1(Class<? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub3 extends AnnotatedBase {
@Override
public @A Iterable<String> m1(Class<? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub4 extends AnnotatedBase {
@Override
public Iterable<@A String> m1(Class<? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub5 extends AnnotatedBase {
@Override
public Iterable<String> m1(@A Class<? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub6 extends AnnotatedBase {
@Override
public Iterable<String> m1(Class<@A ? extends CharSequence> p1, int[] p2);
}
interface AnnotatedSub7 extends AnnotatedBase {
@Override
public Iterable<String> m1(Class<? extends @A CharSequence> p1, int[] p2);
}
interface AnnotatedSub8 extends AnnotatedBase {
@Override
public Iterable<String> m1(Class<? extends CharSequence> p1, int @A [] p2);
}
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@Documented
@interface A {}

View File

@ -309,7 +309,7 @@ public class TestVisibleMembers extends JavadocTester {
checkOrder("p/C.html",
"METHOD DETAIL",
"public", "void", "method", "See Also:", "sub()", "I.sub1()",
"public", "void", "method", "See Also:", "sub()", "sub1()",
"public", "void", "m", "Method in C. See", "I.length()"
);
@ -325,9 +325,8 @@ public class TestVisibleMembers extends JavadocTester {
"METHOD DETAIL",
"Method sub in p.IImpl",
"Specified by:", "I.html",
"Specified by:", "II.html",
"END OF CLASS DATA");
checkUnique("p/IImpl.html", "Specified by:");
}
// see j.u.Spliterator