-
Notifications
You must be signed in to change notification settings - Fork 101
mergeFrom() on supertypes and their builders #220
Conversation
- merge from super types builders is allowed only if the type and super type are in the same package due to Enum Property visibility and non-default values.
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
1 similar comment
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
I signed it! |
CLAs look good, thanks! |
1 similar comment
CLAs look good, thanks! |
fb3afcd
to
57b22dd
Compare
57b22dd
to
b1c924e
Compare
1f468f0
to
4475921
Compare
4475921
to
f592eb8
Compare
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.
Hi @ph4r05, and thanks for contributing! I've attached my high-level feedback: there are a number of critical issues you'll need to address before we get to work on cleanup/testing. Feel free to chat me on https://gitter.im/inferred-freebuilder/Lobby !
" * Returns true if the required property corresponding to", | ||
" * {@link Person#getName()} is set.", | ||
" */", | ||
" public boolean isPropertyNameSet() {", |
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.
As per discussion on issue #41, I'm not happy to have these methods added: they can't be removed when a default is set; and they make customization harder. Use a try/catch loop to discard the IllegalStateException thrown by getName().
public abstract ImmutableSet<ParameterizedType> getSuperBuilderTypes(); | ||
|
||
/** Returns super type properties */ | ||
public abstract ImmutableMap<ParameterizedType, ImmutableList<Property>> getSuperTypeProperties(); |
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'd prefer this map stored a new value type containing a set of properties and a boolean indicating whether there is a builder or not.
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.
Also, generic builders and generic supertypes will be problematic. For generic builders, you'll have to be very careful you're putting the right type parameters in the right places (which you may already be doing, but I'd need to see tests). For generic supertypes, you'll need to figure out the correct wildcard parameterisation to put in.
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.
You'll need to factor in visibility as well; we can't accidentally generate a method accepting a package-scoped type from another package, as that's a compile error.
|
||
// Code builder dance | ||
if (builder.isPresent()) { | ||
final Metadata metadataSuperType = analyse(superType); |
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.
We've already figured out what properties are implied by what getter methods; we should just check to see which of those methods are declared abstract on this supertype, rather than regenerating everything.
Also, you can't call analyse on non-FreeBuilder-annotated types, as they shouldn't be expected to follow FreeBuilder's rules about abstract methods.
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, and covariant return types are going to cause issues. You can either identify those occasions where runtime type checking is going to be safe (not forgetting optionals, collections, etc. can typecheck members), or bail out entirely if the return type doesn't exactly match what you'd expect. I'd recommend the latter, especially as a first PR.
} | ||
|
||
final Optional<AnnotationMirror> freeBuilderMirror = | ||
findAnnotationMirror(superType, FreeBuilder.class); |
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 won't work: the FreeBuilder annotation is source-only. If your two types are not compiled together, or if your IDE decides to compile the two classes separately (e.g. you change your subtype in Eclipse), you'll be given the class definition from the compiled JAR. Check out the logic in BuildablePropertyFactory, for example. In this case, however, you'll need to check for the presence of all the getter methods too, since a user might have generated a broken builder by hand.
} | ||
} | ||
|
||
toRet.put(pType, ImmutableList.copyOf(superPropertiesRet.values())); |
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.
We don't want to generate a merge method for every single supertype, only those which declare a getter method.
Closing due to lack of activity. I hope you manage to get back to this sometime, @ph4r05 |
Hi everyone,
here is my implementation of the mergeFrom() for super types. It basically addresses #160. I am already using in in my project.
It supports mergeFrom() super types and their builders (if the super type is correctly annotated with the FreeBuilder annotation).
I've added one minor test to the analysator. I can add more but at first it would be great to know if my implementation is acceptable.
The #176 can be solved with this as well (metadata now have record about supertypes with builders).
Cheers