@@ -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