8211148: var in implicit lambdas shouldn't be accepted for source < 11
authorvromero
Thu, 04 Oct 2018 08:37:08 -0700
changeset 52016 9ea22a0f9540
parent 52015 821bfc24d750
child 52017 d3424ddad792
8211148: var in implicit lambdas shouldn't be accepted for source < 11 Reviewed-by: mcimadamore
src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
test/langtools/tools/javac/diags/examples/VarInImplicitLambda.java
test/langtools/tools/javac/lambda/LambdaParserTest.java
test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.java
test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.out
test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01_source10.out
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java	Thu Oct 04 08:45:21 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java	Thu Oct 04 08:37:08 2018 -0700
@@ -180,6 +180,7 @@
         UNDERSCORE_IDENTIFIER(MIN, JDK8),
         PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL),
         LOCAL_VARIABLE_TYPE_INFERENCE(JDK10),
+        VAR_SYNTAX_IMPLICIT_LAMBDAS(JDK11, Fragments.FeatureVarSyntaxInImplicitLambda, DiagKind.PLURAL),
         IMPORT_ON_DEMAND_OBSERVABLE_PACKAGES(JDK1_2, JDK8),
         SWITCH_MULTIPLE_CASE_LABELS(JDK12, Fragments.FeatureMultipleCaseLabels, DiagKind.PLURAL),
         SWITCH_RULE(JDK12, Fragments.FeatureSwitchRules, DiagKind.PLURAL),
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 04 08:45:21 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Oct 04 08:37:08 2018 -0700
@@ -1783,7 +1783,9 @@
                 if (param.vartype != null &&
                         isRestrictedLocalVarTypeName(param.vartype, false) &&
                         param.vartype.hasTag(TYPEARRAY)) {
-                    log.error(DiagnosticFlag.SYNTAX, param.pos, Errors.VarNotAllowedArray);
+                    log.error(DiagnosticFlag.SYNTAX, param.pos,
+                        Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source)
+                            ? Errors.VarNotAllowedArray : Errors.VarNotAllowedHere);
                 }
                 lambdaClassifier.addParameter(param);
                 if (lambdaClassifier.result() == LambdaParameterKind.ERROR) {
@@ -1794,7 +1796,9 @@
                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment));
             }
             for (JCVariableDecl param: params) {
-                if (param.vartype != null && isRestrictedLocalVarTypeName(param.vartype, true)) {
+                if (param.vartype != null
+                        && isRestrictedLocalVarTypeName(param.vartype, true)) {
+                    checkSourceLevel(param.pos, Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS);
                     param.startPos = TreeInfo.getStartPos(param.vartype);
                     param.vartype = null;
                 }
@@ -1804,9 +1808,9 @@
     }
 
     enum LambdaParameterKind {
-        EXPLICIT(0),
-        IMPLICIT(1),
-        VAR(2),
+        VAR(0),
+        EXPLICIT(1),
+        IMPLICIT(2),
         ERROR(-1);
 
         private final int index;
@@ -1816,11 +1820,11 @@
         }
     }
 
-    private final static Fragment[][] decisionTable = new Fragment[][]{
-        /*              EXPLICIT                         IMPLICIT                         VAR  */
-        /* EXPLICIT */ {null,                            ImplicitAndExplicitNotAllowed,   VarAndExplicitNotAllowed},
-        /* IMPLICIT */ {ImplicitAndExplicitNotAllowed,   null,                            VarAndImplicitNotAllowed},
-        /* VAR      */ {VarAndExplicitNotAllowed,        VarAndImplicitNotAllowed,        null}
+    private final static Fragment[][] decisionTable = new Fragment[][] {
+        /*              VAR                              EXPLICIT                         IMPLICIT  */
+        /* VAR      */ {null,                            VarAndExplicitNotAllowed,        VarAndImplicitNotAllowed},
+        /* EXPLICIT */ {VarAndExplicitNotAllowed,        null,                            ImplicitAndExplicitNotAllowed},
+        /* IMPLICIT */ {VarAndImplicitNotAllowed,        ImplicitAndExplicitNotAllowed,   null},
     };
 
     class LambdaClassifier {
@@ -1849,7 +1853,10 @@
             } else if (kind != newKind && kind != LambdaParameterKind.ERROR) {
                 LambdaParameterKind currentKind = kind;
                 kind = LambdaParameterKind.ERROR;
-                diagFragment = decisionTable[currentKind.index][newKind.index];
+                boolean varIndex = currentKind.index == LambdaParameterKind.VAR.index ||
+                        newKind.index == LambdaParameterKind.VAR.index;
+                diagFragment = Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source) || !varIndex ?
+                        decisionTable[currentKind.index][newKind.index] : null;
             }
         }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 04 08:45:21 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Oct 04 08:37:08 2018 -0700
@@ -2832,6 +2832,9 @@
 compiler.misc.feature.raw.string.literals=\
     raw string literals
 
