diff --git a/rewrite-groovy/src/main/java/org/openrewrite/groovy/DeleteStatement.java b/rewrite-groovy/src/main/java/org/openrewrite/groovy/DeleteStatement.java
deleted file mode 100644
index aacd9944cbe..00000000000
--- a/rewrite-groovy/src/main/java/org/openrewrite/groovy/DeleteStatement.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.openrewrite.groovy;
-
-import org.openrewrite.groovy.tree.G;
-import org.openrewrite.internal.ListUtils;
-import org.openrewrite.java.tree.Statement;
-
-/**
- * Deletes standalone statements.
- */
-public class DeleteStatement
extends GroovyIsoVisitor
{
- private final Statement statement;
-
- public DeleteStatement(Statement statement) {
- this.statement = statement;
- doAfterVisit(new org.openrewrite.java.DeleteStatement<>(statement));
- }
-
- @Override
- public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, P p) {
- G.CompilationUnit g = super.visitCompilationUnit(cu, p);
- return g.withStatements(ListUtils.map(g.getStatements(), s ->
- statement.isScope(s) ? null : s));
- }
-}
diff --git a/rewrite-groovy/src/test/java/org/openrewrite/groovy/DeleteStatementTest.java b/rewrite-groovy/src/test/java/org/openrewrite/groovy/DeleteStatementTest.java
new file mode 100644
index 00000000000..4f3d48f3411
--- /dev/null
+++ b/rewrite-groovy/src/test/java/org/openrewrite/groovy/DeleteStatementTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.groovy;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.groovy.tree.G;
+import org.openrewrite.java.DeleteStatement;
+import org.openrewrite.java.tree.Statement;
+import org.openrewrite.test.RewriteTest;
+
+import java.util.List;
+
+import static org.openrewrite.groovy.Assertions.groovy;
+import static org.openrewrite.test.RewriteTest.toRecipe;
+
+class DeleteStatementTest implements RewriteTest {
+ @Test
+ void deleteStatement() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new GroovyIsoVisitor<>() {
+ @Override
+ public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) {
+ G.CompilationUnit g = super.visitCompilationUnit(cu, ctx);
+ List statements = g.getStatements();
+ for (int i = 0; i < statements.size(); i++) {
+ Statement s = statements.get(i);
+ if (i == 1) {
+ g = (G.CompilationUnit) new DeleteStatement<>(s).visit(cu, ctx);
+ }
+ }
+ return g;
+ }
+ })),
+ groovy(
+ """
+ int i = 0
+ i = 1
+ """,
+ """
+ int i = 0
+ """
+ )
+ );
+ }
+}
diff --git a/rewrite-java-test/src/test/java/org/openrewrite/java/DeleteStatementTest.java b/rewrite-java-test/src/test/java/org/openrewrite/java/DeleteStatementTest.java
index ac3c6c4e165..671b15a77ee 100644
--- a/rewrite-java-test/src/test/java/org/openrewrite/java/DeleteStatementTest.java
+++ b/rewrite-java-test/src/test/java/org/openrewrite/java/DeleteStatementTest.java
@@ -143,4 +143,263 @@ public class A {
)
);
}
+
+ @Test
+ void deleteIfThenBody() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.If visitIf(J.If iff, ExecutionContext ctx) {
+ J.If i = super.visitIf(iff, ctx);
+ if (!((J.Block) i.getThenPart()).getStatements().isEmpty()) {
+ doAfterVisit(new DeleteStatement<>(i.getThenPart()));
+ }
+ return i;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ if (true) {
+ int i = 0;
+ }
+ }
+ }
+ """,
+ """
+ public class A {
+ public void a() {
+ if (true){}
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void deleteIfElseBody() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.If visitIf(J.If iff, ExecutionContext ctx) {
+ J.If i = super.visitIf(iff, ctx);
+ if (!((J.Block) i.getElsePart().getBody()).getStatements().isEmpty()) {
+ doAfterVisit(new DeleteStatement<>(i.getElsePart().getBody()));
+ }
+ return i;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ if (false) {
+ int i = 0;
+ } else {
+ int i = 0;
+ }
+ }
+ }
+ """,
+ """
+ public class A {
+ public void a() {
+ if (false) {
+ int i = 0;
+ } else{}
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void deleteForBody() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.ForLoop visitForLoop(J.ForLoop forLoop, ExecutionContext ctx) {
+ J.ForLoop f = super.visitForLoop(forLoop, ctx);
+ if (!((J.Block) f.getBody()).getStatements().isEmpty()) {
+ doAfterVisit(new DeleteStatement<>(f.getBody()));
+ }
+ return f;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ for (int i = 0; i < 1; i++) {
+ int j = 0;
+ }
+ }
+ }
+ """,
+ """
+ public class A {
+ public void a() {
+ for (int i = 0; i < 1; i++){}
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void dontDeleteForControl() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.ForLoop visitForLoop(J.ForLoop forLoop, ExecutionContext ctx) {
+ J.ForLoop f = super.visitForLoop(forLoop, ctx);
+ doAfterVisit(new DeleteStatement<>(f.getControl().getInit().get(0)));
+ doAfterVisit(new DeleteStatement<>(f.getControl().getUpdate().get(0)));
+ return f;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ for (int i = 0; i < 1; i++) {
+ int j = 0;
+ }
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void deleteForEachBody() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.ForEachLoop visitForEachLoop(J.ForEachLoop forLoop, ExecutionContext ctx) {
+ J.ForEachLoop f = super.visitForEachLoop(forLoop, ctx);
+ doAfterVisit(new DeleteStatement<>(f.getControl().getVariable()));
+ return f;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ for (int i : new int[]{ 1 }) {
+ int j = 0;
+ }
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void dontDeleteForEachControl() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.ForEachLoop visitForEachLoop(J.ForEachLoop forLoop, ExecutionContext ctx) {
+ J.ForEachLoop f = super.visitForEachLoop(forLoop, ctx);
+ if (!((J.Block) f.getBody()).getStatements().isEmpty()) {
+ doAfterVisit(new DeleteStatement<>(f.getBody()));
+ }
+ return f;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ for (int i : new int[]{ 1 }) {
+ int j = 0;
+ }
+ }
+ }
+ """,
+ """
+ public class A {
+ public void a() {
+ for (int i : new int[]{ 1 }){}
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void deleteWhileBody() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, ExecutionContext ctx) {
+ J.WhileLoop w = super.visitWhileLoop(whileLoop, ctx);
+ if (!((J.Block) w.getBody()).getStatements().isEmpty()) {
+ doAfterVisit(new DeleteStatement<>(w.getBody()));
+ }
+ return w;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ while (true) {
+ int i = 0;
+ }
+ }
+ }
+ """,
+ """
+ public class A {
+ public void a() {
+ while (true){}
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void deleteDoWhileBody() {
+ rewriteRun(
+ spec -> spec.recipe(toRecipe(() -> new JavaIsoVisitor<>() {
+ @Override
+ public J.DoWhileLoop visitDoWhileLoop(J.DoWhileLoop doWhileLoop, ExecutionContext ctx) {
+ J.DoWhileLoop w = super.visitDoWhileLoop(doWhileLoop, ctx);
+ if (!((J.Block) w.getBody()).getStatements().isEmpty()) {
+ doAfterVisit(new DeleteStatement<>(w.getBody()));
+ }
+ return w;
+ }
+ })),
+ java(
+ """
+ public class A {
+ public void a() {
+ do {
+ int i = 0;
+ } while (true);
+ }
+ }
+ """,
+ """
+ public class A {
+ public void a() {
+ do{} while (true);
+ }
+ }
+ """
+ )
+ );
+ }
}
diff --git a/rewrite-java/src/main/java/org/openrewrite/java/DeleteStatement.java b/rewrite-java/src/main/java/org/openrewrite/java/DeleteStatement.java
index bf4127bf868..89e452b3e87 100644
--- a/rewrite-java/src/main/java/org/openrewrite/java/DeleteStatement.java
+++ b/rewrite-java/src/main/java/org/openrewrite/java/DeleteStatement.java
@@ -16,13 +16,13 @@
package org.openrewrite.java;
import org.openrewrite.internal.ListUtils;
+import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.search.FindReferencedTypes;
import org.openrewrite.java.tree.*;
import org.openrewrite.marker.Markers;
import static java.util.Collections.emptyList;
import static org.openrewrite.Tree.randomId;
-import static org.openrewrite.java.tree.Space.EMPTY;
/**
* Deletes standalone statements. Does not include deletion of control statements present in for loops.
@@ -34,13 +34,24 @@ public DeleteStatement(Statement statement) {
this.statement = statement;
}
+ @Override
+ public @Nullable Statement visitStatement(Statement statement, P p) {
+ Statement s = super.visitStatement(statement, p);
+
+ if (this.statement.isScope(s)) {
+ return s instanceof J.Block ? emptyBlock() : null;
+ }
+
+ return s;
+ }
+
@Override
public J.If visitIf(J.If iff, P p) {
J.If i = super.visitIf(iff, p);
if (statement.isScope(i.getThenPart())) {
i = i.withThenPart(emptyBlock());
- } else if (i.getElsePart() != null && statement.isScope(i.getElsePart())) {
+ } else if (i.getElsePart() != null && statement.isScope(i.getElsePart().getBody())) {
i = i.withElsePart(i.getElsePart().withBody(emptyBlock()));
}
@@ -54,6 +65,11 @@ public J.ForLoop visitForLoop(J.ForLoop forLoop, P p) {
super.visitForLoop(forLoop, p);
}
+ @Override
+ public J.ForLoop.Control visitForControl(J.ForLoop.Control control, P p) {
+ return control;
+ }
+
@Override
public J.ForEachLoop visitForEachLoop(J.ForEachLoop forEachLoop, P p) {
return statement.isScope(forEachLoop.getBody()) ?
@@ -61,6 +77,11 @@ public J.ForEachLoop visitForEachLoop(J.ForEachLoop forEachLoop, P p) {
super.visitForEachLoop(forEachLoop, p);
}
+ @Override
+ public J.ForEachLoop.Control visitForEachControl(J.ForEachLoop.Control control, P p) {
+ return control;
+ }
+
@Override
public J.WhileLoop visitWhileLoop(J.WhileLoop whileLoop, P p) {
return statement.isScope(whileLoop.getBody()) ? whileLoop.withBody(emptyBlock()) :
diff --git a/rewrite-java/src/main/java/org/openrewrite/java/cleanup/RemoveUnusedLocalVariables.java b/rewrite-java/src/main/java/org/openrewrite/java/cleanup/RemoveUnusedLocalVariables.java
index 995e73556f9..b0596f7eff4 100644
--- a/rewrite-java/src/main/java/org/openrewrite/java/cleanup/RemoveUnusedLocalVariables.java
+++ b/rewrite-java/src/main/java/org/openrewrite/java/cleanup/RemoveUnusedLocalVariables.java
@@ -131,10 +131,10 @@ public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations
if (readReferences.isEmpty()) {
List assignmentReferences = References.findLhsReferences(parentScope.getValue(), variable.getName());
for (Statement ref : assignmentReferences) {
- doAfterVisit(new DeleteStatement<>(ref));
- if(ref instanceof J.Assignment) {
+ if (ref instanceof J.Assignment) {
doAfterVisit(new PruneAssignmentExpression((J.Assignment) ref));
}
+ doAfterVisit(new DeleteStatement<>(ref));
}
return null;
}