Move Lombok `onX` `@__` arguments to `onX_` on Java 8+
What problem are you trying to solve?
Lombok has an experimental feature to add annotations to the methods they generate: https://projectlombok.org/features/experimental/onX
On javac7, to use any of the 3
onXfeatures, you must wrap the annotations to be applied to the constructor / method / parameter in@__(@AnnotationGoesHere). To apply multiple annotations, use@__({@Annotation1, @Annotation2}). The annotations can themselves obviously have parameters as well. On javac8 and up, you add an underscore afteronMethod,onParam, oronConstructor.
Folks might not be fully aware of this change, and it does help readability to move away from @__. We already have Lombok best practices recipes here, so it felt like a natural place to have a recipe for this as well.
/cc @timo-a
What precondition(s) should be checked before applying this recipe?
- Uses
@__. - On Java 8+.
Describe the situation before applying the recipe
import lombok.Getter;
import lombok.Setter;
import javax.inject.Inject;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.validation.constraints.Max;
public class OnXExample {
@Getter(onMethod=@__({@Id, @Column(name="unique-id")})) //JDK7
@Setter(onParam=@__(@Max(10000))) //JDK7
private long unid;
}
Describe the situation after applying the recipe
import lombok.Getter;
import lombok.Setter;
import javax.inject.Inject;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.validation.constraints.Max;
public class OnXExample {
@Getter(onMethod_={@Id, @Column(name="unique-id")}) //JDK8
@Setter(onParam_=@Max(10000)) //JDK8
private long unid;
}
Any additional context
This is an experimental feature available for getter, setter, wither and constructors. The example above only shows two.
- https://projectlombok.org/features/experimental/onX
In terms of implementation we'll want a JavaVisitor (not a JavaIsoVisitor) that overrides visitAnnotation, and for any matching @__ annotation returns the arguments passed into the annotation instead of the annotation itself. Do note that you'll want to call super.visitAnnotation for any non-matching annotations to ensure the arguments are visited as well.