63
63
import com .sun .source .util .TreePath ;
64
64
import com .sun .tools .javac .code .Symbol ;
65
65
import com .sun .tools .javac .code .Type ;
66
- import com .sun .tools .javac .tree .JCTree ;
67
66
import com .sun .tools .javac .tree .JCTree .JCAssign ;
68
67
import com .sun .tools .javac .tree .JCTree .JCAssignOp ;
69
68
import com .sun .tools .javac .tree .Pretty ;
@@ -529,8 +528,7 @@ private static SuggestedFix convertDirectlyToExpressionSwitch(
529
528
// For readability, filter out trailing unlabelled break statement because these become a
530
529
// No-Op when used inside expression switches
531
530
ImmutableList <StatementTree > filteredStatements = filterOutRedundantBreak (caseTree );
532
- String transformedBlockSource =
533
- transformBlock (caseTree , state , cases , caseIndex , filteredStatements );
531
+ String transformedBlockSource = transformBlock (caseTree , state , filteredStatements );
534
532
535
533
if (firstCaseInGroup ) {
536
534
groupedCaseCommentsAccumulator = new StringBuilder ();
@@ -623,7 +621,7 @@ private static SuggestedFix convertToReturnSwitch(
623
621
boolean isDefaultCase = caseTree .getExpression () == null ;
624
622
625
623
String transformedBlockSource =
626
- transformReturnOrThrowBlock (caseTree , state , cases , caseIndex , getStatements (caseTree ));
624
+ transformReturnOrThrowBlock (caseTree , state , getStatements (caseTree ));
627
625
628
626
if (firstCaseInGroup ) {
629
627
groupedCaseCommentsAccumulator = new StringBuilder ();
@@ -725,7 +723,7 @@ private static int findBlockStatementIndex(TreePath treePath, BlockTree blockTre
725
723
/**
726
724
* Transforms the supplied statement switch into an assignment switch style of expression switch.
727
725
* 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
729
727
* {@code AnalysisResult} for the {@code SwitchTree} must have deduced that this conversion is
730
728
* possible.
731
729
*/
@@ -760,7 +758,7 @@ private static SuggestedFix convertToAssignmentSwitch(
760
758
ImmutableList <StatementTree > filteredStatements = filterOutRedundantBreak (caseTree );
761
759
762
760
String transformedBlockSource =
763
- transformAssignOrThrowBlock (caseTree , state , cases , caseIndex , filteredStatements );
761
+ transformAssignOrThrowBlock (caseTree , state , filteredStatements );
764
762
765
763
if (firstCaseInGroup ) {
766
764
groupedCaseCommentsAccumulator = new StringBuilder ();
@@ -870,17 +868,13 @@ private static List<? extends StatementTree> getStatements(CaseTree caseTree) {
870
868
871
869
/** Transforms code for this case into the code under an expression switch. */
872
870
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 ) {
878
872
879
873
StringBuilder transformedBlockBuilder = new StringBuilder ();
880
874
int codeBlockStart = extractLhsComments (caseTree , state , transformedBlockBuilder );
881
875
int codeBlockEnd =
882
876
filteredStatements .isEmpty ()
883
- ? getBlockEnd (state , caseTree , cases , caseIndex )
877
+ ? getBlockEnd (state , caseTree )
884
878
: state .getEndPosition (Streams .findLast (filteredStatements .stream ()).get ());
885
879
transformedBlockBuilder .append (state .getSourceCode (), codeBlockStart , codeBlockEnd );
886
880
@@ -913,19 +907,29 @@ private static int extractLhsComments(
913
907
* Finds the position in source corresponding to the end of the code block of the supplied {@code
914
908
* caseIndex} within all {@code cases}.
915
909
*/
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 ) {
918
911
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 )) {
920
920
return state .getEndPosition (caseTree );
921
921
}
922
922
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 ));
924
928
}
925
929
926
930
/**
927
931
* 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.
929
933
*/
930
934
private static boolean shouldTransformCaseWithoutBraces (
931
935
ImmutableList <StatementTree > statementTrees ) {
@@ -995,17 +999,13 @@ private static boolean isSwitchExhaustive(
995
999
* transformed to {@code x+1;}.
996
1000
*/
997
1001
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 ) {
1003
1003
1004
1004
StringBuilder transformedBlockBuilder = new StringBuilder ();
1005
1005
int codeBlockStart ;
1006
1006
int codeBlockEnd =
1007
1007
statements .isEmpty ()
1008
- ? getBlockEnd (state , caseTree , cases , caseIndex )
1008
+ ? getBlockEnd (state , caseTree )
1009
1009
: state .getEndPosition (Streams .findLast (statements .stream ()).get ());
1010
1010
1011
1011
if (statements .size () == 1 && statements .get (0 ).getKind ().equals (RETURN )) {
@@ -1028,17 +1028,13 @@ private static String transformReturnOrThrowBlock(
1028
1028
* {@code >>=}).
1029
1029
*/
1030
1030
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 ) {
1036
1032
1037
1033
StringBuilder transformedBlockBuilder = new StringBuilder ();
1038
1034
int codeBlockStart ;
1039
1035
int codeBlockEnd =
1040
1036
statements .isEmpty ()
1041
- ? getBlockEnd (state , caseTree , cases , caseIndex )
1037
+ ? getBlockEnd (state , caseTree )
1042
1038
: state .getEndPosition (Streams .findLast (statements .stream ()).get ());
1043
1039
1044
1040
if (!statements .isEmpty () && statements .get (0 ).getKind ().equals (EXPRESSION_STATEMENT )) {
0 commit comments