Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

mergeFrom() on supertypes and their builders #220

Closed
wants to merge 3 commits into from

Conversation

ph4r05
Copy link

@ph4r05 ph4r05 commented Dec 8, 2016

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

- 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.
@googlebot
Copy link

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!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

1 similar comment
@googlebot
Copy link

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!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

@ph4r05
Copy link
Author

ph4r05 commented Dec 8, 2016

I signed it!

@googlebot
Copy link

CLAs look good, thanks!

1 similar comment
@googlebot
Copy link

CLAs look good, thanks!

@ph4r05 ph4r05 changed the title Merge supertypes - #160 mergeFrom() on supertypes - #160 Dec 8, 2016
@ph4r05 ph4r05 force-pushed the merge-supertypes branch 4 times, most recently from 1f468f0 to 4475921 Compare December 8, 2016 20:14
@ph4r05 ph4r05 changed the title mergeFrom() on supertypes - #160 mergeFrom() on supertypes and their builders Dec 9, 2016
Copy link
Collaborator

@alicederyn alicederyn left a 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() {",
Copy link
Collaborator

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();
Copy link
Collaborator

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.

Copy link
Collaborator

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.

Copy link
Collaborator

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);
Copy link
Collaborator

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.

Copy link
Collaborator

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);
Copy link
Collaborator

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()));
Copy link
Collaborator

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.

@alicederyn
Copy link
Collaborator

Closing due to lack of activity. I hope you manage to get back to this sometime, @ph4r05

@alicederyn alicederyn closed this Mar 7, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants