diff options
author | Manoj Palat | 2019-01-23 05:01:58 +0000 |
---|---|---|
committer | Manoj Palat | 2019-01-23 08:25:50 +0000 |
commit | 4c49f905582020b5bbace350773b0eba3dc92fb8 (patch) | |
tree | 6067235b81172fc4f318fdffe2e79737dc7003b7 | |
parent | 8af73b7ad8f802149e50026bf795174a23da94e4 (diff) | |
download | eclipse.jdt.core-I20190124-1800.tar.gz eclipse.jdt.core-I20190124-1800.tar.xz eclipse.jdt.core-I20190124-1800.zip |
Bug 541532 - [11] JEP 323: Local-Variable Syntax for Lambda parametersI20190125-1800I20190124-1800I20190124-1235I20190124-0930I20190123-1800
does not work for Function and Predicate
Change-Id: Ibf16295c5d6d262949b6c74fc95a8fbb1b9be9b3
3 files changed, 66 insertions, 35 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP323VarLambdaParamsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP323VarLambdaParamsTest.java index 5bc4f6e811..351fb85796 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP323VarLambdaParamsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP323VarLambdaParamsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 IBM Corporation and others. + * Copyright (c) 2018, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -316,4 +316,29 @@ public void testBug536159_04() throws IOException { "\'var\' is not allowed as an element type of an array\n" + "----------\n"); } +public void testBug541532_01() throws IOException { + runConformTest(new String[] { + "X.java", + "import java.util.Arrays;\n" + + "import java.util.List;\n" + + "\n" + + "public class X {\n" + + "\n" + + " public static void foo(List<String> list) {\n" + + " list.stream()\n" + + " .map((var s) -> s.toLowerCase())\n" + + " .forEach(System.out::println);\n" + + "\n" + + " list.stream()\n" + + " .filter((var s) -> s.length() == 1)\n" + + " .forEach(System.out::println);\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " String[] greetings = {\"hello\", \"world\"};\n" + + " X.foo(Arrays.asList(greetings));\n" + + " }\n" + + "}\n", + "hello\nworld" + }); +} }
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java index 349406911d..08067d8306 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LambdaExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2018 IBM Corporation and others. + * Copyright (c) 2012, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -136,6 +136,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre protected Expression [] resultExpressions = NO_EXPRESSIONS; public InferenceContext18 inferenceContext; // when performing tentative resolve keep a back reference to the driving context private Map<Integer/*sourceStart*/, LocalTypeBinding> localTypes; // support look-up of a local type from this lambda copy + public boolean argumentsTypeVar = false; public LambdaExpression(CompilationResult compilationResult, boolean assistNode, boolean requiresGenericSignature) { @@ -247,7 +248,6 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre public TypeBinding resolveType(BlockScope blockScope, boolean skipKosherCheck) { boolean argumentsTypeElided = argumentsTypeElided(); - boolean argumentsTypeVar = argumentsTypeVar(blockScope); int argumentsLength = this.arguments == null ? 0 : this.arguments.length; if (this.constant != Constant.NotAConstant) { @@ -256,7 +256,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre if (this.original == this) this.ordinal = recordFunctionalType(blockScope); - if (!argumentsTypeElided && !argumentsTypeVar) { + if (!argumentsTypeElided) { for (int i = 0; i < argumentsLength; i++) this.argumentTypes[i] = this.arguments[i].type.resolveType(blockScope, true /* check bounds*/); } @@ -289,7 +289,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre int parametersLength = this.descriptor.parameters.length; if (parametersLength != argumentsLength) { this.scope.problemReporter().lambdaSignatureMismatched(this); - if (argumentsTypeElided || argumentsTypeVar || this.original != this) // no interest in continuing to error check copy. + if (argumentsTypeElided || this.original != this) // no interest in continuing to error check copy. return this.resolvedType = null; // FUBAR, bail out ... else { this.resolvedType = null; // continue to type check. @@ -314,7 +314,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre TypeBinding argumentType; final TypeBinding expectedParameterType = haveDescriptor && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null; - argumentType = (argumentsTypeElided || argumentsTypeVar) ? expectedParameterType : this.argumentTypes[i]; + argumentType = argumentsTypeElided ? expectedParameterType : this.argumentTypes[i]; if (argumentType == null) { argumentsHaveErrors = true; } else if (argumentType == TypeBinding.VOID) { @@ -329,7 +329,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre } } } - if (!argumentsTypeElided && !argumentsTypeVar && !argumentsHaveErrors) { + if (!argumentsTypeElided && !argumentsHaveErrors) { ReferenceBinding groundType = null; ReferenceBinding expectedSAMType = null; if (this.expectedType instanceof IntersectionTypeBinding18) @@ -365,7 +365,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre Argument argument = this.arguments[i]; TypeBinding argumentType; final TypeBinding expectedParameterType = haveDescriptor && i < this.descriptor.parameters.length ? this.descriptor.parameters[i] : null; - argumentType = (argumentsTypeElided || argumentsTypeVar) ? expectedParameterType : this.argumentTypes[i]; + argumentType = argumentsTypeElided ? expectedParameterType : this.argumentTypes[i]; expectedParameterTypes[i] = expectedParameterType; if (argumentType != null && argumentType != TypeBinding.VOID) { if (haveDescriptor && expectedParameterType != null && argumentType.isValidBinding() && TypeBinding.notEquals(argumentType, expectedParameterType)) { @@ -396,7 +396,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre } } } - if (argumentsTypeVar) { + if (this.argumentsTypeVar) { for (int i = 0; i < argumentsLength; ++i) { this.arguments[i].type.resolvedType = expectedParameterTypes[i]; } @@ -408,7 +408,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre this.binding.setParameterAnnotations(parameterAnnotations); } - if (!argumentsTypeElided && !argumentsTypeVar && !argumentsHaveErrors && this.binding.isVarargs()) { + if (!argumentsTypeElided && !argumentsHaveErrors && this.binding.isVarargs()) { if (!this.binding.parameters[this.binding.parameters.length - 1].isReifiable()) { this.scope.problemReporter().possibleHeapPollutionFromVararg(this.arguments[this.arguments.length - 1]); } @@ -438,7 +438,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre } // TODO (stephan): else? (can that happen?) if (haveDescriptor && !argumentsHaveErrors && blockScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) { - if (!argumentsTypeElided && !argumentsTypeVar) { + if (!argumentsTypeElided) { AbstractMethodDeclaration.createArgumentBindings(this.arguments, this.binding, this.scope); // includes validation // no application of null-ness default, hence also no warning regarding redundant null annotation mergeParameterNullAnnotations(blockScope); @@ -533,28 +533,7 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre @Override public boolean argumentsTypeElided() { - return this.arguments.length > 0 && this.arguments[0].hasElidedType(); - } - - private boolean argumentsTypeVar(BlockScope blockScope) { - if (blockScope.compilerOptions().complianceLevel < ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) return false; - boolean retval = false, isVar = false, mixReported = false; - Argument[] args = this.arguments; - for (int i = 0, l = args.length; i < l; ++i) { - Argument arg = args[i]; - TypeReference type = arg.type; - if (type == null) continue; - boolean prev = isVar; - retval |= isVar = type.isTypeNameVar(blockScope); - if (i > 0 && prev != isVar && !mixReported) { // report only once per list - blockScope.problemReporter().varCannotBeMixedWithNonVarParams(isVar ? arg : args[i - 1]); - mixReported = true; - } - if (isVar && (type.dimensions() > 0 || type.extraDimensions() > 0)) { - blockScope.problemReporter().varLocalCannotBeArray(arg); - } - } - return retval; + return (this.arguments.length > 0 && this.arguments[0].hasElidedType()) || this.argumentsTypeVar; } private void analyzeExceptions() { @@ -710,7 +689,6 @@ public class LambdaExpression extends FunctionalExpression implements IPolyExpre if (targetType == null) // assumed to signal another primary error return true; - if (argumentsTypeElided()) return false; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java index 885fc4cc3a..a9e213965a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -941,6 +941,7 @@ protected int valueLambdaNestDepth = -1; private int stateStackLengthStack[] = new int[0]; protected boolean parsingJava8Plus; protected boolean parsingJava9Plus; +protected boolean parsingJava11Plus; protected int unstackedAct = ERROR_ACTION; private boolean haltOnSyntaxError = false; private boolean tolerateDefaultClassMethods = false; @@ -959,6 +960,7 @@ public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) { initializeScanner(); this.parsingJava8Plus = this.options.sourceLevel >= ClassFileConstants.JDK1_8; this.parsingJava9Plus = this.options.sourceLevel >= ClassFileConstants.JDK9; + this.parsingJava11Plus = this.options.sourceLevel >= ClassFileConstants.JDK11; this.astLengthStack = new int[50]; this.expressionLengthStack = new int[30]; this.typeAnnotationLengthStack = new int[30]; @@ -8552,6 +8554,31 @@ protected void consumeLambdaHeader() { this.currentElement.lambdaNestLevel++; } } +private void setArgumentsTypeVar(LambdaExpression lexp) { + Argument[] args = lexp.arguments; + if (!this.parsingJava11Plus || args == null || args.length == 0) { + lexp.argumentsTypeVar = false; + return; + } + + boolean isVar = false, mixReported = false; + for (int i = 0, l = args.length; i < l; ++i) { + Argument arg = args[i]; + TypeReference type = arg.type; + char[][] typeName = type != null ? type.getTypeName() : null; + boolean prev = isVar; + isVar = typeName != null && typeName.length == 1 && + CharOperation.equals(typeName[0], TypeConstants.VAR); + lexp.argumentsTypeVar |= isVar; + if (i > 0 && prev != isVar && !mixReported) { // report only once per list + this.problemReporter().varCannotBeMixedWithNonVarParams(isVar ? arg : args[i - 1]); + mixReported = true; + } + if (isVar && (type.dimensions() > 0 || type.extraDimensions() > 0)) { + this.problemReporter().varLocalCannotBeArray(arg); + } + } +} protected void consumeLambdaExpression() { // LambdaExpression ::= LambdaHeader LambdaBody @@ -8581,6 +8608,7 @@ protected void consumeLambdaExpression() { if (!this.parsingJava8Plus) { problemReporter().lambdaExpressionsNotBelow18(lexp); } + setArgumentsTypeVar(lexp); pushOnExpressionStack(lexp); if (this.currentElement != null) { this.lastCheckPoint = body.sourceEnd + 1; |