Skip to content

Commit a0fd907

Browse files
mickaelistriarobstryker
authored andcommitted
Use more EitherOrMultiPattern when expected
1 parent 9bf9580 commit a0fd907

File tree

1 file changed

+60
-39
lines changed

1 file changed

+60
-39
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,15 +2567,18 @@ private Statement convertStatement(JCStatement javac, ASTNode parent) {
25672567
private Statement convertSwitchCase(JCCase jcCase) {
25682568
SwitchCase res = this.ast.newSwitchCase();
25692569
commonSettings(res, jcCase);
2570-
if( this.ast.apiLevel >= AST.JLS14_INTERNAL) {
2571-
if (jcCase.getGuard() != null && (jcCase.getLabels().size() > 1 || jcCase.getLabels().get(0) instanceof JCPatternCaseLabel)) {
2572-
GuardedPattern guardedPattern = this.ast.newGuardedPattern();
2573-
guardedPattern.setExpression(convertExpression(jcCase.getGuard()));
2574-
guardedPattern.setRestrictedIdentifierStartPosition(jcCase.guard.getStartPosition() - 5); // javac gives start position without "when " while jdt expects it with
2570+
boolean isSwitchLabeledRule = jcCase.getCaseKind() == CaseKind.RULE;
2571+
if (this.ast.apiLevel >= AST.JLS14_INTERNAL) {
2572+
res.setSwitchLabeledRule(isSwitchLabeledRule);
2573+
}
2574+
if (this.ast.apiLevel >= AST.JLS21_INTERNAL) {
2575+
if (jcCase.getGuard() != null || (jcCase.getLabels().size() > 1 && jcCase.getLabels().stream().anyMatch(JCPatternCaseLabel.class::isInstance))) {
2576+
Pattern pattern = null;
25752577
if (jcCase.getLabels().length() > 1) {
25762578
int start = Integer.MAX_VALUE;
25772579
int end = Integer.MIN_VALUE;
25782580
EitherOrMultiPattern eitherOrMultiPattern = this.ast.newEitherOrMultiPattern();
2581+
pattern = eitherOrMultiPattern;
25792582
for (JCCaseLabel label : jcCase.getLabels()) {
25802583
if (label.pos < start) {
25812584
start = label.pos;
@@ -2589,19 +2592,25 @@ private Statement convertSwitchCase(JCCase jcCase) {
25892592
// skip over any constants, they are not valid anyways
25902593
}
25912594
eitherOrMultiPattern.setSourceRange(start, end - start);
2592-
guardedPattern.setPattern(eitherOrMultiPattern);
25932595
} else if (jcCase.getLabels().length() == 1) {
25942596
if (jcCase.getLabels().get(0) instanceof JCPatternCaseLabel jcPattern) {
2595-
guardedPattern.setPattern(convert(jcPattern.getPattern()));
2597+
pattern = convert(jcPattern.getPattern());
25962598
} else {
25972599
// see same above note regarding guarded case labels using constants
25982600
throw new UnsupportedOperationException("cannot convert case label: " + jcCase.getLabels().get(0));
25992601
}
26002602
}
2601-
int start = guardedPattern.getPattern().getStartPosition();
2602-
int end = guardedPattern.getExpression().getStartPosition() + guardedPattern.getExpression().getLength();
2603-
guardedPattern.setSourceRange(start, end - start);
2604-
res.expressions().add(guardedPattern);
2603+
if (jcCase.getGuard() != null) {
2604+
GuardedPattern guardedPattern = this.ast.newGuardedPattern();
2605+
guardedPattern.setPattern(pattern);
2606+
guardedPattern.setExpression(convertExpression(jcCase.getGuard()));
2607+
guardedPattern.setRestrictedIdentifierStartPosition(jcCase.getGuard().getStartPosition() - "when ".length()); // javac gives start position without "when " while jdt expects it with
2608+
int start = guardedPattern.getPattern().getStartPosition();
2609+
int end = guardedPattern.getExpression().getStartPosition() + guardedPattern.getExpression().getLength();
2610+
guardedPattern.setSourceRange(start, end - start);
2611+
pattern = guardedPattern;
2612+
}
2613+
res.expressions().add(pattern);
26052614
} else {
26062615
if (jcCase.getLabels().length() == 1 && jcCase.getLabels().get(0) instanceof JCPatternCaseLabel jcPattern) {
26072616
Pattern p = convert(jcPattern.getPattern());
@@ -2612,52 +2621,64 @@ private Statement convertSwitchCase(JCCase jcCase) {
26122621
}
26132622
} else {
26142623
// Override length to just be `case blah:`
2615-
for (JCCaseLabel jcLabel : jcCase.getLabels()) {
2616-
switch (jcLabel) {
2617-
case JCConstantCaseLabel constantLabel: {
2618-
if (constantLabel.expr.toString().equals("null")) {
2619-
res.expressions().add(this.ast.newNullLiteral());
2620-
}
2621-
break;
2622-
}
2623-
case JCDefaultCaseLabel defaultCase: {
2624-
if (jcCase.getLabels().size() != 1) {
2625-
res.expressions().add(this.ast.newCaseDefaultExpression());
2626-
}
2627-
break;
2628-
}
2629-
default: {
2630-
break;
2631-
}
2632-
}
2633-
}
2624+
jcCase.getLabels().stream()
2625+
.map(this::convert)
2626+
.forEach(res.expressions()::add);
26342627
int start1 = res.getStartPosition();
2635-
int colon = this.rawText.indexOf(":", start1);
2628+
int colon = this.rawText.indexOf(res.isSwitchLabeledRule() ? "->" : ":", Math.max(start1, ((List<Expression>)res.expressions()).stream().mapToInt(e -> e.getStartPosition() + e.getLength()).max().orElse(-1)));
26362629
if( colon != -1 ) {
26372630
res.setSourceRange(start1, colon - start1 + 1);
26382631
}
26392632
}
2640-
jcCase.getExpressions().stream().map(this::convertExpression).forEach(res.expressions()::add);
26412633
}
2642-
res.setSwitchLabeledRule(jcCase.getCaseKind() == CaseKind.RULE);
26432634
} else {
26442635
// Override length to just be `case blah:`
26452636
int start1 = res.getStartPosition();
2646-
int colon = this.rawText.indexOf(":", start1);
2637+
int colon = this.rawText.indexOf(isSwitchLabeledRule ? "->" : ":", start1);
26472638
if( colon != -1 ) {
26482639
res.setSourceRange(start1, colon - start1 + 1);
26492640
}
2650-
List<JCExpression> l = jcCase.getExpressions();
2651-
if( l.size() == 1 ) {
2652-
res.setExpression(convertExpression(l.get(0)));
2653-
} else if( l.size() == 0 ) {
2654-
res.setExpression(null);
2641+
List<Expression> expressions = new ArrayList<>();
2642+
jcCase.getLabels().stream().map(this::convert).forEach(expressions::add);
2643+
if (expressions.size() == 1 && expressions.getFirst() instanceof CaseDefaultExpression) {
2644+
if (this.ast.apiLevel() < AST.JLS14_INTERNAL) {
2645+
res.setExpression(null);
2646+
}
2647+
} else if (!expressions.isEmpty()) {
2648+
if (this.ast.apiLevel() >= AST.JLS14_INTERNAL) {
2649+
res.expressions().addAll(expressions);
2650+
} else {
2651+
res.setExpression(expressions.getFirst());
2652+
}
26552653
}
26562654
}
2655+
if (this.ast.apiLevel() >= AST.JLS14_INTERNAL && res.expressions().size() == 1 && res.expressions().getFirst() instanceof CaseDefaultExpression) {
2656+
res.expressions().clear();
2657+
}
26572658
// jcCase.getStatements is processed as part of JCSwitch conversion
26582659
return res;
26592660
}
26602661

2662+
private Expression convert(JCCaseLabel javac) {
2663+
if (javac instanceof JCDefaultCaseLabel defaultCase) {
2664+
Expression res = this.ast.newCaseDefaultExpression();
2665+
commonSettings(res, javac);
2666+
return res;
2667+
}
2668+
if (javac instanceof JCPatternCaseLabel jcPattern) {
2669+
Pattern p = convert(jcPattern.getPattern());
2670+
// if( p != null ) {
2671+
// int start = jcPattern.getStartPosition();
2672+
// p.setSourceRange(start, jcPattern.getEndPosition(this.javacCompilationUnit.endPositions)-start);
2673+
// }
2674+
return p;
2675+
}
2676+
if (javac instanceof JCConstantCaseLabel constantLabel) {
2677+
return convertExpression(constantLabel.expr);
2678+
}
2679+
return null;
2680+
}
2681+
26612682
private Expression convertStatementToExpression(JCStatement javac, ASTNode parent) {
26622683
if (javac instanceof JCExpressionStatement jcExpressionStatement) {
26632684
return convertExpression(jcExpressionStatement.getExpression());

0 commit comments

Comments
 (0)