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 }