1515 */
1616package org .openrewrite .java .migrate .lombok ;
1717
18- import lombok .AccessLevel ;
1918import lombok .EqualsAndHashCode ;
19+ import lombok .Setter ;
2020import lombok .Value ;
2121import org .jspecify .annotations .Nullable ;
2222import org .openrewrite .ExecutionContext ;
2323import org .openrewrite .Recipe ;
2424import org .openrewrite .TreeVisitor ;
2525import org .openrewrite .java .JavaIsoVisitor ;
26- import org .openrewrite .java .JavaParser ;
27- import org .openrewrite .java .JavaTemplate ;
2826import org .openrewrite .java .tree .J ;
2927
30- import java .util .*;
28+ import java .util .Collections ;
29+ import java .util .Set ;
3130
32- import static java .util .Comparator .comparing ;
3331import static org .openrewrite .java .tree .JavaType .Variable ;
3432
3533@ Value
@@ -65,25 +63,6 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
6563 @ Value
6664 @ EqualsAndHashCode (callSuper = false )
6765 private static class MethodRemover extends JavaIsoVisitor <ExecutionContext > {
68- private static final String FIELDS_TO_DECORATE_KEY = "FIELDS_TO_DECORATE" ;
69-
70- @ Override
71- public J .ClassDeclaration visitClassDeclaration (J .ClassDeclaration classDecl , ExecutionContext ctx ) {
72-
73- //initialize set of fields to annotate
74- getCursor ().putMessage (FIELDS_TO_DECORATE_KEY , new HashSet <Finding >());
75-
76- //delete methods, note down corresponding fields
77- J .ClassDeclaration classDeclAfterVisit = super .visitClassDeclaration (classDecl , ctx );
78-
79- //only thing that can have changed is removal of setter methods
80- if (classDeclAfterVisit != classDecl ) {
81- //this set collects the fields for which existing methods have already been removed
82- Set <Finding > fieldsToDecorate = getCursor ().pollNearestMessage (FIELDS_TO_DECORATE_KEY );
83- doAfterVisit (new FieldAnnotator (fieldsToDecorate ));
84- }
85- return classDeclAfterVisit ;
86- }
8766
8867 @ Override
8968 public J .@ Nullable MethodDeclaration visitMethodDeclaration (J .MethodDeclaration method , ExecutionContext ctx ) {
@@ -94,68 +73,15 @@ public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, Ex
9473 Variable fieldType = fieldAccess .getName ().getFieldType ();
9574 boolean nameMatch = method .getSimpleName ().equals (LombokUtils .deriveSetterMethodName (fieldType ));
9675 if (nameMatch ) {
97- Set <Finding > set = getCursor ().getNearestMessage (FIELDS_TO_DECORATE_KEY );
98- set .add (new Finding (fieldType .getName (), LombokUtils .getAccessLevel (method )));
76+ doAfterVisit (new FieldAnnotator (
77+ Setter .class ,
78+ fieldType ,
79+ LombokUtils .getAccessLevel (method )
80+ ));
9981 return null ; //delete
10082 }
10183 }
10284 return method ;
10385 }
10486 }
105-
106- @ Value
107- private static class Finding {
108- String fieldName ;
109- AccessLevel accessLevel ;
110- }
111-
112-
113- @ Value
114- @ EqualsAndHashCode (callSuper = false )
115- static class FieldAnnotator extends JavaIsoVisitor <ExecutionContext > {
116-
117- Set <Finding > fieldsToDecorate ;
118-
119- private JavaTemplate getAnnotation (AccessLevel accessLevel ) {
120- JavaTemplate .Builder builder = AccessLevel .PUBLIC .equals (accessLevel ) ?
121- JavaTemplate .builder ("@Setter\n " ) :
122- JavaTemplate .builder ("@Setter(AccessLevel." + accessLevel .name () + ")\n " )
123- .imports ("lombok.AccessLevel" );
124-
125- return builder
126- .imports ("lombok.Setter" )
127- .javaParser (JavaParser .fromJavaVersion ().classpath ("lombok" ))
128- .build ();
129- }
130-
131- @ Override
132- public J .VariableDeclarations visitVariableDeclarations (J .VariableDeclarations multiVariable , ExecutionContext ctx ) {
133-
134- //we accept only one var decl per line, see description
135- if (multiVariable .getVariables ().size () > 1 ) {
136- return multiVariable ;
137- }
138-
139- //we only want to annotate fields and not e.g. method parameters, so we require a lass declaration to be close in the cursor.
140- if (getCursor ().getPathAsStream ().limit (4 ).noneMatch (e -> e instanceof J .ClassDeclaration )) {
141- return multiVariable ;
142- }
143-
144- J .VariableDeclarations .NamedVariable variable = multiVariable .getVariables ().get (0 );
145- Optional <Finding > field = fieldsToDecorate .stream ()
146- .filter (f -> f .fieldName .equals (variable .getSimpleName ()))
147- .findFirst ();
148-
149- if (!field .isPresent ()) {
150- return multiVariable ; //not the field we are looking for
151- }
152-
153- J .VariableDeclarations annotated = getAnnotation (field .get ().getAccessLevel ()).apply (
154- getCursor (),
155- multiVariable .getCoordinates ().addAnnotation (comparing (J .Annotation ::getSimpleName )));
156- maybeAddImport ("lombok.Setter" );
157- maybeAddImport ("lombok.AccessLevel" );
158- return annotated ;
159- }
160- }
16187}
0 commit comments