-
-
Notifications
You must be signed in to change notification settings - Fork 754
Improve generation of generic formatters #1010
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
Conversation
|
That's very interesting, and looks like a good idea. Since there is static code demonstrating use of each closed generic type even in the new generated code, I hope that AOT compilers would still produce the closed generic types in the machine code. @neuecc do you know if that's the case? |
|
Yes, this is an idea that I originally introduced to mayuki, so I think it should work fine. |
|
@AArnott @neuecc @mayuki Also, another issue I found is that generic type constraints are not translated and will result in a compile error: [MessagePackObject]
public class MyGenericClass<T> where T : struct
{
[Key(0)]
public T Value { get; set; }
}Will produce public sealed class MyGenericClassFormatter<T> : IMessagePackFormatter<MyGenericClass<T>>
{ ... }Which will result in a compile error because T is not type constrained to be a struct. Sorry for the late response, I only saw this now after updating my mpc to the latest version |
|
Bummer. It's too bad we don't have many regression tests for mpc. Some were introduced recently though, so we ought to be able to take PRs that add features or fix bugs and add tests to make sure they don't regress in the future. @thorgeirk11 can you file a bug to track the regression? Would you feel up to sending another PR to fix it, perhaps with tests? |
|
Oh, I'm sorry.... I failed to consider such a case, which caused a regression. |
|
@thorgeirk11 [MessagePackObject]
public class TreeNode<T>
{
[Key(0)]
public TreeNode<T> Parent { get; set; }
}
[MessagePackObject]
public class Leaf : TreeNode<Leaf> { }
[MessagePackObject]
public class Leaf2 : TreeNode<Leaf2> { }However, the Generator, as modified by this PR, generates the following Formatters and a Resolver codes. public sealed class LeafFormatter : IMessagePackFormatter<Leaf> { ... }
public sealed class Leaf2Formatter : IMessagePackFormatter<Leaf2> { ... }
public sealed class TreeNodeFormatter<T> : IMessagePackFormatter<TreeNode<T>> { ... }switch (key)
{
case 0: return new TreeNodeFormatter<Leaf>();
case 1: return new TreeNodeFormatter<Leaf2>();
case 2: return new LeafFormatter();
case 3: return new Leaf2Formatter();
default: return null;
}Only one Another problem with generic type parameter constraints is reported, I could reproduce it and will work on it separately. |
|
@mayuki Thanks for the quick response! Yeah on second look that bug doesn't seem to be happening with the latest version. [MessagePackObject]
[Union(0, typeof(ADataModel<int>))]
public class ADataModel<T>
{
[Key(1)]
public List<T> Content { get; set; }
}This code will result in a compile error static GeneratedResolverGetFormatterHelper()
{
lookup = new global::System.Collections.Generic.Dictionary<Type, int>(2)
{
{ typeof(global::MessagePackDemo.ADataModel<int>), 0 },
{ typeof(global::System.Collections.Generic.List<T>), 1 }, // Compie Error: T is not defined in this context
};
}Amazing work! Those tests will help a lot! |
When generating the formatter, the generator generates a formatter for each closed generics type.
In this PR will change this behavior to generate the formatter for open types. And resolver will use closed generics type formatter with type parameters.
The current generator generates the following close type formatters and resolver.
This PR changes the generation of an open generics type formatter as follows.