changeset 654:1bb5b46bb326

Bug fixes: *) binary expression in lambda expression is not parsed correctly (Scanner.popState fails to restore state) *) method references: static vs. non-static selection logic in method references does not always works *) failure to infer exception thrown types from lambda body causes checked exception to be skipped *) lambda expression body (when not a block) cannot be void
author mcimadamore
date Mon, 23 Aug 2010 13:48:15 +0100
parents ce46b6012362
children d66149a0e03c
files src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/parser/Scanner.java src/share/classes/com/sun/tools/javac/tree/TreeInfo.java test/tools/javac/lambda/LambdaExpr05.java test/tools/javac/lambda/LambdaExprNotVoid.java test/tools/javac/lambda/LambdaExprNotVoid.out test/tools/javac/lambda/MethodReference11.java test/tools/javac/lambda/TargetType13.java test/tools/javac/lambda/TargetType13.out
diffstat 10 files changed, 177 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Aug 19 13:11:51 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Aug 23 13:48:15 2010 +0100
@@ -321,7 +321,8 @@
                 isSameTypes(mtype.getParameterTypes(), t.getParameterTypes()) ||
                 containsType(mtype.getParameterTypes(), boxedTypesOrTypes(t.getParameterTypes())));
 
-            boolean thrownOk = chk.unhandled(t.getThrownTypes(), mtype.getThrownTypes()).isEmpty();
+            boolean thrownOk = t.getThrownTypes() == Type.noTypes ||
+                    chk.unhandled(t.getThrownTypes(), mtype.getThrownTypes()).isEmpty();
             return new ConversionResult(isReturnOk && argsOk && thrownOk) {
                 @Override
                 public boolean check(Env<AttrContext> env) {
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Aug 19 13:11:51 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Aug 23 13:48:15 2010 +0100
@@ -2264,7 +2264,7 @@
         //pass, then thrown types are left uninferred (as e.g. calling an unknown
         //method on an unknown type might raise unknown exception types).
         if (log.suppressedDiagnostics.containsKey(JCDiagnostic.Kind.ERROR)) {
-            thrownTypes = List.<Type>nil();
+            thrownTypes = Type.noTypes;
         }
 
         that.type = new FunctionType(argtypes.toList(),
@@ -2315,8 +2315,8 @@
         if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
             Type exprType = attribExpr(that.getBody(), localEnv);
             Type reqType = targetType.getReturnType();
-            if (!types.isSameType(reqType, types.boxedClass(syms.voidType).type) &&
-                    exprType.tag == VOID) {
+            if (!(types.isSameType(reqType, types.boxedClass(syms.voidType).type) &&
+                    exprType.tag == VOID)) {
                 //check the expression type against the (possibly inferred) lambda return type
                 chk.checkType(that.getBody(), localEnv, exprType, reqType);
             }
@@ -2644,7 +2644,7 @@
         Type mtype = tree.meth.type;
         List<Type> args = mtype.getParameterTypes();
         if (!msym.isStatic() &&
-                TreeInfo.isStaticSelector(tree.meth, names) &&
+                TreeInfo.isStaticSelector(base, names) &&
                 (Resolve.isStatic(env) ||
                 types.asSuper(env.enclClass.type, msym.owner) == null)) {
             args = args.prepend(base.type);
--- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Thu Aug 19 13:11:51 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Mon Aug 23 13:48:15 2010 +0100
@@ -205,7 +205,8 @@
             savedName = name;
             savedRadix = radix;
             savedDeprecatedFlag = deprecatedFlag;
-            savedSbuf = sbuf;
+            savedSbuf = new char[sbuf.length];
+            System.arraycopy(sbuf, 0, savedSbuf, 0, sbuf.length);
             savedSp = sp;
             savedBp = bp;
             savedBuflen = buflen;
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Aug 19 13:11:51 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Aug 23 13:48:15 2010 +0100
@@ -683,22 +683,16 @@
     }
 
     /**
-     * Return true if the AST corresponds to a static select of the kind
-     * A.B.m --- note: this routine only checks the structure of the AST node,
-     * and not whether m itself is a static symbol or not.
+     * Return true if the AST corresponds to a static select of the kind A.B
      */
     public static boolean isStaticSelector(JCTree base, Names names) {
-        return isStaticSelector1(base, names, true);
-    }
-
-    private static boolean isStaticSelector1(JCTree base, Names names, boolean recursive) {
         switch (base.getTag()) {
             case JCTree.IDENT: JCIdent id = (JCIdent)base;
                                return id.name != names._this &&
                                        id.name != names._super &&
-                                       (recursive || isStaticSym(base));
-            case JCTree.SELECT: return (recursive || isStaticSym(base)) &&
-                    isStaticSelector1(((JCFieldAccess)base).selected, names, false);
+                                       isStaticSym(base);
+            case JCTree.SELECT: return isStaticSym(base) &&
+                    isStaticSelector(((JCFieldAccess)base).selected, names);
             case JCTree.TYPEAPPLY: return true;
             default: return false;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExpr05.java	Mon Aug 23 13:48:15 2010 +0100
@@ -0,0 +1,37 @@
+/*
+ * 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 binary expression in lambda expression is parsed correctly
+ * @author  Maurizio Cimadamore
+ * @compile LambdaExpr05.java
+ */
+
+class LambdaExpr05 {
+
+    interface SAM { int foo(int i); }
+
+    SAM s1 = #(i) { i * 2 };
+    SAM s2 = #(i) { 2 * i };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExprNotVoid.java	Mon Aug 23 13:48:15 2010 +0100
@@ -0,0 +1,37 @@
+/*
+ * 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 lambda expression body (when not a block) cannot be void
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=LambdaExprNotVoid.out -XDrawDiagnostics LambdaExprNotVoid.java
+ */
+
+class LambdaExpr05 {
+
+    interface SAM { void foo(int i); }
+
+    SAM s1 = #(i) { i * 2 };
+    SAM s2 = #(i) { 2 * i };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaExprNotVoid.out	Mon Aug 23 13:48:15 2010 +0100
@@ -0,0 +1,3 @@
+LambdaExprNotVoid.java:35:23: compiler.err.prob.found.req: (compiler.misc.incompatible.types), int, void
+LambdaExprNotVoid.java:36:23: compiler.err.prob.found.req: (compiler.misc.incompatible.types), int, void
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference11.java	Mon Aug 23 13:48:15 2010 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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 static vs. non-static selection logic in method references works
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles MethodReference06
+ */
+
+import java.util.*;
+
+class Test {
+    public static void main(String[] args) {
+        String[] strings = new String[] { "D", "C", "B", "A" };
+        Arrays.sort( strings, String.CASE_INSENSITIVE_ORDER#compare( String, String ) );
+        String last = "1";
+        for String s : strings) {
+            if (String.CASE_INSENSITIVE_ORDER.compare(last, s) > 0) {
+                throws new AssertionError();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType13.java	Mon Aug 23 13:48:15 2010 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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 failure to infer exception thrown types from lambda body causes checked exception to be skipped
+ * @author  Maurizio Cimadamore
+ * @compile/fail/ref=TargetType13.out -XDrawDiagnostics TargetType13.java
+ */
+
+class TargetType13 {
+
+    interface SAM<throws E> {
+       void m(Integer x) throws E;
+    }
+
+    static <throws E> void call(SAM<E> s) throws E { }
+
+    void test() {
+        call(#(i) { if (i == 2) throw new Exception(); return; });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType13.out	Mon Aug 23 13:48:15 2010 +0100
@@ -0,0 +1,2 @@
+TargetType13.java:40:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
+1 error