1515 */
1616package org .openrewrite .staticanalysis ;
1717
18+ import java .time .Duration ;
19+ import java .util .ArrayList ;
20+ import java .util .Arrays ;
21+ import java .util .Iterator ;
22+ import java .util .LinkedHashSet ;
23+ import java .util .List ;
24+ import java .util .Optional ;
25+ import java .util .Set ;
26+
1827import org .openrewrite .ExecutionContext ;
1928import org .openrewrite .Recipe ;
2029import org .openrewrite .TreeVisitor ;
2130import org .openrewrite .java .JavaIsoVisitor ;
31+ import org .openrewrite .java .tree .Comment ;
2232import org .openrewrite .java .tree .J ;
23-
24- import java .time .Duration ;
25- import java .util .Arrays ;
26- import java .util .LinkedHashSet ;
27- import java .util .Set ;
33+ import org .openrewrite .java .tree .Space ;
34+ import org .openrewrite .java .tree .Statement ;
2835
2936public class RemoveExtraSemicolons extends Recipe {
3037
@@ -52,20 +59,33 @@ public Duration getEstimatedEffortPerOccurrence() {
5259 @ Override
5360 public TreeVisitor <?, ExecutionContext > getVisitor () {
5461 return new JavaIsoVisitor <ExecutionContext >() {
62+
5563 @ Override
56- public J .Empty visitEmpty (J .Empty empty , ExecutionContext ctx ) {
57- if (getCursor ().getParentTreeCursor ().getValue () instanceof J .Block ) {
58- return null ;
64+ public J .Block visitBlock (final J .Block block , final ExecutionContext executionContext ) {
65+ final Iterator <Statement > iterator = block .getStatements ().iterator ();
66+ final List <Statement > result = new ArrayList <>();
67+ while (iterator .hasNext ()) {
68+ Statement statement = iterator .next ();
69+ if (statement instanceof J .Empty ) {
70+ nextNonEmptyAggregatedWithComments (statement , iterator )
71+ .ifPresent (nextLine -> {
72+ Space updatedPrefix = nextLine .getPrefix ()
73+ .withWhitespace (statement .getPrefix ().getWhitespace ());
74+ result .add (nextLine .withPrefix (updatedPrefix ));
75+ });
76+ } else {
77+ result .add (statement );
78+ }
5979 }
60- return empty ;
80+ return super . visitBlock ( block . withStatements ( result ), executionContext ) ;
6181 }
6282
6383 @ Override
6484 public J .Try .Resource visitTryResource (J .Try .Resource tr , ExecutionContext executionContext ) {
6585 J .Try _try = getCursor ().dropParentUntil (is -> is instanceof J .Try ).getValue ();
6686 if (_try .getResources ().isEmpty () ||
67- _try .getResources ().get (_try .getResources ().size () - 1 ) != tr ||
68- !_try .getResources ().get (_try .getResources ().size () - 1 ).isTerminatedWithSemicolon ()) {
87+ _try .getResources ().get (_try .getResources ().size () - 1 ) != tr ||
88+ !_try .getResources ().get (_try .getResources ().size () - 1 ).isTerminatedWithSemicolon ()) {
6989 return tr ;
7090 }
7191 return tr .withTerminatedWithSemicolon (false );
@@ -81,4 +101,16 @@ public J.EnumValueSet visitEnumValueSet(J.EnumValueSet enums, ExecutionContext e
81101 }
82102 };
83103 }
104+
105+ private Optional <Statement > nextNonEmptyAggregatedWithComments (Statement current , Iterator <Statement > iterator ) {
106+ List <Comment > comments = new ArrayList <>(current .getComments ());
107+ while (iterator .hasNext ()) {
108+ Statement statement = iterator .next ();
109+ comments .addAll (statement .getComments ());
110+ if (!(statement instanceof J .Empty )) {
111+ return Optional .of (statement .withComments (comments ));
112+ }
113+ }
114+ return Optional .empty ();
115+ }
84116}
0 commit comments