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