From fa8596036e205beb1bf94d9579b8f11622313e7f Mon Sep 17 00:00:00 2001 From: Jens Knipper <6333850+JensKnipper@users.noreply.github.com> Date: Fri, 9 Jun 2023 12:54:52 +0200 Subject: [PATCH] #887 add first draft for lombok @Value to java record --- .../ConvertLombokValueAnnotationToRecord.java | 81 +++++++++++++++++++ ...vertLombokValueAnnotationToRecordTest.java | 33 ++++++++ 2 files changed, 114 insertions(+) create mode 100644 rewrite-java/src/main/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecord.java create mode 100644 rewrite-java/src/test/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecordTest.java diff --git a/rewrite-java/src/main/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecord.java b/rewrite-java/src/main/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecord.java new file mode 100644 index 000000000000..0d3158f76439 --- /dev/null +++ b/rewrite-java/src/main/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecord.java @@ -0,0 +1,81 @@ +package org.openrewrite.java.recipes; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.tree.J; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ConvertLombokValueAnnotationToRecord extends Recipe { + @Override + public String getDisplayName() { + return "Convert classes to records where possible"; + } + + @Override + public String getDescription() { + return "Convert classes to records where possible."; + } + + @Override + public TreeVisitor getVisitor() { + return new ConvertLombokValueAnnotationToRecordVisitor(); + } + + private class ConvertLombokValueAnnotationToRecordVisitor extends JavaIsoVisitor { + /* + - lombok @Value to record + - delete @Value annotation + - but keep all other annotations + - delete value import if present + - change class to record + - define fields as parameter list in record + - rename all getters accesses of instances of class + - rename all getter methods in class + - keep all other methods + - ends with Dto or DTO - not relevant, should be included in the others + - predefine package and convert all the dtos in there? + - all with public fields without getters + - change only when final? + - private field with getters + - no setter + - equals, hashcode, toString, getters allowed - when there are other methods, do not convert + */ + + @Override + public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionContext executionContext) { + //System.out.println(TreeVisitingPrinter.printTree(getCursor())); + + List imports = new ArrayList<>(cu.getImports()); + boolean lombokValueImported = imports.removeIf(it -> it.getTypeName().equals("lombok.Value")); + + List classDeclarations = new ArrayList<>(cu + .getClasses()) + .stream() + .map(it -> changeClassDeclaration(it, lombokValueImported, executionContext)) + .collect(Collectors.toList()); + + J.CompilationUnit newCompilationUnit = cu.withImports(imports).withClasses(classDeclarations); + return super.visitCompilationUnit(newCompilationUnit, executionContext); + } + + private J.ClassDeclaration changeClassDeclaration(J.ClassDeclaration classDecl, boolean lombokValueImported, ExecutionContext executionContext) { + + List annotations = new ArrayList<>(classDecl.getLeadingAnnotations()); + boolean isValue = annotations + .removeIf(it -> (it.getSimpleName().equals("Value") && lombokValueImported) + || it.getSimpleName().equals("lombok.Value")); + if (!isValue) { + return super.visitClassDeclaration(classDecl, executionContext); + } + // TODO only for classes or also for interfaces, enums, annotation? + + J.ClassDeclaration newClassDecl = classDecl.withLeadingAnnotations(annotations).withKind(J.ClassDeclaration.Kind.Type.Record); + return super.visitClassDeclaration(newClassDecl, executionContext); + } + } +} diff --git a/rewrite-java/src/test/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecordTest.java b/rewrite-java/src/test/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecordTest.java new file mode 100644 index 000000000000..5d87c9f8e056 --- /dev/null +++ b/rewrite-java/src/test/java/org/openrewrite/java/recipes/ConvertLombokValueAnnotationToRecordTest.java @@ -0,0 +1,33 @@ +package org.openrewrite.java.recipes; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +public class ConvertLombokValueAnnotationToRecordTest + implements RewriteTest { + @Test + void renameFieldRenamesFoundField() { + rewriteRun( + recipeSpec -> recipeSpec.recipe(new ConvertLombokValueAnnotationToRecord()), + java( + """ + package my.test; + + import lombok.Value; + + @Value + class ValueToRecord { + String test; + } + """, + """ + package my.test; + + record ValueToRecord(String test) {} + """ + ) + ); + } +}