diff options
author | Jay Arthanareeswaran | 2020-05-05 17:31:13 +0000 |
---|---|---|
committer | Jay Arthanareeswaran | 2020-05-06 03:44:50 +0000 |
commit | 27a3363782077f04200df5641b28cd5beb4a24af (patch) | |
tree | 322247e9dd7516e3d80647d4faff650885c81154 | |
parent | 261283cb409f0bedd24b6e6d1b920375f2d487b0 (diff) | |
download | eclipse.jdt.core-27a3363782077f04200df5641b28cd5beb4a24af.tar.gz eclipse.jdt.core-27a3363782077f04200df5641b28cd5beb4a24af.tar.xz eclipse.jdt.core-27a3363782077f04200df5641b28cd5beb4a24af.zip |
when not in scope
Change-Id: I151a46e258131a56a358065b909fd09b3c692603
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
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); |