Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Arthanareeswaran2020-05-05 17:31:13 +0000
committerJay Arthanareeswaran2020-05-06 03:44:50 +0000
commit27a3363782077f04200df5641b28cd5beb4a24af (patch)
tree322247e9dd7516e3d80647d4faff650885c81154
parent261283cb409f0bedd24b6e6d1b920375f2d487b0 (diff)
downloadeclipse.jdt.core-27a3363782077f04200df5641b28cd5beb4a24af.tar.gz
eclipse.jdt.core-27a3363782077f04200df5641b28cd5beb4a24af.tar.xz
eclipse.jdt.core-27a3363782077f04200df5641b28cd5beb4a24af.zip
Bug 562758 - [14] Pattern variable conflicts with lambda parameter even
when not in scope Change-Id: I151a46e258131a56a358065b909fd09b3c692603 Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching14Test.java72
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java4
4 files changed, 87 insertions, 4 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching14Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching14Test.java
index 2a8383fde1..9dc03a4a46 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching14Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PatternMatching14Test.java
@@ -2211,7 +2211,8 @@ public class PatternMatching14Test extends AbstractRegressionTest {
"PASS",
compilerOptions);
}
- public void _test056() {
+ // Positive - Test conflicting pattern variable and lambda argument in for loop
+ public void test056() {
Map<String, String> compilerOptions = getCompilerOptions(true);
runConformTest(
new String[] {
@@ -2240,6 +2241,7 @@ public class PatternMatching14Test extends AbstractRegressionTest {
"PASS",
compilerOptions);
}
+ // Positive - Test conflicting pattern variable and lambda argument in for loop (block)
public void test056a() {
Map<String, String> compilerOptions = getCompilerOptions(true);
runConformTest(
@@ -2272,6 +2274,74 @@ public class PatternMatching14Test extends AbstractRegressionTest {
"PASS",
compilerOptions);
}
+ // Positive - Test conflicting pattern variable and lambda argument in if
+ public void test056b() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ runConformTest(
+ new String[] {
+ "X.java",
+ "@SuppressWarnings(\"preview\")\n" +
+ "public class X {\n" +
+ " public static int impl(I a) {\n" +
+ " return a.foo(\"Default\");\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " String result = \"\";\n" +
+ " Object obj = \"a\";\n" +
+ " if (!(obj instanceof String a)) {\n" +
+ " int i = impl(a -> a.length());\n" +
+ " }\n" +
+ " if (!result.equals(\"\"))\n" +
+ " System.out.println(\"FAIL\");\n" +
+ " else\n" +
+ " System.out.println(\"PASS\");\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {\n" +
+ " int foo(String s);\n" +
+ "}\n",
+ },
+ "PASS",
+ compilerOptions);
+ }
+ // Positive - Test conflicting pattern variable and lambda argument in if
+ public void test056d() {
+ Map<String, String> compilerOptions = getCompilerOptions(true);
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "@SuppressWarnings(\"preview\")\n" +
+ "public class X {\n" +
+ " public static int impl(I a) {\n" +
+ " return a.foo(\"Default\");\n" +
+ " }\n" +
+ " public static void main(String argv[]) {\n" +
+ " String result = \"\";\n" +
+ " Object obj = \"a\";\n" +
+ " for (int i = 0; (obj instanceof String a); i = impl(a -> a.length())) {\n" +
+ " obj = null;\n" +
+ " }\n" +
+ " if (!result.equals(\"\"))\n" +
+ " System.out.println(\"FAIL\");\n" +
+ " else\n" +
+ " System.out.println(\"PASS\");\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {\n" +
+ " int foo(String s);\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 9)\n" +
+ " for (int i = 0; (obj instanceof String a); i = impl(a -> a.length())) {\n" +
+ " ^\n" +
+ "Lambda expression\'s parameter a cannot redeclare another local variable defined in an enclosing scope. \n" +
+ "----------\n",
+ "",
+ null,
+ true,
+ compilerOptions);
+ }
/*
* Test we report only one duplicate variable, i.e., in THEN stmt
* where pattern variable is in scope.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 93955b1419..91e91be98d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -240,6 +240,9 @@ public abstract class AbstractMethodDeclaration
}
}
}
+ if (methodArguments[i].duplicateCheckObligation != null) {
+ methodArguments[i].duplicateCheckObligation.accept(flowInfo);
+ }
// tag parameters as being set:
flowInfo.markAsDefinitelyAssigned(methodArguments[i].binding);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
index 82ae705d15..2a00cbc764 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -118,7 +118,15 @@ public class Argument extends LocalDeclaration {
final boolean localExists = existingVariable instanceof LocalVariableBinding;
if (localExists && this.hiddenVariableDepth == 0) {
if ((this.bits & ASTNode.ShadowsOuterLocal) != 0 && scope.isLambdaSubscope()) {
- scope.problemReporter().lambdaRedeclaresArgument(this);
+ if ((((LocalVariableBinding) existingVariable).modifiers & ExtraCompilerModifiers.AccPatternVariable) != 0) {
+ this.duplicateCheckObligation = (flowInfo) -> {
+ if (flowInfo.isDefinitelyAssigned((LocalVariableBinding) existingVariable)) {
+ scope.problemReporter().lambdaRedeclaresArgument(this);
+ }
+ };
+ } else {
+ scope.problemReporter().lambdaRedeclaresArgument(this);
+ }
} else if (scope.referenceContext instanceof CompactConstructorDeclaration) {
// skip error reporting - hidden params - already reported in record components
} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index 4a889766c2..de737e275e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -309,8 +309,10 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
Binding existingVariable = scope.getBinding(this.name, Binding.VARIABLE, this, false /*do not resolve hidden field*/);
if (existingVariable != null && existingVariable.isValidBinding()){
boolean localExists = existingVariable instanceof LocalVariableBinding;
- if (localExists && (((LocalVariableBinding) existingVariable).modifiers & ExtraCompilerModifiers.AccPatternVariable) != 0)
+ if (localExists && (isPatternVariable
+ || (((LocalVariableBinding) existingVariable).modifiers & ExtraCompilerModifiers.AccPatternVariable) != 0))
{
+ // Do this only if either one of them is a pattern variable.
this.duplicateCheckObligation = (flowInfo) -> {
if (flowInfo.isDefinitelyAssigned((LocalVariableBinding) existingVariable)) {
scope.problemReporter().redefineLocal(this);

Back to the top