Skip to content

Commit 4e95f40

Browse files
authored
Support JDT's implicit yield in switch statements (#10100)
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 See #10059
1 parent ae25120 commit 4e95f40

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,13 @@ public void endVisit(YieldStatement x, BlockScope scope) {
547547
try {
548548
SourceInfo info = makeSourceInfo(x);
549549
JExpression expression = pop(x.expression);
550-
push(new JYieldStatement(info, expression));
550+
if (x.switchExpression == null) {
551+
// This is an implicit 'yield' in a case with an arrow - synthesize a break instead and
552+
// wrap with a block so that the child count in JDT and GWT matches.
553+
push(new JBlock(info, expression.makeStatement(), new JBreakStatement(info, null)));
554+
} else {
555+
push(new JYieldStatement(info, expression));
556+
}
551557
} catch (Throwable e) {
552558
throw translateException(x, e);
553559
}

user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java17Test.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,4 +494,50 @@ public void testInlinedStringConstantsInCase() {
494494
};
495495
assertEquals(4, value);
496496
}
497+
498+
// https://github.com/gwtproject/gwt/issues/10044
499+
public void testCaseArrowLabelsVoidExpression() {
500+
// Each switch is extracted to its own method to avoid the early return bug.
501+
assertEquals("success", arrowWithVoidExpr());
502+
503+
// Arrow with non-void expr
504+
assertEquals("success", arrowWithStringExpr());
505+
assertEquals("success", arrowWithIntExpr());
506+
507+
// Arrow with a statement - doesn't fail as part of this bug. This exists to verify
508+
// that JDT won't give us a yield with a statement somehow.
509+
assertEquals("success", arrowWithStatement());
510+
}
511+
512+
private static String arrowWithVoidExpr() {
513+
switch(0) {
514+
case 0 -> assertTrue(true);
515+
};
516+
return "success";
517+
}
518+
519+
private static String arrowWithStringExpr() {
520+
switch(0) {
521+
case 0 -> new Object().toString();
522+
};
523+
return "success";
524+
}
525+
526+
private static String arrowWithIntExpr() {
527+
switch(0) {
528+
case 0 -> new Object().hashCode();
529+
};
530+
return "success";
531+
}
532+
533+
private static String arrowWithStatement() {
534+
switch(0) {
535+
case 0 -> {
536+
if (true) {
537+
new Object().toString();
538+
}
539+
}
540+
};
541+
return "success";
542+
}
497543
}

user/test/com/google/gwt/dev/jjs/test/Java17Test.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ public void testSwitchExprInlining() {
121121
public void testInlinedStringConstantsInCase() {
122122
assertFalse(isGwtSourceLevel17());
123123
}
124+
public void testCaseArrowLabelsVoidExpression() {
125+
assertFalse(isGwtSourceLevel17());
126+
}
124127

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

0 commit comments

Comments
 (0)