mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8003280: Add lambda tests
Turn on lambda expression, method reference and default method support Reviewed-by: jjg
This commit is contained in:
parent
c39f1d99b4
commit
a494f0ab86
451 changed files with 15433 additions and 488 deletions
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test that lambda conversion is only for SAM interface, not abstract class
|
||||
* @compile/fail/ref=AbstractClass_neg.out -XDrawDiagnostics AbstractClass_neg.java
|
||||
*/
|
||||
|
||||
public class AbstractClass_neg {
|
||||
|
||||
abstract class SAM {
|
||||
abstract int m();
|
||||
}
|
||||
|
||||
void test() {
|
||||
SAM s = ()-> 6;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
AbstractClass_neg.java:16:17: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
|
||||
1 error
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test accessing non-static variable from lambda expressions in static context
|
||||
* @compile/fail/ref=AccessNonStatic_neg.out -XDrawDiagnostics AccessNonStatic_neg.java
|
||||
*/
|
||||
|
||||
public class AccessNonStatic_neg {
|
||||
|
||||
private int n = 0;
|
||||
|
||||
static {
|
||||
((Runnable) ()-> {
|
||||
System.out.println(this);
|
||||
System.out.println(n);
|
||||
}).run();
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
((Runnable) ()-> {
|
||||
Object o = this;
|
||||
n++;
|
||||
}).run();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
AccessNonStatic_neg.java:15:32: compiler.err.non-static.cant.be.ref: kindname.variable, this
|
||||
AccessNonStatic_neg.java:16:32: compiler.err.non-static.cant.be.ref: kindname.variable, n
|
||||
AccessNonStatic_neg.java:22:24: compiler.err.non-static.cant.be.ref: kindname.variable, this
|
||||
AccessNonStatic_neg.java:23:13: compiler.err.non-static.cant.be.ref: kindname.variable, n
|
||||
4 errors
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Negative test of capture of "effectively final" local variable in lambda expressions
|
||||
* @compile/fail/ref=EffectivelyFinal_neg.out -XDrawDiagnostics EffectivelyFinal_neg.java
|
||||
*/
|
||||
|
||||
public class EffectivelyFinal_neg {
|
||||
|
||||
void test() {
|
||||
String s = "a";
|
||||
String s2 = "a";
|
||||
int n = 1;
|
||||
((Runnable)
|
||||
()-> {
|
||||
s2 = "b"; //re-assign illegal here
|
||||
System.out.println(n);
|
||||
System.out.println(s);
|
||||
s = "b"; // not effectively final
|
||||
}
|
||||
).run();
|
||||
n = 2; // not effectively final
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
EffectivelyFinal_neg.java:17:17: compiler.err.cant.ref.non.effectively.final.var: s2, (compiler.misc.lambda)
|
||||
EffectivelyFinal_neg.java:18:36: compiler.err.cant.ref.non.effectively.final.var: n, (compiler.misc.lambda)
|
||||
EffectivelyFinal_neg.java:19:36: compiler.err.cant.ref.non.effectively.final.var: s, (compiler.misc.lambda)
|
||||
EffectivelyFinal_neg.java:20:17: compiler.err.cant.ref.non.effectively.final.var: s, (compiler.misc.lambda)
|
||||
4 errors
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test invalid lambda expressions
|
||||
* @compile/fail/ref=InvalidExpression1.out -XDrawDiagnostics InvalidExpression1.java
|
||||
*/
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class InvalidExpression1 {
|
||||
|
||||
void test() {
|
||||
Comparator<Number> c = (Number n1, Number n2)-> { 42; }; //not a statement
|
||||
Comparator<Number> c = (Number n1, Number n2)-> { return 42 }; //";" expected
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
InvalidExpression1.java:14:59: compiler.err.not.stmt
|
||||
InvalidExpression1.java:15:68: compiler.err.expected: ';'
|
||||
2 errors
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test invalid lambda expressions
|
||||
* @compile/fail/ref=InvalidExpression3.out -XDrawDiagnostics InvalidExpression3.java
|
||||
*/
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class InvalidExpression3 {
|
||||
|
||||
void test() {
|
||||
Comparator<Integer> c2 = (Integer i1, Integer i2) -> { return "0"; }; //return type need to match
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidExpression3.java:14:71: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.String, int))
|
||||
1 error
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test invalid lambda expressions
|
||||
* @compile/fail/ref=InvalidExpression4.out -XDrawDiagnostics InvalidExpression4.java
|
||||
*/
|
||||
|
||||
public class InvalidExpression4 {
|
||||
|
||||
interface SAM {
|
||||
void m(int i);
|
||||
}
|
||||
|
||||
void test() {
|
||||
SAM s = (Integer i) -> { }; //parameters not match, boxing not allowed here
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidExpression4.java:16:17: compiler.err.prob.found.req: (compiler.misc.incompatible.arg.types.in.lambda)
|
||||
1 error
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test invalid lambda expressions
|
||||
* @compile/fail/ref=InvalidExpression5.out -XDrawDiagnostics InvalidExpression5.java
|
||||
*/
|
||||
|
||||
public class InvalidExpression5 {
|
||||
|
||||
void test() {
|
||||
Object o = (int n) -> { }; // Invalid target type
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
InvalidExpression5.java:12:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf)
|
||||
1 error
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test invalid lambda expressions
|
||||
* @compile/fail/ref=InvalidExpression6.out -XDrawDiagnostics InvalidExpression6.java
|
||||
*/
|
||||
|
||||
public class InvalidExpression6 {
|
||||
|
||||
interface SAM {
|
||||
void m(int i);
|
||||
}
|
||||
|
||||
void test() {
|
||||
SAM s = (int n) -> { break; }; //break not allowed
|
||||
s = (int n) -> { continue; }; //continue not allowed
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
InvalidExpression6.java:16:30: compiler.err.break.outside.switch.loop
|
||||
InvalidExpression6.java:17:26: compiler.err.cont.outside.loop
|
||||
2 errors
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test lambda expressions for existing SAM interfaces like Runnable and Comparator<T>
|
||||
* @compile LambdaTest1.java
|
||||
* @run main LambdaTest1
|
||||
*/
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
public class LambdaTest1 {
|
||||
|
||||
private static String assertionStr = "";
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static void test1(Runnable r) {
|
||||
r.run();
|
||||
}
|
||||
|
||||
void test2(Object o) {
|
||||
if(o instanceof Runnable)
|
||||
((Runnable)o).run();
|
||||
}
|
||||
|
||||
Runnable test3() {
|
||||
return ()-> { assertionStr += "Runnable6"; };
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
//lambda expressions for SAM interface Runnable:
|
||||
//assign:
|
||||
Runnable r = ()-> { assertionStr += "Runnable1 "; };
|
||||
r.run();
|
||||
|
||||
//cast:
|
||||
((Runnable)()-> { assertionStr += "Runnable2 "; }).run();
|
||||
|
||||
Object o = (Runnable)()-> {};
|
||||
|
||||
o = (Runnable)()-> {
|
||||
switch (assertionStr) {
|
||||
case "Runnable1 Runnable2 ":
|
||||
assertionStr += "Runnable3 ";
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
//method parameter:
|
||||
test1(()-> { assertionStr += "Runnable4 "; return; });
|
||||
|
||||
LambdaTest1 test = new LambdaTest1();
|
||||
test.test2((Runnable)()-> { assertionStr += "Runnable5 "; });
|
||||
|
||||
//return type:
|
||||
r = test.test3();
|
||||
r.run();
|
||||
|
||||
assertTrue(assertionStr.equals("Runnable1 Runnable2 Runnable4 Runnable5 Runnable6"));
|
||||
|
||||
//lambda expressions for SAM interface Comparator<T>:
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
list.add(4);
|
||||
list.add(10);
|
||||
list.add(-5);
|
||||
list.add(100);
|
||||
list.add(9);
|
||||
Collections.sort(list, (Integer i1, Integer i2)-> i2 - i1);
|
||||
String result = "";
|
||||
for(int i : list)
|
||||
result += i + " ";
|
||||
assertTrue(result.equals("100 10 9 4 -5 "));
|
||||
|
||||
Collections.sort(list,
|
||||
(i1, i2) -> {
|
||||
String s1 = i1.toString();
|
||||
String s2 = i2.toString();
|
||||
return s1.length() - s2.length();
|
||||
});
|
||||
result = "";
|
||||
for(int i : list)
|
||||
result += i + " ";
|
||||
assertTrue(result.equals("9 4 10 -5 100 "));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test lambda expressions for different method signatures (parameter and return type)
|
||||
* @compile LambdaTest2.java
|
||||
* @run main LambdaTest2
|
||||
*/
|
||||
|
||||
public class LambdaTest2 {
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
LambdaTest2 test = new LambdaTest2();
|
||||
|
||||
test.method2((int n) -> { ; });
|
||||
test.method2(n -> { }); // "int" is optional here
|
||||
test.method2((int n) -> { }); // ";" is optional here
|
||||
test.method2((int n) -> { return; }); // ";" is mandatory here
|
||||
test.method2((int n) -> { count += n; });
|
||||
assertTrue(count == 10);
|
||||
|
||||
VoidInt vi = (int i) -> {
|
||||
switch (i) {
|
||||
case 0:
|
||||
System.out.println("normal");
|
||||
break;
|
||||
default:
|
||||
System.out.println("invalid");
|
||||
}
|
||||
};
|
||||
|
||||
test.method3(()-> { count++; });
|
||||
test.method3(() -> {});
|
||||
assertTrue(count == 11);
|
||||
|
||||
VoidVoid vv = ()-> { while(true)
|
||||
if(false)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
};
|
||||
|
||||
IntVoid iv1 = () -> 42;
|
||||
IntVoid iv2 = () -> { return 43; };//";" is mandatory here
|
||||
assertTrue(iv1.ivMethod() == 42);
|
||||
assertTrue(iv2.ivMethod() == 43);
|
||||
|
||||
IntInt ii1 = (int n) -> n+1;
|
||||
IntInt ii2 = n -> 42;
|
||||
IntInt ii3 = n -> { return 43; };
|
||||
IntInt ii4 =
|
||||
(int n) -> {
|
||||
if(n > 0)
|
||||
return n+1;
|
||||
else
|
||||
return n-1;
|
||||
};
|
||||
assertTrue(ii1.iiMethod(1) == 2);
|
||||
assertTrue(ii2.iiMethod(1) == 42);
|
||||
assertTrue(ii3.iiMethod(1) == 43);
|
||||
assertTrue(ii4.iiMethod(-1) == -2);
|
||||
}
|
||||
|
||||
void method2(VoidInt a) {
|
||||
a.viMethod(10);
|
||||
}
|
||||
|
||||
void method3(VoidVoid a) {
|
||||
a.vvMethod();
|
||||
}
|
||||
|
||||
//SAM type interfaces
|
||||
interface VoidInt {
|
||||
void viMethod(int n);
|
||||
}
|
||||
|
||||
interface VoidVoid {
|
||||
void vvMethod();
|
||||
}
|
||||
|
||||
interface IntVoid {
|
||||
int ivMethod();
|
||||
}
|
||||
|
||||
interface IntInt {
|
||||
int iiMethod(int n);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test capture of "effectively final" local variable in lambda expressions
|
||||
* @compile LambdaTest3.java
|
||||
* @run main LambdaTest3
|
||||
*/
|
||||
|
||||
public class LambdaTest3 {
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final int N = 100;
|
||||
int n = 2; //effectively final variable
|
||||
|
||||
Runnable r = ((Runnable)
|
||||
() -> {
|
||||
count += N;
|
||||
count += n;
|
||||
}
|
||||
);
|
||||
assertTrue(count == 0);
|
||||
r.run();
|
||||
assertTrue(count == 102);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test accessing "this" in lambda expressions
|
||||
* @compile LambdaTest4.java
|
||||
* @run main LambdaTest4
|
||||
*/
|
||||
|
||||
public class LambdaTest4 {
|
||||
|
||||
private String thisStr;
|
||||
private static int count = 0;
|
||||
|
||||
{
|
||||
((Runnable)
|
||||
()-> {
|
||||
this.init();
|
||||
assertTrue(this.toString().equals(thisStr));
|
||||
count++;
|
||||
}
|
||||
).run();
|
||||
}
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
thisStr = this.toString();
|
||||
}
|
||||
|
||||
private void m() {
|
||||
String s1 = this.toString();
|
||||
((Runnable)
|
||||
()-> {
|
||||
assertTrue(this.toString().equals(thisStr));
|
||||
assertTrue(this.toString().equals(s1));
|
||||
}
|
||||
).run();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
LambdaTest4 test = new LambdaTest4();
|
||||
assertTrue(count == 1);
|
||||
test.m();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test lambda expressions inside lambda expressions
|
||||
* @compile LambdaTest5.java
|
||||
* @run main LambdaTest5
|
||||
*/
|
||||
|
||||
public class LambdaTest5 {
|
||||
|
||||
interface A {
|
||||
int m();
|
||||
}
|
||||
|
||||
interface B {
|
||||
int make (int i);
|
||||
}
|
||||
|
||||
private static int count = 0;
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
static A a;
|
||||
static A a2;
|
||||
static A a3;
|
||||
static A a4;
|
||||
|
||||
public static void main(String[] args) {
|
||||
B b = (int i) -> ((A)()-> 5).m();
|
||||
assertTrue(b.make(0) == 5);
|
||||
|
||||
a = () -> ((A)()-> { return 6; }).m(); //self reference
|
||||
assertTrue(a.m() == 6);
|
||||
|
||||
a2 = ()-> {
|
||||
A an = ()-> { return 7; }; //self reference
|
||||
return an.m();
|
||||
};
|
||||
assertTrue(a2.m() == 7);
|
||||
|
||||
a3 = () -> a3.m(); //self reference
|
||||
try {
|
||||
a3.m();
|
||||
} catch(StackOverflowError e) {
|
||||
count++;
|
||||
}
|
||||
assertTrue(count==1);
|
||||
|
||||
a4 = ()-> ((B)(int i)-> ((A)()-> 9).m() ).make(0);
|
||||
assertTrue(a4.m() == 9);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test bridge methods for certain SAM conversions
|
||||
* @compile LambdaTest6.java
|
||||
* @run main LambdaTest6
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LambdaTest6<T> {
|
||||
|
||||
interface H {Object m();}
|
||||
|
||||
interface K<U> {void m(U element);}
|
||||
|
||||
interface L extends K<String> {} //generic substitution
|
||||
|
||||
interface M {void m(String s);}
|
||||
|
||||
interface KM extends K<String>, M{} //generic substitution
|
||||
|
||||
interface N extends H {String m();} //covariant return
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private Set<String> setOfStringObject() {
|
||||
Set<String> s = new HashSet<>();
|
||||
s.add("java.lang.String");
|
||||
s.add("java.lang.Object");
|
||||
return s;
|
||||
}
|
||||
|
||||
private void test1()
|
||||
{
|
||||
L la = s -> { };
|
||||
la.m("hi");
|
||||
Class<? extends L> c1 = la.getClass();
|
||||
Method[] methods = c1.getDeclaredMethods();
|
||||
Set<String> types = setOfStringObject();
|
||||
for(Method m : methods) {
|
||||
assertTrue(m.getName().equals("m"));
|
||||
Class[] parameterTypes = m.getParameterTypes();
|
||||
assertTrue(parameterTypes.length == 1);
|
||||
assertTrue(types.remove(parameterTypes[0].getName()));
|
||||
}
|
||||
assertTrue(types.isEmpty() || (types.size() == 1 && types.contains("java.lang.String")));
|
||||
}
|
||||
|
||||
private void test2()
|
||||
{
|
||||
KM km = s -> { };
|
||||
//km.m("hi");
|
||||
Class<? extends KM> c2 = km.getClass();
|
||||
Method[] methods = c2.getDeclaredMethods();
|
||||
Set<String> types = setOfStringObject();
|
||||
for(Method m : methods) {
|
||||
assertTrue(m.getName().equals("m"));
|
||||
Class[] parameterTypes = m.getParameterTypes();
|
||||
assertTrue(parameterTypes.length == 1);
|
||||
assertTrue(types.remove(parameterTypes[0].getName()));
|
||||
}
|
||||
assertTrue(types.isEmpty());
|
||||
}
|
||||
|
||||
private void test3()
|
||||
{
|
||||
N na = ()-> "hi";
|
||||
assertTrue( na.m().equals("hi") );
|
||||
assertTrue( ((H)na).m().equals("hi") );
|
||||
Class<? extends N> c3 = na.getClass();
|
||||
Method[] methods = c3.getDeclaredMethods();
|
||||
Set<String> types = setOfStringObject();
|
||||
for(Method m : methods) {
|
||||
assertTrue(m.getName().equals("m"));
|
||||
Class returnType = m.getReturnType();
|
||||
assertTrue(types.remove(returnType.getName()));
|
||||
}
|
||||
assertTrue(types.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
LambdaTest6 test = new LambdaTest6();
|
||||
test.test1();
|
||||
test.test2();
|
||||
test.test3();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test SAM conversion of lambda expressions in context of assignment, method call, return statement and cast.
|
||||
* @compile SamConversion.java
|
||||
* @run main SamConversion
|
||||
*/
|
||||
|
||||
public class SamConversion {
|
||||
|
||||
static interface Foo {
|
||||
Integer m(int i);
|
||||
}
|
||||
|
||||
static interface Bar {
|
||||
int m(Integer i) throws Exception;
|
||||
}
|
||||
|
||||
private static String assertionStr = "";
|
||||
|
||||
private static void assertTrue(boolean b) {
|
||||
if(!b)
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static void test1(Foo foo) {
|
||||
assertTrue(foo.m(1) == 2);
|
||||
}
|
||||
|
||||
private static void test2(Bar bar) {
|
||||
try {
|
||||
assertTrue(bar.m(1) == 2);
|
||||
} catch (Exception e){
|
||||
assertTrue(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static Bar test3(int i) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return n -> n + 1;
|
||||
case 1:
|
||||
return (Integer n) -> 2 * n;
|
||||
case 2:
|
||||
return (Integer n) -> {return new Integer(n-1);};
|
||||
case 3:
|
||||
return n -> {throw new Exception();};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
//assign:
|
||||
Foo foo = (int n) -> n + 1; //explicit type and boxing
|
||||
assertTrue(foo.m(1) == 2);
|
||||
|
||||
foo = n -> n + 1; //type inferrred and boxing
|
||||
assertTrue(foo.m(1) == 2);
|
||||
|
||||
Bar bar = (Integer n) -> n + 1; //explicit type and unboxing
|
||||
try {
|
||||
assertTrue(bar.m(1) == 2);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
|
||||
bar = (Integer n) -> new Integer(n+1); //explicit type and unboxing twice
|
||||
try {
|
||||
assertTrue(bar.m(1) == 2);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
|
||||
bar = n -> n.intValue() + 1; //type inferred
|
||||
try {
|
||||
assertTrue(bar.m(1) == 2);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
|
||||
bar = n -> n + 1; // type inferred and unboxing
|
||||
try {
|
||||
assertTrue(bar.m(1) == 2);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
|
||||
//cast:
|
||||
assertTrue(((Foo)n -> {return n+1;}).m(1) == 2); //statement (instead of expression) in lambda body
|
||||
try {
|
||||
assertTrue(((Bar)n -> {return n+1;}).m(1) == 2); //statement in lambda body
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
|
||||
//method parameter:
|
||||
test1((int n) -> new Integer(n+1)); //explicit type
|
||||
test2((Integer n) -> n.intValue() + 1); //explicit type
|
||||
|
||||
//return statement:
|
||||
bar = test3(0);
|
||||
try {
|
||||
assertTrue(bar.m(1) == 2);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
bar = test3(1);
|
||||
try {
|
||||
assertTrue(bar.m(3) == 6);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
bar = test3(2);
|
||||
try {
|
||||
assertTrue(bar.m(10) == 9);
|
||||
} catch (Exception e) {
|
||||
assertTrue(false);
|
||||
}
|
||||
bar = test3(3);
|
||||
try {
|
||||
bar.m(10);
|
||||
assertTrue(false);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @summary Add lambda tests
|
||||
* Test SAM conversion of lambda expressions in combinations of different contexts,
|
||||
* lambda body types(statement/expression), explict/implicit target type etc, to verify
|
||||
* SAM conversion being conducted successfully as expected.
|
||||
*/
|
||||
|
||||
import com.sun.source.util.JavacTask;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
public class SamConversionComboTest {
|
||||
|
||||
enum FInterface {
|
||||
A("A", "interface A { Integer m(int i); }"),
|
||||
B("B", "interface B { int m(Integer i); }"),
|
||||
C("C", "interface C { int m(Integer i) throws Exception; }");
|
||||
|
||||
String interfaceType;
|
||||
String interfaceDef;
|
||||
|
||||
FInterface(String interfaceType, String interfaceDef) {
|
||||
this.interfaceType = interfaceType;
|
||||
this.interfaceDef = interfaceDef;
|
||||
}
|
||||
|
||||
String getParameterType() {
|
||||
switch(this) {
|
||||
case A:
|
||||
return "int";
|
||||
case B:
|
||||
case C:
|
||||
return "Integer";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Context {
|
||||
ASSIGNMENT("#FType f = #LBody;"),
|
||||
METHOD_CALL("void method1(#FType f) { }\n" +
|
||||
" void method2() {\n" +
|
||||
" method1(#LBody);\n" +
|
||||
" }"),
|
||||
CONSTRUCTOR("X x = new X(#LBody);"),
|
||||
RETURN_OF_METHOD("#FType method1() {\n" +
|
||||
" return #LBody;\n" +
|
||||
"}"),
|
||||
ARRAY_INITIALIZER("Object[] oarray = {\"a\", 1, (#FType)#LBody};"),
|
||||
LAMBDA_BODY("#FType f = n -> ((#FType)#LBody).m(n);"),
|
||||
CAST("void test() throws Exception { int n = ((#FType)#LBody).m(1); }"),
|
||||
CONDITIONAL_EXPRESSION("#FType f = 2 > 1 ? #LBody : null;");
|
||||
|
||||
String context;
|
||||
|
||||
Context(String context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
String getContext(FInterface f, LambdaKind lk, LambdaBody lb, ReturnValue rv) {
|
||||
return context.replace("#FType", f.interfaceType).replace("#LBody", lb.getLambdaBody(f, lk, rv));
|
||||
}
|
||||
}
|
||||
|
||||
enum LambdaKind {
|
||||
EXPRESSION("#VAL"),
|
||||
STATEMENT("{return #VAL;}"),
|
||||
EXCEPTION_STMT("{throw new Exception();}");
|
||||
|
||||
String stmt;
|
||||
|
||||
LambdaKind(String stmt) {
|
||||
this.stmt = stmt;
|
||||
}
|
||||
}
|
||||
|
||||
enum ReturnValue {
|
||||
INT("i + 1"),
|
||||
INTEGER("new Integer(i+1)"),
|
||||
INT2("i.intValue() + 1"),
|
||||
STRING("i + \"\""),
|
||||
DOUBLE("i * 1.0");
|
||||
|
||||
String rValue;
|
||||
|
||||
ReturnValue(String rValue) {
|
||||
this.rValue = rValue;
|
||||
}
|
||||
}
|
||||
|
||||
enum LambdaBody {
|
||||
IMPLICIT("i -> #RET"),//type inferred
|
||||
EXPLICIT("(#Type i) -> #RET");//explicit type
|
||||
|
||||
String bodyStr;
|
||||
|
||||
LambdaBody(String bodyStr) {
|
||||
this.bodyStr = bodyStr;
|
||||
}
|
||||
|
||||
String getLambdaBody(FInterface fi, LambdaKind lk, ReturnValue rv) {
|
||||
return bodyStr.replace("#Type", fi.getParameterType()).replace("#RET", lk.stmt.replace("#VAL", rv.rValue));
|
||||
}
|
||||
}
|
||||
|
||||
boolean checkSamConversion() {
|
||||
if(lambdaKind != LambdaKind.EXCEPTION_STMT && (returnValue == ReturnValue.DOUBLE || returnValue == ReturnValue.STRING)) //return type mismatch
|
||||
return false;
|
||||
if(context != Context.CONSTRUCTOR) {//context other than construcotr argument
|
||||
if(fInterface != FInterface.C && lambdaKind == LambdaKind.EXCEPTION_STMT)
|
||||
return false;
|
||||
if(fInterface == FInterface.A && returnValue == ReturnValue.INT2)
|
||||
return false;
|
||||
}
|
||||
else { //constructor argument context
|
||||
//match X(A a) or X(B b) or X(C c)
|
||||
if (lambdaKind == LambdaKind.EXCEPTION_STMT) {
|
||||
return false; //ambiguous target type
|
||||
}
|
||||
else if(lambdaBody == LambdaBody.IMPLICIT) {
|
||||
if(returnValue != ReturnValue.INTEGER) //ambiguous target type
|
||||
return false;
|
||||
}
|
||||
else { //explicit parameter type
|
||||
if(fInterface.getParameterType().equals("Integer")) //ambiguous target type
|
||||
//e.g. X x = new X((Integer i) -> i + 1);
|
||||
return false;
|
||||
if(returnValue == ReturnValue.INT2)
|
||||
//e.g. X x = new X(int i -> i.intValue() + 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SourceFile samSourceFile = new SourceFile("FInterface.java", "#C") {
|
||||
public String toString() {
|
||||
String interfaces = "";
|
||||
for(FInterface fi : FInterface.values())
|
||||
interfaces += fi.interfaceDef + "\n";
|
||||
return template.replace("#C", interfaces);
|
||||
}
|
||||
};
|
||||
|
||||
String clientTemplate = "class Client {\n" +
|
||||
" #Context\n" +
|
||||
"}\n\n" +
|
||||
|
||||
"class X {\n" +
|
||||
" int value = 0;\n\n" +
|
||||
|
||||
" X(A a) {\n" +
|
||||
" value = a.m(6);\n" +
|
||||
" }\n\n" +
|
||||
|
||||
" X(B b) {\n" +
|
||||
" value = b.m(7);\n" +
|
||||
" }\n\n" +
|
||||
|
||||
" X(C c) {\n" +
|
||||
" try {\n" +
|
||||
" value = c.m(8);\n" +
|
||||
" } catch (Exception e){}\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
SourceFile clientSourceFile = new SourceFile("Client.java", clientTemplate) {
|
||||
public String toString() {
|
||||
return template.replace("#Context", context.getContext(fInterface, lambdaKind, lambdaBody, returnValue));
|
||||
}
|
||||
};
|
||||
|
||||
void test() throws Exception {
|
||||
System.out.println("\n====================================");
|
||||
System.out.println(fInterface + ", " + context + ", " + lambdaKind + ", " + lambdaBody + ", " + returnValue);
|
||||
System.out.println(samSourceFile + "\n");
|
||||
String clientFileStr = clientSourceFile.toString();
|
||||
System.out.println(clientFileStr.substring(0, clientFileStr.indexOf("\n\n")));
|
||||
|
||||
final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||
DiagnosticChecker dc = new DiagnosticChecker();
|
||||
JavacTask ct = (JavacTask)tool.getTask(null, null, dc, null, null, Arrays.asList(samSourceFile, clientSourceFile));
|
||||
ct.analyze();
|
||||
if (dc.errorFound == checkSamConversion()) {
|
||||
throw new AssertionError(samSourceFile + "\n\n" + clientSourceFile);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
abstract class SourceFile extends SimpleJavaFileObject {
|
||||
|
||||
protected String template;
|
||||
|
||||
public SourceFile(String filename, String template) {
|
||||
super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return toString();
|
||||
}
|
||||
|
||||
public abstract String toString();
|
||||
}
|
||||
|
||||
static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||
|
||||
boolean errorFound = false;
|
||||
|
||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||
errorFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FInterface fInterface;
|
||||
Context context;
|
||||
LambdaBody lambdaBody;
|
||||
LambdaKind lambdaKind;
|
||||
ReturnValue returnValue;
|
||||
static int count = 0;
|
||||
|
||||
SamConversionComboTest(FInterface f, Context c, LambdaBody lb, LambdaKind lk, ReturnValue rv) {
|
||||
fInterface = f;
|
||||
context = c;
|
||||
lambdaKind = lk;
|
||||
lambdaBody = lb;
|
||||
returnValue = rv;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for(Context ct : Context.values()) {
|
||||
for (FInterface fi : FInterface.values()) {
|
||||
for (LambdaKind lk: LambdaKind.values()) {
|
||||
for (LambdaBody lb : LambdaBody.values()) {
|
||||
for(ReturnValue rv : ReturnValue.values()) {
|
||||
new SamConversionComboTest(fi, ct, lb, lk, rv).test();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("total tests: " + count);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue