test/tools/javac/lambda/methodReference/SamConversion.java

Fri, 30 Nov 2012 15:14:36 +0000

author
mcimadamore
date
Fri, 30 Nov 2012 15:14:36 +0000
changeset 1435
9b26c96f5138
parent 1415
01c9d4161882
child 1510
7873d37f5b37
permissions
-rw-r--r--

8004101: Add checks for method reference well-formedness
Summary: Bring method reference type-checking in sync with latest EDR
Reviewed-by: jjg

     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.
     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  */
    24 /**
    25  * @test
    26  * @bug 8003280
    27  * @summary Add lambda tests
    28  *   Test SAM conversion of method references in contexts of assignment, method/constructor argument,
    29  *           return statement, array initializer, lambda expression body, conditional expression and cast.
    30  * @compile SamConversion.java
    31  * @run main SamConversion
    32  */
    34 public class SamConversion {
    36     static int assertionCount = 0;
    38     static interface Foo {
    39         Integer m(int i);
    40     }
    42     static interface Bar {
    43         int m(Integer i) throws MyException;
    44     }
    46     private static void assertTrue(boolean b) {
    47         assertionCount++;
    48         if(!b)
    49             throw new AssertionError();
    50     }
    52     private static int test1(Foo foo) {
    53         return foo.m(1);
    54     }
    56     private static void test2(Bar bar, int result) {
    57         try {
    58             assertTrue(bar.m(1) == result);
    59         } catch (Exception e){
    60             assertTrue(false);
    61         }
    62     }
    64     private static Bar test3(int i) {
    65         switch (i) {
    66         case 0:
    67             return A::method1;
    68         case 1:
    69             return new A()::method2;
    70         case 2:
    71             return A::method3;
    72         case 3:
    73             return new A()::method4;
    74         case 4:
    75             return new A()::method5;
    76         case 5:
    77             return A::method6;
    78         default:
    79             return null;
    80         }
    81     }
    83     /**
    84      * Test SAM conversion of method reference in assignment context
    85      */
    86     private static void testAssignment() {
    87         Foo foo = A::method1; //static reference, parameter type matching and return type matching
    88         assertTrue(foo.m(1) == 2);
    90         foo = new A()::method2; //instance reference, parameter type unboxing and return type boxing
    91         assertTrue(foo.m(1) == 3);
    93         foo = A::method3; //static reference, parameter type matching and return type boxing
    94         assertTrue(foo.m(1) == 4);
    96         foo = new A()::method4; //instance reference, parameter type unboxing and return type matching
    97         assertTrue(foo.m(1) == 5);
    99         foo = new A()::method5; //instance reference, parameter type unboxing and return type matching
   100         assertTrue(foo.m(1) == 6);
   102         Bar bar = A::method1;
   103         try {
   104             assertTrue(bar.m(1) == 2);
   105         } catch (Exception e) {
   106             assertTrue(false);
   107         }
   109         bar = new A()::method2;
   110         try {
   111             assertTrue(bar.m(1) == 3);
   112         } catch (Exception e) {
   113             assertTrue(false);
   114         }
   116         bar = A::method3;
   117         try {
   118             assertTrue(bar.m(1) == 4);
   119         } catch (Exception e) {
   120             assertTrue(false);
   121         }
   123         bar = new A()::method4;
   124         try {
   125             assertTrue(bar.m(1) == 5);
   126         } catch (Exception e) {
   127             assertTrue(false);
   128         }
   130         bar = new A()::method5;
   131         try {
   132             assertTrue(bar.m(1) == 6);
   133         } catch (Exception e) {
   134             assertTrue(false);
   135         }
   136     }
   138     /**
   139      * Test SAM conversion of method reference in method/constructor argument context
   140      */
   141     private static void testMethodArgument() {
   142         assertTrue(test1(A::method1) == 2);
   143         assertTrue(test1(new A()::method2) == 3);
   144         assertTrue(test1(A::method3) == 4);
   145         assertTrue(test1(new A()::method4) == 5);
   146         assertTrue(test1(new A()::method5) == 6);
   147         test2(A::method1, 2);
   148         test2(new A()::method2, 3);
   149         test2(A::method3, 4);
   150         test2(new A()::method4, 5);
   151         test2(new A()::method5, 6);
   152         A a = new A(A::method1); //A(Foo f) called
   153         assertTrue(a.method2(1) == 11);
   154         assertTrue(a.method4(1) == 11);
   155         assertTrue(a.method5(1) == 11);
   156         A a2 = new A(new A()::method2); //A(Bar b) called
   157         assertTrue(a2.method2(1) == 12);
   158         assertTrue(a2.method4(1) == 12);
   159         assertTrue(a2.method5(1) == 12);
   160     }
   162     /**
   163      * Test SAM conversion of method reference in return statement context
   164      */
   165     private static void testReturnStatement() {
   166         Bar bar = test3(0);
   167         try {
   168             assertTrue(bar.m(1) == 2);
   169         } catch (Exception e) {
   170             assertTrue(false);
   171         }
   172         bar = test3(1);
   173         try {
   174             assertTrue(bar.m(1) == 3);
   175         } catch (Exception e) {
   176             assertTrue(false);
   177         }
   178         bar = test3(2);
   179         try {
   180             assertTrue(bar.m(1) == 4);
   181         } catch (Exception e) {
   182             assertTrue(false);
   183         }
   184         bar = test3(3);
   185         try {
   186             assertTrue(bar.m(1) == 5);
   187         } catch (Exception e) {
   188             assertTrue(false);
   189         }
   190         bar = test3(4);
   191         try {
   192             assertTrue(bar.m(1) == 6);
   193         } catch (Exception e) {
   194             assertTrue(false);
   195         }
   196         bar = test3(5);
   197         try {
   198             bar.m(1);
   199             assertTrue(false);
   200         } catch (MyException e) {
   201         } catch (Exception e) {
   202             assertTrue(false);
   203         }
   204     }
   206     /**
   207      * Test SAM conversion of method reference in cast context
   208      */
   209     private static void testCast() {
   210         assertTrue(((Foo)A::method1).m(1) == 2);
   211         try {
   212             assertTrue(((Bar)new A()::method2).m(1) == 3);
   213         } catch (Exception e) {
   214             assertTrue(false);
   215         }
   216     }
   218     /**
   219      * Test SAM conversion of method reference in array initializer context
   220      */
   221     private static void testArrayInitializer() {
   222         Object[] oarray = {"a", 1, (Foo)A::method3}; //last element need a cast
   223         Object[] oarray2 = {"a", 1, (Bar)new A()::method4}; //last element need a cast
   224         Foo[] farray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5};
   225         Bar[] barray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5, A::method6};
   226     }
   228     /**
   229      * Test SAM conversion of method reference in conditional expression context
   230      */
   231     private static void testConditionalExpression(boolean b) {
   232         Foo f = b ? A::method3 : new A()::method5;
   233         if(b)
   234             assertTrue(f.m(1) == 4);
   235         else
   236             assertTrue(f.m(1) == 6);
   238         Bar bar = b ? A::method1 : A::method6;
   239         if(b) {
   240             try {
   241                 assertTrue(bar.m(1) == 2);
   242             } catch (Exception e) {
   243                 assertTrue(false);
   244             }
   245         }
   246         else {
   247             try {
   248                 bar.m(1);
   249                 assertTrue(false);
   250             } catch (MyException e) {
   251             } catch (Exception e) {
   252                 assertTrue(false);
   253             }
   254         }
   255     }
   257     /**
   258      * Test SAM conversion of method reference in lambda expression body
   259      */
   260     private static void testLambdaExpressionBody() {
   261         Foo f = n -> ((Foo)A::method3).m(n);
   262         assertTrue(f.m(1) == 4);
   264         Bar b = n -> { return ((Foo)new A()::method5).m(n); };
   265         try {
   266             assertTrue(b.m(1) == 6);
   267         } catch (Exception e) {
   268             assertTrue(false);
   269         }
   270     }
   272     public static void main(String[] args) {
   273         testAssignment();
   274         testMethodArgument();
   275         testReturnStatement();
   276         testCast();
   277         testArrayInitializer();
   278         testConditionalExpression(true);
   279         testConditionalExpression(false);
   280         testLambdaExpressionBody();
   282         assertTrue(assertionCount == 38);
   283     }
   285     static class MyException extends Exception {}
   287     static class A {
   289         int value = 0;
   291         A() {
   292         }
   294         A(Foo f) {
   295             value = f.m(9);
   296         }
   298         A(Bar b) {
   299             try {
   300                 value = b.m(9);
   301             } catch (MyException e){}
   302         }
   304         static Integer method1(int n) {
   305             return n + 1;
   306         }
   308         int method2(Integer n) {
   309             return value == 0 ? n + 2 : n + value;
   310         }
   312         static int method3(int n) {
   313             return n + 3;
   314         }
   316         Integer method4(Integer n) {
   317             return value == 0 ? n + 4 : n + value;
   318         }
   320         Integer method5(Integer n) {
   321             return value == 0 ? new Integer(n + 5) : new Integer(n + value);
   322         }
   324         static int method6(Integer n) throws MyException{
   325             throw new MyException();
   326         }
   327     }
   328 }

mercurial