Skip to content

Commit 1c033bc

Browse files
Merge pull request #830 from opsidjflksdf/generics-in-mpc-2-simpler-faster
Generics in mpc 2 simpler faster
2 parents f0816a3 + 8b17016 commit 1c033bc

File tree

6 files changed

+73
-14
lines changed

6 files changed

+73
-14
lines changed

src/MessagePack.GeneratorCore/CodeAnalysis/Definitions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public class ObjectSerializationInfo : IResolverRegisterInfo
2424

2525
public string FullName { get; set; }
2626

27+
public string TemplateParametersString { get; set; }
28+
2729
public string Namespace { get; set; }
2830

2931
public bool IsIntKey { get; set; }

src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using System.Linq;
9+
using System.Text;
910
using Microsoft.CodeAnalysis;
1011

1112
namespace MessagePackCompiler.CodeAnalysis
@@ -269,6 +270,7 @@ public class TypeCollector
269270
private List<EnumSerializationInfo> collectedEnumInfo;
270271
private List<GenericSerializationInfo> collectedGenericInfo;
271272
private List<UnionSerializationInfo> collectedUnionInfo;
273+
private List<ObjectSerializationInfo> collectedUnboundGenericInfo;
272274

273275
public TypeCollector(Compilation compilation, bool disallowInternal, bool isForceUseMap, Action<string> logger)
274276
{
@@ -307,10 +309,11 @@ private void ResetWorkspace()
307309
this.collectedEnumInfo = new List<EnumSerializationInfo>();
308310
this.collectedGenericInfo = new List<GenericSerializationInfo>();
309311
this.collectedUnionInfo = new List<UnionSerializationInfo>();
312+
this.collectedUnboundGenericInfo = new List<ObjectSerializationInfo>();
310313
}
311314

312315
// EntryPoint
313-
public (ObjectSerializationInfo[] objectInfo, EnumSerializationInfo[] enumInfo, GenericSerializationInfo[] genericInfo, UnionSerializationInfo[] unionInfo) Collect()
316+
public (ObjectSerializationInfo[] objectInfo, EnumSerializationInfo[] enumInfo, GenericSerializationInfo[] genericInfo, UnionSerializationInfo[] unionInfo, ObjectSerializationInfo[] unboundGenericInfo) Collect()
314317
{
315318
this.ResetWorkspace();
316319

@@ -323,7 +326,8 @@ private void ResetWorkspace()
323326
this.collectedObjectInfo.OrderBy(x => x.FullName).ToArray(),
324327
this.collectedEnumInfo.OrderBy(x => x.FullName).ToArray(),
325328
this.collectedGenericInfo.Distinct().OrderBy(x => x.FullName).ToArray(),
326-
this.collectedUnionInfo.OrderBy(x => x.FullName).ToArray());
329+
this.collectedUnionInfo.OrderBy(x => x.FullName).ToArray(),
330+
this.collectedUnboundGenericInfo.OrderBy(x => x.FullName).ToArray());
327331
}
328332

329333
// Gate of recursive collect
@@ -533,10 +537,49 @@ private void CollectGeneric(INamedTypeSymbol type)
533537

534538
this.collectedGenericInfo.Add(enumerableInfo);
535539
}
540+
541+
return;
542+
}
543+
544+
if (type.IsDefinition)
545+
{
546+
ObjectSerializationInfo unboundGenericInfo = GetObjectInfo(type);
547+
collectedUnboundGenericInfo.Add(unboundGenericInfo);
548+
}
549+
else
550+
{
551+
foreach (ITypeSymbol item in type.TypeArguments)
552+
{
553+
this.CollectCore(item);
554+
}
555+
556+
StringBuilder formatterBuilder = new StringBuilder();
557+
if (!type.ContainingNamespace.IsGlobalNamespace)
558+
{
559+
formatterBuilder.Append(type.ContainingNamespace.ToDisplayString() + ".");
560+
}
561+
562+
formatterBuilder.Append(type.Name + "Formatter");
563+
formatterBuilder.Append("<" + string.Join(", ", type.TypeArguments) + ">");
564+
565+
GenericSerializationInfo info = new GenericSerializationInfo
566+
{
567+
FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
568+
569+
FormatterName = formatterBuilder.ToString(),
570+
};
571+
572+
this.collectedGenericInfo.Add(info);
536573
}
537574
}
538575

539576
private void CollectObject(INamedTypeSymbol type)
577+
{
578+
ObjectSerializationInfo info = GetObjectInfo(type);
579+
collectedObjectInfo.Add(info);
580+
}
581+
582+
private ObjectSerializationInfo GetObjectInfo(INamedTypeSymbol type)
540583
{
541584
var isClass = !type.IsValueType;
542585

@@ -929,20 +972,32 @@ private void CollectObject(INamedTypeSymbol type)
929972
needsCastOnAfter = !type.GetMembers("OnAfterDeserialize").Any();
930973
}
931974

