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