< prev index next >

test/java/lang/reflect/DefaultMethodMembers/FilterNotMostSpecific.java

Print this page




  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")
  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")
  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 
 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 
 118     private String failMsg(MethodDesc expected, Method m, Class<?> iface) {
 119         return "\nOn interface: " + iface +
 120             "\nexpected: " + toMethodString(expected) +
 121             "\nfound: " + m;
 122     }
 123 
 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 
 130     private String toMethodString(MethodDesc m) {
 131         return m.declaringClass().getSimpleName().toString() + "." +
 132             m.name() + "()";





 133     }
 134 
 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 {
 144         String name();


 145         Class<?> declaringClass();
 146         MethodKind kind() default MethodKind.ABSTRACT;
 147         boolean isGetMethodReturn() default false;
 148     }
 149 



 150     @Retention(RetentionPolicy.RUNTIME)
 151     public @interface MethodDescs {
 152         MethodDesc[] value();
 153     }
 154 
 155     public static enum MethodKind {
 156         ABSTRACT,
 157         CONCRETE,
 158         DEFAULT,
 159     }
 160     // base interfaces
 161     interface I { void nonDefault(); }
 162     interface J extends I { void nonDefault(); }
 163 
 164     interface Jprim extends I {}
 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)
 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)
 213     interface K2M extends J, I { void nonDefault(); }
 214 
 215     // base interfaces default methods
 216     interface L { default void isDefault() {} void nonDefault(); }
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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
 435     interface Z1 { void 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 
 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
 481     interface X1 { default void 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)
 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 
 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
 546     interface B1A { Object 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)
 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)
 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
 584     interface A1 { void m(); void m(int i); void m(int i, int j); }
 585     interface A2A extends A1 { void m(); void m(int i); void m(int i, int j); }
 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
 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 


 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 }


  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")
  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")
  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 
  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 
 114     private String failMsg(MethodDesc expected, Method m, Class<?> iface) {
 115         return "\nOn interface: " + iface +
 116             "\nexpected: " + toMethodString(expected) +
 117             "\nfound: " + m;
 118     }
 119 
 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 
 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 
 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 {
 145         String name();
 146         Class<?> returnType() default NotSpecified.class;
 147         Class<?>[] parameterTypes() default {};
 148         Class<?> declaringClass();
 149         MethodKind kind() default MethodKind.ABSTRACT;
 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 {
 158         MethodDesc[] value();
 159     }
 160 
 161     public static enum MethodKind {
 162         ABSTRACT,
 163         CONCRETE,
 164         DEFAULT,
 165     }
 166     // base interfaces
 167     interface I { void nonDefault(); }
 168     interface J extends I { void nonDefault(); }
 169 
 170     interface Jprim extends I {}
 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)
 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)
 213     interface K2M extends J, I { void nonDefault(); }
 214 
 215     // base interfaces default methods
 216     interface L { default void isDefault() {} void nonDefault(); }
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)
 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)


 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)

 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)
 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
 386     interface Z1 { void 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 
 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
 424     interface X1 { default void 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)
 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 
 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 
 481     interface B1 { Object m(); }
 482     interface B2A extends B1 { Map 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)
 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)
 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
 538     interface A1 { void m(); void m(int i); void m(int i, int j); }
 539     interface A2A extends A1 { void m(); void m(int i); void m(int i, int j); }
 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 
 561     interface E { void 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
 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 


 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 }
< prev index next >