test/tools/javac/lambda/lambdaExecution/LambdaTranslationTest2.java

Tue, 14 May 2013 11:11:09 -0700

author
rfield
date
Tue, 14 May 2013 11:11:09 -0700
changeset 1752
c09b7234cded
parent 0
959103a6100f
permissions
-rw-r--r--

8012556: Implement lambda methods on interfaces as static
8006140: Javac NPE compiling Lambda expression on initialization expression of static field in interface
Summary: Lambdas occurring in static contexts or those not needing instance information should be generated into static methods. This has long been the case for classes. However, as a work-around to the lack of support for statics on interfaces, interface lambda methods have been generated into default methods. For lambdas in interface static contexts (fields and static methods) this causes an NPE in javac because there is no 'this'. MethodHandles now support static methods on interfaces. This changeset allows lambda methods to be generated as static interface methods. An existing bug in Hotspot (8013875) is exposed in a test when the "-esa" flag is used. This test and another test that already exposed this bug have been marked with @ignore.
Reviewed-by: mcimadamore

     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 /**
    27  * @test
    28  * @bug 8003639
    29  * @summary convert lambda testng tests to jtreg and add them
    30  * @run testng LambdaTranslationTest2
    31  */
    33 import org.testng.annotations.Test;
    35 import java.util.ArrayList;
    36 import java.util.List;
    38 import static org.testng.Assert.assertEquals;
    39 import static org.testng.Assert.assertTrue;
    41 /**
    42  * LambdaTranslationTest2 -- end-to-end smoke tests for lambda evaluation
    43  */
    45 @Test
    46 public class LambdaTranslationTest2 {
    48     final String dummy = "dummy";
    50     public void testLambdas() {
    51         TPredicate<String> isEmpty = s -> s.isEmpty();
    52         assertTrue(isEmpty.test(""));
    53         assertTrue(!isEmpty.test("foo"));
    55         TPredicate<Object> oIsEmpty = s -> ((String) s).isEmpty();
    56         assertTrue(oIsEmpty.test(""));
    57         assertTrue(!oIsEmpty.test("foo"));
    59         TPredicate<Object> alwaysTrue = o -> true;
    60         assertTrue(alwaysTrue.test(""));
    61         assertTrue(alwaysTrue.test(null));
    63         TPredicate<Object> alwaysFalse = o -> false;
    64         assertTrue(!alwaysFalse.test(""));
    65         assertTrue(!alwaysFalse.test(null));
    67         // tests local capture
    68         String foo = "foo";
    69         TPredicate<String> equalsFoo = s -> s.equals(foo);
    70         assertTrue(!equalsFoo.test(""));
    71         assertTrue(equalsFoo.test("foo"));
    73         // tests instance capture
    74         TPredicate<String> equalsDummy = s -> s.equals(dummy);
    75         assertTrue(!equalsDummy.test(""));
    76         assertTrue(equalsDummy.test("dummy"));
    78         TMapper<Object, Object> ident = s -> s;
    80         assertEquals("blarf", ident.map("blarf"));
    81         assertEquals("wooga", ident.map("wooga"));
    82         assertTrue("wooga" == ident.map("wooga"));
    84         // constant capture
    85         TMapper<Object, Object> prefixer = s -> "p" + s;
    86         assertEquals("pblarf", prefixer.map("blarf"));
    87         assertEquals("pwooga", prefixer.map("wooga"));
    89         // instance capture
    90         TMapper<Object, Object> prefixer2 = s -> dummy + s;
    91         assertEquals("dummyblarf", prefixer2.map("blarf"));
    92         assertEquals("dummywooga", prefixer2.map("wooga"));
    93     }
    95     interface Factory<T> {
    96         T make();
    97     }
    99     interface StringFactory extends Factory<String> { }
   101     interface StringFactory2 extends Factory<String> {
   102         String make();
   103     }
   105     public void testBridges() {
   106         Factory<String> of = () -> "y";
   107         Factory<?> ef = () -> "z";
   109         assertEquals("y", of.make());
   110         assertEquals("y", ((Factory<?>) of).make());
   111         assertEquals("y", ((Factory) of).make());
   113         assertEquals("z", ef.make());
   114         assertEquals("z", ((Factory) ef).make());
   115     }
   117     public void testBridgesImplicitSpecialization() {
   118         StringFactory sf = () -> "x";
   120         assertEquals("x", sf.make());
   121         assertEquals("x", ((Factory<String>) sf).make());
   122         assertEquals("x", ((Factory<?>) sf).make());
   123         assertEquals("x", ((Factory) sf).make());
   124     }
   126     public void testBridgesExplicitSpecialization() {
   127         StringFactory2 sf = () -> "x";
   129         assertEquals("x", sf.make());
   130         assertEquals("x", ((Factory<String>) sf).make());
   131         assertEquals("x", ((Factory<?>) sf).make());
   132         assertEquals("x", ((Factory) sf).make());
   133     }
   135     public void testSuperCapture() {
   136         class A {
   137             String make() { return "x"; }
   138         }
   140         class B extends A {
   141             void testSuperCapture() {
   142                 StringFactory sf = () -> super.make();
   143                 assertEquals("x", sf.make());
   144             }
   145         }
   147         new B().testSuperCapture();
   148     }
   150     interface WidenD {
   151         public String m(float a0, double a1);
   152     }
   154     interface WidenS {
   155         public String m(byte a0, short a1);
   156     }
   158     interface WidenI {
   159         public String m(byte a0, short a1, char a2, int a3);
   160     }
   162     interface WidenL {
   163         public String m(byte a0, short a1, char a2, int a3, long a4);
   164     }
   166     interface Box {
   167         public String m(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7);
   168     }
   170     static String pb(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7) {
   171         return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
   172     }
   174     static String pwI1(int a0, int a1, int a2, int a3) {
   175         return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
   176     }
   178     static String pwI2(Integer a0, Integer a1, Integer a2, Integer a3) {
   179         return String.format("b%d s%d c%d i%d", a0, a1, a2, a3);
   180     }
   182     static String pwL1(long a0, long a1, long a2, long a3, long a4) {
   183         return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
   184     }
   186     static String pwL2(Long a0, Long a1, Long a2, Long a3, Long a4) {
   187         return String.format("b%d s%d c%d i%d j%d", a0, a1, a2, a3, a4);
   188     }
   190     static String pwS1(short a0, short a1) {
   191         return String.format("b%d s%d", a0, a1);
   192     }
   194     static String pwS2(Short a0, Short a1) {
   195         return String.format("b%d s%d", a0, a1);
   196     }
   198     static String pwD1(double a0, double a1) {
   199         return String.format("f%f d%f", a0, a1);
   200     }
   202     static String pwD2(Double a0, Double a1) {
   203         return String.format("f%f d%f", a0, a1);
   204     }
   206     public void testPrimitiveWidening() {
   207         WidenS ws1 = LambdaTranslationTest2::pwS1;
   208         assertEquals("b1 s2", ws1.m((byte) 1, (short) 2));
   210         WidenD wd1 = LambdaTranslationTest2::pwD1;
   211         assertEquals("f1.000000 d2.000000", wd1.m(1.0f, 2.0));
   213         WidenI wi1 = LambdaTranslationTest2::pwI1;
   214         assertEquals("b1 s2 c3 i4", wi1.m((byte) 1, (short) 2, (char) 3, 4));
   216         WidenL wl1 = LambdaTranslationTest2::pwL1;
   217         assertEquals("b1 s2 c3 i4 j5", wl1.m((byte) 1, (short) 2, (char) 3, 4, 5L));
   219         // @@@ TODO: clarify spec on widen+box conversion
   220     }
   222     interface Unbox {
   223         public String m(Byte a0, Short a1, Character a2, Integer a3, Long a4, Boolean a5, Float a6, Double a7);
   224     }
   226     static String pu(byte a0, short a1, char a2, int a3, long a4, boolean a5, float a6, double a7) {
   227         return String.format("b%d s%d c%c i%d j%d z%b f%f d%f", a0, a1, a2, a3, a4, a5, a6, a7);
   228     }
   230     public void testUnboxing() {
   231         Unbox u = LambdaTranslationTest2::pu;
   232         assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", u.m((byte)1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
   233     }
   235     public void testBoxing() {
   236         Box b = LambdaTranslationTest2::pb;
   237         assertEquals("b1 s2 cA i4 j5 ztrue f6.000000 d7.000000", b.m((byte) 1, (short) 2, 'A', 4, 5L, true, 6.0f, 7.0));
   238     }
   240     static boolean cc(Object o) {
   241         return ((String) o).equals("foo");
   242     }
   244     public void testArgCastingAdaptation() {
   245         TPredicate<String> p = LambdaTranslationTest2::cc;
   246         assertTrue(p.test("foo"));
   247         assertTrue(!p.test("bar"));
   248     }
   250     interface SonOfPredicate<T> extends TPredicate<T> { }
   252     public void testExtendsSAM() {
   253         SonOfPredicate<String> p = s -> s.isEmpty();
   254         assertTrue(p.test(""));
   255         assertTrue(!p.test("foo"));
   256     }
   258     public void testConstructorRef() {
   259         Factory<List<String>> lf = ArrayList<String>::new;
   260         List<String> list = lf.make();
   261         assertTrue(list instanceof ArrayList);
   262         assertTrue(list != lf.make());
   263         list.add("a");
   264         assertEquals("[a]", list.toString());
   265     }
   267     private static String privateMethod() {
   268         return "private";
   269     }
   271     public void testPrivateMethodRef() {
   272         Factory<String> sf = LambdaTranslationTest2::privateMethod;
   273         assertEquals("private", sf.make());
   274     }
   276     private interface PrivateIntf {
   277         String make();
   278     }
   280     public void testPrivateIntf() {
   281         PrivateIntf p = () -> "foo";
   282         assertEquals("foo", p.make());
   283     }
   285     interface Op<T> {
   286         public T op(T a, T b);
   287     }
   289     public void testBoxToObject() {
   290         Op<Integer> maxer = Math::max;
   291         for (int i=-100000; i < 100000; i += 100)
   292             for (int j=-100000; j < 100000; j += 99) {
   293                 assertEquals((int) maxer.op(i,j), Math.max(i,j));
   294             }
   295     }
   297     protected static String protectedMethod() {
   298         return "protected";
   299     }
   301     public void testProtectedMethodRef() {
   302         Factory<String> sf = LambdaTranslationTest2::protectedMethod;
   303         assertEquals("protected", sf.make());
   304     }
   306     class Inner1 {
   307         String m1() {
   308             return "Inner1.m1()";
   309         }
   311         class Inner2 {
   312             public String m1() {
   313                 return "Inner1.Inner2.m1()";
   314             }
   316             protected String m2() {
   317                 return "Inner1.Inner2.m2()";
   318             }
   320             String m3() {
   321                 return "Inner1.Inner2.m3()";
   322             }
   324             class Inner3<T> {
   325                 T t = null;
   326                 Inner3(T t) {
   327                     this.t = t;
   328                 }
   329                 T m1() {
   330                     return t;
   331                 }
   332             }
   333         }
   334     }
   336     public void testInnerClassMethodRef() {
   337         Factory<String> fs = new Inner1()::m1;
   338         assertEquals("Inner1.m1()", fs.make());
   340         fs = new Inner1().new Inner2()::m1;
   341         assertEquals("Inner1.Inner2.m1()", fs.make());
   343         fs = new Inner1().new Inner2()::m2;
   344         assertEquals("Inner1.Inner2.m2()", fs.make());
   346         fs = new Inner1().new Inner2()::m3;
   347         assertEquals("Inner1.Inner2.m3()", fs.make());
   349         fs = new Inner1().new Inner2().new Inner3<String>("Inner1.Inner2.Inner3")::m1;
   350         assertEquals("Inner1.Inner2.Inner3", fs.make());
   352         Factory<Integer> fsi = new Inner1().new Inner2().new Inner3<Integer>(100)::m1;
   353         assertEquals(100, (int)fsi.make());
   354     }
   355 }

mercurial