diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java index 10468434b4f..7bfefdbb812 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java @@ -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 } @@ -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 } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java index e19cf5b599a..217c2b21fba 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java @@ -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"); + } }