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

Add support of the inheritance with generics. #99

Merged
merged 3 commits into from
Nov 19, 2018
Merged

Conversation

ma1uta
Copy link
Contributor

@ma1uta ma1uta commented Oct 17, 2018

This also fixes the #97.

@@ -109,10 +117,32 @@ private void asFormatConverter(final StructInfo si, final String name, final Str
code.append("\t\tprivate final java.lang.reflect.Type[] actualTypes;\n");
}

Map<String, TypeMirror> genericAttributes = new HashMap<>();
Copy link
Member

Choose a reason for hiding this comment

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

It would be more consistent to do this analysis in Analysis.java (in analyze() method)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, I will move this analysis to the Analysis class.

@@ -109,10 +117,32 @@ private void asFormatConverter(final StructInfo si, final String name, final Str
code.append("\t\tprivate final java.lang.reflect.Type[] actualTypes;\n");
}

Map<String, TypeMirror> genericAttributes = new HashMap<>();
for (AttributeInfo attr : si.attributes.values()) {
if (!si.isParameterized && attr.isGeneric) {
Copy link
Member

Choose a reason for hiding this comment

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

We can handle generics later.... but in that case at least leave a TODO comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can lost the actual generic values later. I will double check this code.

@@ -227,7 +265,11 @@ private void asFormatConverter(final StructInfo si, final String name, final Str
if (attr.isArray) {
type = typeForGeneric(((ArrayType) attr.type).getComponentType(), attr.typeVariablesIndex);
} else {
type = typeForGeneric(attr.type, attr.typeVariablesIndex);
if (si.isParameterized) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you pretty please fix your alignments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, of course.

* @param stream where to write resulting JSON
* @throws IOException error when unable to serialize instance
*/
public final void serialize(@Nullable final Object value, @Nullable Class<?> typeManifest, final OutputStream stream) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

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

If we are gonna have such method, it should accept a Type instead of Class and it should not be nullable

I guess the method is useful (even if there are already too many methods here...)

I kind of am not a fan of such method (since you can send in a different object from the signature),
but it is useful.
What might make more sense it to have a generic signature if we are passing in a Class

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can avoid this method. Also I found a bug (?) if deserialize a child class the resulting json will be without discriminator.

@ma1uta
Copy link
Contributor Author

ma1uta commented Oct 18, 2018

Fix remarks. Please don't merge this commit, I'll try to fix the bug with serialization and remove a new method in the DslJson.

@ma1uta
Copy link
Contributor Author

ma1uta commented Oct 18, 2018

I've fixed the bug with missing descriptor. Could you please code review changes again?

@@ -24,11 +30,13 @@
private final Writer code;
private final Context context;
private final EnumTemplate enumTemplate;
private final ProcessingEnvironment processingEnv;
Copy link
Member

Choose a reason for hiding this comment

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

You are not using this anymore. Please clean it up

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I will do it.

@@ -425,7 +441,33 @@ void fromObject(final StructInfo si, final String className) throws IOException
code.append("\t}\n");
}

private void writeObject(final String className, List<AttributeInfo> sortedAttributes) throws IOException {
private void writeDiscriminator(final StructInfo si) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't look right.
There is the MixinFormatter which adds discriminator.
Discriminator makes sense only on base/abstract classes and interfaces.
If you are serializing concrete class it should be serialized without the discriminator.
If you are serializing interface/abstract it should be serialized with the discriminator.

You mentioned some issue which you found? Which test covers that specific issue and this generated code?

Copy link
Member

Choose a reason for hiding this comment

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

I thought a bit about what you are trying to do here and I think I understand.
It makes sense to always serialize discriminator when it's defined on an object.
The current deserializeDiscriminator was kind of useless on non abstract things anyway, and this would make it useful.
In that regard it would be better if I called it just discriminator (it's still new so I'm fine with making that breaking change).
But in that case, discriminator should be written outside of writeContentFull, since that is reused by the mixin thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, might be the MixinFormatter is better place where we can write deserializer.

Copy link
Member

Choose a reason for hiding this comment

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

MixinFormatter already does the expected thing. If we want to have this new feature to always put discriminator even on classes, you should do it outside of writeContent method, eg, here: https://github.com/ngs-doo/dsl-json/blob/master/java8/src/main/java/com/dslplatform/json/processor/ConverterTemplate.java#L442 and https://github.com/ngs-doo/dsl-json/blob/master/java8/src/main/java/com/dslplatform/json/processor/ConverterTemplate.java#L599

path.pop();
}
} while (total != structs.size());
}

private void findGenericAttributes(StructInfo si) {
Copy link
Member

Choose a reason for hiding this comment

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

This looks like it can be done when we register the attribute, instead of later changing the attribute with genericType info

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might be better if we avoid the genericType and fix the type (?) attribute which should point to the correct class. The problem is the concrete class may be lost if we go deep into parent. This method in general is a workaround, for example declaredType.getTypeArguments() return correct class. If we do Element element = declaredType.asElement() the element will lost the information about this class and return the parameter value T.

Copy link
Member

Choose a reason for hiding this comment

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

@varahash added the support for generics so he might know better
I know of two main cases:

  • where we need runtime info to fully construct the correct type (in which case we pass in some additional type info to the converter and do it in runtime)
  • where we have all the info at compile time

Here is the conversion for the runtime case: https://github.com/ngs-doo/dsl-json/blob/master/java8/src/main/java/com/dslplatform/json/processor/ConverterTemplate.java#L274
But compile time case should be just a type?

@@ -35,6 +35,7 @@
public final boolean isGeneric;
public final Map<String, Integer> typeVariablesIndex;
public final boolean containsStructOwnerType;
public TypeMirror genericType;
Copy link
Member

Choose a reason for hiding this comment

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

Ideally it should be final, unless there is some important reason it cant be

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see my previous comment. I don't know the code well and might be we can remove this parameter.

assertTrue(child.getBoolValue());

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
dslJson.serialize(child, outputStream);
Copy link
Member

Choose a reason for hiding this comment

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

The previous test where you explicitly specified the type was the expected behavior.
This doesn't look like the expected behavior to me unless you explicitly add that discriminator also to the class annotation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree.

@zapov
Copy link
Member

zapov commented Oct 21, 2018

btw. This is really close to done (with some behavior changes)
I can merge it as is and fix remaining stuff next weekend if that will help

@ma1uta
Copy link
Contributor Author

ma1uta commented Oct 24, 2018

Sorry, I was busy. I have time to wait and we can do it correct. I will try to find time to fix remarks and improve the code.

@zapov
Copy link
Member

zapov commented Oct 24, 2018

Np. We are not in hurry :)

@zapov
Copy link
Member

zapov commented Nov 17, 2018

@ma1uta do you have any ETA when you will be able to finish this?

@zapov zapov merged commit 8687416 into ngs-doo:master Nov 19, 2018
@ma1uta
Copy link
Contributor Author

ma1uta commented Dec 17, 2018

Sorry, unfortunately I was off these days.
Thanks for changes.

@zapov
Copy link
Member

zapov commented Dec 18, 2018

Np. Tnx for the initial effort

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants