Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler has trouble parsing multipattern case label expressions. #3003

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5176,6 +5176,7 @@ public VanguardParser(ProblemReporter reporter) {

// Canonical LALR pushdown automaton identical to Parser.parse() minus side effects of any kind, returns the rule reduced.
protected boolean parse(Goal goal) {
int parenthesized = 0;
this.currentGoal = goal;
try {
int act = START_STATE;
Expand All @@ -5201,6 +5202,10 @@ protected boolean parse(Goal goal) {
this.unstackedAct = act;
try {
this.currentToken = this.scanner.getNextToken();
if (this.currentToken == TokenNameLPAREN)
parenthesized++;
else if (this.currentToken == TokenNameRPAREN)
parenthesized --;
} finally {
this.unstackedAct = ERROR_ACTION;
}
Expand All @@ -5210,6 +5215,10 @@ protected boolean parse(Goal goal) {
this.unstackedAct = act;
try {
this.currentToken = this.scanner.getNextToken();
if (this.currentToken == TokenNameLPAREN)
parenthesized++;
else if (this.currentToken == TokenNameRPAREN)
parenthesized --;
} finally {
this.unstackedAct = ERROR_ACTION;
}
Expand All @@ -5220,6 +5229,15 @@ protected boolean parse(Goal goal) {

// ProcessNonTerminals :
do { /* reduce */
// mimic the unfortunate side effect introduced by org.eclipse.jdt.internal.compiler.parser.Parser.consumeCaseLabelElement(CaseLabelKind)
if (parenthesized == 0 && this.currentToken == TerminalTokens.TokenNameCOMMA && this.scanner.caseStartPosition < this.scanner.startPosition) {
for (int patternRule : Goal.PatternRules) {
if (act == patternRule) {
this.scanner.multiCaseLabelComma = true;
break;
}
}
}
if (goal.hasBeenReached(act, this.currentToken))
return SUCCESS;
if (this.currentToken == TokenNameIdentifier) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -836,4 +836,126 @@ public static void main(String... args) {
""", },
"success");
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2070
// [Switch] Compiler is unable to parse a particular multicase construct
public void testIssue2070() {
runConformTest(
new String[] {
"X.java",
"""
public class X {
public boolean foo(Object o) {
return switch (o) {
case Integer _, Integer[] _ -> true;
default -> false;
};
}
public static void main(String argv[]) {
System.out.println(new X().foo(new Object()));
}
}
"""
},
"false");
}

// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2956
// Unnamed patterns inside of multi case patterns fail to parse
public void testIssue2956() {
runConformTest(
new String[] {
"Main.java",
"""
public class Main {
public sealed interface MyType {
record A() implements MyType {
}

record B(int value) implements MyType {
}

record C() implements MyType {
}
}

public static void main(String[] args) {
MyType myType = new MyType.A();
switch (myType) {
case MyType.A(), MyType.B(_) -> { System.out.println("A or B");}
case MyType.C() -> {}
}
}
}
"""
},
"A or B");
}


// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2956
// Unnamed patterns inside of multi case patterns fail to parse
public void testIssue2956_2() {
runConformTest(
new String[] {
"Main.java",
"""
public class Main {
public sealed interface MyType {
record A() implements MyType {
}

record B(int value) implements MyType {
}

record C() implements MyType {
}
}

public static void main(String[] args) {
MyType myType = new MyType.A();
switch (myType) {
case MyType.A() -> { System.out.println("A");}
case MyType.B(_) -> { System.out.println("B");}
case MyType.C() -> { System.out.println("C");}
}
}
}
"""
},
"A");
}


// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2956
// Unnamed patterns inside of multi case patterns fail to parse
public void testIssue2956_3() {
runConformTest(
new String[] {
"Main.java",
"""
public class Main {
public sealed interface MyType {
record A() implements MyType {
}

record B(int value) implements MyType {
}

record C() implements MyType {
}
}

public static void main(String[] args) {
MyType myType = new MyType.A();
switch (myType) {
case MyType.B(_), MyType.A() -> { System.out.println("A or B");}
case MyType.C() -> {}
}
}
}
"""
},
"A or B");
}
}