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 configurable method name prefixes to builders #86
Conversation
d2fc1b1
to
c70ac01
Compare
Thanks for the submission - interesting idea to make this a more useful transition from Immutables. What about this - when these options are active create an additional interface (like
This way, you can add |
That's actually quite clever. I like it. I would, however, hide it behind some flag. Lastly: |
Up to you - let me know. |
I will take a stab at it in approx 14 hours :-) |
Just posting to let you know I took a stab at it and did not arrive at a result I was happy with. Here's why:
The end of this train of thought would be to introduce a whole new class; So you would possibly have a new build method that returned this bean type rather than the original record. The issue here is that now suddenly all your calling code needs to dereference this generated bean type which merely wraps the original record. I don't really like the thought of not only having to use generated types when building records, but also when using them.. The record sort of ends up never actually being used for anything in the codebase apart from being the metadata input to this library. Even Sonar thinks this approach is dodgy: https://rules.sonarsource.com/java/RSPEC-6211 So in closing, I'm not going to try to make something I cannot personally recommend the use of, so I suppose it's up to you to figure out something super-clever :) |
It can be a separate interface just like With - it doesn't needs to extend With. So:
|
Haha, how did I miss that. Alright, hold on for an hour or so :) |
Add configurable Bean interface to add prefixed getters to record
c70ac01
to
8a770af
Compare
@@ -72,6 +73,9 @@ | |||
.addTypeVariables(typeVariables); | |||
addVisibility(recordActualPackage.equals(packageName), record.getModifiers()); | |||
addWithNestedClass(); | |||
if (!metaData.beanClassName().isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also check that the other required options are set. I did a quick test where I removed setterPrefix = "set", getterPrefix = "get", booleanPrefix = "is",
and you then get compilation failure. Let's either just ignore this setting if the others aren't sent or output a message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really? I did the same in CustomMethodNames.class, and it built just fine with an empty bean interface:
/** * Add getters to {@code CustomMethodNames} */ @Generated("io.soabase.recordbuilder.core.RecordBuilder") public interface Bean { }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used this:
@RecordBuilder
@RecordBuilder.Options(beanClassName = "Bean")
public record CustomMethodNames(
int theValue,
List<Integer> theList,
boolean theBoolean) implements Bean {
}
I then get:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile (default-testCompile) on project record-builder-test: Compilation failure: Compilation failure:
[ERROR] /Users/jordanzimmerman/dev/oss/soabase/record-builder/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestCustomMethodNames.java:[29,9] cannot find symbol
[ERROR] symbol: method setTheValue(int)
[ERROR] location: class io.soabase.recordbuilder.test.CustomMethodNamesBuilder
[ERROR] /Users/jordanzimmerman/dev/oss/soabase/record-builder/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestCustomMethodNames.java:[41,13] cannot find symbol
[ERROR] symbol: method setTheValue(int)
[ERROR] location: class io.soabase.recordbuilder.test.CustomMethodNamesBuilder
[ERROR] /Users/jordanzimmerman/dev/oss/soabase/record-builder/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestCustomMethodNames.java:[53,24] cannot find symbol
[ERROR] symbol: method getTheValue()
[ERROR] location: variable obj of type io.soabase.recordbuilder.test.CustomMethodNames
[ERROR] /Users/jordanzimmerman/dev/oss/soabase/record-builder/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestCustomMethodNames.java:[54,33] cannot find symbol
[ERROR] symbol: method getTheList()
[ERROR] location: variable obj of type io.soabase.recordbuilder.test.CustomMethodNames
[ERROR] /Users/jordanzimmerman/dev/oss/soabase/record-builder/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestCustomMethodNames.java:[55,19] cannot find symbol
[ERROR] symbol: method isTheBoolean()
[ERROR] location: variable obj of type io.soabase.recordbuilder.test.CustomMethodNames
[ERROR] -> [Help 1]
[ERROR]
[ERR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait - those errors are from the test - never mind
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, you do end up with an empty Bean
class. Do we want that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, while completely useless, you did enable the feature to generate the interface, so I would claim it's expected behavior. I can of course add a clause to the if to make it go away in this case, but there's still two corner cases that would result in the same empty interface:
Only getter prefix is enabled, but only boolean fields in record
Only boolean prefix is enabled, but no booleans in record
These two would require me to scan the record for these fields, and at that point I feel I'm making a non-negligible amount of code to check for very little gain. Let me know if you still want me to amend that if and just ignore these corner cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, while completely useless, you did enable the feature to generate the interface
Sure - that makes sense.
Sometimes I feel old and conservative and want to do things the old way.
Just kidding;
We have a giant codebase built on top of Immutables.org. It makes builders with setter methods. To make our migration to records as painless as possible, it is nice to migrate without having to rename the usage of Immutables builders for thousands of classes.
Also, get* set* and is* have been idiomatic Java since "forever". Some people might prefer these prefixes, even if they do make the methods three characters longer