975+
string templateParametersString;
976+
if (type.TypeParameters.Count() > 0)
977+
{
978+
templateParametersString = "<" + string.Join(", ", type.TypeParameters) + ">";
979+
}
980+
else
981+
{
982+
templateParametersString = null;
983+
}
984+
932985
var info = new ObjectSerializationInfo
933986
{
934987
IsClass = isClass,
935988
ConstructorParameters = constructorParameters.ToArray(),
936989
IsIntKey = isIntKey,
937990
Members = isIntKey ? intMembers.Values.ToArray() : stringMembers.Values.ToArray(),
938991
Name = type.ToDisplayString(ShortTypeNameFormat).Replace(".", "_"),
992+
TemplateParametersString = templateParametersString,
939993
FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
940994
Namespace = type.ContainingNamespace.IsGlobalNamespace ? null : type.ContainingNamespace.ToDisplayString(),
941995
HasIMessagePackSerializationCallbackReceiver = hasSerializationConstructor,
942996
NeedsCastOnAfter = needsCastOnAfter,
943997
NeedsCastOnBefore = needsCastOnBefore,
944998
};
945-
this.collectedObjectInfo.Add(info);
999+
1000+
return info;
9461001
}
9471002

9481003
private static bool TryGetNextConstructor(IEnumerator<IMethodSymbol> ctorEnumerator, ref IMethodSymbol ctor)

src/MessagePack.GeneratorCore/CodeGenerator.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public async Task GenerateFileAsync(
5555
sw.Restart();
5656
logger("Method Collect Start");
5757

58-
var (objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect();
58+
var (objectInfo, enumInfo, genericInfo, unionInfo, unboundGenericInfo) = collector.Collect();
5959

6060
logger("Method Collect Complete:" + sw.Elapsed.ToString());
6161

@@ -66,6 +66,7 @@ public async Task GenerateFileAsync(
6666
{
6767
// SingleFile Output
6868
var objectFormatterTemplates = objectInfo
69+
.Concat(unboundGenericInfo)
6970
.GroupBy(x => x.Namespace)
7071
.Select(x => new FormatterTemplate()
7172
{
@@ -137,7 +138,7 @@ public async Task GenerateFileAsync(
137138
else
138139
{
139140
// Multiple File output
140-
foreach (var x in objectInfo)
141+
foreach (var x in objectInfo.Concat(unboundGenericInfo))
141142
{
142143
var template = new FormatterTemplate()
143144
{
@@ -184,7 +185,7 @@ public async Task GenerateFileAsync(
184185
await OutputToDirAsync(output, resolverTemplate.Namespace, resolverTemplate.ResolverName, multioutSymbol, resolverTemplate.TransformText(), cancellationToken).ConfigureAwait(false);
185186
}
186187

187-
if (objectInfo.Length == 0 && enumInfo.Length == 0 && genericInfo.Length == 0 & unionInfo.Length == 0)
188+
if (objectInfo.Length == 0 && enumInfo.Length == 0 && genericInfo.Length == 0 && unionInfo.Length == 0 && unboundGenericInfo.Length == 0)
188189
{
189190
logger("Generated result is empty, unexpected result?");
190191
}

src/MessagePack.GeneratorCore/Generator/FormatterTemplate.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ namespace ");
4747
foreach(var objInfo in ObjectSerializationInfos) {
4848
this.Write("\r\n public sealed class ");
4949
this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.Name));
50-
this.Write("Formatter : global::MessagePack.Formatters.IMessagePackFormatter<");
50+
this.Write("Formatter");
51+
this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.TemplateParametersString != null? objInfo.TemplateParametersString : ""));
52+
this.Write(" : global::MessagePack.Formatters.IMessagePackFormatter<");
5153
this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FullName));
5254
this.Write(">\r\n {\r\n");
5355
foreach(var item in objInfo.Members) {

src/MessagePack.GeneratorCore/Generator/FormatterTemplate.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace <#= Namespace #>
2626
using MessagePack;
2727
<# foreach(var objInfo in ObjectSerializationInfos) { #>
2828

29-
public sealed class <#= objInfo.Name #>Formatter : global::MessagePack.Formatters.IMessagePackFormatter<<#= objInfo.FullName #>>
29+
public sealed class <#= objInfo.Name #>Formatter<#= objInfo.TemplateParametersString != null? objInfo.TemplateParametersString : "" #> : global::MessagePack.Formatters.IMessagePackFormatter<<#= objInfo.FullName #>>
3030
{
3131
<# foreach(var item in objInfo.Members) { #>
3232
<# if(item.CustomFormatterTypeName != null) { #>

src/MessagePack.GeneratorCore/Generator/ResolverTemplate.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// ------------------------------------------------------------------------------
22
// <auto-generated>
3-
// このコードはツールによって生成されました。
4-
// ランタイム バージョン: 16.0.0.0
3+
// This code was generated by a tool.
4+
// Runtime Version: 16.0.0.0
55
//
6-
// このファイルへの変更は、正しくない動作の原因になる可能性があり、
7-
// コードが再生成されると失われます。
6+
// Changes to this file may cause incorrect behavior and will be lost if
7+
// the code is regenerated.
88
// </auto-generated>
99
// ------------------------------------------------------------------------------
1010
namespace MessagePackCompiler.Generator
@@ -40,8 +40,7 @@ public virtual string TransformText()
4040
4141
namespace ");
4242
this.Write(this.ToStringHelper.ToStringWithCulture(Namespace));
43-
this.Write("\r\n{\r\n using System;\r\n using System.Buffers;\r\n using MessagePack;\r\n\r\n " +
44-
"public class ");
43+
this.Write("\r\n{\r\n using System;\r\n\r\n public class ");
4544
this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName));
4645
this.Write(" : global::MessagePack.IFormatterResolver\r\n {\r\n public static readonly " +
4746
"global::MessagePack.IFormatterResolver Instance = new ");

0 commit comments

Comments
 (0)