1/* 2 * Copyright (c) 2012, 2013, 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 24package org.openjdk.tests.vm; 25 26import org.openjdk.tests.separate.Compiler; 27import org.openjdk.tests.separate.TestHarness; 28import org.testng.annotations.Test; 29 30import static org.openjdk.tests.separate.SourceModel.AbstractMethod; 31import static org.openjdk.tests.separate.SourceModel.AccessFlag; 32import static org.openjdk.tests.separate.SourceModel.Class; 33import static org.openjdk.tests.separate.SourceModel.ConcreteMethod; 34import static org.openjdk.tests.separate.SourceModel.DefaultMethod; 35import static org.openjdk.tests.separate.SourceModel.Extends; 36import static org.openjdk.tests.separate.SourceModel.Interface; 37import static org.openjdk.tests.separate.SourceModel.MethodParameter; 38import static org.openjdk.tests.separate.SourceModel.TypeParameter; 39import static org.testng.Assert.assertEquals; 40import static org.testng.Assert.assertNotNull; 41import static org.testng.Assert.fail; 42 43@Test(groups = "vm") 44public class DefaultMethodsTest extends TestHarness { 45 public DefaultMethodsTest() { 46 super(false, false); 47 } 48 49 /** 50 * class C { public int m() { return 22; } } 51 * 52 * TEST: C c = new C(); c.m() == 22 53 */ 54 public void testHarnessInvokeVirtual() { 55 Class C = new Class("C", ConcreteMethod.std("22")); 56 assertInvokeVirtualEquals(22, C); 57 } 58 59 /** 60 * interface I { int m(); } 61 * class C implements I { public int m() { return 33; } } 62 * 63 * TEST: I i = new C(); i.m() == 33; 64 */ 65 public void testHarnessInvokeInterface() { 66 Interface I = new Interface("I", AbstractMethod.std()); 67 Class C = new Class("C", I, ConcreteMethod.std("33")); 68 assertInvokeInterfaceEquals(33, C, I); 69 } 70 71 /** 72 * class C {} 73 * 74 * TEST: C c = new C(); c.m() throws NoSuchMethod 75 */ 76 public void testHarnessThrows() { 77 Class C = new Class("C"); 78 assertThrows(NoSuchMethodError.class, C); 79 } 80 81 /** 82 * interface I { int m() default { return 44; } } 83 * class C implements I {} 84 * 85 * TEST: C c = new C(); c.m() == 44; 86 * TEST: I i = new C(); i.m() == 44; 87 */ 88 public void testBasicDefault() { 89 Interface I = new Interface("I", DefaultMethod.std("44")); 90 Class C = new Class("C", I); 91 92 assertInvokeVirtualEquals(44, C); 93 assertInvokeInterfaceEquals(44, C, I); 94 } 95 96 /** 97 * interface I { default int m() { return 44; } } 98 * interface J extends I {} 99 * interface K extends J {} 100 * class C implements K {} 101 * 102 * TEST: C c = new C(); c.m() == 44; 103 * TEST: I i = new C(); i.m() == 44; 104 */ 105 public void testFarDefault() { 106 Interface I = new Interface("I", DefaultMethod.std("44")); 107 Interface J = new Interface("J", I); 108 Interface K = new Interface("K", J); 109 Class C = new Class("C", K); 110 111 assertInvokeVirtualEquals(44, C); 112 assertInvokeInterfaceEquals(44, C, K); 113 } 114 115 /** 116 * interface I { int m(); } 117 * interface J extends I { default int m() { return 44; } } 118 * interface K extends J {} 119 * class C implements K {} 120 * 121 * TEST: C c = new C(); c.m() == 44; 122 * TEST: K k = new C(); k.m() == 44; 123 */ 124 public void testOverrideAbstract() { 125 Interface I = new Interface("I", AbstractMethod.std()); 126 Interface J = new Interface("J", I, DefaultMethod.std("44")); 127 Interface K = new Interface("K", J); 128 Class C = new Class("C", K); 129 130 assertInvokeVirtualEquals(44, C); 131 assertInvokeInterfaceEquals(44, C, K); 132 } 133 134 /** 135 * interface I { int m() default { return 44; } } 136 * class C implements I { public int m() { return 55; } } 137 * 138 * TEST: C c = new C(); c.m() == 55; 139 * TEST: I i = new C(); i.m() == 55; 140 */ 141 public void testExisting() { 142 Interface I = new Interface("I", DefaultMethod.std("44")); 143 Class C = new Class("C", I, ConcreteMethod.std("55")); 144 145 assertInvokeVirtualEquals(55, C); 146 assertInvokeInterfaceEquals(55, C, I); 147 } 148 149 /** 150 * interface I { default int m() { return 99; } } 151 * class B implements I {} 152 * class C extends B {} 153 * 154 * TEST: C c = new C(); c.m() == 99; 155 * TEST: I i = new C(); i.m() == 99; 156 */ 157 public void testInherited() { 158 Interface I = new Interface("I", DefaultMethod.std("99")); 159 Class B = new Class("B", I); 160 Class C = new Class("C", B); 161 162 assertInvokeVirtualEquals(99, C); 163 assertInvokeInterfaceEquals(99, C, I); 164 } 165 166 /** 167 * interface I { default int m() { return 99; } } 168 * class C { public int m() { return 11; } } 169 * class D extends C implements I {} 170 * 171 * TEST: D d = new D(); d.m() == 11; 172 * TEST: I i = new D(); i.m() == 11; 173 */ 174 public void testExistingInherited() { 175 Interface I = new Interface("I", DefaultMethod.std("99")); 176 Class C = new Class("C", ConcreteMethod.std("11")); 177 Class D = new Class("D", C, I); 178 179 assertInvokeVirtualEquals(11, D); 180 assertInvokeInterfaceEquals(11, D, I); 181 } 182 183 /** 184 * interface I { default int m() { return 44; } } 185 * class C implements I { public int m() { return 11; } } 186 * class D extends C { public int m() { return 22; } } 187 * 188 * TEST: D d = new D(); d.m() == 22; 189 * TEST: I i = new D(); i.m() == 22; 190 */ 191 public void testExistingInheritedOverride() { 192 Interface I = new Interface("I", DefaultMethod.std("99")); 193 Class C = new Class("C", I, ConcreteMethod.std("11")); 194 Class D = new Class("D", C, ConcreteMethod.std("22")); 195 196 assertInvokeVirtualEquals(22, D); 197 assertInvokeInterfaceEquals(22, D, I); 198 } 199 200 /** 201 * interface I { default int m() { return 99; } } 202 * interface J { defaultint m() { return 88; } } 203 * class C implements I { public int m() { return 11; } } 204 * class D extends C { public int m() { return 22; } } 205 * class E extends D implements J {} 206 * 207 * TEST: E e = new E(); e.m() == 22; 208 * TEST: J j = new E(); j.m() == 22; 209 */ 210 public void testExistingInheritedPlusDefault() { 211 Interface I = new Interface("I", DefaultMethod.std("99")); 212 Interface J = new Interface("J", DefaultMethod.std("88")); 213 Class C = new Class("C", I, ConcreteMethod.std("11")); 214 Class D = new Class("D", C, ConcreteMethod.std("22")); 215 Class E = new Class("E", D, J); 216 217 assertInvokeVirtualEquals(22, E); 218 assertInvokeInterfaceEquals(22, E, J); 219 } 220 221 /** 222 * interface I { default int m() { return 99; } } 223 * class B implements I {} 224 * class C extends B { public int m() { return 77; } } 225 * 226 * TEST: C c = new C(); c.m() == 77; 227 * TEST: I i = new C(); i.m() == 77; 228 */ 229 public void testInheritedWithConcrete() { 230 Interface I = new Interface("I", DefaultMethod.std("99")); 231 Class B = new Class("B", I); 232 Class C = new Class("C", B, ConcreteMethod.std("77")); 233 234 assertInvokeVirtualEquals(77, C); 235 assertInvokeInterfaceEquals(77, C, I); 236 } 237 238 /** 239 * interface I { default int m() { return 99; } } 240 * class B implements I {} 241 * class C extends B implements I { public int m() { return 66; } } 242 * 243 * TEST: C c = new C(); c.m() == 66; 244 * TEST: I i = new C(); i.m() == 66; 245 */ 246 public void testInheritedWithConcreteAndImpl() { 247 Interface I = new Interface("I", DefaultMethod.std("99")); 248 Class B = new Class("B", I); 249 Class C = new Class("C", B, I, ConcreteMethod.std("66")); 250 251 assertInvokeVirtualEquals(66, C); 252 assertInvokeInterfaceEquals(66, C, I); 253 } 254 255 /** 256 * interface I { default int m() { return 99; } } 257 * interface J { default int m() { return 88; } } 258 * class C implements I, J {} 259 * 260 * TEST: C c = new C(); c.m() throws ICCE 261 */ 262 public void testConflict() { 263 Interface I = new Interface("I", DefaultMethod.std("99")); 264 Interface J = new Interface("J", DefaultMethod.std("88")); 265 Class C = new Class("C", I, J); 266 267 assertThrows(IncompatibleClassChangeError.class, C); 268 } 269 270 /** 271 * interface I { int m(); } 272 * interface J { default int m() { return 88; } } 273 * class C implements I, J {} 274 * 275 * TEST: C c = new C(); c.m() == 88 276 */ 277 public void testAmbiguousReabstract() { 278 Interface I = new Interface("I", AbstractMethod.std()); 279 Interface J = new Interface("J", DefaultMethod.std("88")); 280 Class C = new Class("C", I, J); 281 282 assertInvokeVirtualEquals(88, C); 283 } 284 285 /** 286 * interface I { default int m() { return 99; } } 287 * interface J extends I { } 288 * interface K extends I { } 289 * class C implements J, K {} 290 * 291 * TEST: C c = new C(); c.m() == 99 292 * TEST: J j = new C(); j.m() == 99 293 * TEST: K k = new C(); k.m() == 99 294 * TEST: I i = new C(); i.m() == 99 295 */ 296 public void testDiamond() { 297 Interface I = new Interface("I", DefaultMethod.std("99")); 298 Interface J = new Interface("J", I); 299 Interface K = new Interface("K", I); 300 Class C = new Class("C", J, K); 301 302 assertInvokeVirtualEquals(99, C); 303 assertInvokeInterfaceEquals(99, C, J); 304 assertInvokeInterfaceEquals(99, C, K); 305 assertInvokeInterfaceEquals(99, C, I); 306 } 307 308 /** 309 * interface I { default int m() { return 99; } } 310 * interface J extends I { } 311 * interface K extends I { } 312 * interface L extends I { } 313 * interface M extends I { } 314 * class C implements I, J, K, L, M {} 315 * 316 * TEST: C c = new C(); c.m() == 99 317 * TEST: J j = new C(); j.m() == 99 318 * TEST: K k = new C(); k.m() == 99 319 * TEST: I i = new C(); i.m() == 99 320 * TEST: L l = new C(); l.m() == 99 321 * TEST: M m = new C(); m.m() == 99 322 */ 323 public void testExpandedDiamond() { 324 Interface I = new Interface("I", DefaultMethod.std("99")); 325 Interface J = new Interface("J", I); 326 Interface K = new Interface("K", I); 327 Interface L = new Interface("L", I); 328 Interface M = new Interface("M", L); 329 Class C = new Class("C", I, J, K, L, M); 330 331 assertInvokeVirtualEquals(99, C); 332 assertInvokeInterfaceEquals(99, C, J); 333 assertInvokeInterfaceEquals(99, C, K); 334 assertInvokeInterfaceEquals(99, C, I); 335 assertInvokeInterfaceEquals(99, C, L); 336 assertInvokeInterfaceEquals(99, C, M); 337 } 338 339 /** 340 * interface I { int m() default { return 99; } } 341 * interface J extends I { int m(); } 342 * class C implements J {} 343 * 344 * TEST: C c = new C(); c.m() throws AME 345 */ 346 public void testReabstract() { 347 Interface I = new Interface("I", DefaultMethod.std("99")); 348 Interface J = new Interface("J", I, AbstractMethod.std()); 349 Class C = new Class("C", J); 350 351 assertThrows(AbstractMethodError.class, C); 352 } 353 354 /** 355 * interface I { default int m() { return 88; } } 356 * interface J extends I { default int m() { return 99; } } 357 * class C implements J {} 358 * 359 * TEST: C c = new C(); c.m() == 99; 360 * TEST: J j = new C(); j.m() == 99; 361 * TEST: I i = new C(); i.m() == 99; 362 */ 363 public void testShadow() { 364 Interface I = new Interface("I", DefaultMethod.std("88")); 365 Interface J = new Interface("J", I, DefaultMethod.std("99")); 366 Class C = new Class("C", J); 367 368 assertInvokeVirtualEquals(99, C); 369 assertInvokeInterfaceEquals(99, C, J); 370 assertInvokeInterfaceEquals(99, C, I); 371 } 372 373 /** 374 * interface I { default int m() { return 88; } } 375 * interface J extends I { default int m() { return 99; } } 376 * class C implements I, J {} 377 * 378 * TEST: C c = new C(); c.m() == 99; 379 * TEST: J j = new C(); j.m() == 99; 380 * TEST: I i = new C(); i.m() == 99; 381 */ 382 public void testDisqualified() { 383 Interface I = new Interface("I", DefaultMethod.std("88")); 384 Interface J = new Interface("J", I, DefaultMethod.std("99")); 385 Class C = new Class("C", I, J); 386 387 assertInvokeVirtualEquals(99, C); 388 assertInvokeInterfaceEquals(99, C, J); 389 assertInvokeInterfaceEquals(99, C, I); 390 } 391 392 /** 393 * interface I<T> { default int m(T t) { return 99; } } 394 * Class C implements I<String> { public int m(String s) { return 88; } } 395 * 396 * TEST: C c = new C(); c.m("string") == 88; 397 * TEST: I i = new C(); i.m("string") == 88; 398 */ 399 public void testSelfFill() { 400 // This test ensures that a concrete method overrides a default method 401 // that matches at the language-level, but has a different method 402 // signature due to erasure. 403 404 DefaultMethod dm = new DefaultMethod( 405 "int", "m", "return 99;", new MethodParameter("T", "t")); 406 ConcreteMethod cm = new ConcreteMethod( 407 "int", "m", "return 88;", AccessFlag.PUBLIC, 408 new MethodParameter("String", "s")); 409 410 Interface I = new Interface("I", new TypeParameter("T"), dm); 411 Class C = new Class("C", I.with("String"), cm); 412 413 AbstractMethod pm = new AbstractMethod( 414 "int", "m", new MethodParameter("T", "t")); 415 416 assertInvokeVirtualEquals(88, C, cm, "-1", "\"string\""); 417 assertInvokeInterfaceEquals(99, C, I.with("String"), pm, "\"string\""); 418 419 C.setFullCompilation(true); // Force full bridge generation 420 assertInvokeInterfaceEquals(88, C, I.with("String"), pm, "\"string\""); 421 } 422 423 /** 424 * interface I { default int m() { return 99; } } 425 * class C implements I {} 426 * 427 * TEST: C.class.getMethod("m").invoke(new C()) == 99 428 */ 429 public void testReflectCall() { 430 Interface I = new Interface("I", DefaultMethod.std("99")); 431 //workaround accessibility issue when loading C with DirectedClassLoader 432 I.addAccessFlag(AccessFlag.PUBLIC); 433 Class C = new Class("C", I); 434 435 Compiler.Flags[] flags = this.verbose ? 436 new Compiler.Flags[] { Compiler.Flags.VERBOSE } : 437 new Compiler.Flags[] {}; 438 Compiler compiler = new Compiler(flags); 439 java.lang.Class<?> cls = null; 440 try { 441 cls = compiler.compileAndLoad(C); 442 } catch (ClassNotFoundException e) { 443 fail("Could not load class"); 444 } 445 446 java.lang.reflect.Method method = null; 447 try { 448 method = cls.getMethod(stdMethodName); 449 } catch (NoSuchMethodException e) { 450 fail("Could not find method in class"); 451 } 452 assertNotNull(method); 453 454 Object c = null; 455 try { 456 c = cls.newInstance(); 457 } catch (InstantiationException | IllegalAccessException e) { 458 fail("Could not create instance of class"); 459 } 460 assertNotNull(c); 461 462 Integer res = null; 463 try { 464 res = (Integer)method.invoke(c); 465 } catch (IllegalAccessException | 466 java.lang.reflect.InvocationTargetException e) { 467 fail("Could not invoke default instance method"); 468 } 469 assertNotNull(res); 470 471 assertEquals(res.intValue(), 99); 472 473 compiler.cleanup(); 474 } 475 476 /** 477 * interface I<T,V,W> { default int m(T t, V v, W w) { return 99; } } 478 * interface J<T,V> extends I<String,T,V> { int m(T t, V v, String w); } } 479 * interface K<T> extends J<String,T> { int m(T t, String v, String w); } } 480 * class C implements K<String> { 481 * public int m(String t, String v, String w) { return 88; } 482 * } 483 * 484 * TEST: I<String,String,String> i = new C(); i.m("A","B","C") == 88; 485 * TEST: J<String,String> j = new C(); j.m("A","B","C") == 88; 486 * TEST: K<String> k = new C(); k.m("A","B","C") == 88; 487 */ 488 public void testBridges() { 489 DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", 490 new MethodParameter("T", "t"), new MethodParameter("V", "v"), 491 new MethodParameter("W", "w")); 492 493 AbstractMethod pm0 = new AbstractMethod("int", stdMethodName, 494 new MethodParameter("T", "t"), new MethodParameter("V", "v"), 495 new MethodParameter("W", "w")); 496 497 AbstractMethod pm1 = new AbstractMethod("int", stdMethodName, 498 new MethodParameter("T", "t"), new MethodParameter("V", "v"), 499 new MethodParameter("String", "w")); 500 501 AbstractMethod pm2 = new AbstractMethod("int", stdMethodName, 502 new MethodParameter("T", "t"), new MethodParameter("String", "v"), 503 new MethodParameter("String", "w")); 504 505 ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;", 506 AccessFlag.PUBLIC, 507 new MethodParameter("String", "t"), 508 new MethodParameter("String", "v"), 509 new MethodParameter("String", "w")); 510 511 Interface I = new Interface("I", new TypeParameter("T"), 512 new TypeParameter("V"), new TypeParameter("W"), dm); 513 Interface J = new Interface("J", 514 new TypeParameter("T"), new TypeParameter("V"), 515 I.with("String", "T", "V"), pm1); 516 Interface K = new Interface("K", new TypeParameter("T"), 517 J.with("String", "T"), pm2); 518 Class C = new Class("C", K.with("String"), cm); 519 520 // First, without compiler bridges 521 String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" }; 522 assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), pm0, args); 523 assertInvokeInterfaceThrows(AbstractMethodError.class, C, J.with("String", "String"), pm1, args); 524 assertInvokeInterfaceThrows(AbstractMethodError.class, C, K.with("String"), pm2, args); 525 526 // Then with compiler bridges 527 C.setFullCompilation(true); 528 assertInvokeInterfaceEquals(88, C, I.with("String", "String", "String"), pm0, args); 529 assertInvokeInterfaceEquals(88, C, J.with("String", "String"), pm1, args); 530 assertInvokeInterfaceEquals(88, C, K.with("String"), pm2, args); 531 } 532 533 /** 534 * interface J { default int m() { return 88; } } 535 * interface I extends J { default int m() { return J.super.m(); } } 536 * class C implements I {} 537 * 538 * TEST: C c = new C(); c.m() == 88; 539 * TEST: I i = new C(); i.m() == 88; 540 */ 541 public void testSuperBasic() { 542 Interface J = new Interface("J", DefaultMethod.std("88")); 543 Interface I = new Interface("I", J, new DefaultMethod( 544 "int", stdMethodName, "return J.super.m();")); 545 I.addCompilationDependency(J.findMethod(stdMethodName)); 546 Class C = new Class("C", I); 547 548 assertInvokeVirtualEquals(88, C); 549 assertInvokeInterfaceEquals(88, C, I); 550 } 551 552 /** 553 * interface K { int m() default { return 99; } } 554 * interface L { int m() default { return 101; } } 555 * interface J extends K, L {} 556 * interface I extends J, K { int m() default { J.super.m(); } } 557 * class C implements I {} 558 * 559 * TEST: C c = new C(); c.m() throws ICCE 560 * TODO: add case for K k = new C(); k.m() throws ICCE 561 */ 562 public void testSuperConflict() { 563 Interface K = new Interface("K", DefaultMethod.std("99")); 564 Interface L = new Interface("L", DefaultMethod.std("101")); 565 Interface J = new Interface("J", K, L); 566 Interface I = new Interface("I", J, K, new DefaultMethod( 567 "int", stdMethodName, "return J.super.m();")); 568 Interface Jstub = new Interface("J", DefaultMethod.std("-1")); 569 I.addCompilationDependency(Jstub); 570 I.addCompilationDependency(Jstub.findMethod(stdMethodName)); 571 Class C = new Class("C", I); 572 573 assertThrows(IncompatibleClassChangeError.class, C); 574 } 575 576 /** 577 * interface I { default int m() { return 99; } } 578 * interface J extends I { default int m() { return 55; } } 579 * class C implements I, J { public int m() { return I.super.m(); } } 580 * 581 * TEST: C c = new C(); c.m() == 99 582 * TODO: add case for J j = new C(); j.m() == ??? 583 */ 584 public void testSuperDisqual() { 585 Interface I = new Interface("I", DefaultMethod.std("99")); 586 Interface J = new Interface("J", I, DefaultMethod.std("55")); 587 Class C = new Class("C", I, J, 588 new ConcreteMethod("int", stdMethodName, "return I.super.m();", 589 AccessFlag.PUBLIC)); 590 C.addCompilationDependency(I.findMethod(stdMethodName)); 591 592 assertInvokeVirtualEquals(99, C); 593 } 594 595 /** 596 * interface J { int m(); } 597 * interface I extends J { default int m() { return J.super.m(); } } 598 * class C implements I {} 599 * 600 * TEST: C c = new C(); c.m() throws AME 601 * TODO: add case for I i = new C(); i.m() throws AME 602 */ 603 public void testSuperNull() { 604 Interface J = new Interface("J", AbstractMethod.std()); 605 Interface I = new Interface("I", J, new DefaultMethod( 606 "int", stdMethodName, "return J.super.m();")); 607 Interface Jstub = new Interface("J", DefaultMethod.std("99")); 608 I.addCompilationDependency(Jstub); 609 I.addCompilationDependency(Jstub.findMethod(stdMethodName)); 610 Class C = new Class("C", I); 611 612 assertThrows(AbstractMethodError.class, C); 613 } 614 615 /** 616 * interface J<T> { default int m(T t) { return 88; } } 617 * interface I extends J<String> { 618 * int m(String s) default { return J.super.m(); } 619 * } 620 * class C implements I {} 621 * 622 * TEST: I i = new C(); i.m("") == 88; 623 */ 624 public void testSuperGeneric() { 625 Interface J = new Interface("J", new TypeParameter("T"), 626 new DefaultMethod("int", stdMethodName, "return 88;", 627 new MethodParameter("T", "t"))); 628 Interface I = new Interface("I", J.with("String"), 629 new DefaultMethod("int", stdMethodName, "return J.super.m(s);", 630 new MethodParameter("String", "s"))); 631 I.addCompilationDependency(J.findMethod(stdMethodName)); 632 Class C = new Class("C", I); 633 634 AbstractMethod pm = new AbstractMethod("int", stdMethodName, 635 new MethodParameter("String", "s")); 636 637 assertInvokeInterfaceEquals(88, C, new Extends(I), pm, "\"\""); 638 } 639 640 /** 641 * interface I<T> { int m(T t) default { return 44; } } 642 * interface J extends I<String> { int m(String s) default { return 55; } } 643 * class C implements I<String>, J { 644 * public int m(String s) { return I.super.m(s); } 645 * } 646 * 647 * TEST: C c = new C(); c.m("string") == 44 648 */ 649 public void testSuperGenericDisqual() { 650 MethodParameter t = new MethodParameter("T", "t"); 651 MethodParameter s = new MethodParameter("String", "s"); 652 653 Interface I = new Interface("I", new TypeParameter("T"), 654 new DefaultMethod("int", stdMethodName, "return 44;", t)); 655 Interface J = new Interface("J", I.with("String"), 656 new DefaultMethod("int", stdMethodName, "return 55;", s)); 657 Class C = new Class("C", I.with("String"), J, 658 new ConcreteMethod("int", stdMethodName, 659 "return I.super.m(s);", AccessFlag.PUBLIC, s)); 660 C.addCompilationDependency(I.findMethod(stdMethodName)); 661 662 assertInvokeVirtualEquals(44, C, 663 new ConcreteMethod( 664 "int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s), 665 "-1", "\"string\""); 666 } 667 668 /** 669 * interface I { default Integer m() { return new Integer(88); } } 670 * class C { Number m() { return new Integer(99); } } 671 * class D extends C implements I {} 672 * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; 673 * TEST: S s = new S(); s.foo() == new Integer(99) 674 */ 675 public void testCovarBridge() { 676 Interface I = new Interface("I", new DefaultMethod( 677 "Integer", "m", "return new Integer(88);")); 678 Class C = new Class("C", new ConcreteMethod( 679 "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC)); 680 Class D = new Class("D", I, C); 681 682 ConcreteMethod DstubMethod = new ConcreteMethod( 683 "Integer", "m", "return null;", AccessFlag.PUBLIC); 684 Class Dstub = new Class("D", DstubMethod); 685 686 ConcreteMethod toCall = new ConcreteMethod( 687 "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); 688 Class S = new Class("S", D, toCall); 689 S.addCompilationDependency(Dstub); 690 S.addCompilationDependency(DstubMethod); 691 692 // NEGATIVE test for separate compilation -- dispatches to I, not C 693 assertInvokeVirtualEquals(88, S, toCall, "null"); 694 } 695 696 /** 697 * interface I { default Integer m() { return new Integer(88); } } 698 * class C { int m() { return 99; } } 699 * class D extends C implements I {} 700 * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; 701 * TEST: S s = new S(); s.foo() == new Integer(88) 702 */ 703 public void testNoCovarNoBridge() { 704 Interface I = new Interface("I", new DefaultMethod( 705 "Integer", "m", "return new Integer(88);")); 706 Class C = new Class("C", new ConcreteMethod( 707 "int", "m", "return 99;", AccessFlag.PUBLIC)); 708 Class D = new Class("D", I, C); 709 710 ConcreteMethod DstubMethod = new ConcreteMethod( 711 "Integer", "m", "return null;", AccessFlag.PUBLIC); 712 Class Dstub = new Class("D", DstubMethod); 713 714 ConcreteMethod toCall = new ConcreteMethod( 715 "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); 716 Class S = new Class("S", D, toCall); 717 S.addCompilationDependency(Dstub); 718 S.addCompilationDependency(DstubMethod); 719 720 assertInvokeVirtualEquals(88, S, toCall, "null"); 721 } 722 723 /** 724 * interface J { int m(); } 725 * interface I extends J { default int m() { return 99; } } 726 * class B implements J {} 727 * class C extends B implements I {} 728 * TEST: C c = new C(); c.m() == 99 729 * 730 * The point of this test is that B does not get default method analysis, 731 * and C does not generate any new miranda methods in the vtable. 732 * It verifies that default method analysis occurs when mirandas have been 733 * inherited and the supertypes don't have any overpass methods. 734 */ 735 public void testNoNewMiranda() { 736 Interface J = new Interface("J", AbstractMethod.std()); 737 Interface I = new Interface("I", J, DefaultMethod.std("99")); 738 Class B = new Class("B", J); 739 Class C = new Class("C", B, I); 740 assertInvokeVirtualEquals(99, C); 741 } 742 743 /** 744 * interface I<T,V,W> { int m(T t, V v, W w); } 745 * interface J<T,V> implements I<T,V,String> { int m(T t, V v, String w); } 746 * interface K<T> implements J<T,String> { 747 * int m(T t, String v, String w); { return 99; } } 748 * class C implements K<String> { 749 * public int m(Object t, Object v, String w) { return 77; } 750 * } 751 * TEST C = new C(); ((I)c).m(Object,Object,Object) == 99 752 * TEST C = new C(); ((J)c).m(Object,Object,String) == 77 753 * TEST C = new C(); ((K)c).m(Object,String,String) == 99 754 * 755 * Test that a erased-signature-matching method does not implement 756 * non-language-level matching methods 757 */ 758 public void testNonConcreteFill() { 759 AbstractMethod ipm = new AbstractMethod("int", "m", 760 new MethodParameter("T", "t"), 761 new MethodParameter("V", "s"), 762 new MethodParameter("W", "w")); 763 Interface I = new Interface("I", 764 new TypeParameter("T"), 765 new TypeParameter("V"), 766 new TypeParameter("W"), ipm); 767 768 AbstractMethod jpm = new AbstractMethod("int", "m", 769 new MethodParameter("T", "t"), 770 new MethodParameter("V", "s"), 771 new MethodParameter("String", "w")); 772 Interface J = new Interface("J", 773 new TypeParameter("T"), 774 new TypeParameter("V"), 775 I.with("T", "V", "String"), jpm); 776 777 AbstractMethod kpm = new AbstractMethod("int", "m", 778 new MethodParameter("T", "t"), 779 new MethodParameter("String", "s"), 780 new MethodParameter("String", "w")); 781 DefaultMethod kdm = new DefaultMethod("int", "m", "return 99;", 782 new MethodParameter("T", "t"), 783 new MethodParameter("String", "v"), 784 new MethodParameter("String", "w")); 785 Interface K = new Interface("K", 786 new TypeParameter("T"), 787 J.with("T", "String"), 788 kdm); 789 790 Class C = new Class("C", 791 K.with("String"), 792 new ConcreteMethod("int", "m", "return 77;", 793 AccessFlag.PUBLIC, 794 new MethodParameter("Object", "t"), 795 new MethodParameter("Object", "v"), 796 new MethodParameter("String", "w"))); 797 798 // First, without compiler bridges 799 String a = "\"\""; 800 assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); 801 assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); 802 assertInvokeInterfaceThrows(AbstractMethodError.class, C, I.with("String", "String", "String"), ipm, a, a, a); 803 804 // Now, with bridges 805 J.setFullCompilation(true); 806 K.setFullCompilation(true); 807 assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); 808 assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); 809 assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), ipm, a, a, a); 810 } 811 812 public void testStrictfpDefault() { 813 try { 814 java.lang.Class.forName("org.openjdk.tests.vm.StrictfpDefault"); 815 } catch (Exception e) { 816 fail("Could not load class", e); 817 } 818 } 819} 820 821interface StrictfpDefault { 822 default strictfp void m() {} 823} 824