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