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")
  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 
 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 }