Skip to content

Commit

Permalink
Support JDT's implicit yield in switch statements (#10059)
Browse files Browse the repository at this point in the history
JDT generates a yield for arrow cases if the arrow points at a
expression, even though the expression cannot be returned. Synthesize a
block wrapping that expression as a statement, and add a break to the
end of it.

Fixes #10044
  • Loading branch information
niloc132 authored Dec 19, 2024
1 parent 23e73f9 commit 35c4666
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
8 changes: 7 additions & 1 deletion dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,13 @@ public void endVisit(YieldStatement x, BlockScope scope) {
try {
SourceInfo info = makeSourceInfo(x);
JExpression expression = pop(x.expression);
push(new JYieldStatement(info, expression));
if (x.switchExpression == null) {
// This is an implicit 'yield' in a case with an arrow - synthesize a break instead and
// wrap with a block so that the child count in JDT and GWT matches.
push(new JBlock(info, expression.makeStatement(), new JBreakStatement(info, null)));
} else {
push(new JYieldStatement(info, expression));
}
} catch (Throwable e) {
throw translateException(x, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,4 +494,50 @@ public void testInlinedStringConstantsInCase() {
};
assertEquals(4, value);
}

// https://github.com/gwtproject/gwt/issues/10044
public void testCaseArrowLabelsVoidExpression() {
// Each switch is extracted to its own method to avoid the early return bug.
assertEquals("success", arrowWithVoidExpr());

// Arrow with non-void expr
assertEquals("success", arrowWithStringExpr());
assertEquals("success", arrowWithIntExpr());

// Arrow with a statement - doesn't fail as part of this bug. This exists to verify
// that JDT won't give us a yield with a statement somehow.
assertEquals("success", arrowWithStatement());
}

private static String arrowWithVoidExpr() {
switch(0) {
case 0 -> assertTrue(true);
};
return "success";
}

private static String arrowWithStringExpr() {
switch(0) {
case 0 -> new Object().toString();
};
return "success";
}

private static String arrowWithIntExpr() {
switch(0) {
case 0 -> new Object().hashCode();
};
return "success";
}

private static String arrowWithStatement() {
switch(0) {
case 0 -> {
if (true) {
new Object().toString();
}
}
};
return "success";
}
}
3 changes: 3 additions & 0 deletions user/test/com/google/gwt/dev/jjs/test/Java17Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ public void testSwitchExprInlining() {
public void testInlinedStringConstantsInCase() {
assertFalse(isGwtSourceLevel17());
}
public void testCaseArrowLabelsVoidExpression() {
assertFalse(isGwtSourceLevel17());
}

private boolean isGwtSourceLevel17() {
return JUnitShell.getCompilerOptions().getSourceLevel().compareTo(SourceLevel.JAVA17) >= 0;
Expand Down

0 comments on commit 35c4666

Please sign in to comment.