From c0ea0aec992368b3d252fc44f0d3d75a70e454a2 Mon Sep 17 00:00:00 2001 From: Shannon Pamperl Date: Wed, 11 Jan 2023 12:11:09 -0600 Subject: [PATCH] Flesh out tests for DeleteStatement and ensure that statements on (#2627) G.CompilationUnit can be removed --- .../openrewrite/groovy/DeleteStatement.java | 39 --- .../groovy/DeleteStatementTest.java | 59 ++++ .../openrewrite/java/DeleteStatementTest.java | 259 ++++++++++++++++++ .../org/openrewrite/java/DeleteStatement.java | 25 +- .../cleanup/RemoveUnusedLocalVariables.java | 4 +- 5 files changed, 343 insertions(+), 43 deletions(-) delete mode 100644 rewrite-groovy/src/main/java/org/openrewrite/groovy/DeleteStatement.java create mode 100644 rewrite-groovy/src/test/java/org/openrewrite/groovy/DeleteStatementTest.java 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; }