changeset 854:89631f9e86b7

Method reference bug fixes: *) spurious transitional 292 warnings when using method references *) new semantics of statically qualified method references when used in non-static contexts *) casting a method reference to a SAM type causes ClassCastException
author mcimadamore
date Thu, 06 Jan 2011 13:19:18 +0000
parents f9e407ab55b4
children 9a616df38d88
files src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Lower.java test/tools/javac/lambda/MethodReference14.java test/tools/javac/lambda/MethodReference15.java test/tools/javac/lambda/MethodReference16.java
diffstat 5 files changed, 187 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jan 06 10:13:25 2011 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jan 06 13:19:18 2011 +0000
@@ -2799,9 +2799,7 @@
         Type mtype = tree.meth.type;
         List<Type> args = mtype.getParameterTypes();
         if (!msym.isStatic() &&
-                TreeInfo.isStaticSelector(base, names) &&
-                (Resolve.isStatic(env) ||
-                types.asSuper(env.enclClass.type, msym.owner) == null)) {
+                TreeInfo.isStaticSelector(base, names)) {
             args = args.prepend(base.type);
         }
         return new FunctionType(args,
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Jan 06 10:13:25 2011 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Jan 06 13:19:18 2011 +0000
@@ -42,7 +42,6 @@
 import com.sun.tools.javac.code.Type.*;
 
 import com.sun.tools.javac.jvm.Target;
-import com.sun.tools.javac.main.OptionName;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
@@ -1932,8 +1931,19 @@
 
     private JCMethodInvocation makeImplicitCall(JCExpression left, Name name, List<JCExpression> args, JCExpression restype) {
         assert left.type != null;
-        Symbol funcsym = lookupImplicitMethod(make_pos, name, left.type,
+        Queue<JCDiagnostic> prevDiags = log.deferredDiagnostics;
+        boolean prevDeferredDiags = log.deferDiagnostics;
+        Symbol funcsym = null;
+        try {
+            log.deferredDiagnostics = ListBuffer.lb();
+            log.deferDiagnostics = true;
+            funcsym = lookupImplicitMethod(make_pos, name, left.type,
                                       TreeInfo.types(args), restype.type);
+        }
+        finally {
+            log.deferDiagnostics = prevDeferredDiags;
+            log.deferredDiagnostics = prevDiags;
+        }
         return make.App(make.Select(left, funcsym), args);
     }
 
@@ -2742,7 +2752,8 @@
 
     public void visitTypeCast(JCTypeCast tree) {
         tree.clazz = translate(tree.clazz);
-        if (tree.type.isPrimitive() != tree.expr.type.isPrimitive())
+        if (tree.type.isPrimitive() != tree.expr.type.isPrimitive() ||
+                types.isSameType(tree.expr.type, syms.methodHandleType))
             tree.expr = translate(tree.expr, tree.type);
         else
             tree.expr = translate(tree.expr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference14.java	Thu Jan 06 13:19:18 2011 +0000
@@ -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 casting a method reference to a SAM type does not result in a CCE
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles MethodReference14
+ */
+
+public class MethodReference14 {
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static int assertionCount = 0;
+
+    interface SAM1 {
+        void m();
+    }
+
+    static abstract class SAM2 {
+        abstract void m();
+    }
+
+    static void m() { assertTrue(true); }
+
+    public static void main(String[] args) {
+        SAM1 s1 = (SAM1)MethodReference14#m;
+        s1.m();
+        SAM2 s2 = (SAM2)MethodReference14#m;
+        s2.m();
+        assertTrue(assertionCount == 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference15.java	Thu Jan 06 13:19:18 2011 +0000
@@ -0,0 +1,47 @@
+/*
+ * 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 assignments involving method references do not trigger transitional 292 warnings
+ * @author  Maurizio Cimadamore
+ * @compile -Werror MethodReference15.java
+ */
+
+public class MethodReference15 {
+
+    interface SAM1 {
+        void m();
+    }
+
+    static abstract class SAM2 {
+        abstract void m();
+    }
+
+    static void m() { }
+
+    static void test() {
+        SAM1 s1 = MethodReference14#m;
+        SAM2 s2 = MethodReference14#m;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference16.java	Thu Jan 06 13:19:18 2011 +0000
@@ -0,0 +1,67 @@
+/*
+ * 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 semantics of statically qualified method reference should not depend on the context
+ * @author  Maurizio Cimadamore
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles MethodReference16
+ */
+
+public class MethodReference16 {
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError();
+    }
+
+    static int assertionCount = 0;
+
+    interface SAM1 {
+        void m(MethodReference16 receiver);
+    }
+
+    static abstract class SAM2 {
+        abstract void m(MethodReference16 receiver);
+    }
+
+    void m() { assertTrue(true); }
+
+    void test() {
+        SAM1 s1 = (SAM1)MethodReference16#m;
+        s1.m(this);
+        SAM2 s2 = (SAM2)MethodReference16#m;
+        s2.m(this);
+    }
+
+    public static void main(String[] args) {
+        MethodReference16 rec = new MethodReference16();
+        SAM1 s1 = (SAM1)MethodReference16#m;
+        s1.m(rec);
+        SAM2 s2 = (SAM2)MethodReference16#m;
+        s2.m(rec);
+        rec.test();
+        assertTrue(assertionCount == 4);
+    }
+}