diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java index f887e4d9975..384cd8fb7f9 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java @@ -518,9 +518,9 @@ public TypeBinding resolveType(BlockScope scope) { return null; } else { if (this.originalValueIfTrueType.kind() == Binding.POLY_TYPE) - this.originalValueIfTrueType = this.valueIfTrue.resolveType(scope); + this.originalValueIfTrueType = this.valueIfTrue.resolveTypeWithBindings(this.condition.bindingsWhenTrue(), scope); if (this.originalValueIfFalseType.kind() == Binding.POLY_TYPE) - this.originalValueIfFalseType = this.valueIfFalse.resolveType(scope); + this.originalValueIfFalseType = this.valueIfFalse.resolveTypeWithBindings(this.condition.bindingsWhenFalse(), scope); if (this.originalValueIfTrueType == null || !this.originalValueIfTrueType.isValidBinding()) return this.resolvedType = null; @@ -814,8 +814,27 @@ public boolean isPolyExpression() throws UnsupportedOperationException { @Override public boolean isCompatibleWith(TypeBinding left, Scope scope) { - return isPolyExpression() ? this.valueIfTrue.isCompatibleWith(left, scope) && this.valueIfFalse.isCompatibleWith(left, scope) : + if (!isPolyExpression()) super.isCompatibleWith(left, scope); + + scope.include(this.condition.bindingsWhenTrue()); + try { + if (!this.valueIfTrue.isCompatibleWith(left, scope)) + return false; + } finally { + scope.exclude(this.condition.bindingsWhenTrue()); + } + + scope.include(this.condition.bindingsWhenFalse()); + try { + if (!this.valueIfFalse.isCompatibleWith(left, scope)) + return false; + } finally { + scope.exclude(this.condition.bindingsWhenFalse()); + } + + return true; + } @Override diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java index 761b1b9fa04..63d7841b6aa 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java @@ -1460,23 +1460,4 @@ public void reportClashingDeclarations(LocalVariableBinding [] left, LocalVariab public boolean resolvingGuardExpression() { return this.resolvingGuardExpression; } - -public void include(LocalVariableBinding[] bindings) { - // `this` is assumed to be populated with bindings. - if (bindings != null) { - for (LocalVariableBinding binding : bindings) { - binding.modifiers &= ~ExtraCompilerModifiers.AccOutOfFlowScope; - } - } -} - -public void exclude(LocalVariableBinding[] bindings) { - // `this` is assumed to be populated with bindings. - if (bindings != null) { - for (LocalVariableBinding binding : bindings) { - binding.modifiers |= ExtraCompilerModifiers.AccOutOfFlowScope; - } - } -} - } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java index 383b0b116d1..fe5bbebe33b 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -5797,4 +5797,21 @@ public List collectClassesBeingInitialized() { return list; } + public void include(LocalVariableBinding[] bindings) { + // `this` is assumed to be populated with bindings. + if (bindings != null) { + for (LocalVariableBinding binding : bindings) { + binding.modifiers &= ~ExtraCompilerModifiers.AccOutOfFlowScope; + } + } + } + + public void exclude(LocalVariableBinding[] bindings) { + // `this` is assumed to be populated with bindings. + if (bindings != null) { + for (LocalVariableBinding binding : bindings) { + binding.modifiers |= ExtraCompilerModifiers.AccOutOfFlowScope; + } + } + } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java index 2e1d5eeaaae..97553036bd2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/InstanceofPrimaryPatternTest.java @@ -15,7 +15,6 @@ import java.util.Map; import junit.framework.Test; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; public class InstanceofPrimaryPatternTest extends AbstractRegressionTest { @@ -35,26 +34,7 @@ public static Test suite() { public InstanceofPrimaryPatternTest(String testName){ super(testName); } - // Enables the tests to run individually - protected Map getCompilerOptions(boolean preview) { - Map defaultOptions = super.getCompilerOptions(); - if (this.complianceLevel >= ClassFileConstants.getLatestJDKLevel() - && preview) { - defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED); - } - return defaultOptions; - } - - protected Map getCompilerOptions() { - return getCompilerOptions(true); - } - @Override - protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions) { - if(!isJRE17Plus) - return; - runConformTest(testFiles, expectedOutput, customOptions, new String[] {"--enable-preview"}, JAVAC_OPTIONS); - } protected void runNegativeTest( String[] testFiles, String expectedCompilerLog, @@ -71,7 +51,6 @@ protected void runNegativeTest( runner.runNegativeTest(); } public void test001() { - Map options = getCompilerOptions(true); runConformTest( new String[] { "X.java", @@ -86,8 +65,7 @@ public void test001() { " }\n" + "}\n", }, - "Hello World!", - options); + "Hello World!"); } public void test002() { String expectedDiagnostics = this.complianceLevel < ClassFileConstants.JDK20 ? @@ -670,4 +648,89 @@ private void foo(String x) { ---------- """); } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3222 + // [Patterns][Ternary] Pattern binding variable not recognized in poly conditional operator expression + public void testIssue3222() { + runConformTest( + new String[] { + "X.java", + """ + public class X { + + interface I { + int foo(); + } + + static void foo(I i) { + System.out.println(i.foo()); + } + + public static void main(String[] args) { + foo(args instanceof String [] argv ? () -> argv.length + 13 : () -> 42); + } + + } + """ + }, + "13"); + } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3222 + // [Patterns][Ternary] Pattern binding variable not recognized in poly conditional operator expression + public void testIssue3222_2() { + runConformTest( + new String[] { + "X.java", + """ + public class X { + + interface I { + int foo(); + } + + static void foo(I i) { + System.out.println(i.foo()); + } + + public static void main(String[] args) { + foo(!(args instanceof String [] argv) ? () -> 42 : () -> argv.length + 13); + } + + } + """ + }, + "13"); + } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3222 + // [Patterns][Ternary] Pattern binding variable not recognized in poly conditional operator expression + public void testIssue3222_3() { + runConformTest( + new String[] { + "X.java", + """ + import java.util.function.Supplier; + + public class X { + interface I { + int foo(Supplier arg); + default int foo(Object arg) { + return 13; + } + } + public X() { + super(); + } + public static void main(String[] argv) { + int i = ((I) (x) -> { + return x.get(); + }).foo((argv instanceof String [] args ? () -> args.length + 42 : (Supplier) null)); + System.out.println(i); + } + } + """ + }, + "42"); + } } \ No newline at end of file