-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add optional prefixes to Builder setter method names #2174
Add optional prefixes to Builder setter method names #2174
Conversation
Related to #1805, this change adds an optional `setterPrefix` parameter to the `Builder` annotation; if this parameter is unspecified or blank the behavior of the `Builder` annotation is unchanged, but if it is present the value specified will be prefixed to the generated methods. For example, using: ``` @builder(setterPrefix = "include") class Foo { private int someValue; } ``` will result in a generated `Builder` class containing an `includeSomeValue(int someValue)` method instead of the default `someValue(int someValue)`.
…builder-setter-prefixes
@rzwitserloot is there anything you'd like to see added to this PR? |
I wish you talked to us first; what's the use case? By far the most common requests we've heard is for 'setX' and 'withX', and we think both of these are objectively bad: 'with' is a term that ought to be reserved for pure, immutable updaters (a builder is the opposite of pure/immutable, hence, a misnomer), and 'set' suggests it's a POJO/bean; builders aren't, hence a misnomer. This include business is new and even stranger. Why would you want your 'builder-setter' method to be prefixed with 'include'? This isn't a case of "hey, if it does not help, at least it doesn't hurt": But it DOES hurt; this is a parameter on the annotation. I can cook up 49 other exotic weird things that we can't explain, at which point If there is a solid use-case, then maybe this can be a feature, but it probably needs a But most of all, this needs an explanation for why; without a solid use case we have to deny the PR. |
I don't disagree on any point; my use case is for working with legacy and/or third-party conventions that don't match those used by Lombok (they use
or
Both of these are non-starters given the number and spread of pre-existing builders, and I don't think this situation is particularly uncommon for other teams.
This was just an example demonstrating that the prefix can be configured to whatever is needed; I'm not actually suggesting it as a practice or anything.
Right; I'm not suggesting adding "exotic weird things" or a large number of parameters or anything like that. This addition is intended to help those of us working with large pre-existing or third-party code bases that don't follow ideal conventions and can't be feasibly updated to do so. |
Regarding:
This PR already has tests in
I didn't make any other changes (to docs or what have you) as I wasn't certain this PR would be accepted, but I'd be more than happy to do so if you decide this is a desirable feature. |
@rzwitserloot first of all huge kudos for the Lombok. I'm surprised you still keep asking about use case / justification after it was given multiple times under #1805 and here. Let me sum this up:
Anyway, it'd be nice to see this accepted. |
Okay, all. We held a long debate, and, the legacy support thing won out. We'll allow it. However, a few notes:
|
@rzwitserloot thanks for taking the time to consider this PR and provide feedback! I appreciate that this probably wasn't an easy decision to come to. I'll take care of all the changes you requested; for prefixing singulars, I was thinking of adding a new So for the md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); to this: char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray(); Would that be acceptable? I haven't spent much time looking at singulars or how the code behind them is generated so if I'm just way off-base please don't hesitate to let me know 😅 |
…floralvikings/lombok into feature/builder-setter-prefixes
fbf8c41
to
650e037
Compare
@rzwitserloot I've duplicated all of the existing I think I've covered every case in which the If the code changes look good to you I'll go ahead and get started on the docs. |
@rzwitserloot just checking in to make sure this PR is still something you'd be willing to bring in; if the code changes look alright I'll write up the docs |
Yup, still active. We've been swamped with presentations (3 separate once in a span of a month) whilst @rspilker had lots of business trips planned and I'm in the middle of a very busy time of the year at my dayjob too. No new lombok version is going to be released without this unless something very drastic happens. |
Updated a bunch of stuff and I think I'm going to eliminate some of these tests, I think you went a tad overboard :) I'll soon push out an edge release with this; next stable lombok release will have it (We'll try to get a move on; current stable lombok has some issues with JDK13 which this edge release fixes...) |
@rzwitserloot Awesome! I definitely went overboard on the tests, but I wanted to be sure I wasn't missing any use cases because I missed quite a few with my first attempt 😅 Please let me know if there's anything other input/assistance you'd like on this, and thanks again for taking the time to review, respond and merge (and for all the other work you do maintaining this awesome project😄) |
Wow, I cant believe you guys finally came off your high horse and implemented the most requested feature in lombok.. lol |
Related to #1805, this change adds an optional
setterPrefix
parameterto the
Builder
annotation; if this parameter is unspecified or blankthe behavior of the
Builder
annotation is unchanged, but if it ispresent the value specified will be prefixed to the generated methods.
For example, using:
will result in a generated
Builder
class containing anincludeSomeValue(int someValue)
method instead of the default
someValue(int someValue)
.