changeset 620:f5d1e87d77f6

Local break/continue in lambda expressions should *still* be allowed (aka: never do hg push on a late friday :-)) Added regression test.
author mcimadamore
date Fri, 30 Jul 2010 21:03:57 +0100
parents bc4c0b43b515
children 443eb1d3b96c
files src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/resources/compiler.properties test/tools/javac/lambda/BadBreakContinue.out test/tools/javac/lambda/LocalBreakAndContinue.java
diffstat 4 files changed, 59 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jul 30 18:53:18 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jul 30 21:03:57 2010 +0100
@@ -1199,22 +1199,12 @@
     }
 
     public void visitBreak(JCBreak tree) {
-        if ((env.enclClass.sym.flags() & LAMBDA) != 0) {
-            //cannot use break inside lambda
-            log.error(tree, "break.inside.lambda");
-        } else {
-            tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
-        }
+        tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
         result = null;
     }
 
     public void visitContinue(JCContinue tree) {
-        if ((env.enclClass.sym.flags() & LAMBDA) != 0) {
-            //cannot use continue inside lambda
-            log.error(tree, "continue.inside.lambda");
-        } else {
-            tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
-        }
+        tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
         result = null;
     }
     //where
@@ -1237,6 +1227,7 @@
                                     Env<AttrContext> env) {
             // Search environments outwards from the point of jump.
             Env<AttrContext> env1 = env;
+            boolean seenLambda = false;
             LOOP:
             while (env1 != null) {
                 switch (env1.tree.getTag()) {
@@ -1269,6 +1260,7 @@
                     break;
                 case JCTree.METHODDEF:
                 case JCTree.CLASSDEF:
+                    seenLambda = (env1.enclClass.sym.flags() & LAMBDA) != 0;
                     break LOOP;
                 default:
                 }
@@ -1277,9 +1269,13 @@
             if (label != null)
                 log.error(pos, "undef.label", label);
             else if (tag == JCTree.CONTINUE)
-                log.error(pos, "cont.outside.loop");
+                log.error(pos, seenLambda ?
+                    "cont.inside.lambda" :
+                    "cont.outside.loop");
             else
-                log.error(pos, "break.outside.switch.loop");
+                log.error(pos, seenLambda ?
+                    "break.inside.lambda" :
+                    "break.outside.switch.loop");
             return null;
         }
 
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jul 30 18:53:18 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jul 30 21:03:57 2010 +0100
@@ -119,9 +119,9 @@
     local variable {0} cannot be referenced\n\
     local variables referenced from the body of a lambda expression must be ''effectively final''
 compiler.err.break.inside.lambda=\
-    ''break'' not allowed in the body of a lambda expression
-compiler.err.continue.inside.lambda=\
-    ''continue'' not allowed in the body of a lambda expression
+    ''break'' outside the scope of a lambda expression
+compiler.err.cont.inside.lambda=\
+    ''continue'' outside the scope of a lambda expression
 compiler.err.cant.deref=\
     {0} cannot be dereferenced
 compiler.err.cant.extend.intf.annotation=\
--- a/test/tools/javac/lambda/BadBreakContinue.out	Fri Jul 30 18:53:18 2010 +0100
+++ b/test/tools/javac/lambda/BadBreakContinue.out	Fri Jul 30 21:03:57 2010 +0100
@@ -1,9 +1,9 @@
 BadBreakContinue.java:37:17: compiler.err.break.inside.lambda
-BadBreakContinue.java:38:17: compiler.err.continue.inside.lambda
+BadBreakContinue.java:38:17: compiler.err.cont.inside.lambda
 BadBreakContinue.java:40:23: compiler.err.break.inside.lambda
-BadBreakContinue.java:41:23: compiler.err.continue.inside.lambda
-BadBreakContinue.java:46:25: compiler.err.break.inside.lambda
-BadBreakContinue.java:47:25: compiler.err.continue.inside.lambda
-BadBreakContinue.java:49:31: compiler.err.break.inside.lambda
-BadBreakContinue.java:50:31: compiler.err.continue.inside.lambda
+BadBreakContinue.java:41:23: compiler.err.cont.inside.lambda
+BadBreakContinue.java:46:25: compiler.err.undef.label: loop
+BadBreakContinue.java:47:25: compiler.err.undef.label: loop
+BadBreakContinue.java:49:31: compiler.err.undef.label: loop
+BadBreakContinue.java:50:31: compiler.err.undef.label: loop
 8 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LocalBreakAndContinue.java	Fri Jul 30 21:03:57 2010 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 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 local break/continue is allowed in lambda expressions
+ * @author  Maurizio Cimadamore
+ * @compile LocalBreakAndContinue.java
+ */
+
+class LocalBreakAndContinue {
+
+    static interface SAM {
+       void m();
+    }
+
+    SAM s1 = #{ while (true) break; };
+    SAM s2 = #{ while (true) continue; };
+}