Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RemoveExtraSemicolons removes newline if semicolon is in front of statement #100

Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,23 @@
*/
package org.openrewrite.staticanalysis;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.Comment;
import org.openrewrite.java.tree.J;

import java.time.Duration;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.openrewrite.java.tree.Space;
import org.openrewrite.java.tree.Statement;

public class RemoveExtraSemicolons extends Recipe {

Expand Down Expand Up @@ -52,20 +59,33 @@ public Duration getEstimatedEffortPerOccurrence() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<ExecutionContext>() {

@Override
public J.Empty visitEmpty(J.Empty empty, ExecutionContext ctx) {
if (getCursor().getParentTreeCursor().getValue() instanceof J.Block) {
return null;
public J.Block visitBlock(final J.Block block, final ExecutionContext executionContext) {
final Iterator<Statement> iterator = block.getStatements().iterator();
final List<Statement> result = new ArrayList<>();
while (iterator.hasNext()) {
Statement statement = iterator.next();
if (statement instanceof J.Empty) {
nextNonEmptyAggregatedWithComments(statement, iterator)
.ifPresent(nextLine -> {
Space updatedPrefix = nextLine.getPrefix()
.withWhitespace(statement.getPrefix().getWhitespace());
result.add(nextLine.withPrefix(updatedPrefix));
});
} else {
result.add(statement);
}
}
return empty;
return super.visitBlock(block.withStatements(result), executionContext);
}

@Override
public J.Try.Resource visitTryResource(J.Try.Resource tr, ExecutionContext executionContext) {
J.Try _try = getCursor().dropParentUntil(is -> is instanceof J.Try).getValue();
if (_try.getResources().isEmpty() ||
_try.getResources().get(_try.getResources().size() - 1) != tr ||
!_try.getResources().get(_try.getResources().size() - 1).isTerminatedWithSemicolon()) {
_try.getResources().get(_try.getResources().size() - 1) != tr ||
!_try.getResources().get(_try.getResources().size() - 1).isTerminatedWithSemicolon()) {
return tr;
}
return tr.withTerminatedWithSemicolon(false);
Expand All @@ -81,4 +101,16 @@ public J.EnumValueSet visitEnumValueSet(J.EnumValueSet enums, ExecutionContext e
}
};
}

private Optional<Statement> nextNonEmptyAggregatedWithComments(Statement current, Iterator<Statement> iterator) {
List<Comment> comments = new ArrayList<>(current.getComments());
while (iterator.hasNext()) {
Statement statement = iterator.next();
comments.addAll(statement.getComments());
if (!(statement instanceof J.Empty)) {
return Optional.of(statement.withComments(comments));
}
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,80 @@ public J.Try visitTry(J.Try t, Object o) {
)
);
}

@Issue("https://github.com/openrewrite/rewrite-static-analysis/issues/99")
@Test
void semicolonBeforeStatement() {
rewriteRun(
//language=java
java(
"""
class Test {
void test() {
int a = 1;
;int b = 2;
}
}
""",
"""
class Test {
void test() {
int a = 1;
int b = 2;
}
}
"""
)
);
}

@Issue("https://github.com/openrewrite/rewrite-static-analysis/issues/99")
@Test
void manySemicolonBeforeStatement() {
rewriteRun(
//language=java
java(
"""
class Test {
int test() {
int a = 1; //first we set a to 1
;a = 2;/*then we set a to 2 */
a = 3;//then we set a to 3
;a = 4;;;;;//then we set a to 4
;a = 5;//then we set a to 5
a = 6;;//then we set a to 6
if (a == 6) { //if a is 6
;a = 7;;//then if a is 6 we set a to 7
}
;;
;//next we set a to 8
;a = 8;
return a;
;
//we are done!
}
}
""",
"""
class Test {
int test() {
int a = 1; //first we set a to 1
a = 2;/*then we set a to 2 */
a = 3;//then we set a to 3
a = 4;//then we set a to 4
a = 5;//then we set a to 5
a = 6;//then we set a to 6
if (a == 6) { //if a is 6
a = 7;//then if a is 6 we set a to 7
}
//next we set a to 8
a = 8;
return a;
//we are done!
}
}
"""
)
);
}
}