changeset 52894:eaf0bc8fc95c concise-method-declarations

restrict the LHS of a bound method to one of: constant expression, final field
author vromero
date Tue, 16 Oct 2018 10:13:13 -0700
parents 6aac02158033
children 14f96db5f5f8 dd5c0716ba41
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/langtools/tools/javac/concise_methods/ConciseMethodsNegTest01.java test/langtools/tools/javac/concise_methods/ConciseMethodsNegTest01.out test/langtools/tools/javac/concise_methods/NPEQualifierIsCall.java
diffstat 6 files changed, 29 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Oct 08 12:15:34 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Oct 16 10:13:13 2018 -0700
@@ -395,6 +395,10 @@
         return (flags_field & Flags.AccessFlags) == PRIVATE;
     }
 
+    public boolean isFinal() {
+        return (flags_field & Flags.FINAL) != 0;
+    }
+
     public boolean isEnum() {
         return (flags() & ENUM) != 0;
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Oct 08 12:15:34 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Oct 16 10:13:13 2018 -0700
@@ -1118,6 +1118,19 @@
                         log.error(tree.conciseMethodRef, Errors.OnlyMethodReferencesAllowed);
                     }
                     attribTree(tree.conciseMethodRef, localEnv, statInfo);
+                    if (tree.conciseMethodRef.hasTag(REFERENCE)) {
+                        JCMemberReference mreference = (JCMemberReference)tree.conciseMethodRef;
+                        boolean isConstant = mreference.expr.type.constValue() != null;
+                        boolean isArray = mreference.expr.hasTag(Tag.TYPEARRAY);
+                        Symbol sym = TreeInfo.symbol(mreference.expr);
+                        boolean isTypeOrFinalField = sym != null &&
+                                (sym.kind == Kind.TYP ||
+                                sym.owner.kind == Kind.TYP &&
+                                sym.isFinal());
+                        if (!isConstant && !isArray && !isTypeOrFinalField) {
+                            log.error(mreference.expr, Errors.ExpressionMustBeTypeOrConstantOrFinalField);
+                        }
+                    }
                 } else {
                     attribStat(tree.body, localEnv);
                 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Oct 08 12:15:34 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Oct 16 10:13:13 2018 -0700
@@ -3476,3 +3476,6 @@
 
 compiler.err.only.method.references.allowed=\
     the expression after the '=' in a concise method must be a method reference
+
+compiler.err.expression.must.be.type.or.constant.or.final.field=\
+    the expression to the left of '::' must be: type, a constant or a final field
--- a/test/langtools/tools/javac/concise_methods/ConciseMethodsNegTest01.java	Mon Oct 08 12:15:34 2018 -0700
+++ b/test/langtools/tools/javac/concise_methods/ConciseMethodsNegTest01.java	Tue Oct 16 10:13:13 2018 -0700
@@ -4,7 +4,7 @@
  * @compile/fail/ref=ConciseMethodsNegTest01.out -XDrawDiagnostics ConciseMethodsNegTest01.java
  */
 
-class ConciseMethodsNegTest01 {
+class ConciseMethodsNegTest01 implements Runnable {
     int length(String s) = s::length;
 
     abstract int length2(String s) = String::length;
@@ -20,4 +20,10 @@
     private static void all() {}
 
     public static void foo() = ConciseMethodsNegTest01.all();
+
+    public void run() -> null;
+
+    Runnable f(Runnable r) -> r;
+
+    void m() = f(this)::run;
 }
--- a/test/langtools/tools/javac/concise_methods/ConciseMethodsNegTest01.out	Mon Oct 08 12:15:34 2018 -0700
+++ b/test/langtools/tools/javac/concise_methods/ConciseMethodsNegTest01.out	Tue Oct 16 10:13:13 2018 -0700
@@ -4,4 +4,5 @@
 ConciseMethodsNegTest01.java:12:16: compiler.err.native.meth.cant.have.body
 ConciseMethodsNegTest01.java:18:5: compiler.err.constructors.cant.have.concise.body
 ConciseMethodsNegTest01.java:22:59: compiler.err.only.method.references.allowed
-6 errors
+ConciseMethodsNegTest01.java:28:17: compiler.err.expression.must.be.type.or.constant.or.final.field
+7 errors
--- a/test/langtools/tools/javac/concise_methods/NPEQualifierIsCall.java	Mon Oct 08 12:15:34 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2018, 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 the verifier is failing when a field of the enclosing class is accessed from a concise method
- * @compile NPEQualifierIsCall.java
- */
-
-public class NPEQualifierIsCall implements Runnable {
-    public void run() -> null;
-
-    Runnable f(Runnable r) -> r;
-
-    void m() = f(this)::run;
-}