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 b54e4a368f..2ba6a51c4b 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVar.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVar.java @@ -61,7 +61,13 @@ public TreeVisitor getVisitor() { private static class LombokValToFinalVarVisitor extends JavaIsoVisitor { @Override public J.CompilationUnit visitCompilationUnit(J.CompilationUnit compilationUnit, ExecutionContext ctx) { - maybeRemoveImport(LOMBOK_VAR); + for (J.Import imp : compilationUnit.getImports()) { + if (!imp.isStatic() && LOMBOK_VAR.equals(imp.getTypeName()) && + !"*".equals(imp.getQualid().getSimpleName())) { + maybeRemoveImport(LOMBOK_VAR); + break; + } + } return super.visitCompilationUnit(compilationUnit, ctx); } 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 680ff5157a..44ca317d1a 100755 --- a/src/test/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVarTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/LombokValToFinalVarTest.java @@ -21,6 +21,7 @@ import org.openrewrite.java.JavaParser; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; import static org.openrewrite.java.Assertions.java; import static org.openrewrite.java.Assertions.version; @@ -113,6 +114,141 @@ void bar() { ); } + @Test + void preserveStarImportWithoutVarUsage() { + //language=java + rewriteRun( + spec -> spec.parser(JavaParser.fromJavaVersion()) + .typeValidationOptions(TypeValidation.none()), + version( + java( + """ + import lombok.*; + + @AllArgsConstructor + @NoArgsConstructor + @ToString + @Data + @EqualsAndHashCode + public class AuthHeaders { + String authHeader; + String token; + } + """ + ), + 17 + ) + ); + } + + @Test + void preserveStarImportWithVarUsage() { + //language=java + rewriteRun( + spec -> spec.parser(JavaParser.fromJavaVersion()) + .typeValidationOptions(TypeValidation.none()), + version( + java( + """ + import lombok.*; + + @Data + class A { + void bar() { + var foo = "foo"; + } + } + """ + ), + 17 + ) + ); + } + + @Test + void removeExplicitVarImport() { + //language=java + rewriteRun( + spec -> spec.parser(JavaParser.fromJavaVersion()) + .typeValidationOptions(TypeValidation.none()), + version( + java( + """ + import lombok.var; + class A { + void bar() { + var foo = "foo"; + } + } + """, + """ + class A { + void bar() { + var foo = "foo"; + } + } + """ + ), + 17 + ) + ); + } + + @Test + void removeStarImportWhenOnlyValUsed() { + //language=java + rewriteRun( + spec -> spec.parser(JavaParser.fromJavaVersion()) + .typeValidationOptions(TypeValidation.none()), + version( + java( + """ + import lombok.*; + class A { + void bar() { + val foo = "foo"; + } + } + """, + """ + class A { + void bar() { + final var foo = "foo"; + } + } + """ + ), + 17 + ) + ); + } + + @Test + void starImportRemainsWhenOnlyVarUsed() { + // When `import lombok.*;` exists only for `var`, the star import remains unused after + // the recipe runs. This is acceptable: removing a star import with incomplete type info + // risks breaking compilation by dropping imports that + // other lombok types still need. An unused import is preferable to broken code. + //language=java + rewriteRun( + spec -> spec.parser(JavaParser.fromJavaVersion()) + .typeValidationOptions(TypeValidation.none()), + version( + java( + """ + import lombok.*; + class A { + void bar() { + var foo = "foo"; + } + } + """ + ), + 17 + ) + ); + } + @Nested @SuppressWarnings({"StatementWithEmptyBody", "RedundantOperationOnEmptyContainer"}) class ValInLoop {