1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,825 @@ 1.4 +/* 1.5 + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package org.openjdk.tests.vm; 1.30 + 1.31 +import org.openjdk.tests.separate.Compiler; 1.32 +import org.openjdk.tests.separate.TestHarness; 1.33 +import org.testng.annotations.Test; 1.34 + 1.35 +import static org.openjdk.tests.separate.SourceModel.AbstractMethod; 1.36 +import static org.openjdk.tests.separate.SourceModel.AccessFlag; 1.37 +import static org.openjdk.tests.separate.SourceModel.Class; 1.38 +import static org.openjdk.tests.separate.SourceModel.ConcreteMethod; 1.39 +import static org.openjdk.tests.separate.SourceModel.DefaultMethod; 1.40 +import static org.openjdk.tests.separate.SourceModel.Extends; 1.41 +import static org.openjdk.tests.separate.SourceModel.Interface; 1.42 +import static org.openjdk.tests.separate.SourceModel.MethodParameter; 1.43 +import static org.openjdk.tests.separate.SourceModel.TypeParameter; 1.44 +import static org.testng.Assert.assertEquals; 1.45 +import static org.testng.Assert.assertNotNull; 1.46 +import static org.testng.Assert.fail; 1.47 + 1.48 +@Test(groups = "vm") 1.49 +public class DefaultMethodsTest extends TestHarness { 1.50 + public DefaultMethodsTest() { 1.51 + super(false, false); 1.52 + } 1.53 + 1.54 + /** 1.55 + * class C { public int m() { return 22; } } 1.56 + * 1.57 + * TEST: C c = new C(); c.m() == 22 1.58 + */ 1.59 + public void testHarnessInvokeVirtual() { 1.60 + Class C = new Class("C", ConcreteMethod.std("22")); 1.61 + assertInvokeVirtualEquals(22, C); 1.62 + } 1.63 + 1.64 + /** 1.65 + * interface I { int m(); } 1.66 + * class C implements I { public int m() { return 33; } } 1.67 + * 1.68 + * TEST: I i = new C(); i.m() == 33; 1.69 + */ 1.70 + public void testHarnessInvokeInterface() { 1.71 + Interface I = new Interface("I", AbstractMethod.std()); 1.72 + Class C = new Class("C", I, ConcreteMethod.std("33")); 1.73 + assertInvokeInterfaceEquals(33, C, I); 1.74 + } 1.75 + 1.76 + /** 1.77 + * class C {} 1.78 + * 1.79 + * TEST: C c = new C(); c.m() throws NoSuchMethod 1.80 + */ 1.81 + public void testHarnessThrows() { 1.82 + Class C = new Class("C"); 1.83 + assertThrows(NoSuchMethodError.class, C); 1.84 + } 1.85 + 1.86 + /** 1.87 + * interface I { int m() default { return 44; } } 1.88 + * class C implements I {} 1.89 + * 1.90 + * TEST: C c = new C(); c.m() == 44; 1.91 + * TEST: I i = new C(); i.m() == 44; 1.92 + */ 1.93 + public void testBasicDefault() { 1.94 + Interface I = new Interface("I", DefaultMethod.std("44")); 1.95 + Class C = new Class("C", I); 1.96 + 1.97 + assertInvokeVirtualEquals(44, C); 1.98 + assertInvokeInterfaceEquals(44, C, I); 1.99 + } 1.100 + 1.101 + /** 1.102 + * interface I { default int m() { return 44; } } 1.103 + * interface J extends I {} 1.104 + * interface K extends J {} 1.105 + * class C implements K {} 1.106 + * 1.107 + * TEST: C c = new C(); c.m() == 44; 1.108 + * TEST: I i = new C(); i.m() == 44; 1.109 + */ 1.110 + public void testFarDefault() { 1.111 + Interface I = new Interface("I", DefaultMethod.std("44")); 1.112 + Interface J = new Interface("J", I); 1.113 + Interface K = new Interface("K", J); 1.114 + Class C = new Class("C", K); 1.115 + 1.116 + assertInvokeVirtualEquals(44, C); 1.117 + assertInvokeInterfaceEquals(44, C, K); 1.118 + } 1.119 + 1.120 + /** 1.121 + * interface I { int m(); } 1.122 + * interface J extends I { default int m() { return 44; } } 1.123 + * interface K extends J {} 1.124 + * class C implements K {} 1.125 + * 1.126 + * TEST: C c = new C(); c.m() == 44; 1.127 + * TEST: K k = new C(); k.m() == 44; 1.128 + */ 1.129 + public void testOverrideAbstract() { 1.130 + Interface I = new Interface("I", AbstractMethod.std()); 1.131 + Interface J = new Interface("J", I, DefaultMethod.std("44")); 1.132 + Interface K = new Interface("K", J); 1.133 + Class C = new Class("C", K); 1.134 + 1.135 + assertInvokeVirtualEquals(44, C); 1.136 + assertInvokeInterfaceEquals(44, C, K); 1.137 + } 1.138 + 1.139 + /** 1.140 + * interface I { int m() default { return 44; } } 1.141 + * class C implements I { public int m() { return 55; } } 1.142 + * 1.143 + * TEST: C c = new C(); c.m() == 55; 1.144 + * TEST: I i = new C(); i.m() == 55; 1.145 + */ 1.146 + public void testExisting() { 1.147 + Interface I = new Interface("I", DefaultMethod.std("44")); 1.148 + Class C = new Class("C", I, ConcreteMethod.std("55")); 1.149 + 1.150 + assertInvokeVirtualEquals(55, C); 1.151 + assertInvokeInterfaceEquals(55, C, I); 1.152 + } 1.153 + 1.154 + /** 1.155 + * interface I { default int m() { return 99; } } 1.156 + * class B implements I {} 1.157 + * class C extends B {} 1.158 + * 1.159 + * TEST: C c = new C(); c.m() == 99; 1.160 + * TEST: I i = new C(); i.m() == 99; 1.161 + */ 1.162 + public void testInherited() { 1.163 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.164 + Class B = new Class("B", I); 1.165 + Class C = new Class("C", B); 1.166 + 1.167 + assertInvokeVirtualEquals(99, C); 1.168 + assertInvokeInterfaceEquals(99, C, I); 1.169 + } 1.170 + 1.171 + /** 1.172 + * interface I { default int m() { return 99; } } 1.173 + * class C { public int m() { return 11; } } 1.174 + * class D extends C implements I {} 1.175 + * 1.176 + * TEST: D d = new D(); d.m() == 11; 1.177 + * TEST: I i = new D(); i.m() == 11; 1.178 + */ 1.179 + public void testExistingInherited() { 1.180 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.181 + Class C = new Class("C", ConcreteMethod.std("11")); 1.182 + Class D = new Class("D", C, I); 1.183 + 1.184 + assertInvokeVirtualEquals(11, D); 1.185 + assertInvokeInterfaceEquals(11, D, I); 1.186 + } 1.187 + 1.188 + /** 1.189 + * interface I { default int m() { return 44; } } 1.190 + * class C implements I { public int m() { return 11; } } 1.191 + * class D extends C { public int m() { return 22; } } 1.192 + * 1.193 + * TEST: D d = new D(); d.m() == 22; 1.194 + * TEST: I i = new D(); i.m() == 22; 1.195 + */ 1.196 + public void testExistingInheritedOverride() { 1.197 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.198 + Class C = new Class("C", I, ConcreteMethod.std("11")); 1.199 + Class D = new Class("D", C, ConcreteMethod.std("22")); 1.200 + 1.201 + assertInvokeVirtualEquals(22, D); 1.202 + assertInvokeInterfaceEquals(22, D, I); 1.203 + } 1.204 + 1.205 + /** 1.206 + * interface I { default int m() { return 99; } } 1.207 + * interface J { defaultint m() { return 88; } } 1.208 + * class C implements I { public int m() { return 11; } } 1.209 + * class D extends C { public int m() { return 22; } } 1.210 + * class E extends D implements J {} 1.211 + * 1.212 + * TEST: E e = new E(); e.m() == 22; 1.213 + * TEST: J j = new E(); j.m() == 22; 1.214 + */ 1.215 + public void testExistingInheritedPlusDefault() { 1.216 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.217 + Interface J = new Interface("J", DefaultMethod.std("88")); 1.218 + Class C = new Class("C", I, ConcreteMethod.std("11")); 1.219 + Class D = new Class("D", C, ConcreteMethod.std("22")); 1.220 + Class E = new Class("E", D, J); 1.221 + 1.222 + assertInvokeVirtualEquals(22, E); 1.223 + assertInvokeInterfaceEquals(22, E, J); 1.224 + } 1.225 + 1.226 + /** 1.227 + * interface I { default int m() { return 99; } } 1.228 + * class B implements I {} 1.229 + * class C extends B { public int m() { return 77; } } 1.230 + * 1.231 + * TEST: C c = new C(); c.m() == 77; 1.232 + * TEST: I i = new C(); i.m() == 77; 1.233 + */ 1.234 + public void testInheritedWithConcrete() { 1.235 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.236 + Class B = new Class("B", I); 1.237 + Class C = new Class("C", B, ConcreteMethod.std("77")); 1.238 + 1.239 + assertInvokeVirtualEquals(77, C); 1.240 + assertInvokeInterfaceEquals(77, C, I); 1.241 + } 1.242 + 1.243 + /** 1.244 + * interface I { default int m() { return 99; } } 1.245 + * class B implements I {} 1.246 + * class C extends B implements I { public int m() { return 66; } } 1.247 + * 1.248 + * TEST: C c = new C(); c.m() == 66; 1.249 + * TEST: I i = new C(); i.m() == 66; 1.250 + */ 1.251 + public void testInheritedWithConcreteAndImpl() { 1.252 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.253 + Class B = new Class("B", I); 1.254 + Class C = new Class("C", B, I, ConcreteMethod.std("66")); 1.255 + 1.256 + assertInvokeVirtualEquals(66, C); 1.257 + assertInvokeInterfaceEquals(66, C, I); 1.258 + } 1.259 + 1.260 + /** 1.261 + * interface I { default int m() { return 99; } } 1.262 + * interface J { default int m() { return 88; } } 1.263 + * class C implements I, J {} 1.264 + * 1.265 + * TEST: C c = new C(); c.m() throws ICCE 1.266 + */ 1.267 + public void testConflict() { 1.268 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.269 + Interface J = new Interface("J", DefaultMethod.std("88")); 1.270 + Class C = new Class("C", I, J); 1.271 + 1.272 + assertThrows(IncompatibleClassChangeError.class, C); 1.273 + } 1.274 + 1.275 + /** 1.276 + * interface I { int m(); } 1.277 + * interface J { default int m() { return 88; } } 1.278 + * class C implements I, J {} 1.279 + * 1.280 + * TEST: C c = new C(); c.m() == 88 1.281 + */ 1.282 + public void testAmbiguousReabstract() { 1.283 + Interface I = new Interface("I", AbstractMethod.std()); 1.284 + Interface J = new Interface("J", DefaultMethod.std("88")); 1.285 + Class C = new Class("C", I, J); 1.286 + 1.287 + assertInvokeVirtualEquals(88, C); 1.288 + } 1.289 + 1.290 + /** 1.291 + * interface I { default int m() { return 99; } } 1.292 + * interface J extends I { } 1.293 + * interface K extends I { } 1.294 + * class C implements J, K {} 1.295 + * 1.296 + * TEST: C c = new C(); c.m() == 99 1.297 + * TEST: J j = new C(); j.m() == 99 1.298 + * TEST: K k = new C(); k.m() == 99 1.299 + * TEST: I i = new C(); i.m() == 99 1.300 + */ 1.301 + public void testDiamond() { 1.302 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.303 + Interface J = new Interface("J", I); 1.304 + Interface K = new Interface("K", I); 1.305 + Class C = new Class("C", J, K); 1.306 + 1.307 + assertInvokeVirtualEquals(99, C); 1.308 + assertInvokeInterfaceEquals(99, C, J); 1.309 + assertInvokeInterfaceEquals(99, C, K); 1.310 + assertInvokeInterfaceEquals(99, C, I); 1.311 + } 1.312 + 1.313 + /** 1.314 + * interface I { default int m() { return 99; } } 1.315 + * interface J extends I { } 1.316 + * interface K extends I { } 1.317 + * interface L extends I { } 1.318 + * interface M extends I { } 1.319 + * class C implements I, J, K, L, M {} 1.320 + * 1.321 + * TEST: C c = new C(); c.m() == 99 1.322 + * TEST: J j = new C(); j.m() == 99 1.323 + * TEST: K k = new C(); k.m() == 99 1.324 + * TEST: I i = new C(); i.m() == 99 1.325 + * TEST: L l = new C(); l.m() == 99 1.326 + * TEST: M m = new C(); m.m() == 99 1.327 + */ 1.328 + public void testExpandedDiamond() { 1.329 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.330 + Interface J = new Interface("J", I); 1.331 + Interface K = new Interface("K", I); 1.332 + Interface L = new Interface("L", I); 1.333 + Interface M = new Interface("M", L); 1.334 + Class C = new Class("C", I, J, K, L, M); 1.335 + 1.336 + assertInvokeVirtualEquals(99, C); 1.337 + assertInvokeInterfaceEquals(99, C, J); 1.338 + assertInvokeInterfaceEquals(99, C, K); 1.339 + assertInvokeInterfaceEquals(99, C, I); 1.340 + assertInvokeInterfaceEquals(99, C, L); 1.341 + assertInvokeInterfaceEquals(99, C, M); 1.342 + } 1.343 + 1.344 + /** 1.345 + * interface I { int m() default { return 99; } } 1.346 + * interface J extends I { int m(); } 1.347 + * class C implements J {} 1.348 + * 1.349 + * TEST: C c = new C(); c.m() throws AME 1.350 + */ 1.351 + public void testReabstract() { 1.352 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.353 + Interface J = new Interface("J", I, AbstractMethod.std()); 1.354 + Class C = new Class("C", J); 1.355 + 1.356 + assertThrows(AbstractMethodError.class, C); 1.357 + } 1.358 + 1.359 + /** 1.360 + * interface I { default int m() { return 88; } } 1.361 + * interface J extends I { default int m() { return 99; } } 1.362 + * class C implements J {} 1.363 + * 1.364 + * TEST: C c = new C(); c.m() == 99; 1.365 + * TEST: J j = new C(); j.m() == 99; 1.366 + * TEST: I i = new C(); i.m() == 99; 1.367 + */ 1.368 + public void testShadow() { 1.369 + Interface I = new Interface("I", DefaultMethod.std("88")); 1.370 + Interface J = new Interface("J", I, DefaultMethod.std("99")); 1.371 + Class C = new Class("C", J); 1.372 + 1.373 + assertInvokeVirtualEquals(99, C); 1.374 + assertInvokeInterfaceEquals(99, C, J); 1.375 + assertInvokeInterfaceEquals(99, C, I); 1.376 + } 1.377 + 1.378 + /** 1.379 + * interface I { default int m() { return 88; } } 1.380 + * interface J extends I { default int m() { return 99; } } 1.381 + * class C implements I, J {} 1.382 + * 1.383 + * TEST: C c = new C(); c.m() == 99; 1.384 + * TEST: J j = new C(); j.m() == 99; 1.385 + * TEST: I i = new C(); i.m() == 99; 1.386 + */ 1.387 + public void testDisqualified() { 1.388 + Interface I = new Interface("I", DefaultMethod.std("88")); 1.389 + Interface J = new Interface("J", I, DefaultMethod.std("99")); 1.390 + Class C = new Class("C", I, J); 1.391 + 1.392 + assertInvokeVirtualEquals(99, C); 1.393 + assertInvokeInterfaceEquals(99, C, J); 1.394 + assertInvokeInterfaceEquals(99, C, I); 1.395 + } 1.396 + 1.397 + /** 1.398 + * interface I<T> { default int m(T t) { return 99; } } 1.399 + * Class C implements I<String> { public int m(String s) { return 88; } } 1.400 + * 1.401 + * TEST: C c = new C(); c.m("string") == 88; 1.402 + * TEST: I i = new C(); i.m("string") == 88; 1.403 + */ 1.404 + public void testSelfFill() { 1.405 + // This test ensures that a concrete method overrides a default method 1.406 + // that matches at the language-level, but has a different method 1.407 + // signature due to erasure. 1.408 + 1.409 + DefaultMethod dm = new DefaultMethod( 1.410 + "int", "m", "return 99;", new MethodParameter("T", "t")); 1.411 + ConcreteMethod cm = new ConcreteMethod( 1.412 + "int", "m", "return 88;", AccessFlag.PUBLIC, 1.413 + new MethodParameter("String", "s")); 1.414 + 1.415 + Interface I = new Interface("I", new TypeParameter("T"), dm); 1.416 + Class C = new Class("C", I.with("String"), cm); 1.417 + 1.418 + AbstractMethod pm = new AbstractMethod( 1.419 + "int", "m", new MethodParameter("T", "t")); 1.420 + 1.421 + assertInvokeVirtualEquals(88, C, cm, "-1", "\"string\""); 1.422 + assertInvokeInterfaceEquals(99, C, I.with("String"), pm, "\"string\""); 1.423 + 1.424 + C.setFullCompilation(true); // Force full bridge generation 1.425 + assertInvokeInterfaceEquals(88, C, I.with("String"), pm, "\"string\""); 1.426 + } 1.427 + 1.428 + /** 1.429 + * interface I { default int m() { return 99; } } 1.430 + * class C implements I {} 1.431 + * 1.432 + * TEST: C.class.getMethod("m").invoke(new C()) == 99 1.433 + */ 1.434 + public void testReflectCall() { 1.435 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.436 + //workaround accessibility issue when loading C with DirectedClassLoader 1.437 + I.addAccessFlag(AccessFlag.PUBLIC); 1.438 + Class C = new Class("C", I); 1.439 + 1.440 + Compiler.Flags[] flags = this.verbose ? 1.441 + new Compiler.Flags[] { Compiler.Flags.VERBOSE } : 1.442 + new Compiler.Flags[] {}; 1.443 + Compiler compiler = new Compiler(flags); 1.444 + java.lang.Class<?> cls = null; 1.445 + try { 1.446 + cls = compiler.compileAndLoad(C); 1.447 + } catch (ClassNotFoundException e) { 1.448 + fail("Could not load class"); 1.449 + } 1.450 + 1.451 + java.lang.reflect.Method method = null; 1.452 + try { 1.453 + method = cls.getMethod(stdMethodName); 1.454 + } catch (NoSuchMethodException e) { 1.455 + fail("Could not find method in class"); 1.456 + } 1.457 + assertNotNull(method); 1.458 + 1.459 + Object c = null; 1.460 + try { 1.461 + c = cls.newInstance(); 1.462 + } catch (InstantiationException | IllegalAccessException e) { 1.463 + fail("Could not create instance of class"); 1.464 + } 1.465 + assertNotNull(c); 1.466 + 1.467 + Integer res = null; 1.468 + try { 1.469 + res = (Integer)method.invoke(c); 1.470 + } catch (IllegalAccessException | 1.471 + java.lang.reflect.InvocationTargetException e) { 1.472 + fail("Could not invoke default instance method"); 1.473 + } 1.474 + assertNotNull(res); 1.475 + 1.476 + assertEquals(res.intValue(), 99); 1.477 + 1.478 + compiler.cleanup(); 1.479 + } 1.480 + 1.481 + /** 1.482 + * interface I<T,V,W> { default int m(T t, V v, W w) { return 99; } } 1.483 + * interface J<T,V> extends I<String,T,V> { int m(T t, V v, String w); } } 1.484 + * interface K<T> extends J<String,T> { int m(T t, String v, String w); } } 1.485 + * class C implements K<String> { 1.486 + * public int m(String t, String v, String w) { return 88; } 1.487 + * } 1.488 + * 1.489 + * TEST: I<String,String,String> i = new C(); i.m("A","B","C") == 88; 1.490 + * TEST: J<String,String> j = new C(); j.m("A","B","C") == 88; 1.491 + * TEST: K<String> k = new C(); k.m("A","B","C") == 88; 1.492 + */ 1.493 + public void testBridges() { 1.494 + DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", 1.495 + new MethodParameter("T", "t"), new MethodParameter("V", "v"), 1.496 + new MethodParameter("W", "w")); 1.497 + 1.498 + AbstractMethod pm0 = new AbstractMethod("int", stdMethodName, 1.499 + new MethodParameter("T", "t"), new MethodParameter("V", "v"), 1.500 + new MethodParameter("W", "w")); 1.501 + 1.502 + AbstractMethod pm1 = new AbstractMethod("int", stdMethodName, 1.503 + new MethodParameter("T", "t"), new MethodParameter("V", "v"), 1.504 + new MethodParameter("String", "w")); 1.505 + 1.506 + AbstractMethod pm2 = new AbstractMethod("int", stdMethodName, 1.507 + new MethodParameter("T", "t"), new MethodParameter("String", "v"), 1.508 + new MethodParameter("String", "w")); 1.509 + 1.510 + ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;", 1.511 + AccessFlag.PUBLIC, 1.512 + new MethodParameter("String", "t"), 1.513 + new MethodParameter("String", "v"), 1.514 + new MethodParameter("String", "w")); 1.515 + 1.516 + Interface I = new Interface("I", new TypeParameter("T"), 1.517 + new TypeParameter("V"), new TypeParameter("W"), dm); 1.518 + Interface J = new Interface("J", 1.519 + new TypeParameter("T"), new TypeParameter("V"), 1.520 + I.with("String", "T", "V"), pm1); 1.521 + Interface K = new Interface("K", new TypeParameter("T"), 1.522 + J.with("String", "T"), pm2); 1.523 + Class C = new Class("C", K.with("String"), cm); 1.524 + 1.525 + // First, without compiler bridges 1.526 + String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" }; 1.527 + assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), pm0, args); 1.528 + assertInvokeInterfaceThrows(AbstractMethodError.class, C, J.with("String", "String"), pm1, args); 1.529 + assertInvokeInterfaceThrows(AbstractMethodError.class, C, K.with("String"), pm2, args); 1.530 + 1.531 + // Then with compiler bridges 1.532 + C.setFullCompilation(true); 1.533 + assertInvokeInterfaceEquals(88, C, I.with("String", "String", "String"), pm0, args); 1.534 + assertInvokeInterfaceEquals(88, C, J.with("String", "String"), pm1, args); 1.535 + assertInvokeInterfaceEquals(88, C, K.with("String"), pm2, args); 1.536 + } 1.537 + 1.538 + /** 1.539 + * interface J { default int m() { return 88; } } 1.540 + * interface I extends J { default int m() { return J.super.m(); } } 1.541 + * class C implements I {} 1.542 + * 1.543 + * TEST: C c = new C(); c.m() == 88; 1.544 + * TEST: I i = new C(); i.m() == 88; 1.545 + */ 1.546 + public void testSuperBasic() { 1.547 + Interface J = new Interface("J", DefaultMethod.std("88")); 1.548 + Interface I = new Interface("I", J, new DefaultMethod( 1.549 + "int", stdMethodName, "return J.super.m();")); 1.550 + I.addCompilationDependency(J.findMethod(stdMethodName)); 1.551 + Class C = new Class("C", I); 1.552 + 1.553 + assertInvokeVirtualEquals(88, C); 1.554 + assertInvokeInterfaceEquals(88, C, I); 1.555 + } 1.556 + 1.557 + /** 1.558 + * interface K { int m() default { return 99; } } 1.559 + * interface L { int m() default { return 101; } } 1.560 + * interface J extends K, L {} 1.561 + * interface I extends J, K { int m() default { J.super.m(); } } 1.562 + * class C implements I {} 1.563 + * 1.564 + * TEST: C c = new C(); c.m() throws ICCE 1.565 + * TODO: add case for K k = new C(); k.m() throws ICCE 1.566 + */ 1.567 + public void testSuperConflict() { 1.568 + Interface K = new Interface("K", DefaultMethod.std("99")); 1.569 + Interface L = new Interface("L", DefaultMethod.std("101")); 1.570 + Interface J = new Interface("J", K, L); 1.571 + Interface I = new Interface("I", J, K, new DefaultMethod( 1.572 + "int", stdMethodName, "return J.super.m();")); 1.573 + Interface Jstub = new Interface("J", DefaultMethod.std("-1")); 1.574 + I.addCompilationDependency(Jstub); 1.575 + I.addCompilationDependency(Jstub.findMethod(stdMethodName)); 1.576 + Class C = new Class("C", I); 1.577 + 1.578 + assertThrows(IncompatibleClassChangeError.class, C); 1.579 + } 1.580 + 1.581 + /** 1.582 + * interface I { default int m() { return 99; } } 1.583 + * interface J extends I { default int m() { return 55; } } 1.584 + * class C implements I, J { public int m() { return I.super.m(); } } 1.585 + * 1.586 + * TEST: C c = new C(); c.m() == 99 1.587 + * TODO: add case for J j = new C(); j.m() == ??? 1.588 + */ 1.589 + public void testSuperDisqual() { 1.590 + Interface I = new Interface("I", DefaultMethod.std("99")); 1.591 + Interface J = new Interface("J", I, DefaultMethod.std("55")); 1.592 + Class C = new Class("C", I, J, 1.593 + new ConcreteMethod("int", stdMethodName, "return I.super.m();", 1.594 + AccessFlag.PUBLIC)); 1.595 + C.addCompilationDependency(I.findMethod(stdMethodName)); 1.596 + 1.597 + assertInvokeVirtualEquals(99, C); 1.598 + } 1.599 + 1.600 + /** 1.601 + * interface J { int m(); } 1.602 + * interface I extends J { default int m() { return J.super.m(); } } 1.603 + * class C implements I {} 1.604 + * 1.605 + * TEST: C c = new C(); c.m() throws AME 1.606 + * TODO: add case for I i = new C(); i.m() throws AME 1.607 + */ 1.608 + public void testSuperNull() { 1.609 + Interface J = new Interface("J", AbstractMethod.std()); 1.610 + Interface I = new Interface("I", J, new DefaultMethod( 1.611 + "int", stdMethodName, "return J.super.m();")); 1.612 + Interface Jstub = new Interface("J", DefaultMethod.std("99")); 1.613 + I.addCompilationDependency(Jstub); 1.614 + I.addCompilationDependency(Jstub.findMethod(stdMethodName)); 1.615 + Class C = new Class("C", I); 1.616 + 1.617 + assertThrows(AbstractMethodError.class, C); 1.618 + } 1.619 + 1.620 + /** 1.621 + * interface J<T> { default int m(T t) { return 88; } } 1.622 + * interface I extends J<String> { 1.623 + * int m(String s) default { return J.super.m(); } 1.624 + * } 1.625 + * class C implements I {} 1.626 + * 1.627 + * TEST: I i = new C(); i.m("") == 88; 1.628 + */ 1.629 + public void testSuperGeneric() { 1.630 + Interface J = new Interface("J", new TypeParameter("T"), 1.631 + new DefaultMethod("int", stdMethodName, "return 88;", 1.632 + new MethodParameter("T", "t"))); 1.633 + Interface I = new Interface("I", J.with("String"), 1.634 + new DefaultMethod("int", stdMethodName, "return J.super.m(s);", 1.635 + new MethodParameter("String", "s"))); 1.636 + I.addCompilationDependency(J.findMethod(stdMethodName)); 1.637 + Class C = new Class("C", I); 1.638 + 1.639 + AbstractMethod pm = new AbstractMethod("int", stdMethodName, 1.640 + new MethodParameter("String", "s")); 1.641 + 1.642 + assertInvokeInterfaceEquals(88, C, new Extends(I), pm, "\"\""); 1.643 + } 1.644 + 1.645 + /** 1.646 + * interface I<T> { int m(T t) default { return 44; } } 1.647 + * interface J extends I<String> { int m(String s) default { return 55; } } 1.648 + * class C implements I<String>, J { 1.649 + * public int m(String s) { return I.super.m(s); } 1.650 + * } 1.651 + * 1.652 + * TEST: C c = new C(); c.m("string") == 44 1.653 + */ 1.654 + public void testSuperGenericDisqual() { 1.655 + MethodParameter t = new MethodParameter("T", "t"); 1.656 + MethodParameter s = new MethodParameter("String", "s"); 1.657 + 1.658 + Interface I = new Interface("I", new TypeParameter("T"), 1.659 + new DefaultMethod("int", stdMethodName, "return 44;", t)); 1.660 + Interface J = new Interface("J", I.with("String"), 1.661 + new DefaultMethod("int", stdMethodName, "return 55;", s)); 1.662 + Class C = new Class("C", I.with("String"), J, 1.663 + new ConcreteMethod("int", stdMethodName, 1.664 + "return I.super.m(s);", AccessFlag.PUBLIC, s)); 1.665 + C.addCompilationDependency(I.findMethod(stdMethodName)); 1.666 + 1.667 + assertInvokeVirtualEquals(44, C, 1.668 + new ConcreteMethod( 1.669 + "int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s), 1.670 + "-1", "\"string\""); 1.671 + } 1.672 + 1.673 + /** 1.674 + * interface I { default Integer m() { return new Integer(88); } } 1.675 + * class C { Number m() { return new Integer(99); } } 1.676 + * class D extends C implements I {} 1.677 + * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; 1.678 + * TEST: S s = new S(); s.foo() == new Integer(99) 1.679 + */ 1.680 + public void testCovarBridge() { 1.681 + Interface I = new Interface("I", new DefaultMethod( 1.682 + "Integer", "m", "return new Integer(88);")); 1.683 + Class C = new Class("C", new ConcreteMethod( 1.684 + "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC)); 1.685 + Class D = new Class("D", I, C); 1.686 + 1.687 + ConcreteMethod DstubMethod = new ConcreteMethod( 1.688 + "Integer", "m", "return null;", AccessFlag.PUBLIC); 1.689 + Class Dstub = new Class("D", DstubMethod); 1.690 + 1.691 + ConcreteMethod toCall = new ConcreteMethod( 1.692 + "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); 1.693 + Class S = new Class("S", D, toCall); 1.694 + S.addCompilationDependency(Dstub); 1.695 + S.addCompilationDependency(DstubMethod); 1.696 + 1.697 + // NEGATIVE test for separate compilation -- dispatches to I, not C 1.698 + assertInvokeVirtualEquals(88, S, toCall, "null"); 1.699 + } 1.700 + 1.701 + /** 1.702 + * interface I { default Integer m() { return new Integer(88); } } 1.703 + * class C { int m() { return 99; } } 1.704 + * class D extends C implements I {} 1.705 + * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; 1.706 + * TEST: S s = new S(); s.foo() == new Integer(88) 1.707 + */ 1.708 + public void testNoCovarNoBridge() { 1.709 + Interface I = new Interface("I", new DefaultMethod( 1.710 + "Integer", "m", "return new Integer(88);")); 1.711 + Class C = new Class("C", new ConcreteMethod( 1.712 + "int", "m", "return 99;", AccessFlag.PUBLIC)); 1.713 + Class D = new Class("D", I, C); 1.714 + 1.715 + ConcreteMethod DstubMethod = new ConcreteMethod( 1.716 + "Integer", "m", "return null;", AccessFlag.PUBLIC); 1.717 + Class Dstub = new Class("D", DstubMethod); 1.718 + 1.719 + ConcreteMethod toCall = new ConcreteMethod( 1.720 + "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC); 1.721 + Class S = new Class("S", D, toCall); 1.722 + S.addCompilationDependency(Dstub); 1.723 + S.addCompilationDependency(DstubMethod); 1.724 + 1.725 + assertInvokeVirtualEquals(88, S, toCall, "null"); 1.726 + } 1.727 + 1.728 + /** 1.729 + * interface J { int m(); } 1.730 + * interface I extends J { default int m() { return 99; } } 1.731 + * class B implements J {} 1.732 + * class C extends B implements I {} 1.733 + * TEST: C c = new C(); c.m() == 99 1.734 + * 1.735 + * The point of this test is that B does not get default method analysis, 1.736 + * and C does not generate any new miranda methods in the vtable. 1.737 + * It verifies that default method analysis occurs when mirandas have been 1.738 + * inherited and the supertypes don't have any overpass methods. 1.739 + */ 1.740 + public void testNoNewMiranda() { 1.741 + Interface J = new Interface("J", AbstractMethod.std()); 1.742 + Interface I = new Interface("I", J, DefaultMethod.std("99")); 1.743 + Class B = new Class("B", J); 1.744 + Class C = new Class("C", B, I); 1.745 + assertInvokeVirtualEquals(99, C); 1.746 + } 1.747 + 1.748 + /** 1.749 + * interface I<T,V,W> { int m(T t, V v, W w); } 1.750 + * interface J<T,V> implements I<T,V,String> { int m(T t, V v, String w); } 1.751 + * interface K<T> implements J<T,String> { 1.752 + * int m(T t, String v, String w); { return 99; } } 1.753 + * class C implements K<String> { 1.754 + * public int m(Object t, Object v, String w) { return 77; } 1.755 + * } 1.756 + * TEST C = new C(); ((I)c).m(Object,Object,Object) == 99 1.757 + * TEST C = new C(); ((J)c).m(Object,Object,String) == 77 1.758 + * TEST C = new C(); ((K)c).m(Object,String,String) == 99 1.759 + * 1.760 + * Test that a erased-signature-matching method does not implement 1.761 + * non-language-level matching methods 1.762 + */ 1.763 + public void testNonConcreteFill() { 1.764 + AbstractMethod ipm = new AbstractMethod("int", "m", 1.765 + new MethodParameter("T", "t"), 1.766 + new MethodParameter("V", "s"), 1.767 + new MethodParameter("W", "w")); 1.768 + Interface I = new Interface("I", 1.769 + new TypeParameter("T"), 1.770 + new TypeParameter("V"), 1.771 + new TypeParameter("W"), ipm); 1.772 + 1.773 + AbstractMethod jpm = new AbstractMethod("int", "m", 1.774 + new MethodParameter("T", "t"), 1.775 + new MethodParameter("V", "s"), 1.776 + new MethodParameter("String", "w")); 1.777 + Interface J = new Interface("J", 1.778 + new TypeParameter("T"), 1.779 + new TypeParameter("V"), 1.780 + I.with("T", "V", "String"), jpm); 1.781 + 1.782 + AbstractMethod kpm = new AbstractMethod("int", "m", 1.783 + new MethodParameter("T", "t"), 1.784 + new MethodParameter("String", "s"), 1.785 + new MethodParameter("String", "w")); 1.786 + DefaultMethod kdm = new DefaultMethod("int", "m", "return 99;", 1.787 + new MethodParameter("T", "t"), 1.788 + new MethodParameter("String", "v"), 1.789 + new MethodParameter("String", "w")); 1.790 + Interface K = new Interface("K", 1.791 + new TypeParameter("T"), 1.792 + J.with("T", "String"), 1.793 + kdm); 1.794 + 1.795 + Class C = new Class("C", 1.796 + K.with("String"), 1.797 + new ConcreteMethod("int", "m", "return 77;", 1.798 + AccessFlag.PUBLIC, 1.799 + new MethodParameter("Object", "t"), 1.800 + new MethodParameter("Object", "v"), 1.801 + new MethodParameter("String", "w"))); 1.802 + 1.803 + // First, without compiler bridges 1.804 + String a = "\"\""; 1.805 + assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); 1.806 + assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); 1.807 + assertInvokeInterfaceThrows(AbstractMethodError.class, C, I.with("String", "String", "String"), ipm, a, a, a); 1.808 + 1.809 + // Now, with bridges 1.810 + J.setFullCompilation(true); 1.811 + K.setFullCompilation(true); 1.812 + assertInvokeInterfaceEquals(99, C, K.with("String"), kpm, a, a, a); 1.813 + assertInvokeInterfaceEquals(77, C, J.with("String", "String"), jpm, a, a, a); 1.814 + assertInvokeInterfaceEquals(99, C, I.with("String", "String", "String"), ipm, a, a, a); 1.815 + } 1.816 + 1.817 + public void testStrictfpDefault() { 1.818 + try { 1.819 + java.lang.Class.forName("org.openjdk.tests.vm.StrictfpDefault"); 1.820 + } catch (Exception e) { 1.821 + fail("Could not load class", e); 1.822 + } 1.823 + } 1.824 +} 1.825 + 1.826 +interface StrictfpDefault { 1.827 + default strictfp void m() {} 1.828 +}