+compiler.misc.feature.var.syntax.in.implicit.lambda=\
+    var syntax in implicit lambdas
+
 compiler.warn.underscore.as.identifier=\
     as of release 9, ''_'' is a keyword, and may not be used as an identifier
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/VarInImplicitLambda.java	Thu Oct 04 08:37:08 2018 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+// key: compiler.misc.feature.var.syntax.in.implicit.lambda
+// key: compiler.err.feature.not.supported.in.source.plural
+// options: -source 10 -Xlint:-options
+
+import java.util.function.*;
+
+class VarInImplicitLambda {
+    IntBinaryOperator f2 = (var x, y) -> x + y;
+}
--- a/test/langtools/tools/javac/lambda/LambdaParserTest.java	Thu Oct 04 08:45:21 2018 -0700
+++ b/test/langtools/tools/javac/lambda/LambdaParserTest.java	Thu Oct 04 08:37:08 2018 -0700
@@ -107,8 +107,8 @@
     }
 
     enum SourceKind {
-        SOURCE_9("9"),
-        SOURCE_10("10");
+        SOURCE_10("10"),
+        SOURCE_11("11");
 
         String sourceNumber;
 
@@ -121,9 +121,9 @@
 
         IMPLICIT_1("", ExplicitKind.IMPLICIT),
         IMPLICIT_2("var", ExplicitKind.IMPLICIT_VAR),
-        EXPLIICT_SIMPLE("A", ExplicitKind.EXPLICIT),
-        EXPLIICT_SIMPLE_ARR1("A[]", ExplicitKind.EXPLICIT),
-        EXPLIICT_SIMPLE_ARR2("A[][]", ExplicitKind.EXPLICIT),
+        EXPLICIT_SIMPLE("A", ExplicitKind.EXPLICIT),
+        EXPLICIT_SIMPLE_ARR1("A[]", ExplicitKind.EXPLICIT),
+        EXPLICIT_SIMPLE_ARR2("A[][]", ExplicitKind.EXPLICIT),
         EXPLICIT_VARARGS("A...", ExplicitKind.EXPLICIT),
         EXPLICIT_GENERIC1("A<X>", ExplicitKind.EXPLICIT),
         EXPLICIT_GENERIC2("A<? extends X, ? super Y>", ExplicitKind.EXPLICIT),
@@ -157,13 +157,7 @@
         }
 
         ExplicitKind explicitKind(SourceKind sk) {
-            switch (explicitKind) {
-                case IMPLICIT_VAR:
-                    return (sk == SourceKind.SOURCE_9) ?
-                            ExplicitKind.EXPLICIT : ExplicitKind.IMPLICIT_VAR;
-                default:
-                    return explicitKind;
-            }
+            return explicitKind;
         }
     }
 
@@ -299,6 +293,15 @@
         errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
                 lk.arity() > 0;
 
+        for (int i = 0; i < lk.arity(); i++) {
+            if (!lk.isShort() &&
+                    pks[i].explicitKind(sk) == LambdaParameterKind.ExplicitKind.IMPLICIT_VAR &&
+                    sk == SourceKind.SOURCE_10) {
+                errorExpected = true;
+                break;
+            }
+        }
+
         if (errorExpected != res.hasErrors()) {
             fail("invalid diagnostics for source:\n" +
                 res.compilationInfo() +
--- a/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.java	Thu Oct 04 08:45:21 2018 -0700
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.java	Thu Oct 04 08:37:08 2018 -0700
@@ -3,6 +3,7 @@
  * @bug 8198512 8199327
  * @summary compiler support for local-variable syntax for lambda parameters
  * @compile/fail/ref=VarInImplicitLambdaNegTest01.out -XDrawDiagnostics VarInImplicitLambdaNegTest01.java
+ * @compile/fail/ref=VarInImplicitLambdaNegTest01_source10.out -source 10 -XDrawDiagnostics VarInImplicitLambdaNegTest01.java
  */
 
 import java.util.function.*;
--- a/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.out	Thu Oct 04 08:45:21 2018 -0700
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01.out	Thu Oct 04 08:37:08 2018 -0700
@@ -1,6 +1,6 @@
-VarInImplicitLambdaNegTest01.java:11:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
 VarInImplicitLambdaNegTest01.java:12:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
-VarInImplicitLambdaNegTest01.java:13:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.explicit.not.allowed)
-VarInImplicitLambdaNegTest01.java:14:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
-VarInImplicitLambdaNegTest01.java:16:52: compiler.err.var.not.allowed.array
+VarInImplicitLambdaNegTest01.java:13:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.implicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:14:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.var.and.explicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:17:52: compiler.err.var.not.allowed.array
 5 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01_source10.out	Thu Oct 04 08:37:08 2018 -0700
@@ -0,0 +1,6 @@
+- compiler.warn.source.no.bootclasspath: 10
+VarInImplicitLambdaNegTest01.java:12:36: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.var.syntax.in.implicit.lambda), 10, 11
+VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed)
+VarInImplicitLambdaNegTest01.java:17:52: compiler.err.var.not.allowed.here
+3 errors
+1 warning