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