changeset 556:81966684ef23

Added simple lookahead in order to disambiguate between lambda expression and variable declaration of function types.
author mcimadamore
date Fri, 28 May 2010 17:19:22 +0100
parents 7586844b51d3
children d74a4b240764
files src/share/classes/com/sun/tools/javac/parser/JavacParser.java src/share/classes/com/sun/tools/javac/parser/Lexer.java src/share/classes/com/sun/tools/javac/parser/Scanner.java test/tools/javac/lambda/FuncType01.java test/tools/javac/lambda/LambdaCapture01.java test/tools/javac/lambda/LambdaExpr03.java
diffstat 6 files changed, 123 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri May 28 12:12:18 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri May 28 17:19:22 2010 +0100
@@ -1289,14 +1289,13 @@
     }
 
     JCExpression lambdaOrFunctionType() {
-        return (mode & EXPR) != 0 ?
-            lambdaExpressionOrStatement() :
-            (mode & TYPE) != 0 ?
-                functionType() :
-                illegal();
+        return S.token() == LPAREN ?
+            lambdaExpressionOrStatement() :            
+            functionType();
     }
 
     JCExpression lambdaExpressionOrStatement() {
+        mode = EXPR;
         checkLambda();
         int pos = S.pos();
         List<JCVariableDecl> args = formalParameters();
@@ -1320,10 +1319,13 @@
     }
 
     JCExpression functionType() {
+        mode = TYPE;
         checkFunctionTypes();
         JCExpression retType = parseType();
         accept(LPAREN);
-        List<JCExpression> args = typeList();
+        List<JCExpression> args = (S.token() == RPAREN) ?
+            List.<JCExpression>nil() :
+            typeList();
         accept(RPAREN);
         List<JCExpression> thrown = List.nil();
         if (S.token() == LPAREN) {
@@ -1828,11 +1830,15 @@
                 return stats.toList();
             case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
             case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
-            case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
+                case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
                 stats.append(parseStatement());
                 break;
+            case HASH:
+                if (S.peekToken() == Token.LPAREN) {
+                    stats.append(parseStatement());
+                    break;
+                }
             case MONKEYS_AT:
-            case HASH:
             case FINAL: {
                 String dc = S.docComment();
                 JCModifiers mods = modifiersOpt();
--- a/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Fri May 28 12:12:18 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/Lexer.java	Fri May 28 17:19:22 2010 +0100
@@ -108,6 +108,11 @@
     void nextToken();
 
     /**
+     * Peek next token (lookahead).
+     */
+    Token peekToken();
+
+    /**
      * Return the current token's position: a 0-based
      *  offset from beginning of the raw input stream
      *  (before unicode translation)
--- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Fri May 28 12:12:18 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Fri May 28 17:19:22 2010 +0100
@@ -809,6 +809,29 @@
         return new String(sbuf, 0, sp);
     }
 
+    public Token peekToken() {
+        Token prevToken = token;
+        int prevPos = pos;
+        int _prevEndPos = endPos;
+        int prevPrevEndPos = prevEndPos;
+        char prevCh = ch;
+        int prevBp = bp;
+        try {
+            if (token != EOF) {
+                nextToken();
+            }
+            return token;
+        }
+        finally {
+            token = prevToken;
+            pos = prevPos;
+            endPos = _prevEndPos;
+            prevEndPos = prevPrevEndPos;
+            ch = prevCh;
+            bp = prevBp;
+        }
+    }
+
     /** Read token.
      */
     public void nextToken() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/FuncType01.java	Fri May 28 17:19:22 2010 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary test function type with no arguments
+ * @author  Maurizio Cimadamore
+ * @compile -XDallowFunctionTypes FuncType01.java
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles FuncType01
+ */
+
+public class FuncType01 {
+
+    static void assertTrue(boolean cond) {
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    public static void main(String[] args) {
+        #boolean() cond = #()( true );
+        assertTrue(cond.());
+    }
+}
--- a/test/tools/javac/lambda/LambdaCapture01.java	Fri May 28 12:12:18 2010 +0100
+++ b/test/tools/javac/lambda/LambdaCapture01.java	Fri May 28 17:19:22 2010 +0100
@@ -26,7 +26,7 @@
  * @summary basic test for capture of non-mutable locals
  * @author  Brian Goetz
  * @author  Maurizio Cimadamore
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles LambdaConv01
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles LambdaCapture01
  */
 
 public class LambdaCapture01 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExpr03.java	Fri May 28 17:19:22 2010 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @summary parser should be able to disambiguate between function types and lambdas
+ * @author  Maurizio Cimadamore
+ * @compile -XDallowFunctionTypes LambdaExpr03.java
+ */
+
+class LambdaExpr03 {
+    static {
+        #(int x){ }.(1); //lambda call
+        #(int x)(null).(2); //lambda call
+        #int() x; //var
+    }
+}