diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/LombokUtils.java b/src/main/java/org/openrewrite/java/migrate/lombok/LombokUtils.java index a397bf9042..778ed30c57 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/LombokUtils.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/LombokUtils.java @@ -17,17 +17,28 @@ import lombok.AccessLevel; import org.jspecify.annotations.Nullable; +import org.openrewrite.Cursor; import org.openrewrite.internal.StringUtils; +import org.openrewrite.java.AnnotationMatcher; +import org.openrewrite.java.service.AnnotationService; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; +import java.util.List; + import static lombok.AccessLevel.*; import static org.openrewrite.java.tree.J.Modifier.Type.*; class LombokUtils { - static boolean isGetter(J.MethodDeclaration method) { + private static final AnnotationMatcher OVERRIDE_MATCHER = new AnnotationMatcher("java.lang.Override"); + + static boolean isGetter(Cursor cursor, AnnotationService service) { + if (!(cursor.getValue() instanceof J.MethodDeclaration)) { + return false; + } + J.MethodDeclaration method = cursor.getValue(); if (method.getMethodType() == null) { return false; } @@ -41,6 +52,10 @@ static boolean isGetter(J.MethodDeclaration method) { !(method.getBody().getStatements().get(0) instanceof J.Return)) { return false; } + // Check there is no annotation except @Overwrite + if (hasAnyAnnotatioOtherThanOverride(cursor, service)) { + return false; + } // Check field is declared on method type JavaType.FullyQualified declaringType = method.getMethodType().getDeclaringType(); Expression returnExpression = ((J.Return) method.getBody().getStatements().get(0)).getExpression(); @@ -83,7 +98,12 @@ private static String deriveGetterMethodName(@Nullable JavaType type, String fie return "get" + StringUtils.capitalize(fieldName); } - static boolean isSetter(J.MethodDeclaration method) { + static boolean isSetter(Cursor cursor, AnnotationService service) { + if (!(cursor.getValue() instanceof J.MethodDeclaration)) { + return false; + } + J.MethodDeclaration method = cursor.getValue(); + // Check return type: void if (method.getType() != JavaType.Primitive.Void) { return false; @@ -99,6 +119,11 @@ static boolean isSetter(J.MethodDeclaration method) { return false; } + // Check there is no annotation except @Overwrite + if (hasAnyAnnotatioOtherThanOverride(cursor, service)) { + return false; + } + // Check there's no up/down cast between parameter and field J.VariableDeclarations.NamedVariable param = ((J.VariableDeclarations) method.getParameters().get(0)).getVariables().get(0); Expression variable = ((J.Assignment) method.getBody().getStatements().get(0)).getVariable(); @@ -141,4 +166,9 @@ static AccessLevel getAccessLevel(J.MethodDeclaration methodDeclaration) { } return PACKAGE; } + + private static boolean hasAnyAnnotatioOtherThanOverride(Cursor cursor, AnnotationService service) { + List annotations = service.getAllAnnotations(cursor); + return !(annotations.isEmpty() || (annotations.size() == 1 && OVERRIDE_MATCHER.matches(annotations.get(0)))); + } } diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokGetter.java b/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokGetter.java index 850610da3a..9928d9985e 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokGetter.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokGetter.java @@ -23,6 +23,7 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.service.AnnotationService; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; @@ -54,7 +55,7 @@ public TreeVisitor getVisitor() { return new JavaIsoVisitor() { @Override public J.@Nullable MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) { - if (LombokUtils.isGetter(method)) { + if (LombokUtils.isGetter(getCursor(), service(AnnotationService.class))) { Expression returnExpression = ((J.Return) method.getBody().getStatements().get(0)).getExpression(); if (returnExpression instanceof J.Identifier && ((J.Identifier) returnExpression).getFieldType() != null) { diff --git a/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokSetter.java b/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokSetter.java index 9bf659606a..d3df969ef2 100644 --- a/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokSetter.java +++ b/src/main/java/org/openrewrite/java/migrate/lombok/UseLombokSetter.java @@ -23,6 +23,7 @@ import org.openrewrite.Recipe; import org.openrewrite.TreeVisitor; import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.service.AnnotationService; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; @@ -53,7 +54,7 @@ public TreeVisitor getVisitor() { return new JavaIsoVisitor() { @Override public J.@Nullable MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) { - if (LombokUtils.isSetter(method)) { + if (LombokUtils.isSetter(getCursor(), service(AnnotationService.class))) { Expression assignmentVariable = ((J.Assignment) method.getBody().getStatements().get(0)).getVariable(); if (assignmentVariable instanceof J.FieldAccess && ((J.FieldAccess) assignmentVariable).getName().getFieldType() != null) { diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokGetterTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokGetterTest.java index 15d082ab02..8544904a96 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokGetterTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokGetterTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; +import org.openrewrite.Issue; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; @@ -528,4 +529,54 @@ public int getFoo() { ) ); } + + @Test + @Issue("https://github.com/openrewrite/rewrite/issues/5015") + void noChangeIfAnnotated() { + rewriteRun(// language=java + java("@interface MyOtherAnnotation {}"), + java( + """ + class A { + + int foo = 9; + + @MyOtherAnnotation + public int getFoo() { + return foo; + } + } + """ + ) + ); + } + + @Test + @Issue("https://github.com/openrewrite/rewrite/issues/5015") + void replaceGetterIfOverwrite() { + rewriteRun(// language=java + java( + """ + class A { + + int foo = 9; + + @Override + public int getFoo() { + return foo; + } + } + """, + """ + import lombok.Getter; + + class A { + + @Getter + int foo = 9; + } + """ + ) + ); + } } diff --git a/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokSetterTest.java b/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokSetterTest.java index 3b0bb02c4c..ef5e9f7b77 100644 --- a/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokSetterTest.java +++ b/src/test/java/org/openrewrite/java/migrate/lombok/UseLombokSetterTest.java @@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; +import org.openrewrite.Issue; import org.openrewrite.java.JavaParser; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; @@ -537,4 +538,54 @@ public void setFoo(int foo) { ) ); } + + @Test + @Issue("https://github.com/openrewrite/rewrite/issues/5015") + void noChangeIfAnnotated() { + rewriteRun(// language=java + java("@interface MyOtherAnnotation {}"), + java( + """ + class A { + + int foo = 9; + + @MyOtherAnnotation + public void setFoo(int fub) { + this.foo = fub; + } + } + """ + ) + ); + } + + @Test + @Issue("https://github.com/openrewrite/rewrite/issues/5015") + void replaceSetterIfOverwrite() { + rewriteRun(// language=java + java( + """ + class A { + + int foo = 9; + + @Override + public void setFoo(int foo) { + this.foo = foo; + } + } + """, + """ + import lombok.Setter; + + class A { + + @Setter + int foo = 9; + } + """ + ) + ); + } }