mcimadamore@1415: /* mcimadamore@1415: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. mcimadamore@1415: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@1415: * mcimadamore@1415: * This code is free software; you can redistribute it and/or modify it mcimadamore@1415: * under the terms of the GNU General Public License version 2 only, as mcimadamore@1415: * published by the Free Software Foundation. mcimadamore@1415: * mcimadamore@1415: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@1415: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@1415: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@1415: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@1415: * accompanied this code). mcimadamore@1415: * mcimadamore@1415: * You should have received a copy of the GNU General Public License version mcimadamore@1415: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@1415: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@1415: * mcimadamore@1415: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mcimadamore@1415: * or visit www.oracle.com if you need additional information or have any mcimadamore@1415: * questions. mcimadamore@1415: */ mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * @test mcimadamore@1415: * @bug 8003280 mcimadamore@1415: * @summary Add lambda tests mcimadamore@1415: * Test SAM conversion of method references in contexts of assignment, method/constructor argument, mcimadamore@1415: * return statement, array initializer, lambda expression body, conditional expression and cast. mcimadamore@1415: * @compile SamConversion.java mcimadamore@1415: * @run main SamConversion mcimadamore@1415: */ mcimadamore@1415: mcimadamore@1415: public class SamConversion { mcimadamore@1415: mcimadamore@1415: static int assertionCount = 0; mcimadamore@1415: mcimadamore@1415: static interface Foo { mcimadamore@1415: Integer m(int i); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: static interface Bar { mcimadamore@1415: int m(Integer i) throws MyException; mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: private static void assertTrue(boolean b) { mcimadamore@1415: assertionCount++; mcimadamore@1415: if(!b) mcimadamore@1415: throw new AssertionError(); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: private static int test1(Foo foo) { mcimadamore@1415: return foo.m(1); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: private static void test2(Bar bar, int result) { mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == result); mcimadamore@1415: } catch (Exception e){ mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: private static Bar test3(int i) { mcimadamore@1415: switch (i) { mcimadamore@1415: case 0: mcimadamore@1415: return A::method1; mcimadamore@1415: case 1: mcimadamore@1415: return new A()::method2; mcimadamore@1415: case 2: mcimadamore@1415: return A::method3; mcimadamore@1415: case 3: mcimadamore@1415: return new A()::method4; mcimadamore@1415: case 4: mcimadamore@1415: return new A()::method5; mcimadamore@1415: case 5: mcimadamore@1415: return A::method6; mcimadamore@1415: default: mcimadamore@1415: return null; mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in assignment context mcimadamore@1415: */ mcimadamore@1415: private static void testAssignment() { mcimadamore@1415: Foo foo = A::method1; //static reference, parameter type matching and return type matching mcimadamore@1415: assertTrue(foo.m(1) == 2); mcimadamore@1415: mcimadamore@1415: foo = new A()::method2; //instance reference, parameter type unboxing and return type boxing mcimadamore@1415: assertTrue(foo.m(1) == 3); mcimadamore@1415: mcimadamore@1415: foo = A::method3; //static reference, parameter type matching and return type boxing mcimadamore@1415: assertTrue(foo.m(1) == 4); mcimadamore@1415: mcimadamore@1415: foo = new A()::method4; //instance reference, parameter type unboxing and return type matching mcimadamore@1415: assertTrue(foo.m(1) == 5); mcimadamore@1415: mcimadamore@1415: foo = new A()::method5; //instance reference, parameter type unboxing and return type matching mcimadamore@1415: assertTrue(foo.m(1) == 6); mcimadamore@1415: mcimadamore@1415: Bar bar = A::method1; mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 2); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: bar = new A()::method2; mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 3); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: bar = A::method3; mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 4); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: bar = new A()::method4; mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 5); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: bar = new A()::method5; mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 6); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in method/constructor argument context mcimadamore@1415: */ mcimadamore@1415: private static void testMethodArgument() { mcimadamore@1415: assertTrue(test1(A::method1) == 2); mcimadamore@1415: assertTrue(test1(new A()::method2) == 3); mcimadamore@1415: assertTrue(test1(A::method3) == 4); mcimadamore@1415: assertTrue(test1(new A()::method4) == 5); mcimadamore@1415: assertTrue(test1(new A()::method5) == 6); mcimadamore@1415: test2(A::method1, 2); mcimadamore@1415: test2(new A()::method2, 3); mcimadamore@1415: test2(A::method3, 4); mcimadamore@1415: test2(new A()::method4, 5); mcimadamore@1415: test2(new A()::method5, 6); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in return statement context mcimadamore@1415: */ mcimadamore@1415: private static void testReturnStatement() { mcimadamore@1415: Bar bar = test3(0); mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 2); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: bar = test3(1); mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 3); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: bar = test3(2); mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 4); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: bar = test3(3); mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 5); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: bar = test3(4); mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 6); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: bar = test3(5); mcimadamore@1415: try { mcimadamore@1415: bar.m(1); mcimadamore@1415: assertTrue(false); mcimadamore@1415: } catch (MyException e) { mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in cast context mcimadamore@1415: */ mcimadamore@1415: private static void testCast() { mcimadamore@1415: assertTrue(((Foo)A::method1).m(1) == 2); mcimadamore@1415: try { mcimadamore@1415: assertTrue(((Bar)new A()::method2).m(1) == 3); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in array initializer context mcimadamore@1415: */ mcimadamore@1415: private static void testArrayInitializer() { mcimadamore@1415: Object[] oarray = {"a", 1, (Foo)A::method3}; //last element need a cast mcimadamore@1415: Object[] oarray2 = {"a", 1, (Bar)new A()::method4}; //last element need a cast mcimadamore@1415: Foo[] farray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5}; mcimadamore@1415: Bar[] barray = {A::method1, new A()::method2, A::method3, new A()::method4, new A()::method5, A::method6}; mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in conditional expression context mcimadamore@1415: */ mcimadamore@1415: private static void testConditionalExpression(boolean b) { mcimadamore@1415: Foo f = b ? A::method3 : new A()::method5; mcimadamore@1415: if(b) mcimadamore@1415: assertTrue(f.m(1) == 4); mcimadamore@1415: else mcimadamore@1415: assertTrue(f.m(1) == 6); mcimadamore@1415: mcimadamore@1415: Bar bar = b ? A::method1 : A::method6; mcimadamore@1415: if(b) { mcimadamore@1415: try { mcimadamore@1415: assertTrue(bar.m(1) == 2); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: else { mcimadamore@1415: try { mcimadamore@1415: bar.m(1); mcimadamore@1415: assertTrue(false); mcimadamore@1415: } catch (MyException e) { mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: /** mcimadamore@1415: * Test SAM conversion of method reference in lambda expression body mcimadamore@1415: */ mcimadamore@1415: private static void testLambdaExpressionBody() { mcimadamore@1415: Foo f = n -> ((Foo)A::method3).m(n); mcimadamore@1415: assertTrue(f.m(1) == 4); mcimadamore@1415: mcimadamore@1415: Bar b = n -> { return ((Foo)new A()::method5).m(n); }; mcimadamore@1415: try { mcimadamore@1415: assertTrue(b.m(1) == 6); mcimadamore@1415: } catch (Exception e) { mcimadamore@1415: assertTrue(false); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: public static void main(String[] args) { mcimadamore@1415: testAssignment(); mcimadamore@1415: testMethodArgument(); mcimadamore@1415: testReturnStatement(); mcimadamore@1415: testCast(); mcimadamore@1415: testArrayInitializer(); mcimadamore@1415: testConditionalExpression(true); mcimadamore@1415: testConditionalExpression(false); mcimadamore@1415: testLambdaExpressionBody(); mcimadamore@1415: mcimadamore@1510: assertTrue(assertionCount == 32); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: static class MyException extends Exception {} mcimadamore@1415: mcimadamore@1415: static class A { mcimadamore@1415: mcimadamore@1415: int value = 0; mcimadamore@1415: mcimadamore@1415: A() { mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: A(Foo f) { mcimadamore@1415: value = f.m(9); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: A(Bar b) { mcimadamore@1415: try { mcimadamore@1415: value = b.m(9); mcimadamore@1415: } catch (MyException e){} mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: static Integer method1(int n) { mcimadamore@1415: return n + 1; mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: int method2(Integer n) { mcimadamore@1415: return value == 0 ? n + 2 : n + value; mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: static int method3(int n) { mcimadamore@1415: return n + 3; mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: Integer method4(Integer n) { mcimadamore@1415: return value == 0 ? n + 4 : n + value; mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: Integer method5(Integer n) { mcimadamore@1415: return value == 0 ? new Integer(n + 5) : new Integer(n + value); mcimadamore@1415: } mcimadamore@1415: mcimadamore@1415: static int method6(Integer n) throws MyException{ mcimadamore@1415: throw new MyException(); mcimadamore@1415: } mcimadamore@1415: } mcimadamore@1415: }