changeset 1135:655f4ec01337

Allow lambdas/method references in array initializers
author mcimadamore
date Thu, 21 Jul 2011 16:26:50 -0700
parents 305594037adf
children 73baee568e9e
files src/share/classes/com/sun/tools/javac/comp/Attr.java test/tools/javac/lambda/LambdaExpr09.java test/tools/javac/lambda/LambdaExpr10.java test/tools/javac/lambda/LambdaExpr10.out
diffstat 4 files changed, 135 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jul 18 14:39:03 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jul 21 16:26:50 2011 -0700
@@ -2007,13 +2007,14 @@
 
     public void visitNewArray(JCNewArray tree) {
         Type owntype = types.createErrorType(tree.type);
+        Env<AttrContext> localEnv = env.dup(tree);
         Type elemtype;
         if (tree.elemtype != null) {
-            elemtype = attribType(tree.elemtype, env);
-            chk.validate(tree.elemtype, env);
+            elemtype = attribType(tree.elemtype, localEnv);
+            chk.validate(tree.elemtype, localEnv);
             owntype = elemtype;
             for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
-                attribExpr(l.head, env, syms.intType);
+                attribExpr(l.head, localEnv, syms.intType);
                 owntype = new ArrayType(owntype, syms.arrayClass);
             }
         } else {
@@ -2030,7 +2031,7 @@
             }
         }
         if (tree.elems != null) {
-            attribExprs(tree.elems, env, elemtype);
+            attribExprs(tree.elems, localEnv, elemtype);
             owntype = new ArrayType(elemtype, syms.arrayClass);
         }
         if (!types.isReifiable(elemtype))
@@ -2207,8 +2208,17 @@
                 }
             }
             return false;
-        }
-        else {
+        } else if (env.tree.getTag() == JCTree.NEWARRAY) {
+            JCNewArray newArray = (JCNewArray)env.tree;
+            if (newArray.elems != null) {
+                for (JCExpression elem : newArray.elems) {
+                    if (elem == lambdaOrReference) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } else {
             return pt.tag == CLASS;
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExpr09.java	Thu Jul 21 16:26:50 2011 -0700
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * @summary check that lambda in array initializers is correctly accepted
+ * @compile LambdaExpr09.java
+ */
+
+class LambdaExpr09 {
+
+    interface Block<T> {
+       void m(T t);
+    }
+
+    void apply(Object[] obj_arr) { }
+
+    void test1() {
+        Block<?>[] arr1 =  { #{ t -> }, #{ t -> } };
+        Block<?>[][] arr2 =  { { #{ t -> }, #{ t -> } }, { #{ t -> }, #{ t -> } } };
+    }
+
+    void test2() {
+        Block<?>[] arr1 =  new Block<?>[]{ #{ t -> }, #{ t -> } };
+        Block<?>[][] arr2 =  new Block<?>[][]{ { #{ t -> }, #{ t -> } }, { #{ t -> }, #{ t -> } } };
+    }
+
+    void test3() {
+        apply(new Block<?>[]{ #{ t -> }, #{ t -> } });
+        apply(new Block<?>[][]{ { #{ t -> }, #{ t -> } }, { #{ t -> }, #{ t -> } } });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExpr10.java	Thu Jul 21 16:26:50 2011 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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
+ * @summary check that lambda in array initializers (with wrong type) are correctly rejected
+ * @compile/fail/ref=LambdaExpr10.out -XDrawDiagnostics LambdaExpr10.java
+ */
+
+class LambdaExpr10 {
+
+    interface Block<T> {
+       void m(T t);
+    }
+
+    void apply(Object[] obj_arr) { }
+
+    void test1() {
+        Object[] arr1 =  { #{ t -> } };
+        Object[][] arr2 =  { { #{ t -> } } };
+    }
+
+    void test2() {
+        Object[] arr1 =  new Object[]{ #{ t -> } };
+        Object[][] arr2 =  new Object[][]{ { #{ t -> } } };
+    }
+
+    void test3() {
+        apply(new Object[]{ #{ t -> } });
+        apply(new Object[][]{ { #{ t -> } } });
+    }
+
+    void test4() {
+        Block<?>[] arr1 =  { #{ t -> t } };
+        Block<?>[] arr2 =  new Block<?>[]{ #{ t -> t } };
+        apply(new Block<?>[]{ #{ t -> }, #{ t -> } });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExpr10.out	Thu Jul 21 16:26:50 2011 -0700
@@ -0,0 +1,9 @@
+LambdaExpr10.java:39:28: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:40:32: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:44:40: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:45:46: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:49:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:50:33: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.target.for.lambda.conv.must.be.interface: null, kindname.class, java.lang.Object)), compiler.misc.type.lambda, java.lang.Object
+LambdaExpr10.java:54:30: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: java.lang.Object)), compiler.misc.type.lambda, LambdaExpr10.Block<?>
+LambdaExpr10.java:55:44: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.incompatible.ret.types.in.lambda: java.lang.Object)), compiler.misc.type.lambda, LambdaExpr10.Block<?>
+8 errors