From 428347dabb2147fa7021f0051313ae4bbff1a7b8 Mon Sep 17 00:00:00 2001 From: Jacob van Lingen Date: Tue, 3 Dec 2024 10:05:48 +0100 Subject: [PATCH] Prove C# support for ExplicitInitialization recipe (#401) * Improve tests and visitor for ExplicitInitialization recipe * Add C# test for ExplicitInitialization recipe * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix license header --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../ExplicitInitializationVisitor.java | 9 +-- .../CatchClauseOnlyRethrowsTest.java | 13 +--- .../ExplicitInitializationTest.java | 21 +++++- ...plicitInitializationVisitorCsharpTest.java | 75 +++++++++++++++++++ .../{ => charp}/JavaToCsharp.java | 21 +++++- 5 files changed, 116 insertions(+), 23 deletions(-) create mode 100644 src/test/java/org/openrewrite/staticanalysis/charp/ExplicitInitializationVisitorCsharpTest.java rename src/test/java/org/openrewrite/staticanalysis/{ => charp}/JavaToCsharp.java (62%) diff --git a/src/main/java/org/openrewrite/staticanalysis/ExplicitInitializationVisitor.java b/src/main/java/org/openrewrite/staticanalysis/ExplicitInitializationVisitor.java index ad0583922..e04fd3cd9 100644 --- a/src/main/java/org/openrewrite/staticanalysis/ExplicitInitializationVisitor.java +++ b/src/main/java/org/openrewrite/staticanalysis/ExplicitInitializationVisitor.java @@ -67,12 +67,9 @@ public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations if (service(AnnotationService.class).matches(variableDeclsCursor, LOMBOK_BUILDER_DEFAULT)) { return v; } - J.Literal literalInit = variable.getInitializer() instanceof J.Literal ? - (J.Literal) variable.getInitializer() : - null; - if (literalInit != null && !variableDecls.hasModifier(J.Modifier.Type.Final)) { - if (TypeUtils.asFullyQualified(variable.getType()) != null && - JavaType.Primitive.Null.equals(literalInit.getType())) { + if (variable.getInitializer() instanceof J.Literal && !variableDecls.hasModifier(J.Modifier.Type.Final)) { + J.Literal literalInit = (J.Literal) variable.getInitializer(); + if (TypeUtils.asFullyQualified(variable.getType()) != null && JavaType.Primitive.Null.equals(literalInit.getType())) { v = v.withInitializer(null); } else if (primitive != null && !Boolean.TRUE.equals(style.getOnlyObjectReferences())) { switch (primitive) { diff --git a/src/test/java/org/openrewrite/staticanalysis/CatchClauseOnlyRethrowsTest.java b/src/test/java/org/openrewrite/staticanalysis/CatchClauseOnlyRethrowsTest.java index 54c862bb8..ce7e07739 100755 --- a/src/test/java/org/openrewrite/staticanalysis/CatchClauseOnlyRethrowsTest.java +++ b/src/test/java/org/openrewrite/staticanalysis/CatchClauseOnlyRethrowsTest.java @@ -20,9 +20,7 @@ import org.openrewrite.ExecutionContext; import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.Tree; -import org.openrewrite.csharp.tree.Cs; import org.openrewrite.java.JavaIsoVisitor; -import org.openrewrite.java.JavaVisitor; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.Space; import org.openrewrite.marker.Markers; @@ -30,7 +28,7 @@ import org.openrewrite.test.RewriteTest; import static org.openrewrite.java.Assertions.java; -import static org.openrewrite.test.RewriteTest.toRecipe; +import static org.openrewrite.staticanalysis.charp.JavaToCsharp.toCsRecipe; @SuppressWarnings("ALL") class CatchClauseOnlyRethrowsTest implements RewriteTest { @@ -340,14 +338,7 @@ void foo() throws IOException { @Test void verifyCsharpImplicitThrow() { rewriteRun( - spec -> spec.recipe(toRecipe(() -> new JavaVisitor<>() { - @Override - public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) { - Cs.CompilationUnit cscu = JavaToCsharp.compilationUnit(cu); - // Exercise the regular recipe with the now modified CSharp compilation unit - return (J) new CatchClauseOnlyRethrows().getVisitor().visit(cscu, ctx); - } - })), + spec -> spec.recipe(toCsRecipe(new CatchClauseOnlyRethrows())), //language=java java( """ diff --git a/src/test/java/org/openrewrite/staticanalysis/ExplicitInitializationTest.java b/src/test/java/org/openrewrite/staticanalysis/ExplicitInitializationTest.java index 9655dea0d..d7126fa51 100644 --- a/src/test/java/org/openrewrite/staticanalysis/ExplicitInitializationTest.java +++ b/src/test/java/org/openrewrite/staticanalysis/ExplicitInitializationTest.java @@ -81,14 +81,13 @@ class Test { } @Test - void ignoreInterfaces() { + void ignoreVariablesInMethods() { rewriteRun( //language=java java( """ - interface Test { - private int a = 0; - void s() { + class Test { + private void test() { int i = 0; } } @@ -97,6 +96,20 @@ void s() { ); } + @Test + void ignoreInterfaces() { + rewriteRun( + //language=java + java( + """ + interface Test { + int a = 0; + } + """ + ) + ); + } + @Test void blockStatement() { rewriteRun( diff --git a/src/test/java/org/openrewrite/staticanalysis/charp/ExplicitInitializationVisitorCsharpTest.java b/src/test/java/org/openrewrite/staticanalysis/charp/ExplicitInitializationVisitorCsharpTest.java new file mode 100644 index 000000000..b8dd25c3a --- /dev/null +++ b/src/test/java/org/openrewrite/staticanalysis/charp/ExplicitInitializationVisitorCsharpTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2024 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.staticanalysis.charp; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.java.JavaParser; +import org.openrewrite.staticanalysis.ExplicitInitialization; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.staticanalysis.charp.JavaToCsharp.toCsRecipe; + +class ExplicitInitializationVisitorCsharpTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(toCsRecipe(new ExplicitInitialization())) + .parser(JavaParser.fromJavaVersion() + .dependsOn( + // C# defines nullable primitive. These are actually in the CLR wrapper objects. + //language=java + """ + class Nullable { + Integer a; + + Nullable(Integer a) { + this.a = a; + } + } + """ + ) + ); + } + + @DocumentExample + @Test + void removeExplicitInitialization() { + rewriteRun( + //language=java + java( + """ + class A { + // C#: int? a + Nullable a = null; + // C#: int? a = 0 + Nullable a = new Nullable<>(0); + } + """, + """ + class A { + // C#: int? a + Nullable a; + // C#: int? a = 0 + Nullable a = new Nullable<>(0); + } + """ + ) + ); + } +} diff --git a/src/test/java/org/openrewrite/staticanalysis/JavaToCsharp.java b/src/test/java/org/openrewrite/staticanalysis/charp/JavaToCsharp.java similarity index 62% rename from src/test/java/org/openrewrite/staticanalysis/JavaToCsharp.java rename to src/test/java/org/openrewrite/staticanalysis/charp/JavaToCsharp.java index 06b5b6221..822f919bc 100644 --- a/src/test/java/org/openrewrite/staticanalysis/JavaToCsharp.java +++ b/src/test/java/org/openrewrite/staticanalysis/charp/JavaToCsharp.java @@ -13,18 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openrewrite.staticanalysis; +package org.openrewrite.staticanalysis.charp; +import org.openrewrite.ExecutionContext; +import org.openrewrite.Recipe; import org.openrewrite.csharp.tree.Cs; +import org.openrewrite.java.JavaVisitor; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JRightPadded; import org.openrewrite.java.tree.Statement; +import org.openrewrite.test.AdHocRecipe; import java.util.List; +import static org.openrewrite.test.RewriteTest.toRecipe; + public class JavaToCsharp { - public static Cs.CompilationUnit compilationUnit(J.CompilationUnit cu) { + public static AdHocRecipe toCsRecipe(Recipe recipe) { + return toRecipe(() -> new JavaVisitor<>() { + @Override + public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) { + Cs.CompilationUnit cscu = compilationUnit(cu); + // Exercise the regular recipe with the now modified CSharp compilation unit + return (J) recipe.getVisitor().visit(cscu, ctx); + } + }); + } + + private static Cs.CompilationUnit compilationUnit(J.CompilationUnit cu) { return new Cs.CompilationUnit( cu.getId(), cu.getPrefix(),