Skip to content
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

Handle duplicate fields from the type and interface #128 #129

Merged
merged 4 commits into from
Apr 29, 2020

Conversation

kobylynskyi
Copy link
Owner

Fixes #128

@kobylynskyi kobylynskyi added the bug Something isn't working label Apr 28, 2020
@kobylynskyi kobylynskyi self-assigned this Apr 28, 2020
@codecov
Copy link

codecov bot commented Apr 28, 2020

Codecov Report

Merging #129 into master will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master     #129   +/-   ##
=========================================
  Coverage     90.83%   90.83%           
- Complexity      404      413    +9     
=========================================
  Files            49       49           
  Lines           993      993           
  Branches        130      131    +1     
=========================================
  Hits            902      902           
- Misses           60       62    +2     
+ Partials         31       29    -2     
Impacted Files Coverage Δ Complexity Δ
...odegen/mapper/TypeDefinitionToDataModelMapper.java 98.52% <100.00%> (ø) 23.00 <11.00> (+9.00)
...kyi/graphql/codegen/model/ParameterDefinition.java 90.90% <0.00%> (ø) 9.00% <0.00%> (ø%)
...l/codegen/model/ProjectionParameterDefinition.java 66.66% <0.00%> (ø) 4.00% <0.00%> (ø%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e2f040c...0ada7b7. Read the comment docs.

FieldDefinitionToParameterMapper.mapFields(mappingConfig, typeDefinition.getFieldDefinitions(), typeDefinition.getName())
.forEach(p -> allParameters.put(p.getName(), p));
// includes parameters from the interface
getInterfacesOfType(typeDefinition, document).stream()
Copy link
Contributor

@joffrey-bion joffrey-bion Apr 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to get fields from the interface in the first place?
By definition, for any implemented interface, all fields should be declared in the type itself as well.

Is it to get metadata like Javadoc?
In this case I think we should "merge" the interface field with the corresponding type's field, because I imagine the doc or directives can also come from the type's field.
Maybe we should take everything from the type's field in priority, and if that field doesn't have a metadata element (like a doc) we fallback to the metadata from the interface's field.

Copy link
Owner Author

@kobylynskyi kobylynskyi Apr 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the example that is shown in the bug, javadoc was present in the interface and not the type.
Another example: you can require custom serialization for a data type that is defined in the interface. And you don’t want to duplicate directives and javadoc in all types for this field. So you will define it in the interface. The type will have just the field.

Copy link
Contributor

@joffrey-bion joffrey-bion Apr 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why we need to read the interface's fields as well, indeed.
However, we could imagine a situation where the doc is overridden in the type (or not even present in the interface), and in that case we need to take the doc from the type's field, not the interface's one.

But with the code as it is here, we would simply override the type's fields data with the interface's one, and lose anything declared directly in the implementing type.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've modified the logic to take JavaDoc and annotations from the type.
And if something is absent then it will be taken from the interface field.

Copy link
Contributor

@joffrey-bion joffrey-bion Apr 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm so sorry to bring this up only now, but now I'm wondering whether we need to look at interface fields at all.
I mean, to generate the Java code for the interface, we use the interface fields and docs. And to generate the Java code for the implementing class, we don't need to look at the interface fields at all, do we?
Javadoc would naturally be inherited by overriding methods (we don't even need to do this at codegen level). And annotations are not inherited, but do we want that?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please create a separate issue with your suggestion?
We can discuss it there.
Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure I can do that, I just felt like it was another way to fix the issue at hand, not a separate issue.
But you're right, we can merge this and fix the bug right away.

allParameters.put(paramDef.getName(), merge(existingParamDef, paramDef));
} else {
allParameters.put(paramDef.getName(), paramDef);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a minor comment, but the whole if block can be replaced by:

allParameters.merge(paramDef.getName(), paramDef, ::merge)

Or something along those lines.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much. I never used this method before.

joffrey-bion
joffrey-bion previously approved these changes Apr 29, 2020
@kobylynskyi kobylynskyi merged commit d188e85 into master Apr 29, 2020
@kobylynskyi kobylynskyi deleted the 128-fix-duplicate-fields-in-type branch April 29, 2020 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Code generation is broken with comments on interfaces' fields (Version: 1.7.0)
2 participants