Skip to content

Commit

Permalink
[Enhanced Switch] Problem with switch and enums - incorrect duplicate
Browse files Browse the repository at this point in the history
case error

* Fixes eclipse-jdt#3344
  • Loading branch information
srikanth-sankaran committed Nov 25, 2024
1 parent 2363e0f commit 32b09fd
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public String toString() {
}

private boolean essentiallyQualifiedEnumerator(Expression e, TypeBinding selectorType) { // "Essentially" as in not "superfluously" qualified.
return e instanceof QualifiedNameReference qnr && qnr.binding instanceof FieldBinding field
return e instanceof NameReference reference && reference.binding instanceof FieldBinding field
&& (field.modifiers & ClassFileConstants.AccEnum) != 0 && !TypeBinding.equalsEquals(e.resolvedType, selectorType); // <<-- essential qualification
}

Expand Down Expand Up @@ -135,13 +135,12 @@ private Constant resolveConstantLabel(BlockScope scope, TypeBinding caseType, Ty
if (expression instanceof NameReference reference && reference.binding instanceof FieldBinding field) {
if ((field.modifiers & ClassFileConstants.AccEnum) == 0)
scope.problemReporter().enumSwitchCannotTargetField(reference, field);
else if (reference instanceof QualifiedNameReference) {
if (options.complianceLevel < ClassFileConstants.JDK21)
scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field);
else if (!TypeBinding.equalsEquals(caseType, selectorType)) {
this.swich.switchBits |= SwitchStatement.QualifiedEnum;
return StringConstant.fromValue(CharOperation.toString(reference.getName()));
}
else if (reference instanceof QualifiedNameReference && options.complianceLevel < ClassFileConstants.JDK21)
scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field);

if (!TypeBinding.equalsEquals(caseType, selectorType)) {
this.swich.switchBits |= SwitchStatement.QualifiedEnum;
return StringConstant.fromValue(CharOperation.toString(reference.getName()));
}
return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9507,4 +9507,84 @@ public static void main(String[] args) {
},
"Default");
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3344
// [Enhanced Switch] Problem with switch and enums - incorrect duplicate case error
public void testIssue3344() {
runConformTest(
new String[] {
"Main.java",
"""
import static p.A.A1;
import static p.A.A2;
import static p.B.B1;
import static p.B.B2;
import java.util.Arrays;
import java.util.stream.Stream;
import p.X;
import p.A;
import p.B;
public class Main {
public static void main(String[] args) {
Stream.concat(Arrays.stream(A.values()), Arrays.stream(B.values())).forEach(
x -> { System.out.printf("%s -> %s, %s\\n", x, bad_switch(x), good_switch(x)); }
);
}
static String bad_switch(X x) {
return switch (x) {
case A1 -> "A1";
case A2 -> "A2";
case B1 -> "B1";
case B2 -> "B2";
default -> "unknown";
};
}
static String good_switch(X x) {
return switch (x) {
case A.A1 -> "A1";
case A.A2 -> "A2";
case B.B1 -> "B1";
case B.B2 -> "B2";
default -> "unknown";
};
}
}
""",
"p/A.java",
"""
package p;
public enum A implements X {
A1,
A2,
}
""",
"p/B.java",
"""
package p;
public enum B implements X {
B1,
B2
}
""",
"p/X.java",
"""
package p;
public interface X {
}
"""
},
"A1 -> A1, A1\n" +
"A2 -> A2, A2\n" +
"B1 -> B1, B1\n" +
"B2 -> B2, B2");
}
}

0 comments on commit 32b09fd

Please sign in to comment.