1 /*
2  * Copyright (c) 2014, 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 /*
25  * @test
26  * @bug 8029674
27  * @summary Verify that the right interface methods are returned by
28  *          Class.getMethod() and Class.getMethods()
29  * @run testng FilterNotMostSpecific
30  */
31 
32 import java.lang.reflect.*;
33 import java.lang.annotation.*;
34 
35 import java.util.Arrays;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.HashMap;
39 import java.util.stream.Collectors;
40 import java.util.stream.Stream;
41 
42 import org.testng.annotations.DataProvider;
43 import org.testng.annotations.Test;
44 
45 import static org.testng.Assert.*;
46 
47 public class FilterNotMostSpecific {
48 
49     @Test(dataProvider="getCases")
testGetMethod(Class<?> iface)50     public void testGetMethod(Class<?> iface) {
51         boolean match = false;
52         MethodDesc[] expectedMethods = iface.getAnnotationsByType(MethodDesc.class);
53 
54         for (MethodDesc expected : expectedMethods) {
55             if (expected.isGetMethodReturn()) {
56                 try {
57                     Method m = iface.getMethod(expected.name(), expected.parameterTypes());
58                     if (!assertMatch(expected, m))
59                         fail(failMsg(expected, m, iface));
60                     else
61                         match = true;
62                 } catch (NoSuchMethodException e) {
63                     fail("expected: " + toMethodString(expected), e);
64                 }
65             }
66         }
67         assert(match);
68     }
69 
70     @Test(dataProvider="getCases")
testGetMethods(Class<?> iface)71     public void testGetMethods(Class<?> iface) {
72         List<Method> foundMethods = filterObjectMethods(iface.getMethods());
73         MethodDesc[] expectedMethods = iface.getAnnotationsByType(MethodDesc.class);
74 
75         for (MethodDesc expected : expectedMethods) {
76             boolean found = false;
77             for (Method m : foundMethods) {
78                 if (assertMatch(expected, m)) {
79                     found = true;
80                     break;
81                 }
82             }
83             if (!found)
84                 fail("On: "+ iface +"\nDid not find " + toMethodString(expected) +
85                      " among " + foundMethods);
86         }
87         assertEquals(foundMethods.size(), expectedMethods.length,
88                 "\non: " + iface +
89                 "\nexpected: " + toMethodStrings(expectedMethods) +
90                 "\nfound: " + foundMethods + "\n");
91     }
92 
assertMatch(MethodDesc expected, Method m)93     private boolean assertMatch(MethodDesc expected, Method m) {
94         if (!expected.name().equals(m.getName()))
95             return false;
96         if (expected.declaringClass() != m.getDeclaringClass())
97             return false;
98         if (!Arrays.equals(expected.parameterTypes(), m.getParameterTypes()))
99             return false;
100         if (expected.returnType() != NotSpecified.class &&
101             expected.returnType() != m.getReturnType())
102             return false;
103 
104         if (expected.kind() == MethodKind.ABSTRACT)
105             assertTrue(Modifier.isAbstract(m.getModifiers()), m + " should be ABSTRACT");
106         else if (expected.kind() == MethodKind.CONCRETE)
107             assertTrue(!Modifier.isAbstract(m.getModifiers()) && !m.isDefault(), m + " should be CONCRETE");
108         else if (expected.kind() == MethodKind.DEFAULT)
109             assertTrue(m.isDefault(), m + " should be DEFAULT");
110 
111         return true;
112     }
113 
failMsg(MethodDesc expected, Method m, Class<?> iface)114     private String failMsg(MethodDesc expected, Method m, Class<?> iface) {
115         return "\nOn interface: " + iface +
116             "\nexpected: " + toMethodString(expected) +
117             "\nfound: " + m;
118     }
119 
filterObjectMethods(Method[] in)120     private static List<Method> filterObjectMethods(Method[] in) {
121         return Arrays.stream(in).
122             filter(m -> (m.getDeclaringClass() != java.lang.Object.class)).
123             collect(Collectors.toList());
124     }
125 
toMethodString(MethodDesc m)126     private String toMethodString(MethodDesc m) {
127         return (m.returnType() != NotSpecified.class
128                 ? m.returnType().getSimpleName() + " "
129                 : "") +
130                m.declaringClass().getSimpleName().toString() + "." +
131                m.name() + Stream.of(m.parameterTypes())
132                                 .map(cl -> cl.getSimpleName())
133                                 .collect(Collectors.joining(", ", "(", ")"));
134     }
135 
toMethodStrings(MethodDesc[] m)136     private List<String> toMethodStrings(MethodDesc[] m) {
137         return Arrays.stream(m).
138             map(this::toMethodString)
139             .collect(Collectors.toList());
140     }
141 
142     @Retention(RetentionPolicy.RUNTIME)
143     @Repeatable(MethodDescs.class)
144     public @interface MethodDesc {
name()145         String name();
returnType()146         Class<?> returnType() default NotSpecified.class;
parameterTypes()147         Class<?>[] parameterTypes() default {};
declaringClass()148         Class<?> declaringClass();
kind()149         MethodKind kind() default MethodKind.ABSTRACT;
isGetMethodReturn()150         boolean isGetMethodReturn() default false;
151     }
152 
153     // special type marking a not-specified return type in @MethodDesc
154     interface NotSpecified {}
155 
156     @Retention(RetentionPolicy.RUNTIME)
157     public @interface MethodDescs {
value()158         MethodDesc[] value();
159     }
160 
161     public static enum MethodKind {
162         ABSTRACT,
163         CONCRETE,
164         DEFAULT,
165     }
166     // base interfaces
nonDefault()167     interface I { void nonDefault(); }
nonDefault()168     interface J extends I { void nonDefault(); }
169 
170     interface Jprim extends I {}
nonDefault()171     interface Jbis extends Jprim { void nonDefault(); }
172 
173     // interesting cases
174 
175     @MethodDesc(name="nonDefault", declaringClass=Jbis.class,
176             isGetMethodReturn=true)
177     interface P1 extends Jbis {}
178 
179     @MethodDesc(name="nonDefault", declaringClass=Jbis.class,
180             isGetMethodReturn=true)
181     interface P2 extends Jbis, Jprim {}
182 
183     @MethodDesc(name="nonDefault", declaringClass=Jbis.class,
184             isGetMethodReturn=true)
185     interface P3 extends Jbis, Jprim, I {}
186 
187     @MethodDesc(name="nonDefault", declaringClass=J.class,
188             isGetMethodReturn=true)
189     interface P4 extends I, J {}
190 
191     @MethodDesc(name="nonDefault", declaringClass=J.class,
192             isGetMethodReturn=true)
193     interface P5 extends J, I {}
194 
195     @MethodDesc(name="nonDefault", declaringClass=J.class,
196             isGetMethodReturn=true)
197     interface K1 extends J {}
198 
199     @MethodDesc(name="nonDefault", declaringClass=K1M.class,
200             isGetMethodReturn=true)
nonDefault()201     interface K1M extends J { void nonDefault(); }
202 
203     @MethodDesc(name="nonDefault", declaringClass=J.class,
204              isGetMethodReturn=true)
205    interface K2 extends I, J {}
206 
207     @MethodDesc(name="nonDefault", declaringClass=J.class,
208             isGetMethodReturn=true)
209     interface K2O extends J, I {}
210 
211     @MethodDesc(name="nonDefault", declaringClass=K2M.class,
212             isGetMethodReturn=true)
nonDefault()213     interface K2M extends J, I { void nonDefault(); }
214 
215     // base interfaces default methods
isDefault()216     interface L { default void isDefault() {} void nonDefault(); }
isDefault()217     interface M extends L { default void isDefault() {} void nonDefault(); }
218 
219     // test cases default methods
220 
221     @MethodDesc(name="nonDefault", declaringClass=M.class,
222             isGetMethodReturn=true)
223     @MethodDesc(name="isDefault", declaringClass=M.class,
224             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
225     interface N1 extends M {}
226 
227     @MethodDesc(name="isDefault", declaringClass=N1D.class,
228             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
229     @MethodDesc(name="nonDefault", declaringClass=M.class,
230             isGetMethodReturn=true)
isDefault()231     interface N1D extends M { default void isDefault() {}}
232 
233     @MethodDesc(name="nonDefault", declaringClass=N1N.class,
234             isGetMethodReturn=true)
235     @MethodDesc(name="isDefault", declaringClass=M.class,
236             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
nonDefault()237     interface N1N extends M { void nonDefault(); }
238 
239     @MethodDesc(name="isDefault", declaringClass=N1DN.class,
240             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
241     @MethodDesc(name="nonDefault", declaringClass=N1DN.class,
242             isGetMethodReturn=true)
isDefault()243     interface N1DN extends M { default void isDefault() {} void nonDefault(); }
244 
245     @MethodDesc(name="isDefault", declaringClass=M.class,
246             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
247     @MethodDesc(name="nonDefault", declaringClass=M.class,
248             isGetMethodReturn=true)
249     interface N2 extends M, L {}
250 
251     @MethodDesc(name="isDefault", declaringClass=M.class,
252             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
253     @MethodDesc(name="nonDefault", declaringClass=M.class,
254             isGetMethodReturn=true)
255     interface N22 extends L, M {}
256 
257     @MethodDesc(name="isDefault", declaringClass=N2D.class,
258             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
259     @MethodDesc(name="nonDefault", declaringClass=M.class,
260             isGetMethodReturn=true)
isDefault()261     interface N2D extends M, L { default void isDefault() {}}
262 
263     @MethodDesc(name="isDefault", declaringClass=M.class,
264             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
265     @MethodDesc(name="nonDefault", declaringClass=N2N.class,
266             isGetMethodReturn=true)
nonDefault()267     interface N2N extends M, L { void nonDefault(); }
268 
269     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
270             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
271     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
272             isGetMethodReturn=true)
isDefault()273     interface N2DN extends M, L { default void isDefault() {} void nonDefault(); }
274 
275     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
276             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
277     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
278             isGetMethodReturn=true)
279     interface O1 extends L, M, N2DN {}
280 
281     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
282             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
283     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
284             isGetMethodReturn=true)
285     interface O2 extends M, N2DN, L {}
286 
287     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
288             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
289     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
290             isGetMethodReturn=true)
291     interface O3 extends N2DN, L, M {}
292 
293     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
294             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
295     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
296             isGetMethodReturn=true)
297     abstract class C1 implements L, M, N2DN {}
298 
299     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
300             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
301     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
302             isGetMethodReturn=true)
303     abstract class C2 implements M, N2DN, L {}
304 
305     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
306             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
307     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
308             isGetMethodReturn=true)
309     abstract class C3 implements N2DN, L, M {}
310 
311     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
312             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
313     @MethodDesc(name="nonDefault", declaringClass=C4.class,
314             kind=MethodKind.CONCRETE, isGetMethodReturn=true)
nonDefault()315     class C4 implements L, M, N2DN { public void nonDefault() {} }
316 
317     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
318             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
319     @MethodDesc(name="nonDefault", declaringClass=C5.class,
320             kind=MethodKind.CONCRETE, isGetMethodReturn=true)
nonDefault()321     class C5 implements M, N2DN, L { public void nonDefault() {} }
322 
323     @MethodDesc(name="isDefault", declaringClass=N2DN.class,
324             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
325     @MethodDesc(name="nonDefault", declaringClass=C6.class,
326             kind=MethodKind.CONCRETE, isGetMethodReturn=true)
nonDefault()327     class C6 implements N2DN, L, M { public void nonDefault() {} }
328 
329     // reabstraction
330 
331     @MethodDesc(name="isDefault", declaringClass=R1.class,
332             isGetMethodReturn=true)
333     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
334             isGetMethodReturn=true)
isDefault()335     interface R1 extends L, M, N2DN { void isDefault(); }
336 
337     @MethodDesc(name="isDefault", declaringClass=R2.class,
338             isGetMethodReturn=true)
339     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
340             isGetMethodReturn=true)
isDefault()341     interface R2 extends M, N2DN, L { void isDefault(); }
342 
343     @MethodDesc(name="isDefault", declaringClass=R3.class,
344             isGetMethodReturn=true)
345     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
346             isGetMethodReturn=true)
isDefault()347     interface R3 extends N2DN, L, M { void isDefault(); }
348 
349     @MethodDesc(name="isDefault", declaringClass=R1.class,
350             isGetMethodReturn=true)
351     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
352             isGetMethodReturn=true)
353     interface R4 extends L, M, N2DN, R1 {}
354 
355     @MethodDesc(name="isDefault", declaringClass=R2.class,
356             isGetMethodReturn=true)
357     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
358             isGetMethodReturn=true)
359     interface R5 extends M, N2DN, R2, L {}
360 
361     @MethodDesc(name="isDefault", declaringClass=R3.class,
362             isGetMethodReturn=true)
363     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
364             isGetMethodReturn=true)
365     interface R6 extends N2DN, R3, L, M {}
366 
367     @MethodDesc(name="isDefault", declaringClass=R1.class,
368             isGetMethodReturn=true)
369     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
370             isGetMethodReturn=true)
371     interface R7 extends L, M, R1, N2DN {}
372 
373     @MethodDesc(name="isDefault", declaringClass=R2.class,
374             isGetMethodReturn=true)
375     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
376             isGetMethodReturn=true)
377     interface R8 extends M, R2, N2DN, L {}
378 
379     @MethodDesc(name="isDefault", declaringClass=R3.class,
380             isGetMethodReturn=true)
381     @MethodDesc(name="nonDefault", declaringClass=N2DN.class,
382             isGetMethodReturn=true)
383     interface R9 extends R3, N2DN, L, M {}
384 
385     // More reabstraction
z()386     interface Z1 { void z(); }
z()387     interface Z2 extends Z1 { default void z() {} }
388 
389     @MethodDesc(name="z", declaringClass=Z2.class,
390             isGetMethodReturn=true, kind=MethodKind.DEFAULT)
391     interface Z31 extends Z1, Z2 {}
392 
393     @MethodDesc(name="z", declaringClass=Z2.class,
394             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
395     interface Z32 extends Z2, Z1 {}
396 
z()397     interface Z3 extends Z2, Z1 { void z(); }
398 
399     @MethodDesc(name="z", declaringClass=Z3.class,
400             isGetMethodReturn = true)
401     interface Z41 extends Z1, Z2, Z3 { }
402 
403     @MethodDesc(name="z", declaringClass=Z3.class,
404             isGetMethodReturn = true)
405     interface Z42 extends Z2, Z3, Z1 { }
406 
407     @MethodDesc(name="z", declaringClass=Z3.class,
408             isGetMethodReturn = true)
409     interface Z43 extends Z3, Z1, Z2 { }
410 
411     @MethodDesc(name="z", declaringClass=Z3.class,
412             isGetMethodReturn = true)
413     abstract class ZC41 implements Z1, Z2, Z3 { }
414 
415     @MethodDesc(name="z", declaringClass=Z3.class,
416             isGetMethodReturn = true)
417     abstract class ZC42 implements Z2, Z3, Z1 { }
418 
419     @MethodDesc(name="z", declaringClass=Z3.class,
420             isGetMethodReturn = true)
421     abstract class ZC43 implements Z3, Z1, Z2 { }
422 
423     // More reabstraction + concretization
x()424     interface X1 { default void x() {} }
x()425     interface X2 extends X1 { void x(); }
426 
427     @MethodDesc(name="x", declaringClass=X2.class,
428             isGetMethodReturn=true)
429     interface X31 extends X1, X2 {}
430 
431     @MethodDesc(name="x", declaringClass=X2.class,
432             isGetMethodReturn=true)
433     interface X32 extends X2, X1 {}
434 
435     @MethodDesc(name="x", declaringClass=X3.class,
436             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
x()437     interface X3 extends X2, X1 { default void x() {} }
438 
439     // order shouldn't matter here
440     @MethodDesc(name="x", declaringClass=X3.class,
441             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
442     interface X41 extends X1, X2, X3 { }
443 
444     @MethodDesc(name="x", declaringClass=X3.class,
445             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
446     interface X42 extends X2, X3, X1 { }
447 
448     @MethodDesc(name="x", declaringClass=X3.class,
449             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
450     interface X43 extends X3, X1, X2 { }
451 
452     // order shouldn't matter here
453     @MethodDesc(name="x", declaringClass=X3.class,
454             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
455     abstract class XC41 implements X1, X2, X3 { }
456 
457     @MethodDesc(name="x", declaringClass=X3.class,
458             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
459     abstract class XC42 implements X2, X3, X1 { }
460 
461     @MethodDesc(name="x", declaringClass=X3.class,
462             kind=MethodKind.DEFAULT, isGetMethodReturn=true)
463     abstract class XC43 implements X3, X1, X2 { }
464 
nonDefault()465     interface K extends I, J { void nonDefault(); }
466 
467     @MethodDesc(name="nonDefault", declaringClass=K.class,
468             isGetMethodReturn=true)
469     abstract class ZZ1 implements I, J, K {}
470 
471     @MethodDesc(name="nonDefault", declaringClass=K.class,
472             isGetMethodReturn=true)
473     abstract class ZZ2 extends ZZ1 implements K, I, J {}
474 
475     @MethodDesc(name="nonDefault", declaringClass=K.class,
476             isGetMethodReturn=true)
477     abstract class ZZ3 extends ZZ2 implements J, K, I {}
478 
479     // bridges...
480 
m()481     interface B1 { Object m(); }
m()482     interface B2A extends B1 { Map m(); }
m()483     interface B2B extends B1 { HashMap m(); }
484 
485     @MethodDesc(name="m", returnType=Object.class, declaringClass=B3A.class,
486             kind = MethodKind.DEFAULT)
487     @MethodDesc(name="m", returnType=Map.class, declaringClass=B3A.class,
488             kind = MethodKind.DEFAULT)
489     @MethodDesc(name="m", returnType=HashMap.class, declaringClass=B3A.class,
490             isGetMethodReturn=true)
m()491     interface B3A extends B2A { HashMap m(); }
492 
493     @MethodDesc(name="m", returnType=Object.class, declaringClass=B4A.class,
494             kind = MethodKind.DEFAULT)
495     @MethodDesc(name="m", returnType=Map.class, declaringClass=B4A.class,
496             kind = MethodKind.DEFAULT)
497     @MethodDesc(name="m", returnType=HashMap.class, declaringClass= B4A.class,
498             isGetMethodReturn=true)
m()499     interface B4A extends B3A { HashMap m(); }
500 
501     @MethodDesc(name="m", returnType=Object.class, declaringClass=B4A.class,
502             kind = MethodKind.DEFAULT)
503     @MethodDesc(name="m", returnType=Map.class, declaringClass=B4A.class,
504             kind = MethodKind.DEFAULT)
505     @MethodDesc(name="m", returnType=HashMap.class, declaringClass= B4A.class,
506             isGetMethodReturn=true)
507     interface B5A2 extends B4A, B1 {}
508 
509     @MethodDesc(name="m", returnType=Object.class, declaringClass=B4A.class,
510             kind = MethodKind.DEFAULT)
511     @MethodDesc(name="m", returnType=Map.class, declaringClass=B4A.class,
512             kind = MethodKind.DEFAULT)
513     @MethodDesc(name="m", returnType=HashMap.class, declaringClass= B4A.class,
514             isGetMethodReturn=true)
515     interface B5A4A extends B4A, B3A {}
516 
517     // ... + most specific return type for getMethod from two unrelated interfaces
518 
519     @MethodDesc(name="m", returnType=Object.class, declaringClass=B2A.class,
520             kind = MethodKind.DEFAULT)
521     @MethodDesc(name="m", returnType=Object.class, declaringClass=B2B.class,
522             kind = MethodKind.DEFAULT)
523     @MethodDesc(name="m", returnType=Map.class, declaringClass=B2A.class)
524     @MethodDesc(name="m", returnType=HashMap.class, declaringClass=B2B.class,
525             isGetMethodReturn=true)
526     interface B3AB extends B2A, B2B {}
527 
528     @MethodDesc(name="m", returnType=Object.class, declaringClass=B2A.class,
529             kind = MethodKind.DEFAULT)
530     @MethodDesc(name="m", returnType=Object.class, declaringClass=B2B.class,
531             kind = MethodKind.DEFAULT)
532     @MethodDesc(name="m", returnType=Map.class, declaringClass=B2A.class)
533     @MethodDesc(name="m", returnType=HashMap.class, declaringClass=B2B.class,
534             isGetMethodReturn=true)
535     interface B3BA extends B2B, B2A {}
536 
537     // same name different params type
m(int i, int j)538     interface A1 { void m(); void m(int i); void m(int i, int j); }
m()539     interface A2A extends A1 { void m(); void m(int i); void m(int i, int j); }
m()540     interface A2B extends A1 { void m(); void m(int i); default void m(int i, int j) {} }
541 
542     @MethodDesc(name="m", parameterTypes = {}, declaringClass=A2A.class,
543             isGetMethodReturn=true)
544     @MethodDesc(name="m", parameterTypes = {int.class}, declaringClass=A2A.class,
545             isGetMethodReturn=true)
546     @MethodDesc(name="m", parameterTypes = {int.class, int.class}, declaringClass=A2A.class,
547             isGetMethodReturn=true)
548     interface A3A extends A1, A2A {}
549 
550     @MethodDesc(name="m", parameterTypes = {}, declaringClass=A2B.class,
551             isGetMethodReturn=true)
552     @MethodDesc(name="m", parameterTypes = {int.class}, declaringClass=A2B.class,
553             isGetMethodReturn=true)
554     @MethodDesc(name="m", parameterTypes = {int.class, int.class}, declaringClass=A2B.class,
555             kind = MethodKind.DEFAULT, isGetMethodReturn=true)
556     interface A3B extends A1, A2B {}
557 
558     // method in directly implemented interface overrides interface method
559     // inherited by superclass
560 
m()561     interface E { void m(); }
m()562     interface F extends E { void m(); }
563     abstract class G implements E {}
564 
565     @MethodDesc(name="m", declaringClass=F.class, isGetMethodReturn=true)
566     abstract class H extends G implements F {}
567 
568     @DataProvider
getCases()569     public Object[][] getCases() { return CASES; }
570     public static final Class<?>[][] CASES =  {
571         { K1.class },
572         { K1M.class },
573         { K2.class },
574         { K2O.class },
575         { K2M.class },
576 
577         { N1.class },
578         { N1D.class },
579         { N1N.class },
580         { N1DN.class },
581 
582         { N2.class },
583         { N22.class },
584         { N2D.class },
585         { N2N.class },
586         { N2DN.class },
587 
588         { P1.class },
589         { P2.class },
590         { P3.class },
591         { P4.class },
592         { P5.class },
593 
594         { O1.class },
595         { O2.class },
596         { O3.class },
597 
598         { C1.class },
599         { C2.class },
600         { C3.class },
601 
602         { C4.class },
603         { C5.class },
604         { C6.class },
605 
606         { R1.class },
607         { R2.class },
608         { R3.class },
609 
610         { R4.class },
611         { R5.class },
612         { R6.class },
613 
614         { R7.class },
615         { R8.class },
616         { R9.class },
617 
618         { Z31.class },
619         { Z32.class },
620 
621         { Z41.class },
622         { Z42.class },
623         { Z43.class },
624 
625         { ZC41.class },
626         { ZC42.class },
627         { ZC43.class },
628 
629         { ZZ1.class },
630         { ZZ2.class },
631         { ZZ3.class },
632 
633         { X3.class },
634         { X31.class },
635         { X32.class },
636 
637         { X41.class },
638         { X42.class },
639         { X43.class },
640 
641         { XC41.class },
642         { XC42.class },
643         { XC43.class },
644 
645         { B3A.class },
646         { B4A.class },
647         { B5A2.class },
648         { B5A4A.class },
649         { B3AB.class },
650         { B3BA.class },
651 
652         { A3A.class },
653         { A3B.class },
654 
655         { H.class },
656     };
657 }
658