-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
LOMBOK CONCEPT: What does it take to become a lombok feature?
We can't accept every feature idea for inclusion into lombok; there are a bunch of rules we have to adhere to. Some are set in stone because of limitations, others are more related to what Lombok as a project aims to do. This wiki page covers the rules.
For any feature request, we calculate the 'worth' of the feature. Good traits for a feature:
- When it's useful at all, it replaces a ton of boilerplate (for example, if you look at what
@Builder
saves in boilerplate, it scores really well. Something like@Log
doesn't do great on this one). - It comes up lots in normal java programming (here,
@Log
does much better).
Bad traits:
- The lombok feature itself is hard to maintain and/or create.
- The lomboked code you end up writing lacks 'obviousness': If someone looks at code that uses the proposed lombok feature, how likely are they to understand what's going on without having read the lombok page on the feature? Something like
@Getter String x;
is very obvious: Even if you have no idea what lombok even is, you can guess what's going on there. Even if you don't,@Getter
is a type, and in most IDEs you can (ctrl/cmd)-click on the identifier to hop to the source and/or read the javadocs. - Leakiness: Do you still need to know what lombok does under the hood to properly use the feature and understand the repercussions? If yes, that's a bad sign.
We get literally many hundreds of feature requests. If we deny a feature request without further comment, assume it just doesn't appear to us that its benefits outweigh the costs. If you are really convinced some feature is a good idea, convince us, in terms of the above good vs. bad traits, that it's worth it as a feature.
Lombok is not invoked at all if the code doesn't parse. So, any code which is not syntactically valid java is not something lombok can modify or use. Example of a feature that we simply cannot do: 'Make lombok support the elvis operator, such that String x = foo?.bar();
makes x be null
if foo
is null
.' – we can't do that, because that's not syntactically valid java. It's acceptable if the code is semantically invalid, but it has to syntactically parse before lombok can do its thing.
(For more detailed entry on this, see LOMBOK CONCEPT: Resolution
Lombok generates class members. For example, Lombok generates getter methods. This results in a chicken-and-egg issue: Lombok cannot know about class members in order to apply a transformation, because by the time the compiler environment knows about them, it's too late to add more. For example, it is not possible for lombok's @Getter
annotation to also generate getters for fields in your superclass: To ask the classpath/sourcepath about the parent class's contents means it's too late to add anything.
Knowing about the existence of classes and/or the members inside them is called resolution. Generally, lombok features cannot rely on resolution.
We CAN technically work around this restriction (and some features even do this; to some extent both val
and especially @Delegate
do this), but it's a very high maintenance burden to do so, and the feature tends to measurably slow down compilation performance. Your feature request needs to be extraordinarily useful in order to be considered if it requires resolution.
Sometimes a feature request is simple enough to implement and easy enough to understand but we still deny it. Imagine this was possible with lombok:
@Getter(instance = true, lazy = true, fixCase = true, access = AccessLevel.PACKAGE, retype = List.class, fluent = true, chain = true, safetyGetter = true, prefix = "f", sync = true)
Trying to maintain the code that powers Getter
if it has that many features, ensuring that any combination of options either makes sense or at least generates a sensible error message, testing the combinatory explosion of options sounds like a nightmare to maintain.
The reality of having that many options thrown at you when you autocomplete on @Getter
's parameter, or covering 50 separate options in Getter
's documentation, sounds like it turns @Getter
into a much worse lombok feature versus what it is now... even though this hypothetical everything-and-the-kitchen-sink variant can do more.
In other words, every feature has the inherent downside of being a thing that needs to be documented, shows up in auto-complete, and needs to be maintained. Sometimes that is enough downside to deny a feature request; if the request is for an exotic feature or something that barely removes any boilerplate (or, often, both), that'll be the case.