diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVar.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVar.java index 3a6826373a..acc7f6e7ec 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVar.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVar.java @@ -15,16 +15,15 @@ */ package org.openrewrite.java.migrate.lombok; -import org.openrewrite.ExecutionContext; -import org.openrewrite.Preconditions; -import org.openrewrite.Recipe; -import org.openrewrite.TreeVisitor; +import org.openrewrite.*; import org.openrewrite.internal.ListUtils; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.JavaTemplate; import org.openrewrite.java.search.MaybeUsesImport; import org.openrewrite.java.search.UsesType; +import org.openrewrite.java.service.AnnotationService; import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.TypeTree; import org.openrewrite.java.tree.TypeUtils; import java.time.Duration; @@ -75,29 +74,32 @@ public J.CompilationUnit visitCompilationUnit(J.CompilationUnit compilationUnit, @Override public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations mv, ExecutionContext ctx) { J.VariableDeclarations varDecls = super.visitVariableDeclarations(mv, ctx); + if (TypeUtils.isOfClassType(varDecls.getType(), LOMBOK_VAL) || - (varDecls.getTypeExpression() instanceof J.Identifier && ((J.Identifier) varDecls.getTypeExpression()).getSimpleName().equals("val"))) { + (varDecls.getTypeExpression() instanceof J.Identifier && "val".equals(((J.Identifier) varDecls.getTypeExpression()).getSimpleName()))) { maybeRemoveImport(LOMBOK_VAL); J.VariableDeclarations.NamedVariable nv = mv.getVariables().get(0); - String finalVarVariableTemplateString; - Object[] args; if (nv.getInitializer() == null) { - finalVarVariableTemplateString = "final var #{}"; - args = new Object[]{nv.getSimpleName()}; - } else { - finalVarVariableTemplateString = "final var #{} = #{any()};"; - args = new Object[]{nv.getSimpleName(), nv.getInitializer()}; + // manually transform to var, as val in this case has no sufficient type information + // and the java template parsing would fail, see https://github.com/openrewrite/rewrite/pull/5637 + TypeTree typeExpression = varDecls.getTypeExpression(); + J.Identifier varType = new J.Identifier(Tree.randomId(), + typeExpression.getPrefix(), + typeExpression.getMarkers(), + service(AnnotationService.class).getAllAnnotations(getCursor()), + "var", + nv.getType(), + null); + return varDecls.withTypeExpression(varType); } - varDecls = JavaTemplate.builder(finalVarVariableTemplateString) + + varDecls = JavaTemplate.builder("final var #{} = #{any()};") .contextSensitive() .build() - .apply(updateCursor(varDecls), varDecls.getCoordinates().replace(), args); - - if (nv.getInitializer() != null) { - varDecls = varDecls.withVariables(ListUtils.map(varDecls.getVariables(), namedVar -> namedVar - .withInitializer(namedVar.getInitializer().withPrefix(nv.getInitializer().getPrefix())))); - } + .apply(updateCursor(varDecls), varDecls.getCoordinates().replace(), nv.getSimpleName(), nv.getInitializer()); + varDecls = varDecls.withVariables(ListUtils.map(varDecls.getVariables(), namedVar -> namedVar + .withInitializer(namedVar.getInitializer().withPrefix(nv.getInitializer().getPrefix())))); } return varDecls; } diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVarTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVarTest.java index 2dc0d3df8b..680ff5157a 100755 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVarTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVarTest.java @@ -15,6 +15,7 @@ */ package org.openrewrite.java.migrate.lombok; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; import org.openrewrite.java.JavaParser; @@ -112,40 +113,108 @@ void bar() { ); } + @Nested @SuppressWarnings({"StatementWithEmptyBody", "RedundantOperationOnEmptyContainer"}) - @Test - void valInForEachStatement() { - //language=java - rewriteRun( - version( - java( - """ - import lombok.val; - import java.util.List; - import java.util.ArrayList; + class ValInLoop { + @Test + void list() { + //language=java + rewriteRun( + version( + java( + """ + import lombok.val; - class A { - void bar() { - List lst = new ArrayList<>(); - for (val s : lst) {} + import java.util.List; + + class A { + void bar(List lst) { + for (val s : lst) {} + } } - } - """, - """ - import java.util.List; - import java.util.ArrayList; + """, + """ + import java.util.List; - class A { - void bar() { - List lst = new ArrayList<>(); - for (final var s : lst) {} + class A { + void bar(List lst) { + for (var s : lst) {} + } } - } + """ + ), + 17 + ) + ); + } + + @Test + void array() { + //language=java + rewriteRun( + version( + java( + """ + import lombok.val; + import java.util.List; + import java.util.ArrayList; + + class A { + void bar(String[] lst) { + for (val s : lst) {} + } + } + """, + """ + import java.util.List; + import java.util.ArrayList; + + class A { + void bar(String[] lst) { + for (var s : lst) {} + } + } + """ + ), + 17 + ) + ); + } + + @Test + void valuesFromMethod() { + //language=java + rewriteRun( + java( """ - ), - 17 - ) - ); + interface Mapper { + String[] getNamesList(); + } + """ + ), + version( + java( + """ + import lombok.val; + + class A { + void bar(Mapper mapper) { + for (val s : mapper.getNamesList()) {} + } + } + """, + """ + class A { + void bar(Mapper mapper) { + for (var s : mapper.getNamesList()) {} + } + } + """ + ), + 17 + ) + ); + } } @Test