6363import com .sun .source .util .TreePath ;
6464import com .sun .tools .javac .code .Symbol ;
6565import com .sun .tools .javac .code .Type ;
66- import com .sun .tools .javac .tree .JCTree ;
6766import com .sun .tools .javac .tree .JCTree .JCAssign ;
6867import com .sun .tools .javac .tree .JCTree .JCAssignOp ;
6968import com .sun .tools .javac .tree .Pretty ;
@@ -529,8 +528,7 @@ private static SuggestedFix convertDirectlyToExpressionSwitch(
529528 // For readability, filter out trailing unlabelled break statement because these become a
530529 // No-Op when used inside expression switches
531530 ImmutableList <StatementTree > filteredStatements = filterOutRedundantBreak (caseTree );
532- String transformedBlockSource =
533- transformBlock (caseTree , state , cases , caseIndex , filteredStatements );
531+ String transformedBlockSource = transformBlock (caseTree , state , filteredStatements );
534532
535533 if (firstCaseInGroup ) {
536534 groupedCaseCommentsAccumulator = new StringBuilder ();
@@ -623,7 +621,7 @@ private static SuggestedFix convertToReturnSwitch(
623621 boolean isDefaultCase = caseTree .getExpression () == null ;
624622
625623 String transformedBlockSource =
626- transformReturnOrThrowBlock (caseTree , state , cases , caseIndex , getStatements (caseTree ));
624+ transformReturnOrThrowBlock (caseTree , state , getStatements (caseTree ));
627625
628626 if (firstCaseInGroup ) {
629627 groupedCaseCommentsAccumulator = new StringBuilder ();
@@ -725,7 +723,7 @@ private static int findBlockStatementIndex(TreePath treePath, BlockTree blockTre
725723 /**
726724 * Transforms the supplied statement switch into an assignment switch style of expression switch.
727725 * In this conversion, each nontrivial statement block is mapped one-to-one to a new expression on
728- * the right-hand side of the arrow. Comments are presevered where possible. Precondition: the
726+ * the right-hand side of the arrow. Comments are preserved where possible. Precondition: the
729727 * {@code AnalysisResult} for the {@code SwitchTree} must have deduced that this conversion is
730728 * possible.
731729 */
@@ -760,7 +758,7 @@ private static SuggestedFix convertToAssignmentSwitch(
760758 ImmutableList <StatementTree > filteredStatements = filterOutRedundantBreak (caseTree );
761759
762760 String transformedBlockSource =
763- transformAssignOrThrowBlock (caseTree , state , cases , caseIndex , filteredStatements );
761+ transformAssignOrThrowBlock (caseTree , state , filteredStatements );
764762
765763 if (firstCaseInGroup ) {
766764 groupedCaseCommentsAccumulator = new StringBuilder ();
@@ -870,17 +868,13 @@ private static List<? extends StatementTree> getStatements(CaseTree caseTree) {
870868
871869 /** Transforms code for this case into the code under an expression switch. */
872870 private static String transformBlock (
873- CaseTree caseTree ,
874- VisitorState state ,
875- List <? extends CaseTree > cases ,
876- int caseIndex ,
877- ImmutableList <StatementTree > filteredStatements ) {
871+ CaseTree caseTree , VisitorState state , ImmutableList <StatementTree > filteredStatements ) {
878872
879873 StringBuilder transformedBlockBuilder = new StringBuilder ();
880874 int codeBlockStart = extractLhsComments (caseTree , state , transformedBlockBuilder );
881875 int codeBlockEnd =
882876 filteredStatements .isEmpty ()
883- ? getBlockEnd (state , caseTree , cases , caseIndex )
877+ ? getBlockEnd (state , caseTree )
884878 : state .getEndPosition (Streams .findLast (filteredStatements .stream ()).get ());
885879 transformedBlockBuilder .append (state .getSourceCode (), codeBlockStart , codeBlockEnd );
886880
@@ -913,19 +907,29 @@ private static int extractLhsComments(
913907 * Finds the position in source corresponding to the end of the code block of the supplied {@code
914908 * caseIndex} within all {@code cases}.
915909 */
916- private static int getBlockEnd (
917- VisitorState state , CaseTree caseTree , List <? extends CaseTree > cases , int caseIndex ) {
910+ private static int getBlockEnd (VisitorState state , CaseTree caseTree ) {
918911
919- if (caseIndex == cases .size () - 1 ) {
912+ List <? extends StatementTree > statements = caseTree .getStatements ();
913+ if (statements == null || statements .size () != 1 ) {
914+ return state .getEndPosition (caseTree );
915+ }
916+
917+ // Invariant: statements.size() == 1
918+ StatementTree onlyStatement = getOnlyElement (statements );
919+ if (!onlyStatement .getKind ().equals (BLOCK )) {
920920 return state .getEndPosition (caseTree );
921921 }
922922
923- return ((JCTree ) cases .get (caseIndex + 1 )).getStartPosition ();
923+ // The RHS of the case has a single enclosing block { ... }
924+ List <? extends StatementTree > blockStatements = ((BlockTree ) onlyStatement ).getStatements ();
925+ return blockStatements .isEmpty ()
926+ ? state .getEndPosition (caseTree )
927+ : state .getEndPosition (blockStatements .get (blockStatements .size () - 1 ));
924928 }
925929
926930 /**
927931 * Determines whether the supplied {@code case}'s logic should be expressed on the right of the
928- * arrow symbol without braces, incorporating both language and readabilitiy considerations.
932+ * arrow symbol without braces, incorporating both language and readability considerations.
929933 */
930934 private static boolean shouldTransformCaseWithoutBraces (
931935 ImmutableList <StatementTree > statementTrees ) {
@@ -995,17 +999,13 @@ private static boolean isSwitchExhaustive(
995999 * transformed to {@code x+1;}.
9961000 */
9971001 private static String transformReturnOrThrowBlock (
998- CaseTree caseTree ,
999- VisitorState state ,
1000- List <? extends CaseTree > cases ,
1001- int caseIndex ,
1002- List <? extends StatementTree > statements ) {
1002+ CaseTree caseTree , VisitorState state , List <? extends StatementTree > statements ) {
10031003
10041004 StringBuilder transformedBlockBuilder = new StringBuilder ();
10051005 int codeBlockStart ;
10061006 int codeBlockEnd =
10071007 statements .isEmpty ()
1008- ? getBlockEnd (state , caseTree , cases , caseIndex )
1008+ ? getBlockEnd (state , caseTree )
10091009 : state .getEndPosition (Streams .findLast (statements .stream ()).get ());
10101010
10111011 if (statements .size () == 1 && statements .get (0 ).getKind ().equals (RETURN )) {
@@ -1028,17 +1028,13 @@ private static String transformReturnOrThrowBlock(
10281028 * {@code >>=}).
10291029 */
10301030 private static String transformAssignOrThrowBlock (
1031- CaseTree caseTree ,
1032- VisitorState state ,
1033- List <? extends CaseTree > cases ,
1034- int caseIndex ,
1035- List <? extends StatementTree > statements ) {
1031+ CaseTree caseTree , VisitorState state , List <? extends StatementTree > statements ) {
10361032
10371033 StringBuilder transformedBlockBuilder = new StringBuilder ();
10381034 int codeBlockStart ;
10391035 int codeBlockEnd =
10401036 statements .isEmpty ()
1041- ? getBlockEnd (state , caseTree , cases , caseIndex )
1037+ ? getBlockEnd (state , caseTree )
10421038 : state .getEndPosition (Streams .findLast (statements .stream ()).get ());
10431039
10441040 if (!statements .isEmpty () && statements .get (0 ).getKind ().equals (EXPRESSION_STATEMENT )) {
0 commit comments