Thu, 11 Jul 2013 14:07:39 +0100
8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
8020010: Move lambda bridge creation from metafactory and VM to compiler
Summary: langtools/javac component of the bridge support and MethodType vs. MethodHandle changes.
Reviewed-by: jjg, vromero, briangoetz, forax
Contributed-by: robert.field@oracle.com
1 /*
2 * Copyright (c) 2012, 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 */
26 package org.openjdk.tests.vm;
28 import java.lang.reflect.*;
29 import java.util.*;
30 import java.io.File;
31 import java.io.IOException;
33 import org.testng.annotations.Test;
34 import org.openjdk.tests.separate.*;
35 import org.openjdk.tests.separate.Compiler;
37 import static org.testng.Assert.*;
38 import static org.openjdk.tests.separate.SourceModel.*;
39 import static org.openjdk.tests.separate.SourceModel.Class;
41 @Test(groups = "vm")
42 public class DefaultMethodsTest extends TestHarness {
43 public DefaultMethodsTest() {
44 super(false, false);
45 }
47 /**
48 * class C { public int m() { return 22; } }
49 *
50 * TEST: C c = new C(); c.m() == 22
51 */
52 public void testHarnessInvokeVirtual() {
53 Class C = new Class("C", ConcreteMethod.std("22"));
54 assertInvokeVirtualEquals(22, C);
55 }
57 /**
58 * interface I { int m(); }
59 * class C implements I { public int m() { return 33; } }
60 *
61 * TEST: I i = new C(); i.m() == 33;
62 */
63 public void testHarnessInvokeInterface() {
64 Interface I = new Interface("I", AbstractMethod.std());
65 Class C = new Class("C", I, ConcreteMethod.std("33"));
66 assertInvokeInterfaceEquals(33, C, I);
67 }
69 /**
70 * class C {}
71 *
72 * TEST: C c = new C(); c.m() throws NoSuchMethod
73 */
74 public void testHarnessThrows() {
75 Class C = new Class("C");
76 assertThrows(NoSuchMethodError.class, C);
77 }
79 /**
80 * interface I { int m() default { return 44; } }
81 * class C implements I {}
82 *
83 * TEST: C c = new C(); c.m() == 44;
84 * TEST: I i = new C(); i.m() == 44;
85 */
86 public void testBasicDefault() {
87 Interface I = new Interface("I", DefaultMethod.std("44"));
88 Class C = new Class("C", I);
90 assertInvokeVirtualEquals(44, C);
91 assertInvokeInterfaceEquals(44, C, I);
92 }
94 /**
95 * interface I { default int m() { return 44; } }
96 * interface J extends I {}
97 * interface K extends J {}
98 * class C implements K {}
99 *
100 * TEST: C c = new C(); c.m() == 44;
101 * TEST: I i = new C(); i.m() == 44;
102 */
103 public void testFarDefault() {
104 Interface I = new Interface("I", DefaultMethod.std("44"));
105 Interface J = new Interface("J", I);
106 Interface K = new Interface("K", J);
107 Class C = new Class("C", K);
109 assertInvokeVirtualEquals(44, C);
110 assertInvokeInterfaceEquals(44, C, K);
111 }
113 /**
114 * interface I { int m(); }
115 * interface J extends I { default int m() { return 44; } }
116 * interface K extends J {}
117 * class C implements K {}
118 *
119 * TEST: C c = new C(); c.m() == 44;
120 * TEST: K k = new C(); k.m() == 44;
121 */
122 public void testOverrideAbstract() {
123 Interface I = new Interface("I", AbstractMethod.std());
124 Interface J = new Interface("J", I, DefaultMethod.std("44"));
125 Interface K = new Interface("K", J);
126 Class C = new Class("C", K);
128 assertInvokeVirtualEquals(44, C);
129 assertInvokeInterfaceEquals(44, C, K);
130 }
132 /**
133 * interface I { int m() default { return 44; } }
134 * class C implements I { public int m() { return 55; } }
135 *
136 * TEST: C c = new C(); c.m() == 55;
137 * TEST: I i = new C(); i.m() == 55;
138 */
139 public void testExisting() {
140 Interface I = new Interface("I", DefaultMethod.std("44"));
141 Class C = new Class("C", I, ConcreteMethod.std("55"));
143 assertInvokeVirtualEquals(55, C);
144 assertInvokeInterfaceEquals(55, C, I);
145 }
147 /**
148 * interface I { default int m() { return 99; } }
149 * class B implements I {}
150 * class C extends B {}
151 *
152 * TEST: C c = new C(); c.m() == 99;
153 * TEST: I i = new C(); i.m() == 99;
154 */
155 public void testInherited() {
156 Interface I = new Interface("I", DefaultMethod.std("99"));
157 Class B = new Class("B", I);
158 Class C = new Class("C", B);
160 assertInvokeVirtualEquals(99, C);
161 assertInvokeInterfaceEquals(99, C, I);
162 }
164 /**
165 * interface I { default int m() { return 99; } }
166 * class C { public int m() { return 11; } }
167 * class D extends C implements I {}
168 *
169 * TEST: D d = new D(); d.m() == 11;
170 * TEST: I i = new D(); i.m() == 11;
171 */
172 public void testExistingInherited() {
173 Interface I = new Interface("I", DefaultMethod.std("99"));
174 Class C = new Class("C", ConcreteMethod.std("11"));
175 Class D = new Class("D", C, I);
177 assertInvokeVirtualEquals(11, D);
178 assertInvokeInterfaceEquals(11, D, I);
179 }
181 /**
182 * interface I { default int m() { return 44; } }
183 * class C implements I { public int m() { return 11; } }
184 * class D extends C { public int m() { return 22; } }
185 *
186 * TEST: D d = new D(); d.m() == 22;
187 * TEST: I i = new D(); i.m() == 22;
188 */
189 void testExistingInheritedOverride() {
190 Interface I = new Interface("I", DefaultMethod.std("99"));
191 Class C = new Class("C", I, ConcreteMethod.std("11"));
192 Class D = new Class("D", C, ConcreteMethod.std("22"));
194 assertInvokeVirtualEquals(22, D);
195 assertInvokeInterfaceEquals(22, D, I);
196 }
198 /**
199 * interface I { default int m() { return 99; } }
200 * interface J { defaultint m() { return 88; } }
201 * class C implements I { public int m() { return 11; } }
202 * class D extends C { public int m() { return 22; } }
203 * class E extends D implements J {}
204 *
205 * TEST: E e = new E(); e.m() == 22;
206 * TEST: J j = new E(); j.m() == 22;
207 */
208 public void testExistingInheritedPlusDefault() {
209 Interface I = new Interface("I", DefaultMethod.std("99"));
210 Interface J = new Interface("J", DefaultMethod.std("88"));
211 Class C = new Class("C", I, ConcreteMethod.std("11"));
212 Class D = new Class("D", C, ConcreteMethod.std("22"));
213 Class E = new Class("E", D, J);
215 assertInvokeVirtualEquals(22, E);
216 assertInvokeInterfaceEquals(22, E, J);
217 }
219 /**
220 * interface I { default int m() { return 99; } }
221 * class B implements I {}
222 * class C extends B { public int m() { return 77; } }
223 *
224 * TEST: C c = new C(); c.m() == 77;
225 * TEST: I i = new C(); i.m() == 77;
226 */
227 public void testInheritedWithConcrete() {
228 Interface I = new Interface("I", DefaultMethod.std("99"));
229 Class B = new Class("B", I);
230 Class C = new Class("C", B, ConcreteMethod.std("77"));
232 assertInvokeVirtualEquals(77, C);
233 assertInvokeInterfaceEquals(77, C, I);
234 }
236 /**
237 * interface I { default int m() { return 99; } }
238 * class B implements I {}
239 * class C extends B implements I { public int m() { return 66; } }
240 *
241 * TEST: C c = new C(); c.m() == 66;
242 * TEST: I i = new C(); i.m() == 66;
243 */
244 public void testInheritedWithConcreteAndImpl() {
245 Interface I = new Interface("I", DefaultMethod.std("99"));
246 Class B = new Class("B", I);
247 Class C = new Class("C", B, I, ConcreteMethod.std("66"));
249 assertInvokeVirtualEquals(66, C);
250 assertInvokeInterfaceEquals(66, C, I);
251 }
253 /**
254 * interface I { default int m() { return 99; } }
255 * interface J { default int m() { return 88; } }
256 * class C implements I, J {}
257 *
258 * TEST: C c = new C(); c.m() throws AME
259 */
260 public void testConflict() {
261 // debugTest();
262 Interface I = new Interface("I", DefaultMethod.std("99"));
263 Interface J = new Interface("J", DefaultMethod.std("88"));
264 Class C = new Class("C", I, J);
266 assertThrows(AbstractMethodError.class, C);
267 }
269 /**
270 * interface I { int m(); }
271 * interface J { default int m() { return 88; } }
272 * class C implements I, J {}
273 *
274 * TEST: C c = new C(); c.m() throws AME
275 */
276 public void testAmbiguousReabstract() {
277 Interface I = new Interface("I", AbstractMethod.std());
278 Interface J = new Interface("J", DefaultMethod.std("88"));
279 Class C = new Class("C", I, J);
281 assertThrows(AbstractMethodError.class, C);
282 }
284 /**
285 * interface I { default int m() { return 99; } }
286 * interface J extends I { }
287 * interface K extends I { }
288 * class C implements J, K {}
289 *
290 * TEST: C c = new C(); c.m() == 99
291 * TEST: J j = new C(); j.m() == 99
292 * TEST: K k = new C(); k.m() == 99
293 * TEST: I i = new C(); i.m() == 99
294 */
295 public void testDiamond() {
296 Interface I = new Interface("I", DefaultMethod.std("99"));
297 Interface J = new Interface("J", I);
298 Interface K = new Interface("K", I);
299 Class C = new Class("C", J, K);
301 assertInvokeVirtualEquals(99, C);
302 assertInvokeInterfaceEquals(99, C, J);
303 assertInvokeInterfaceEquals(99, C, K);
304 assertInvokeInterfaceEquals(99, C, I);
305 }
307 /**
308 * interface I { default int m() { return 99; } }
309 * interface J extends I { }
310 * interface K extends I { }
311 * interface L extends I { }
312 * interface M extends I { }
313 * class C implements I, J, K, L, M {}
314 *
315 * TEST: C c = new C(); c.m() == 99
316 * TEST: J j = new C(); j.m() == 99
317 * TEST: K k = new C(); k.m() == 99
318 * TEST: I i = new C(); i.m() == 99
319 * TEST: L l = new C(); l.m() == 99
320 * TEST: M m = new C(); m.m() == 99
321 */
322 public void testExpandedDiamond() {
323 Interface I = new Interface("I", DefaultMethod.std("99"));
324 Interface J = new Interface("J", I);
325 Interface K = new Interface("K", I);
326 Interface L = new Interface("L", I);
327 Interface M = new Interface("M", L);
328 Class C = new Class("C", I, J, K, L, M);
330 assertInvokeVirtualEquals(99, C);
331 assertInvokeInterfaceEquals(99, C, J);
332 assertInvokeInterfaceEquals(99, C, K);
333 assertInvokeInterfaceEquals(99, C, I);
334 assertInvokeInterfaceEquals(99, C, L);
335 assertInvokeInterfaceEquals(99, C, M);
336 }
338 /**
339 * interface I { int m() default { return 99; } }
340 * interface J extends I { int m(); }
341 * class C implements J {}
342 *
343 * TEST: C c = new C(); c.m() throws AME
344 */
345 public void testReabstract() {
346 Interface I = new Interface("I", DefaultMethod.std("99"));
347 Interface J = new Interface("J", I, AbstractMethod.std());
348 Class C = new Class("C", J);
350 assertThrows(AbstractMethodError.class, C);
351 }
353 /**
354 * interface I { default int m() { return 88; } }
355 * interface J extends I { default int m() { return 99; } }
356 * class C implements J {}
357 *
358 * TEST: C c = new C(); c.m() == 99;
359 * TEST: J j = new C(); j.m() == 99;
360 * TEST: I i = new C(); i.m() == 99;
361 */
362 public void testShadow() {
363 Interface I = new Interface("I", DefaultMethod.std("88"));
364 Interface J = new Interface("J", I, DefaultMethod.std("99"));
365 Class C = new Class("C", J);
367 assertInvokeVirtualEquals(99, C);
368 assertInvokeInterfaceEquals(99, C, J);
369 assertInvokeInterfaceEquals(99, C, I);
370 }
372 /**
373 * interface I { default int m() { return 88; } }
374 * interface J extends I { default int m() { return 99; } }
375 * class C implements I, J {}
376 *
377 * TEST: C c = new C(); c.m() == 99;
378 * TEST: J j = new C(); j.m() == 99;
379 * TEST: I i = new C(); i.m() == 99;
380 */
381 public void testDisqualified() {
382 Interface I = new Interface("I", DefaultMethod.std("88"));
383 Interface J = new Interface("J", I, DefaultMethod.std("99"));
384 Class C = new Class("C", I, J);
386 assertInvokeVirtualEquals(99, C);
387 assertInvokeInterfaceEquals(99, C, J);
388 assertInvokeInterfaceEquals(99, C, I);
389 }
391 /**
392 * interface I<T> { default int m(T t) { return 99; } }
393 * Class C implements I<String> { public int m() { return 88; } }
394 *
395 * TEST: C c = new C(); c.m() == 88;
396 * TEST: I i = new C(); i.m() == 88;
397 */
398 @Test(enabled=false)
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.
404 // debugTest();
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"));
412 Interface I = new Interface("I", new TypeParameter("T"), dm);
413 Class C = new Class("C", I.with("String"), cm);
415 AbstractMethod pm = new AbstractMethod(
416 "int", "m", new MethodParameter("T", "t"));
418 assertInvokeVirtualEquals(new Integer(88), C, cm, "-1", "\"string\"");
419 assertInvokeInterfaceEquals(
420 new Integer(88), C, I.with("String"), pm, "\"string\"");
421 }
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);
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 }
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);
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);
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);
471 assertEquals(res.intValue(), 99);
473 compiler.cleanup();
474 }
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 @Test(enabled=false)
489 public void testBridges() {
490 DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;",
491 new MethodParameter("T", "t"), new MethodParameter("V", "v"),
492 new MethodParameter("W", "w"));
494 AbstractMethod pm0 = new AbstractMethod("int", stdMethodName,
495 new MethodParameter("T", "t"), new MethodParameter("V", "v"),
496 new MethodParameter("W", "w"));
498 AbstractMethod pm1 = new AbstractMethod("int", stdMethodName,
499 new MethodParameter("T", "t"), new MethodParameter("V", "v"),
500 new MethodParameter("String", "w"));
502 AbstractMethod pm2 = new AbstractMethod("int", stdMethodName,
503 new MethodParameter("T", "t"), new MethodParameter("String", "v"),
504 new MethodParameter("String", "w"));
506 ConcreteMethod cm = new ConcreteMethod("int",stdMethodName,"return 88;",
507 AccessFlag.PUBLIC,
508 new MethodParameter("String", "t"),
509 new MethodParameter("String", "v"),
510 new MethodParameter("String", "w"));
512 Interface I = new Interface("I", new TypeParameter("T"),
513 new TypeParameter("V"), new TypeParameter("W"), dm);
514 Interface J = new Interface("J",
515 new TypeParameter("T"), new TypeParameter("V"),
516 I.with("String", "T", "V"), pm1);
517 Interface K = new Interface("K", new TypeParameter("T"),
518 J.with("String", "T"), pm2);
519 Class C = new Class("C", K.with("String"), cm);
521 String[] args = new String[] { "\"A\"", "\"B\"", "\"C\"" };
522 assertInvokeInterfaceEquals(new Integer(88), C,
523 I.with("String", "String", "String"), pm0, args);
524 assertInvokeInterfaceEquals(new Integer(88), C,
525 J.with("String", "String"), pm1, args);
526 assertInvokeInterfaceEquals(new Integer(88), C,
527 K.with("String"), pm2, args);
528 }
530 /**
531 * interface J { default int m() { return 88; } }
532 * interface I extends J { default int m() { return J.super.m(); } }
533 * class C implements I {}
534 *
535 * TEST: C c = new C(); c.m() == 88;
536 * TEST: I i = new C(); i.m() == 88;
537 */
538 public void testSuperBasic() {
539 // debugTest();
541 Interface J = new Interface("J", DefaultMethod.std("88"));
542 Interface I = new Interface("I", J, new DefaultMethod(
543 "int", stdMethodName, "return J.super.m();"));
544 I.addCompilationDependency(J.findMethod(stdMethodName));
545 Class C = new Class("C", I);
547 assertInvokeVirtualEquals(88, C);
548 assertInvokeInterfaceEquals(88, C, I);
549 }
551 /**
552 * interface K { int m() default { return 99; } }
553 * interface L { int m() default { return 101; } }
554 * interface J extends K, L {}
555 * interface I extends J, K { int m() default { J.super.m(); } }
556 * class C implements I {}
557 *
558 * TEST: C c = new C(); c.m() throws AME
559 * TODO: add case for K k = new C(); k.m() throws AME
560 */
561 public void testSuperConflict() {
562 // debugTest();
564 Interface K = new Interface("K", DefaultMethod.std("99"));
565 Interface L = new Interface("L", DefaultMethod.std("101"));
566 Interface J = new Interface("J", K, L);
567 Interface I = new Interface("I", J, K, new DefaultMethod(
568 "int", stdMethodName, "return J.super.m();"));
569 Interface Jstub = new Interface("J", DefaultMethod.std("-1"));
570 I.addCompilationDependency(Jstub);
571 I.addCompilationDependency(Jstub.findMethod(stdMethodName));
572 Class C = new Class("C", I);
574 assertThrows(AbstractMethodError.class, C);
575 }
577 /**
578 * interface I { default int m() { return 99; } }
579 * interface J extends I { default int m() { return 55; } }
580 * class C implements I, J { public int m() { return I.super.m(); } }
581 *
582 * TEST: C c = new C(); c.m() throws AME
583 * TODO: add case for J j = new C(); j.m() throws AME
584 */
585 public void testSuperDisqual() {
586 Interface I = new Interface("I", DefaultMethod.std("99"));
587 Interface J = new Interface("J", I, DefaultMethod.std("55"));
588 Class C = new Class("C", I, J,
589 new ConcreteMethod("int", stdMethodName, "return I.super.m();",
590 AccessFlag.PUBLIC));
591 C.addCompilationDependency(I.findMethod(stdMethodName));
593 assertThrows(AbstractMethodError.class, C);
594 }
596 /**
597 * interface J { int m(); }
598 * interface I extends J { default int m() { return J.super.m(); } }
599 * class C implements I {}
600 *
601 * TEST: C c = new C(); c.m() throws AME
602 * TODO: add case for I i = new C(); i.m() throws AME
603 */
604 public void testSuperNull() {
605 Interface J = new Interface("J", AbstractMethod.std());
606 Interface I = new Interface("I", J, new DefaultMethod(
607 "int", stdMethodName, "return J.super.m();"));
608 Interface Jstub = new Interface("J", DefaultMethod.std("99"));
609 I.addCompilationDependency(Jstub);
610 I.addCompilationDependency(Jstub.findMethod(stdMethodName));
611 Class C = new Class("C", I);
613 assertThrows(AbstractMethodError.class, C);
614 }
616 /**
617 * interface J<T> { default int m(T t) { return 88; } }
618 * interface I extends J<String> {
619 * int m(String s) default { return J.super.m(); }
620 * }
621 * class C implements I {}
622 *
623 * TEST: I i = new C(); i.m("") == 88;
624 */
625 public void testSuperGeneric() {
626 Interface J = new Interface("J", new TypeParameter("T"),
627 new DefaultMethod("int", stdMethodName, "return 88;",
628 new MethodParameter("T", "t")));
629 Interface I = new Interface("I", J.with("String"),
630 new DefaultMethod("int", stdMethodName, "return J.super.m(s);",
631 new MethodParameter("String", "s")));
632 I.addCompilationDependency(J.findMethod(stdMethodName));
633 Class C = new Class("C", I);
635 AbstractMethod pm = new AbstractMethod("int", stdMethodName,
636 new MethodParameter("String", "s"));
638 assertInvokeInterfaceEquals(
639 new Integer(88), C, new Extends(I), pm, "\"\"");
640 }
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") throws AME
650 */
651 public void testSuperGenericDisqual() {
652 MethodParameter t = new MethodParameter("T", "t");
653 MethodParameter s = new MethodParameter("String", "s");
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));
664 assertThrows(AbstractMethodError.class, C,
665 new ConcreteMethod(
666 "int", stdMethodName, "return -1;", AccessFlag.PUBLIC, s),
667 "-1", "\"string\"");
668 }
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 */
677 @Test(enabled=false)
678 public void testCovarBridge() {
679 Interface I = new Interface("I", new DefaultMethod(
680 "Integer", "m", "return new Integer(88);"));
681 Class C = new Class("C", new ConcreteMethod(
682 "Number", "m", "return new Integer(99);", AccessFlag.PUBLIC));
683 Class D = new Class("D", I, C);
685 ConcreteMethod DstubMethod = new ConcreteMethod(
686 "Integer", "m", "return null;", AccessFlag.PUBLIC);
687 Class Dstub = new Class("D", DstubMethod);
689 ConcreteMethod toCall = new ConcreteMethod(
690 "Object", "foo", "return (new D()).m();", AccessFlag.PUBLIC);
691 Class S = new Class("S", D, toCall);
692 S.addCompilationDependency(Dstub);
693 S.addCompilationDependency(DstubMethod);
695 assertInvokeVirtualEquals(new Integer(99), S, toCall, "null");
696 }
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 */
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);
712 ConcreteMethod DstubMethod = new ConcreteMethod(
713 "Integer", "m", "return null;", AccessFlag.PUBLIC);
714 Class Dstub = new Class("D", DstubMethod);
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);
722 assertInvokeVirtualEquals(new Integer(88), S, toCall, "null");
723 }
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 */
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 }
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 */
760 @Test(enabled=false)
761 public void testNonConcreteFill() {
762 AbstractMethod ipm = new AbstractMethod("int", "m",
763 new MethodParameter("T", "t"),
764 new MethodParameter("V", "s"),
765 new MethodParameter("W", "w"));
766 Interface I = new Interface("I",
767 new TypeParameter("T"),
768 new TypeParameter("V"),
769 new TypeParameter("W"), ipm);
771 AbstractMethod jpm = new AbstractMethod("int", "m",
772 new MethodParameter("T", "t"),
773 new MethodParameter("V", "s"),
774 new MethodParameter("String", "w"));
775 Interface J = new Interface("J",
776 new TypeParameter("T"),
777 new TypeParameter("V"),
778 I.with("T", "V", "String"), jpm);
780 AbstractMethod kpm = new AbstractMethod("int", "m",
781 new MethodParameter("T", "t"),
782 new MethodParameter("String", "s"),
783 new MethodParameter("String", "w"));
784 Interface K = new Interface("K",
785 new TypeParameter("T"),
786 J.with("T", "String"),
787 new DefaultMethod("int", "m", "return 99;",
788 new MethodParameter("T", "t"),
789 new MethodParameter("String", "v"),
790 new MethodParameter("String", "w")));
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")));
800 String a = "\"\"";
801 assertInvokeInterfaceEquals(99, C,
802 K.with("String"), kpm, a, a, a);
803 assertInvokeInterfaceEquals(77, C,
804 J.with("String", "String"), jpm, a, a, a);
805 assertInvokeInterfaceEquals(99, C,
806 I.with("String", "String", "String"), ipm, a, a, a);
807 }
809 public void testStrictfpDefault() {
810 try {
811 java.lang.Class.forName("org.openjdk.tests.vm.StrictfpDefault");
812 } catch (Exception e) {
813 fail("Could not load class", e);
814 }
815 }
816 }
818 interface StrictfpDefault {
819 default strictfp void m() {}
820 }