Skip to content

Commit

Permalink
Pattern binding variable not recognized in poly conditional operator
Browse files Browse the repository at this point in the history
expression

 * Fixes eclipse-jdt#3222
  • Loading branch information
srikanth-sankaran committed Nov 26, 2024
1 parent e1e6a71 commit 86184d0
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5797,4 +5797,21 @@ public List<ClassScope> 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;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -35,26 +34,7 @@ public static Test suite() {
public InstanceofPrimaryPatternTest(String testName){
super(testName);
}
// Enables the tests to run individually
protected Map<String, String> getCompilerOptions(boolean preview) {
Map<String, String> defaultOptions = super.getCompilerOptions();
if (this.complianceLevel >= ClassFileConstants.getLatestJDKLevel()
&& preview) {
defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
}
return defaultOptions;
}

protected Map<String, String> getCompilerOptions() {
return getCompilerOptions(true);
}

@Override
protected void runConformTest(String[] testFiles, String expectedOutput, Map<String, String> customOptions) {
if(!isJRE17Plus)
return;
runConformTest(testFiles, expectedOutput, customOptions, new String[] {"--enable-preview"}, JAVAC_OPTIONS);
}
protected void runNegativeTest(
String[] testFiles,
String expectedCompilerLog,
Expand All @@ -71,7 +51,6 @@ protected void runNegativeTest(
runner.runNegativeTest();
}
public void test001() {
Map<String, String> options = getCompilerOptions(true);
runConformTest(
new String[] {
"X.java",
Expand All @@ -86,8 +65,7 @@ public void test001() {
" }\n" +
"}\n",
},
"Hello World!",
options);
"Hello World!");
}
public void test002() {
String expectedDiagnostics = this.complianceLevel < ClassFileConstants.JDK20 ?
Expand Down Expand Up @@ -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<Integer> 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<Integer>) null));
System.out.println(i);
}
}
"""
},
"42");
}
}

0 comments on commit 86184d0

Please sign in to comment.