diff --git a/MessagePack.sln b/MessagePack.sln index 77206860..ba71e640 100644 --- a/MessagePack.sln +++ b/MessagePack.sln @@ -23,8 +23,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sandbox", "sandbox", "{BF4C EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "sandbox\Sandbox\Sandbox.csproj", "{ED43BDA5-947C-4769-A47A-F07D3C6142AE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.CodeGenerator", "src\MessagePack.CodeGenerator\MessagePack.CodeGenerator.csproj", "{D8B195AC-9E93-438E-8331-EF3A1F613D0B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynamicCodeDumper", "sandbox\DynamicCodeDumper\DynamicCodeDumper.csproj", "{8E511130-F838-4B47-842B-0FB27AD175B5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedData", "sandbox\SharedData\SharedData.csproj", "{3ABC5C4C-2CE4-459E-8666-F2B181C3DEF3}" @@ -57,7 +55,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{301F812B version.json = version.json EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.UniversalCodeGenerator", "src\MessagePack.UniversalCodeGenerator\MessagePack.UniversalCodeGenerator.csproj", "{10AD85DD-929D-49B8-BD43-45242C2644B7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.UniversalCodeGenerator", "src\MessagePack.UniversalCodeGenerator\MessagePack.UniversalCodeGenerator.csproj", "{10AD85DD-929D-49B8-BD43-45242C2644B7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MessagePack.AspNetCoreMvcFormatter.Tests", "tests\MessagePack.AspNetCoreMvcFormatter.Tests\MessagePack.AspNetCoreMvcFormatter.Tests.csproj", "{79C2B2CB-872A-4BA9-82DC-60F6DD77F940}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -105,18 +105,6 @@ Global {ED43BDA5-947C-4769-A47A-F07D3C6142AE}.Release|x64.Build.0 = Release|Any CPU {ED43BDA5-947C-4769-A47A-F07D3C6142AE}.Release|x86.ActiveCfg = Release|Any CPU {ED43BDA5-947C-4769-A47A-F07D3C6142AE}.Release|x86.Build.0 = Release|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Debug|x64.ActiveCfg = Debug|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Debug|x64.Build.0 = Debug|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Debug|x86.ActiveCfg = Debug|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Debug|x86.Build.0 = Debug|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Release|Any CPU.Build.0 = Release|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Release|x64.ActiveCfg = Release|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Release|x64.Build.0 = Release|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Release|x86.ActiveCfg = Release|Any CPU - {D8B195AC-9E93-438E-8331-EF3A1F613D0B}.Release|x86.Build.0 = Release|Any CPU {8E511130-F838-4B47-842B-0FB27AD175B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8E511130-F838-4B47-842B-0FB27AD175B5}.Debug|Any CPU.Build.0 = Debug|Any CPU {8E511130-F838-4B47-842B-0FB27AD175B5}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -261,6 +249,18 @@ Global {10AD85DD-929D-49B8-BD43-45242C2644B7}.Release|x64.Build.0 = Release|Any CPU {10AD85DD-929D-49B8-BD43-45242C2644B7}.Release|x86.ActiveCfg = Release|Any CPU {10AD85DD-929D-49B8-BD43-45242C2644B7}.Release|x86.Build.0 = Release|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Debug|x64.ActiveCfg = Debug|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Debug|x64.Build.0 = Debug|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Debug|x86.ActiveCfg = Debug|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Debug|x86.Build.0 = Debug|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|Any CPU.Build.0 = Release|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x64.ActiveCfg = Release|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x64.Build.0 = Release|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x86.ActiveCfg = Release|Any CPU + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -269,7 +269,6 @@ Global {7ABB33EE-A2F1-492B-8DAF-5DF89F0F0B79} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC} {9E1A55CA-711D-4F58-A332-735960E3434C} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE} {ED43BDA5-947C-4769-A47A-F07D3C6142AE} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700} - {D8B195AC-9E93-438E-8331-EF3A1F613D0B} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC} {8E511130-F838-4B47-842B-0FB27AD175B5} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700} {3ABC5C4C-2CE4-459E-8666-F2B181C3DEF3} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700} {C01E1407-7FEC-4C1D-B0B4-74D95A317AA6} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC} @@ -282,6 +281,7 @@ Global {814F94D6-1413-4ACB-B1B5-A3488CAA1E6B} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700} {2A32A538-BA26-4D89-85D0-E4249AFA0837} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700} {10AD85DD-929D-49B8-BD43-45242C2644B7} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC} + {79C2B2CB-872A-4BA9-82DC-60F6DD77F940} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {26F0752B-06F7-44AD-BFEE-8F2E36B3AA27} diff --git a/src/MessagePack.AspNetCoreMvcFormatter/Formatter.cs b/src/MessagePack.AspNetCoreMvcFormatter/Formatter.cs deleted file mode 100644 index 4bc2025a..00000000 --- a/src/MessagePack.AspNetCoreMvcFormatter/Formatter.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Microsoft.AspNetCore.Mvc.Formatters; -using System.Threading.Tasks; - -namespace MessagePack.AspNetCoreMvcFormatter -{ - public class MessagePackOutputFormatter : IOutputFormatter //, IApiResponseTypeMetadataProvider - { - const string ContentType = "application/x-msgpack"; - static readonly string[] SupportedContentTypes = new[] { ContentType }; - - readonly IFormatterResolver resolver; - - public MessagePackOutputFormatter() - : this(null) - { - - } - public MessagePackOutputFormatter(IFormatterResolver resolver) - { - this.resolver = resolver ?? MessagePackSerializer.DefaultResolver; - } - - //public IReadOnlyList GetSupportedContentTypes(string contentType, Type objectType) - //{ - // return SupportedContentTypes; - //} - - public bool CanWriteResult(OutputFormatterCanWriteContext context) - { - return true; - } - - public Task WriteAsync(OutputFormatterWriteContext context) - { - context.HttpContext.Response.ContentType = ContentType; - - // 'object' want to use anonymous type serialize, etc... - if (context.ObjectType == typeof(object)) - { - if (context.Object == null) - { - context.HttpContext.Response.Body.WriteByte(MessagePackCode.Nil); - return Task.CompletedTask; - } - else - { - // use concrete type. - MessagePackSerializer.NonGeneric.Serialize(context.Object.GetType(), context.HttpContext.Response.Body, context.Object, resolver); - return Task.CompletedTask; - } - } - else - { - MessagePackSerializer.NonGeneric.Serialize(context.ObjectType, context.HttpContext.Response.Body, context.Object, resolver); - return Task.CompletedTask; - } - } - } - - public class MessagePackInputFormatter : IInputFormatter // , IApiRequestFormatMetadataProvider - { - const string ContentType = "application/x-msgpack"; - static readonly string[] SupportedContentTypes = new[] { ContentType }; - - readonly IFormatterResolver resolver; - - public MessagePackInputFormatter() - : this(null) - { - - } - - public MessagePackInputFormatter(IFormatterResolver resolver) - { - this.resolver = resolver ?? MessagePackSerializer.DefaultResolver; - } - - //public IReadOnlyList GetSupportedContentTypes(string contentType, Type objectType) - //{ - // return SupportedContentTypes; - //} - - public bool CanRead(InputFormatterContext context) - { - return true; - } - - public Task ReadAsync(InputFormatterContext context) - { - var request = context.HttpContext.Request; - var result = MessagePackSerializer.NonGeneric.Deserialize(context.ModelType, request.Body, resolver); - return InputFormatterResult.SuccessAsync(result); - } - } -} \ No newline at end of file diff --git a/src/MessagePack.AspNetCoreMvcFormatter/LZ4MessagePackInputFormatter.cs b/src/MessagePack.AspNetCoreMvcFormatter/LZ4MessagePackInputFormatter.cs new file mode 100644 index 00000000..bed5a917 --- /dev/null +++ b/src/MessagePack.AspNetCoreMvcFormatter/LZ4MessagePackInputFormatter.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace MessagePack.AspNetCoreMvcFormatter +{ + public class LZ4MessagePackInputFormatter : IInputFormatter + { + private const string ContentType = "application/x-msgpack"; + private readonly IFormatterResolver resolver; + + public LZ4MessagePackInputFormatter() : this(null) + { + } + + public LZ4MessagePackInputFormatter(IFormatterResolver resolver) + { + this.resolver = resolver ?? MessagePackSerializer.DefaultResolver; + } + + public bool CanRead(InputFormatterContext context) => + context.HttpContext.Request.ContentType == ContentType; + + public Task ReadAsync(InputFormatterContext context) + { + var request = context.HttpContext.Request; + var result = LZ4MessagePackSerializer.NonGeneric.Deserialize(context.ModelType, request.Body, resolver); + return InputFormatterResult.SuccessAsync(result); + } + } +} diff --git a/src/MessagePack.AspNetCoreMvcFormatter/LZ4MessagePackOutputFormatter.cs b/src/MessagePack.AspNetCoreMvcFormatter/LZ4MessagePackOutputFormatter.cs new file mode 100644 index 00000000..cf852cb0 --- /dev/null +++ b/src/MessagePack.AspNetCoreMvcFormatter/LZ4MessagePackOutputFormatter.cs @@ -0,0 +1,47 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace MessagePack.AspNetCoreMvcFormatter +{ + public class LZ4MessagePackOutputFormatter : IOutputFormatter + { + private const string ContentType = "application/x-msgpack"; + private readonly IFormatterResolver resolver; + + public LZ4MessagePackOutputFormatter() : this(null) + { + } + + public LZ4MessagePackOutputFormatter(IFormatterResolver resolver) + { + this.resolver = resolver ?? MessagePackSerializer.DefaultResolver; + } + + public bool CanWriteResult(OutputFormatterCanWriteContext context) => + context.HttpContext.Request.ContentType == ContentType; + + public Task WriteAsync(OutputFormatterWriteContext context) + { + context.HttpContext.Response.ContentType = ContentType; + + if (context.ObjectType == typeof(object)) + { + if (context.Object == null) + { + context.HttpContext.Response.Body.WriteByte(MessagePackCode.Nil); + return Task.CompletedTask; + } + else + { + LZ4MessagePackSerializer.NonGeneric.Serialize(context.Object.GetType(), context.HttpContext.Response.Body, context.Object, resolver); + return Task.CompletedTask; + } + } + else + { + LZ4MessagePackSerializer.NonGeneric.Serialize(context.ObjectType, context.HttpContext.Response.Body, context.Object, resolver); + return Task.CompletedTask; + } + } + } +} diff --git a/src/MessagePack.AspNetCoreMvcFormatter/MessagePackInputFormatter.cs b/src/MessagePack.AspNetCoreMvcFormatter/MessagePackInputFormatter.cs new file mode 100644 index 00000000..2a3ae8fa --- /dev/null +++ b/src/MessagePack.AspNetCoreMvcFormatter/MessagePackInputFormatter.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace MessagePack.AspNetCoreMvcFormatter +{ + public class MessagePackInputFormatter : IInputFormatter + { + private const string ContentType = "application/x-msgpack"; + private readonly IFormatterResolver resolver; + + public MessagePackInputFormatter() : this(null) + { + } + + public MessagePackInputFormatter(IFormatterResolver resolver) + { + this.resolver = resolver ?? MessagePackSerializer.DefaultResolver; + } + + public bool CanRead(InputFormatterContext context) => + context.HttpContext.Request.ContentType == ContentType; + + public Task ReadAsync(InputFormatterContext context) + { + var request = context.HttpContext.Request; + var result = MessagePackSerializer.NonGeneric.Deserialize(context.ModelType, request.Body, resolver); + return InputFormatterResult.SuccessAsync(result); + } + } +} diff --git a/src/MessagePack.AspNetCoreMvcFormatter/MessagePackOutputFormatter.cs b/src/MessagePack.AspNetCoreMvcFormatter/MessagePackOutputFormatter.cs new file mode 100644 index 00000000..b11b5595 --- /dev/null +++ b/src/MessagePack.AspNetCoreMvcFormatter/MessagePackOutputFormatter.cs @@ -0,0 +1,47 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.Formatters; + +namespace MessagePack.AspNetCoreMvcFormatter +{ + public class MessagePackOutputFormatter : IOutputFormatter + { + private const string ContentType = "application/x-msgpack"; + private readonly IFormatterResolver resolver; + + public MessagePackOutputFormatter() : this(null) + { + } + + public MessagePackOutputFormatter(IFormatterResolver resolver) + { + this.resolver = resolver ?? MessagePackSerializer.DefaultResolver; + } + + public bool CanWriteResult(OutputFormatterCanWriteContext context) => + context.HttpContext.Request.ContentType == ContentType; + + public Task WriteAsync(OutputFormatterWriteContext context) + { + context.HttpContext.Response.ContentType = ContentType; + + if (context.ObjectType == typeof(object)) + { + if (context.Object == null) + { + context.HttpContext.Response.Body.WriteByte(MessagePackCode.Nil); + return Task.CompletedTask; + } + else + { + MessagePackSerializer.NonGeneric.Serialize(context.Object.GetType(), context.HttpContext.Response.Body, context.Object, resolver); + return Task.CompletedTask; + } + } + else + { + MessagePackSerializer.NonGeneric.Serialize(context.ObjectType, context.HttpContext.Response.Body, context.Object, resolver); + return Task.CompletedTask; + } + } + } +} diff --git a/src/MessagePack.CodeGenerator/CodeAnalysis/Definitions.cs b/src/MessagePack.CodeGenerator/CodeAnalysis/Definitions.cs deleted file mode 100644 index e754d576..00000000 --- a/src/MessagePack.CodeGenerator/CodeAnalysis/Definitions.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MessagePack.CodeGenerator -{ - public interface IResolverRegisterInfo - { - string FullName { get; } - string FormatterName { get; } - } - - public class ObjectSerializationInfo : IResolverRegisterInfo - { - public string Name { get; set; } - public string FullName { get; set; } - public string Namespace { get; set; } - public bool IsIntKey { get; set; } - public bool IsStringKey { get { return !IsIntKey; } } - public bool IsClass { get; set; } - public bool IsStruct { get { return !IsClass; } } - public MemberSerializationInfo[] ConstructorParameters { get; set; } - public MemberSerializationInfo[] Members { get; set; } - public bool HasIMessagePackSerializationCallbackReceiver { get; set; } - public bool NeedsCastOnBefore { get; set; } - public bool NeedsCastOnAfter { get; set; } - public string FormatterName => (Namespace == null ? Name : Namespace + "." + Name) + "Formatter"; - - public int WriteCount - { - get - { - if (IsStringKey) - { - return Members.Count(x => x.IsReadable); - } - else - { - return MaxKey; - } - } - } - - public int MaxKey - { - get - { - return Members.Where(x => x.IsReadable).Select(x => x.IntKey).DefaultIfEmpty(-1).Max(); - } - } - - public MemberSerializationInfo GetMember(int index) - { - return Members.FirstOrDefault(x => x.IntKey == index); - } - - public string GetConstructorString() - { - var args = string.Join(", ", ConstructorParameters.Select(x => "__" + x.Name + "__")); - return $"{FullName}({args})"; - } - } - - public class MemberSerializationInfo - { - public bool IsProperty { get; set; } - public bool IsField { get; set; } - public bool IsWritable { get; set; } - public bool IsReadable { get; set; } - public int IntKey { get; set; } - public string StringKey { get; set; } - public string Type { get; set; } - public string Name { get; set; } - public string ShortTypeName { get; set; } - - readonly HashSet primitiveTypes = new HashSet(new string[] - { - "short", - "int", - "long", - "ushort", - "uint", - "ulong", - "float", - "double", - "bool", - "byte", - "sbyte", - "char", - //"global::System.DateTime", - //"byte[]", - //"string", - }); - - public string GetSerializeMethodString() - { - if (primitiveTypes.Contains(Type)) - { - return $"MessagePackBinary.Write{ShortTypeName.Replace("[]", "s")}(ref bytes, offset, value.{Name})"; - } - else - { - return $"formatterResolver.GetFormatterWithVerify<{Type}>().Serialize(ref bytes, offset, value.{Name}, formatterResolver)"; - } - } - - public string GetDeserializeMethodString() - { - if (primitiveTypes.Contains(Type)) - { - return $"MessagePackBinary.Read{ShortTypeName.Replace("[]", "s")}(bytes, offset, out readSize)"; - } - else - { - return $"formatterResolver.GetFormatterWithVerify<{Type}>().Deserialize(bytes, offset, formatterResolver, out readSize)"; - } - } - } - - public class EnumSerializationInfo : IResolverRegisterInfo - { - public string Namespace { get; set; } - public string Name { get; set; } - public string FullName { get; set; } - public string UnderlyingType { get; set; } - - public string FormatterName => (Namespace == null ? Name : Namespace + "." + Name) + "Formatter"; - } - - public class GenericSerializationInfo : IResolverRegisterInfo, IEquatable - { - public string FullName { get; set; } - - public string FormatterName { get; set; } - - public bool Equals(GenericSerializationInfo other) - { - return FullName.Equals(other.FullName); - } - - public override int GetHashCode() - { - return FullName.GetHashCode(); - } - } - - public class UnionSerializationInfo : IResolverRegisterInfo - { - public string Namespace { get; set; } - public string Name { get; set; } - public string FullName { get; set; } - public string FormatterName => (Namespace == null ? Name : Namespace + "." + Name) + "Formatter"; - public UnionSubTypeInfo[] SubTypes { get; set; } - } - - public class UnionSubTypeInfo - { - public string Type { get; set; } - public int Key { get; set; } - } -} \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/CodeAnalysis/TypeCollector.cs b/src/MessagePack.CodeGenerator/CodeAnalysis/TypeCollector.cs deleted file mode 100644 index e51ebf70..00000000 --- a/src/MessagePack.CodeGenerator/CodeAnalysis/TypeCollector.cs +++ /dev/null @@ -1,844 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace MessagePack.CodeGenerator -{ - public class ReferenceSymbols - { - public readonly INamedTypeSymbol Task; - public readonly INamedTypeSymbol TaskOfT; - public readonly INamedTypeSymbol MessagePackObjectAttribute; - public readonly INamedTypeSymbol UnionAttribute; - public readonly INamedTypeSymbol SerializationConstructorAttribute; - public readonly INamedTypeSymbol KeyAttribute; - public readonly INamedTypeSymbol IgnoreAttribute; - public readonly INamedTypeSymbol IgnoreDataMemberAttribute; - public readonly INamedTypeSymbol IMessagePackSerializationCallbackReceiver; - - public ReferenceSymbols(Compilation compilation) - { - TaskOfT = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1"); - Task = compilation.GetTypeByMetadataName("System.Threading.Tasks.Task"); - MessagePackObjectAttribute = compilation.GetTypeByMetadataName("MessagePack.MessagePackObjectAttribute"); - UnionAttribute = compilation.GetTypeByMetadataName("MessagePack.UnionAttribute"); - SerializationConstructorAttribute = compilation.GetTypeByMetadataName("MessagePack.SerializationConstructorAttribute"); - KeyAttribute = compilation.GetTypeByMetadataName("MessagePack.KeyAttribute"); - IgnoreAttribute = compilation.GetTypeByMetadataName("MessagePack.IgnoreMemberAttribute"); - IgnoreDataMemberAttribute = compilation.GetTypeByMetadataName("System.Runtime.Serialization.IgnoreDataMemberAttribute"); - IMessagePackSerializationCallbackReceiver = compilation.GetTypeByMetadataName("MessagePack.IMessagePackSerializationCallbackReceiver"); - } - } - - public class TypeCollector - { - const string CodegeneratorOnlyPreprocessorSymbol = "INCLUDE_ONLY_CODE_GENERATION"; - - static readonly SymbolDisplayFormat binaryWriteFormat = new SymbolDisplayFormat( - genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - miscellaneousOptions: SymbolDisplayMiscellaneousOptions.ExpandNullable, - typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly); - - static readonly SymbolDisplayFormat shortTypeNameFormat = new SymbolDisplayFormat( - typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes); - - readonly string csProjPath; - readonly bool isForceUseMap; - readonly ReferenceSymbols typeReferences; - readonly INamedTypeSymbol[] targetTypes; - readonly HashSet embeddedTypes = new HashSet(new string[] - { - "short", - "int", - "long", - "ushort", - "uint", - "ulong", - "float", - "double", - "bool", - "byte", - "sbyte", - "decimal", - "char", - "string", - "object", - "System.Guid", - "System.TimeSpan", - "System.DateTime", - "System.DateTimeOffset", - - "MessagePack.Nil", - - // and arrays - - "short[]", - "int[]", - "long[]", - "ushort[]", - "uint[]", - "ulong[]", - "float[]", - "double[]", - "bool[]", - "byte[]", - "sbyte[]", - "decimal[]", - "char[]", - "string[]", - "System.DateTime[]", - "System.ArraySegment", - "System.ArraySegment?", - - // extensions - - "UnityEngine.Vector2", - "UnityEngine.Vector3", - "UnityEngine.Vector4", - "UnityEngine.Quaternion", - "UnityEngine.Color", - "UnityEngine.Bounds", - "UnityEngine.Rect", - "UnityEngine.AnimationCurve", - "UnityEngine.RectOffset", - "UnityEngine.Gradient", - "UnityEngine.WrapMode", - "UnityEngine.GradientMode", - "UnityEngine.Keyframe", - "UnityEngine.Matrix4x4", - "UnityEngine.GradientColorKey", - "UnityEngine.GradientAlphaKey", - "UnityEngine.Color32", - "UnityEngine.LayerMask", - "UnityEngine.Vector2Int", - "UnityEngine.Vector3Int", - "UnityEngine.RangeInt", - "UnityEngine.RectInt", - "UnityEngine.BoundsInt", - - "System.Reactive.Unit", - }); - - readonly Dictionary knownGenericTypes = new Dictionary - { - {"System.Collections.Generic.List<>", "global::MessagePack.Formatters.ListFormatter" }, - {"System.Collections.Generic.LinkedList<>", "global::MessagePack.Formatters.LinkedListFormatter"}, - {"System.Collections.Generic.Queue<>", "global::MessagePack.Formatters.QeueueFormatter"}, - {"System.Collections.Generic.Stack<>", "global::MessagePack.Formatters.StackFormatter"}, - {"System.Collections.Generic.HashSet<>", "global::MessagePack.Formatters.HashSetFormatter"}, - {"System.Collections.ObjectModel.ReadOnlyCollection<>", "global::MessagePack.Formatters.ReadOnlyCollectionFormatter"}, - {"System.Collections.Generic.IList<>", "global::MessagePack.Formatters.InterfaceListFormatter"}, - {"System.Collections.Generic.ICollection<>", "global::MessagePack.Formatters.InterfaceCollectionFormatter"}, - {"System.Collections.Generic.IEnumerable<>", "global::MessagePack.Formatters.InterfaceEnumerableFormatter"}, - {"System.Collections.Generic.Dictionary<,>", "global::MessagePack.Formatters.DictionaryFormatter"}, - {"System.Collections.Generic.IDictionary<,>", "global::MessagePack.Formatters.InterfaceDictionaryFormatter"}, - {"System.Collections.Generic.SortedDictionary<,>", "global::MessagePack.Formatters.SortedDictionaryFormatter"}, - {"System.Collections.Generic.SortedList<,>", "global::MessagePack.Formatters.SortedListFormatter"}, - {"System.Linq.ILookup<,>", "global::MessagePack.Formatters.InterfaceLookupFormatter"}, - {"System.Linq.IGrouping<,>", "global::MessagePack.Formatters.InterfaceGroupingFormatter"}, - {"System.Collections.ObjectModel.ObservableCollection<>", "global::MessagePack.Formatters.ObservableCollectionFormatter"}, - {"System.Collections.ObjectModel.ReadOnlyObservableCollection<>", "global::MessagePack.Formatters.ReadOnlyObservableCollectionFormatter" }, - {"System.Collections.Generic.IReadOnlyList<>", "global::MessagePack.Formatters.InterfaceReadOnlyListFormatter"}, - {"System.Collections.Generic.IReadOnlyCollection<>", "global::MessagePack.Formatters.InterfaceReadOnlyCollectionFormatter"}, - {"System.Collections.Generic.ISet<>", "global::MessagePack.Formatters.InterfaceSetFormatter"}, - {"System.Collections.Concurrent.ConcurrentBag<>", "global::MessagePack.Formatters.ConcurrentBagFormatter"}, - {"System.Collections.Concurrent.ConcurrentQueue<>", "global::MessagePack.Formatters.ConcurrentQueueFormatter"}, - {"System.Collections.Concurrent.ConcurrentStack<>", "global::MessagePack.Formatters.ConcurrentStackFormatter"}, - {"System.Collections.ObjectModel.ReadOnlyDictionary<,>", "global::MessagePack.Formatters.ReadOnlyDictionaryFormatter"}, - {"System.Collections.Generic.IReadOnlyDictionary<,>", "global::MessagePack.Formatters.InterfaceReadOnlyDictionaryFormatter"}, - {"System.Collections.Concurrent.ConcurrentDictionary<,>", "global::MessagePack.Formatters.ConcurrentDictionaryFormatter"}, - {"System.Lazy<>", "global::MessagePack.Formatters.LazyFormatter"}, - {"System.Threading.Tasks<>", "global::MessagePack.Formatters.TaskValueFormatter"}, - - {"System.Tuple<>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,,>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,,,>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,,,,>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,,,,,>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,,,,,,>", "global::MessagePack.Formatters.TupleFormatter"}, - {"System.Tuple<,,,,,,,>", "global::MessagePack.Formatters.TupleFormatter"}, - - {"System.ValueTuple<>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,,,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,,,,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,,,,,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,,,,,,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - {"System.ValueTuple<,,,,,,,>", "global::MessagePack.Formatters.ValueTupleFormatter"}, - - {"System.Collections.Generic.KeyValuePair<,>", "global::MessagePack.Formatters.KeyValuePairFormatter"}, - {"System.Threading.Tasks.ValueTask<>", "global::MessagePack.Formatters.KeyValuePairFormatter"}, - {"System.ArraySegment<>", "global::MessagePack.Formatters.ArraySegmentFormatter"}, - - // extensions - - {"System.Collections.Immutable.ImmutableArray<>", "global::MessagePack.ImmutableCollection.ImmutableArrayFormatter"}, - {"System.Collections.Immutable.ImmutableList<>", "global::MessagePack.ImmutableCollection.ImmutableListFormatter"}, - {"System.Collections.Immutable.ImmutableDictionary<,>", "global::MessagePack.ImmutableCollection.ImmutableDictionaryFormatter"}, - {"System.Collections.Immutable.ImmutableHashSet<>", "global::MessagePack.ImmutableCollection.ImmutableHashSetFormatter"}, - {"System.Collections.Immutable.ImmutableSortedDictionary<,>", "global::MessagePack.ImmutableCollection.ImmutableSortedDictionaryFormatter"}, - {"System.Collections.Immutable.ImmutableSortedSet<>", "global::MessagePack.ImmutableCollection.ImmutableSortedSetFormatter"}, - {"System.Collections.Immutable.ImmutableQueue<>", "global::MessagePack.ImmutableCollection.ImmutableQueueFormatter"}, - {"System.Collections.Immutable.ImmutableStack<>", "global::MessagePack.ImmutableCollection.ImmutableStackFormatter"}, - {"System.Collections.Immutable.IImmutableList<>", "global::MessagePack.ImmutableCollection.InterfaceImmutableListFormatter"}, - {"System.Collections.Immutable.IImmutableDictionary<,>", "global::MessagePack.ImmutableCollection.InterfaceImmutableDictionaryFormatter"}, - {"System.Collections.Immutable.IImmutableQueue<>", "global::MessagePack.ImmutableCollection.InterfaceImmutableQueueFormatter"}, - {"System.Collections.Immutable.IImmutableSet<>", "global::MessagePack.ImmutableCollection.InterfaceImmutableSetFormatter"}, - {"System.Collections.Immutable.IImmutableStack<>", "global::MessagePack.ImmutableCollection.InterfaceImmutableStackFormatter"}, - - {"Reactive.Bindings.ReactiveProperty<>", "global::MessagePack.ReactivePropertyExtension.ReactivePropertyFormatter"}, - {"Reactive.Bindings.IReactiveProperty<>", "global::MessagePack.ReactivePropertyExtension.InterfaceReactivePropertyFormatter"}, - {"Reactive.Bindings.IReadOnlyReactiveProperty<>", "global::MessagePack.ReactivePropertyExtension.InterfaceReadOnlyReactivePropertyFormatter"}, - {"Reactive.Bindings.ReactiveCollection<>", "global::MessagePack.ReactivePropertyExtension.ReactiveCollectionFormatter"}, - }; - - readonly bool disallowInternal; - - // visitor workspace: - HashSet alreadyCollected; - List collectedObjectInfo; - List collectedEnumInfo; - List collectedGenericInfo; - List collectedUnionInfo; - - // --- - - public TypeCollector(string csProjPath, IEnumerable conditinalSymbols, bool disallowInternal, bool isForceUseMap) - { - this.csProjPath = csProjPath; - var compilation = RoslynExtensions.GetCompilationFromProject(csProjPath, conditinalSymbols.Concat(new[] { CodegeneratorOnlyPreprocessorSymbol }).ToArray()).GetAwaiter().GetResult(); - this.typeReferences = new ReferenceSymbols(compilation); - this.disallowInternal = disallowInternal; - this.isForceUseMap = isForceUseMap; - - targetTypes = compilation.GetNamedTypeSymbols() - .Where(x => - { - if (x.DeclaredAccessibility == Accessibility.Public) return true; - if (!disallowInternal) - { - return (x.DeclaredAccessibility == Accessibility.Friend); - } - - return false; - }) - .Where(x => - ((x.TypeKind == TypeKind.Interface) && x.GetAttributes().Any(x2 => x2.AttributeClass == typeReferences.UnionAttribute)) - || ((x.TypeKind == TypeKind.Class && x.IsAbstract) && x.GetAttributes().Any(x2 => x2.AttributeClass == typeReferences.UnionAttribute)) - || ((x.TypeKind == TypeKind.Class) && x.GetAttributes().Any(x2 => x2.AttributeClass == typeReferences.MessagePackObjectAttribute)) - || ((x.TypeKind == TypeKind.Struct) && x.GetAttributes().Any(x2 => x2.AttributeClass == typeReferences.MessagePackObjectAttribute)) - ) - .ToArray(); - } - - void ResetWorkspace() - { - alreadyCollected = new HashSet(); - collectedObjectInfo = new List(); - collectedEnumInfo = new List(); - collectedGenericInfo = new List(); - collectedUnionInfo = new List(); - } - - // EntryPoint - public (ObjectSerializationInfo[] objectInfo, EnumSerializationInfo[] enumInfo, GenericSerializationInfo[] genericInfo, UnionSerializationInfo[] unionInfo) Collect() - { - ResetWorkspace(); - - foreach (var item in targetTypes) - { - CollectCore(item); - } - - return (collectedObjectInfo.ToArray(), collectedEnumInfo.ToArray(), collectedGenericInfo.Distinct().ToArray(), collectedUnionInfo.ToArray()); - } - - // Gate of recursive collect - void CollectCore(ITypeSymbol typeSymbol) - { - if (!alreadyCollected.Add(typeSymbol)) - { - return; - } - - if (embeddedTypes.Contains(typeSymbol.ToString())) - { - return; - } - - if (typeSymbol.TypeKind == TypeKind.Array) - { - CollectArray(typeSymbol as IArrayTypeSymbol); - return; - } - - if (!IsAllowAccessibility(typeSymbol)) - { - return; - } - - var type = typeSymbol as INamedTypeSymbol; - - if (typeSymbol.TypeKind == TypeKind.Enum) - { - CollectEnum(type); - return; - } - - if (type.IsGenericType) - { - CollectGeneric(type); - return; - } - - if (type.Locations[0].IsInMetadata) - { - return; - } - - if (type.TypeKind == TypeKind.Interface || (type.TypeKind == TypeKind.Class && type.IsAbstract)) - { - CollectUnion(type); - return; - } - - CollectObject(type); - return; - } - - void CollectEnum(INamedTypeSymbol type) - { - var info = new EnumSerializationInfo - { - Name = type.Name, - Namespace = type.ContainingNamespace.IsGlobalNamespace ? null : type.ContainingNamespace.ToDisplayString(), - FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - UnderlyingType = type.EnumUnderlyingType.ToDisplayString(binaryWriteFormat) - }; - - collectedEnumInfo.Add(info); - } - - void CollectUnion(INamedTypeSymbol type) - { - var unionAttrs = type.GetAttributes().Where(x => x.AttributeClass == typeReferences.UnionAttribute).Select(x => x.ConstructorArguments).ToArray(); - if (unionAttrs.Length == 0) - { - throw new MessagePackGeneratorResolveFailedException("Serialization Type must mark UnionAttribute." + " type: " + type.Name); - } - - // 0, Int 1, SubType - var info = new UnionSerializationInfo - { - Name = type.Name, - Namespace = type.ContainingNamespace.IsGlobalNamespace ? null : type.ContainingNamespace.ToDisplayString(), - FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - SubTypes = unionAttrs.Select(x => new UnionSubTypeInfo - { - Key = (int)x[0].Value, - Type = (x[1].Value as ITypeSymbol).ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - }).OrderBy(x => x.Key).ToArray() - }; - - collectedUnionInfo.Add(info); - } - - void CollectArray(IArrayTypeSymbol array) - { - var elemType = array.ElementType; - CollectCore(elemType); - - var info = new GenericSerializationInfo - { - FullName = array.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - }; - - if (array.IsSZArray) - { - info.FormatterName = $"global::MessagePack.Formatters.ArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; - } - else if (array.Rank == 2) - { - info.FormatterName = $"global::MessagePack.Formatters.TwoDimentionalArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; - } - else if (array.Rank == 3) - { - info.FormatterName = $"global::MessagePack.Formatters.ThreeDimentionalArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; - } - else if (array.Rank == 4) - { - info.FormatterName = $"global::MessagePack.Formatters.FourDimentionalArrayFormatter<{elemType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>"; - } - else - { - throw new InvalidOperationException("does not supports array dimention, " + info.FullName); - } - - collectedGenericInfo.Add(info); - - return; - } - - void CollectGeneric(INamedTypeSymbol type) - { - var genericType = type.ConstructUnboundGenericType(); - var genericTypeString = genericType.ToDisplayString(); - var fullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - - // special case - if (fullName == "global::System.ArraySegment" || fullName == "global::System.ArraySegment?") - { - return; - } - - // nullable - if (genericTypeString == "T?") - { - CollectCore(type.TypeArguments[0]); - - if (!embeddedTypes.Contains(type.TypeArguments[0].ToString())) - { - var info = new GenericSerializationInfo - { - FormatterName = $"global::MessagePack.Formatters.NullableFormatter<{type.TypeArguments[0].ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>", - FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - }; - - collectedGenericInfo.Add(info); - } - return; - } - - // collection - if (knownGenericTypes.TryGetValue(genericTypeString, out var formatter)) - { - foreach (var item in type.TypeArguments) - { - CollectCore(item); - } - - var typeArgs = string.Join(", ", type.TypeArguments.Select(x => x.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat))); - var f = formatter.Replace("TREPLACE", typeArgs); - - var info = new GenericSerializationInfo - { - FormatterName = f, - FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - }; - - collectedGenericInfo.Add(info); - - if (genericTypeString == "System.Linq.ILookup<,>") - { - formatter = knownGenericTypes["System.Linq.IGrouping<,>"]; - f = formatter.Replace("TREPLACE", typeArgs); - - var groupingInfo = new GenericSerializationInfo - { - FormatterName = f, - FullName = $"global::System.Linq.IGrouping<{typeArgs}>", - }; - - collectedGenericInfo.Add(groupingInfo); - - formatter = knownGenericTypes["System.Collections.Generic.IEnumerable<>"]; - typeArgs = type.TypeArguments[1].ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - f = formatter.Replace("TREPLACE", typeArgs); - - var enumerableInfo = new GenericSerializationInfo - { - FormatterName = f, - FullName = $"global::System.Collections.Generic.IEnumerable<{typeArgs}>", - }; - - collectedGenericInfo.Add(enumerableInfo); - } - } - } - - void CollectObject(INamedTypeSymbol type) - { - var isClass = !type.IsValueType; - - var contractAttr = type.GetAttributes().FirstOrDefault(x => x.AttributeClass == typeReferences.MessagePackObjectAttribute); - if (contractAttr == null) - { - throw new MessagePackGeneratorResolveFailedException("Serialization Object must mark MessagePackObjectAttribute." + " type: " + type.Name); - } - - var isIntKey = true; - var intMemebrs = new Dictionary(); - var stringMembers = new Dictionary(); - - if (isForceUseMap || (bool)contractAttr.ConstructorArguments[0].Value) - { - // All public members are serialize target except [Ignore] member. - isIntKey = false; - - var hiddenIntKey = 0; - - foreach (var item in type.GetAllMembers().OfType().Where(x => !x.IsOverride)) - { - if (item.GetAttributes().Any(x => x.AttributeClass == typeReferences.IgnoreAttribute || x.AttributeClass == typeReferences.IgnoreDataMemberAttribute)) continue; - - var member = new MemberSerializationInfo - { - IsReadable = (item.GetMethod != null) && item.GetMethod.DeclaredAccessibility == Accessibility.Public && !item.IsStatic, - IsWritable = (item.SetMethod != null) && item.SetMethod.DeclaredAccessibility == Accessibility.Public && !item.IsStatic, - StringKey = item.Name, - IsProperty = true, - IsField = false, - Name = item.Name, - Type = item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - ShortTypeName = item.Type.ToDisplayString(binaryWriteFormat) - }; - if (!member.IsReadable && !member.IsWritable) continue; - member.IntKey = hiddenIntKey++; - stringMembers.Add(member.StringKey, member); - - CollectCore(item.Type); // recursive collect - } - foreach (var item in type.GetAllMembers().OfType()) - { - if (item.GetAttributes().Any(x => x.AttributeClass == typeReferences.IgnoreAttribute || x.AttributeClass == typeReferences.IgnoreDataMemberAttribute)) continue; - if (item.IsImplicitlyDeclared) continue; - - var member = new MemberSerializationInfo - { - IsReadable = item.DeclaredAccessibility == Accessibility.Public && !item.IsStatic, - IsWritable = item.DeclaredAccessibility == Accessibility.Public && !item.IsReadOnly && !item.IsStatic, - StringKey = item.Name, - IsProperty = false, - IsField = true, - Name = item.Name, - Type = item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - ShortTypeName = item.Type.ToDisplayString(binaryWriteFormat) - }; - if (!member.IsReadable && !member.IsWritable) continue; - member.IntKey = hiddenIntKey++; - stringMembers.Add(member.StringKey, member); - CollectCore(item.Type); // recursive collect - } - } - else - { - // Only KeyAttribute members - var searchFirst = true; - var hiddenIntKey = 0; - - foreach (var item in type.GetAllMembers().OfType()) - { - if (item.GetAttributes().Any(x => x.AttributeClass == typeReferences.IgnoreAttribute || x.AttributeClass == typeReferences.IgnoreDataMemberAttribute)) continue; - - var member = new MemberSerializationInfo - { - IsReadable = (item.GetMethod != null) && item.GetMethod.DeclaredAccessibility == Accessibility.Public && !item.IsStatic, - IsWritable = (item.SetMethod != null) && item.SetMethod.DeclaredAccessibility == Accessibility.Public && !item.IsStatic, - IsProperty = true, - IsField = false, - Name = item.Name, - Type = item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - ShortTypeName = item.Type.ToDisplayString(binaryWriteFormat) - }; - if (!member.IsReadable && !member.IsWritable) continue; - - var key = item.GetAttributes().FirstOrDefault(x => x.AttributeClass == typeReferences.KeyAttribute)?.ConstructorArguments[0]; - if (key == null) throw new MessagePackGeneratorResolveFailedException("all public members must mark KeyAttribute or IgnoreMemberAttribute." + " type: " + type.Name + " member:" + item.Name); - - var intKey = (key.Value.Value is int) ? (int)key.Value.Value : (int?)null; - var stringKey = (key.Value.Value is string) ? (string)key.Value.Value : (string)null; - if (intKey == null && stringKey == null) throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.Name + " member:" + item.Name); - - if (searchFirst) - { - searchFirst = false; - isIntKey = intKey != null; - } - else - { - if ((isIntKey && intKey == null) || (!isIntKey && stringKey == null)) - { - throw new MessagePackGeneratorResolveFailedException("all members key type must be same." + " type: " + type.Name + " member:" + item.Name); - } - } - - if (isIntKey) - { - member.IntKey = (int)intKey; - if (intMemebrs.ContainsKey(member.IntKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); - - intMemebrs.Add(member.IntKey, member); - } - else - { - member.StringKey = (string)stringKey; - if (stringMembers.ContainsKey(member.StringKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); - - member.IntKey = hiddenIntKey++; - stringMembers.Add(member.StringKey, member); - } - - CollectCore(item.Type); // recursive collect - } - - foreach (var item in type.GetAllMembers().OfType()) - { - if (item.IsImplicitlyDeclared) continue; - if (item.GetAttributes().Any(x => x.AttributeClass == typeReferences.IgnoreAttribute)) continue; - - var member = new MemberSerializationInfo - { - IsReadable = item.DeclaredAccessibility == Accessibility.Public && !item.IsStatic, - IsWritable = item.DeclaredAccessibility == Accessibility.Public && !item.IsReadOnly && !item.IsStatic, - IsProperty = true, - IsField = false, - Name = item.Name, - Type = item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - ShortTypeName = item.Type.ToDisplayString(binaryWriteFormat) - }; - if (!member.IsReadable && !member.IsWritable) continue; - - var key = item.GetAttributes().FirstOrDefault(x => x.AttributeClass == typeReferences.KeyAttribute)?.ConstructorArguments[0]; - if (key == null) throw new MessagePackGeneratorResolveFailedException("all public members must mark KeyAttribute or IgnoreMemberAttribute." + " type: " + type.Name + " member:" + item.Name); - - var intKey = (key.Value.Value is int) ? (int)key.Value.Value : (int?)null; - var stringKey = (key.Value.Value is string) ? (string)key.Value.Value : (string)null; - if (intKey == null && stringKey == null) throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.Name + " member:" + item.Name); - - if (searchFirst) - { - searchFirst = false; - isIntKey = intKey != null; - } - else - { - if ((isIntKey && intKey == null) || (!isIntKey && stringKey == null)) - { - throw new MessagePackGeneratorResolveFailedException("all members key type must be same." + " type: " + type.Name + " member:" + item.Name); - } - } - - if (isIntKey) - { - member.IntKey = (int)intKey; - if (intMemebrs.ContainsKey(member.IntKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); - - intMemebrs.Add(member.IntKey, member); - } - else - { - member.StringKey = (string)stringKey; - if (stringMembers.ContainsKey(member.StringKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); - - member.IntKey = hiddenIntKey++; - stringMembers.Add(member.StringKey, member); - } - - CollectCore(item.Type); // recursive collect - } - } - - // GetConstructor - IEnumerator ctorEnumerator = null; - var ctor = type.Constructors.Where(x => x.DeclaredAccessibility == Accessibility.Public).SingleOrDefault(x => x.GetAttributes().Any(y => y.AttributeClass == typeReferences.SerializationConstructorAttribute)); - if (ctor == null) - { - ctorEnumerator = - type.Constructors.Where(x => x.DeclaredAccessibility == Accessibility.Public && !x.IsImplicitlyDeclared).OrderBy(x => x.Parameters.Length) - .Concat(type.Constructors.Where(x => x.DeclaredAccessibility == Accessibility.Public).OrderBy(x => x.Parameters.Length).Take(1)) - .GetEnumerator(); - - if (ctorEnumerator.MoveNext()) - { - ctor = ctorEnumerator.Current; - } - } - - // struct allows null ctor - if (ctor == null && isClass) throw new MessagePackGeneratorResolveFailedException("can't find public constructor. type:" + type.Name); - - var constructorParameters = new List(); - if (ctor != null) - { - var constructorLookupDictionary = stringMembers.ToLookup(x => x.Key, x => x, StringComparer.OrdinalIgnoreCase); - do - { - constructorParameters.Clear(); - var ctorParamIndex = 0; - foreach (var item in ctor.Parameters) - { - MemberSerializationInfo paramMember; - if (isIntKey) - { - if (intMemebrs.TryGetValue(ctorParamIndex, out paramMember)) - { - if (item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) == paramMember.Type && paramMember.IsReadable) - { - constructorParameters.Add(paramMember); - } - else - { - if (ctorEnumerator != null) - { - ctor = null; - continue; - } - else - { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.Name + " parameterIndex:" + ctorParamIndex + " paramterType:" + item.Type.Name); - } - } - } - else - { - if (ctorEnumerator != null) - { - ctor = null; - continue; - } - else - { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.Name + " parameterIndex:" + ctorParamIndex); - } - } - } - else - { - var hasKey = constructorLookupDictionary[item.Name]; - var len = hasKey.Count(); - if (len != 0) - { - if (len != 1) - { - if (ctorEnumerator != null) - { - ctor = null; - continue; - } - else - { - throw new MessagePackGeneratorResolveFailedException("duplicate matched constructor parameter name:" + type.Name + " parameterName:" + item.Name + " paramterType:" + item.Type.Name); - } - } - - paramMember = hasKey.First().Value; - if (item.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) == paramMember.Type && paramMember.IsReadable) - { - constructorParameters.Add(paramMember); - } - else - { - if (ctorEnumerator != null) - { - ctor = null; - continue; - } - else - { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.Name + " parameterName:" + item.Name + " paramterType:" + item.Type.Name); - } - } - } - else - { - if (ctorEnumerator != null) - { - ctor = null; - continue; - } - else - { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.Name + " parameterName:" + item.Name); - } - } - } - ctorParamIndex++; - } - } while (TryGetNextConstructor(ctorEnumerator, ref ctor)); - - if (ctor == null) - { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor. type:" + type.Name); - } - } - - var hasSerializationConstructor = type.AllInterfaces.Any(x => x == typeReferences.IMessagePackSerializationCallbackReceiver); - var needsCastOnBefore = true; - var needsCastOnAfter = true; - if (hasSerializationConstructor) - { - needsCastOnBefore = !type.GetMembers("OnBeforeSerialize").Any(); - needsCastOnAfter = !type.GetMembers("OnAfterDeserialize").Any(); - } - - var info = new ObjectSerializationInfo - { - IsClass = isClass, - ConstructorParameters = constructorParameters.ToArray(), - IsIntKey = isIntKey, - Members = (isIntKey) ? intMemebrs.Values.ToArray() : stringMembers.Values.ToArray(), - Name = type.ToDisplayString(shortTypeNameFormat).Replace(".", "_"), - FullName = type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - Namespace = type.ContainingNamespace.IsGlobalNamespace ? null : type.ContainingNamespace.ToDisplayString(), - HasIMessagePackSerializationCallbackReceiver = hasSerializationConstructor, - NeedsCastOnAfter = needsCastOnAfter, - NeedsCastOnBefore = needsCastOnBefore - }; - collectedObjectInfo.Add(info); - } - - static bool TryGetNextConstructor(IEnumerator ctorEnumerator, ref IMethodSymbol ctor) - { - if (ctorEnumerator == null || ctor != null) - { - return false; - } - - if (ctorEnumerator.MoveNext()) - { - ctor = ctorEnumerator.Current; - return true; - } - else - { - ctor = null; - return false; - } - } - - bool IsAllowAccessibility(ITypeSymbol symbol) - { - do - { - if (symbol.DeclaredAccessibility != Accessibility.Public) - { - if (disallowInternal) - { - return false; - } - - if (symbol.DeclaredAccessibility != Accessibility.Internal) - { - return true; - } - } - - symbol = symbol.ContainingType; - } while (symbol != null); - - return true; - } - } - - public class MessagePackGeneratorResolveFailedException : Exception - { - public MessagePackGeneratorResolveFailedException(string message) - : base(message) - { - - } - } -} \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/Generator/EnumTemplate.cs b/src/MessagePack.CodeGenerator/Generator/EnumTemplate.cs deleted file mode 100644 index ba322bdb..00000000 --- a/src/MessagePack.CodeGenerator/Generator/EnumTemplate.cs +++ /dev/null @@ -1,391 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// このコードはツールによって生成されました。 -// ランタイム バージョン: 15.0.0.0 -// -// このファイルへの変更は、正しくない動作の原因になる可能性があり、 -// コードが再生成されると失われます。 -// -// ------------------------------------------------------------------------------ -namespace MessagePack.CodeGenerator.Generator -{ - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System; - - /// - /// Class to produce the template output - /// - - #line 1 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public partial class EnumTemplate : EnumTemplateBase - { -#line hidden - /// - /// Create the template output - /// - public virtual string TransformText() - { - this.Write("#pragma warning disable 618\r\n#pragma warning disable 612\r\n#pragma warning disable" + - " 414\r\n#pragma warning disable 168\r\n\r\nnamespace "); - - #line 11 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - - #line default - #line hidden - this.Write("\r\n{\r\n using System;\r\n using MessagePack;\r\n\r\n"); - - #line 16 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - foreach(var info in enumSerializationInfos) { - - #line default - #line hidden - this.Write(" public sealed class "); - - #line 17 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.Name)); - - #line default - #line hidden - this.Write("Formatter : global::MessagePack.Formatters.IMessagePackFormatter<"); - - #line 17 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(">\r\n {\r\n public int Serialize(ref byte[] bytes, int offset, "); - - #line 19 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(" value, global::MessagePack.IFormatterResolver formatterResolver)\r\n {\r\n " + - " return MessagePackBinary.Write"); - - #line 21 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.UnderlyingType)); - - #line default - #line hidden - this.Write("(ref bytes, offset, ("); - - #line 21 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.UnderlyingType)); - - #line default - #line hidden - this.Write(")value);\r\n }\r\n \r\n public "); - - #line 24 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(" Deserialize(byte[] bytes, int offset, global::MessagePack.IFormatterResolver for" + - "matterResolver, out int readSize)\r\n {\r\n return ("); - - #line 26 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(")MessagePackBinary.Read"); - - #line 26 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.UnderlyingType)); - - #line default - #line hidden - this.Write("(bytes, offset, out readSize);\r\n }\r\n }\r\n\r\n"); - - #line 30 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\EnumTemplate.tt" - } - - #line default - #line hidden - this.Write("\r\n}\r\n\r\n#pragma warning restore 168\r\n#pragma warning restore 414\r\n#pragma warning " + - "restore 618\r\n#pragma warning restore 612"); - return this.GenerationEnvironment.ToString(); - } - } - - #line default - #line hidden - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public class EnumTemplateBase - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - protected System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} diff --git a/src/MessagePack.CodeGenerator/Generator/EnumTemplate.tt b/src/MessagePack.CodeGenerator/Generator/EnumTemplate.tt deleted file mode 100644 index 846ee8d0..00000000 --- a/src/MessagePack.CodeGenerator/Generator/EnumTemplate.tt +++ /dev/null @@ -1,37 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -#pragma warning disable 618 -#pragma warning disable 612 -#pragma warning disable 414 -#pragma warning disable 168 - -namespace <#= Namespace #> -{ - using System; - using MessagePack; - -<# foreach(var info in enumSerializationInfos) { #> - public sealed class <#= info.Name #>Formatter : global::MessagePack.Formatters.IMessagePackFormatter<<#= info.FullName #>> - { - public int Serialize(ref byte[] bytes, int offset, <#= info.FullName #> value, global::MessagePack.IFormatterResolver formatterResolver) - { - return MessagePackBinary.Write<#= info.UnderlyingType #>(ref bytes, offset, (<#= info.UnderlyingType #>)value); - } - - public <#= info.FullName #> Deserialize(byte[] bytes, int offset, global::MessagePack.IFormatterResolver formatterResolver, out int readSize) - { - return (<#= info.FullName #>)MessagePackBinary.Read<#= info.UnderlyingType #>(bytes, offset, out readSize); - } - } - -<# } #> - -} - -#pragma warning restore 168 -#pragma warning restore 414 -#pragma warning restore 618 -#pragma warning restore 612 \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/Generator/FormatterTemplate.cs b/src/MessagePack.CodeGenerator/Generator/FormatterTemplate.cs deleted file mode 100644 index 1d9f52c6..00000000 --- a/src/MessagePack.CodeGenerator/Generator/FormatterTemplate.cs +++ /dev/null @@ -1,818 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// このコードはツールによって生成されました。 -// ランタイム バージョン: 15.0.0.0 -// -// このファイルへの変更は、正しくない動作の原因になる可能性があり、 -// コードが再生成されると失われます。 -// -// ------------------------------------------------------------------------------ -namespace MessagePack.CodeGenerator.Generator -{ - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System; - - /// - /// Class to produce the template output - /// - - #line 1 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public partial class FormatterTemplate : FormatterTemplateBase - { -#line hidden - /// - /// Create the template output - /// - public virtual string TransformText() - { - this.Write("#pragma warning disable 618\r\n#pragma warning disable 612\r\n#pragma warning disable" + - " 414\r\n#pragma warning disable 168\r\n\r\nnamespace "); - - #line 11 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - - #line default - #line hidden - this.Write("\r\n{\r\n using System;\r\n using MessagePack;\r\n\r\n"); - - #line 16 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - foreach(var objInfo in objectSerializationInfos) { - - #line default - #line hidden - this.Write("\r\n public sealed class "); - - #line 18 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.Name)); - - #line default - #line hidden - this.Write("Formatter : global::MessagePack.Formatters.IMessagePackFormatter<"); - - #line 18 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FullName)); - - #line default - #line hidden - this.Write(">\r\n {\r\n"); - - #line 20 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if( objInfo.IsStringKey) { - - #line default - #line hidden - this.Write("\r\n readonly global::MessagePack.Internal.AutomataDictionary ____keyMapping" + - ";\r\n readonly byte[][] ____stringByteKeys;\r\n\r\n public "); - - #line 25 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.Name)); - - #line default - #line hidden - this.Write("Formatter()\r\n {\r\n this.____keyMapping = new global::MessagePack" + - ".Internal.AutomataDictionary()\r\n {\r\n"); - - #line 29 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - foreach(var x in objInfo.Members) { - - #line default - #line hidden - this.Write(" { \""); - - #line 30 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.StringKey)); - - #line default - #line hidden - this.Write("\", "); - - #line 30 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.IntKey)); - - #line default - #line hidden - this.Write("},\r\n"); - - #line 31 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" };\r\n\r\n this.____stringByteKeys = new byte[][]\r\n " + - " {\r\n"); - - #line 36 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - foreach(var x in objInfo.Members.Where(x => x.IsReadable)) { - - #line default - #line hidden - this.Write(" global::MessagePack.MessagePackBinary.GetEncodedStringBytes(\""); - - #line 37 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.StringKey)); - - #line default - #line hidden - this.Write("\"),\r\n"); - - #line 38 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" \r\n };\r\n }\r\n\r\n"); - - #line 42 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write("\r\n public int Serialize(ref byte[] bytes, int offset, "); - - #line 44 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FullName)); - - #line default - #line hidden - this.Write(" value, global::MessagePack.IFormatterResolver formatterResolver)\r\n {\r\n"); - - #line 46 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if( objInfo.IsClass) { - - #line default - #line hidden - this.Write(" if (value == null)\r\n {\r\n return global::Mes" + - "sagePack.MessagePackBinary.WriteNil(ref bytes, offset);\r\n }\r\n"); - - #line 51 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" \r\n"); - - #line 52 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" -if(objInfo.HasIMessagePackSerializationCallbackReceiver && objInfo.NeedsCastOnBefore) { - - #line default - #line hidden - this.Write(" ((IMessagePackSerializationCallbackReceiver)value).OnBeforeSerialize(" + - ");\r\n"); - - #line 54 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else if(objInfo.HasIMessagePackSerializationCallbackReceiver) { - - #line default - #line hidden - this.Write(" value.OnBeforeSerialize();\r\n"); - - #line 56 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" var startOffset = offset;\r\n"); - - #line 58 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if( objInfo.IsIntKey) { if( (objInfo.MaxKey + 1) <= 15) { - - #line default - #line hidden - this.Write(" offset += global::MessagePack.MessagePackBinary.WriteFixedArrayHeader" + - "Unsafe(ref bytes, offset, "); - - #line 59 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.MaxKey + 1)); - - #line default - #line hidden - this.Write(");\r\n"); - - #line 60 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else { - - #line default - #line hidden - this.Write(" offset += global::MessagePack.MessagePackBinary.WriteArrayHeader(ref " + - "bytes, offset, "); - - #line 61 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.MaxKey + 1)); - - #line default - #line hidden - this.Write(");\r\n"); - - #line 62 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } } else if( objInfo.WriteCount <= 15) { - - #line default - #line hidden - this.Write(" offset += global::MessagePack.MessagePackBinary.WriteFixedMapHeaderUn" + - "safe(ref bytes, offset, "); - - #line 63 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.WriteCount)); - - #line default - #line hidden - this.Write(");\r\n"); - - #line 64 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else { - - #line default - #line hidden - this.Write(" offset += global::MessagePack.MessagePackBinary.WriteMapHeader(ref by" + - "tes, offset, "); - - #line 65 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.WriteCount)); - - #line default - #line hidden - this.Write(");\r\n"); - - #line 66 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - - #line 67 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if(objInfo.IsIntKey) { - - #line default - #line hidden - - #line 68 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - for(var i =0; i<= objInfo.MaxKey; i++) { var member = objInfo.GetMember(i); - - #line default - #line hidden - - #line 69 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if( member == null) { - - #line default - #line hidden - this.Write(" offset += global::MessagePack.MessagePackBinary.WriteNil(ref bytes, o" + - "ffset);\r\n"); - - #line 71 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else { - - #line default - #line hidden - this.Write(" offset += "); - - #line 72 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(member.GetSerializeMethodString())); - - #line default - #line hidden - this.Write(";\r\n"); - - #line 73 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } } } else { - - #line default - #line hidden - - #line 74 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - var index = 0; foreach(var x in objInfo.Members) { - - #line default - #line hidden - this.Write(" offset += global::MessagePack.MessagePackBinary.WriteRaw(ref bytes, o" + - "ffset, this.____stringByteKeys["); - - #line 75 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(index++)); - - #line default - #line hidden - this.Write("]);\r\n offset += "); - - #line 76 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.GetSerializeMethodString())); - - #line default - #line hidden - this.Write(";\r\n"); - - #line 77 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } } - - #line default - #line hidden - this.Write(" return offset - startOffset;\r\n }\r\n\r\n public "); - - #line 81 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.FullName)); - - #line default - #line hidden - this.Write(" Deserialize(byte[] bytes, int offset, global::MessagePack.IFormatterResolver for" + - "matterResolver, out int readSize)\r\n {\r\n if (global::MessagePac" + - "k.MessagePackBinary.IsNil(bytes, offset))\r\n {\r\n"); - - #line 85 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if( objInfo.IsClass) { - - #line default - #line hidden - this.Write(" readSize = 1;\r\n return null;\r\n"); - - #line 88 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else { - - #line default - #line hidden - this.Write(" throw new InvalidOperationException(\"typecode is null, struct not" + - " supported\");\r\n"); - - #line 90 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" }\r\n\r\n var startOffset = offset;\r\n"); - - #line 94 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if(objInfo.IsStringKey) { - - #line default - #line hidden - this.Write(" var length = global::MessagePack.MessagePackBinary.ReadMapHeader(byte" + - "s, offset, out readSize);\r\n"); - - #line 96 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else { - - #line default - #line hidden - this.Write(" var length = global::MessagePack.MessagePackBinary.ReadArrayHeader(by" + - "tes, offset, out readSize);\r\n"); - - #line 98 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" offset += readSize;\r\n\r\n"); - - #line 101 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - foreach(var x in objInfo.Members) { - - #line default - #line hidden - this.Write(" var __"); - - #line 102 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.Name)); - - #line default - #line hidden - this.Write("__ = default("); - - #line 102 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.Type)); - - #line default - #line hidden - this.Write(");\r\n"); - - #line 103 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write("\r\n for (int i = 0; i < length; i++)\r\n {\r\n"); - - #line 107 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if(objInfo.IsStringKey) { - - #line default - #line hidden - this.Write(@" var stringKey = global::MessagePack.MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); - offset += readSize; - int key; - if (!____keyMapping.TryGetValueSafe(stringKey, out key)) - { - readSize = global::MessagePack.MessagePackBinary.ReadNextBlock(bytes, offset); - goto NEXT_LOOP; - } -"); - - #line 116 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else { - - #line default - #line hidden - this.Write(" var key = i;\r\n"); - - #line 118 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write("\r\n switch (key)\r\n {\r\n"); - - #line 122 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - foreach(var x in objInfo.Members) { - - #line default - #line hidden - this.Write(" case "); - - #line 123 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.IntKey)); - - #line default - #line hidden - this.Write(":\r\n __"); - - #line 124 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.Name)); - - #line default - #line hidden - this.Write("__ = "); - - #line 124 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.GetDeserializeMethodString())); - - #line default - #line hidden - this.Write(";\r\n break;\r\n"); - - #line 126 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" default:\r\n readSize = global::MessageP" + - "ack.MessagePackBinary.ReadNextBlock(bytes, offset);\r\n bre" + - "ak;\r\n }\r\n"); - - #line 131 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - if(objInfo.IsStringKey) { - - #line default - #line hidden - this.Write(" \r\n NEXT_LOOP:\r\n"); - - #line 133 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" offset += readSize;\r\n }\r\n\r\n readSize = offs" + - "et - startOffset;\r\n\r\n var ____result = new "); - - #line 139 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(objInfo.GetConstructorString())); - - #line default - #line hidden - this.Write(";\r\n"); - - #line 140 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - foreach(var x in objInfo.Members.Where(x => x.IsWritable)) { - - #line default - #line hidden - this.Write(" ____result."); - - #line 141 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.Name)); - - #line default - #line hidden - this.Write(" = __"); - - #line 141 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.Name)); - - #line default - #line hidden - this.Write("__;\r\n"); - - #line 142 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - - #line 143 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" -if(objInfo.HasIMessagePackSerializationCallbackReceiver && objInfo.NeedsCastOnAfter) { - - #line default - #line hidden - this.Write(" ((IMessagePackSerializationCallbackReceiver)____result).OnAfterDeseri" + - "alize();\r\n"); - - #line 145 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } else if(objInfo.HasIMessagePackSerializationCallbackReceiver) { - - #line default - #line hidden - this.Write(" ____result.OnAfterDeserialize();\r\n"); - - #line 147 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write(" return ____result;\r\n }\r\n }\r\n\r\n"); - - #line 152 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\FormatterTemplate.tt" - } - - #line default - #line hidden - this.Write("}\r\n\r\n#pragma warning restore 168\r\n#pragma warning restore 414\r\n#pragma warning re" + - "store 618\r\n#pragma warning restore 612"); - return this.GenerationEnvironment.ToString(); - } - } - - #line default - #line hidden - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public class FormatterTemplateBase - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - protected System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} diff --git a/src/MessagePack.CodeGenerator/Generator/FormatterTemplate.tt b/src/MessagePack.CodeGenerator/Generator/FormatterTemplate.tt deleted file mode 100644 index e05e432f..00000000 --- a/src/MessagePack.CodeGenerator/Generator/FormatterTemplate.tt +++ /dev/null @@ -1,158 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -#pragma warning disable 618 -#pragma warning disable 612 -#pragma warning disable 414 -#pragma warning disable 168 - -namespace <#= Namespace #> -{ - using System; - using MessagePack; - -<# foreach(var objInfo in objectSerializationInfos) { #> - - public sealed class <#= objInfo.Name #>Formatter : global::MessagePack.Formatters.IMessagePackFormatter<<#= objInfo.FullName #>> - { -<# if( objInfo.IsStringKey) { #> - - readonly global::MessagePack.Internal.AutomataDictionary ____keyMapping; - readonly byte[][] ____stringByteKeys; - - public <#= objInfo.Name #>Formatter() - { - this.____keyMapping = new global::MessagePack.Internal.AutomataDictionary() - { -<# foreach(var x in objInfo.Members) { #> - { "<#= x.StringKey #>", <#= x.IntKey #>}, -<# } #> - }; - - this.____stringByteKeys = new byte[][] - { -<# foreach(var x in objInfo.Members.Where(x => x.IsReadable)) { #> - global::MessagePack.MessagePackBinary.GetEncodedStringBytes("<#= x.StringKey #>"), -<# } #> - }; - } - -<# } #> - - public int Serialize(ref byte[] bytes, int offset, <#= objInfo.FullName #> value, global::MessagePack.IFormatterResolver formatterResolver) - { -<# if( objInfo.IsClass) { #> - if (value == null) - { - return global::MessagePack.MessagePackBinary.WriteNil(ref bytes, offset); - } -<# } #> -<#if(objInfo.HasIMessagePackSerializationCallbackReceiver && objInfo.NeedsCastOnBefore) { #> - ((IMessagePackSerializationCallbackReceiver)value).OnBeforeSerialize(); -<# } else if(objInfo.HasIMessagePackSerializationCallbackReceiver) { #> - value.OnBeforeSerialize(); -<# } #> - var startOffset = offset; -<# if( objInfo.IsIntKey) { if( (objInfo.MaxKey + 1) <= 15) { #> - offset += global::MessagePack.MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, <#= objInfo.MaxKey + 1 #>); -<# } else { #> - offset += global::MessagePack.MessagePackBinary.WriteArrayHeader(ref bytes, offset, <#= objInfo.MaxKey + 1 #>); -<# } } else if( objInfo.WriteCount <= 15) { #> - offset += global::MessagePack.MessagePackBinary.WriteFixedMapHeaderUnsafe(ref bytes, offset, <#= objInfo.WriteCount #>); -<# } else { #> - offset += global::MessagePack.MessagePackBinary.WriteMapHeader(ref bytes, offset, <#= objInfo.WriteCount #>); -<# } #> -<# if(objInfo.IsIntKey) { #> -<# for(var i =0; i<= objInfo.MaxKey; i++) { var member = objInfo.GetMember(i); #> -<# if( member == null) { #> - offset += global::MessagePack.MessagePackBinary.WriteNil(ref bytes, offset); -<# } else { #> - offset += <#= member.GetSerializeMethodString() #>; -<# } } } else { #> -<# var index = 0; foreach(var x in objInfo.Members) { #> - offset += global::MessagePack.MessagePackBinary.WriteRaw(ref bytes, offset, this.____stringByteKeys[<#= index++ #>]); - offset += <#= x.GetSerializeMethodString() #>; -<# } } #> - return offset - startOffset; - } - - public <#= objInfo.FullName #> Deserialize(byte[] bytes, int offset, global::MessagePack.IFormatterResolver formatterResolver, out int readSize) - { - if (global::MessagePack.MessagePackBinary.IsNil(bytes, offset)) - { -<# if( objInfo.IsClass) { #> - readSize = 1; - return null; -<# } else { #> - throw new InvalidOperationException("typecode is null, struct not supported"); -<# } #> - } - - var startOffset = offset; -<# if(objInfo.IsStringKey) { #> - var length = global::MessagePack.MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); -<# } else { #> - var length = global::MessagePack.MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); -<# } #> - offset += readSize; - -<# foreach(var x in objInfo.Members) { #> - var __<#= x.Name #>__ = default(<#= x.Type #>); -<# } #> - - for (int i = 0; i < length; i++) - { -<# if(objInfo.IsStringKey) { #> - var stringKey = global::MessagePack.MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); - offset += readSize; - int key; - if (!____keyMapping.TryGetValueSafe(stringKey, out key)) - { - readSize = global::MessagePack.MessagePackBinary.ReadNextBlock(bytes, offset); - goto NEXT_LOOP; - } -<# } else { #> - var key = i; -<# } #> - - switch (key) - { -<# foreach(var x in objInfo.Members) { #> - case <#= x.IntKey #>: - __<#= x.Name #>__ = <#= x.GetDeserializeMethodString() #>; - break; -<# } #> - default: - readSize = global::MessagePack.MessagePackBinary.ReadNextBlock(bytes, offset); - break; - } -<# if(objInfo.IsStringKey) { #> - NEXT_LOOP: -<# } #> - offset += readSize; - } - - readSize = offset - startOffset; - - var ____result = new <#= objInfo.GetConstructorString() #>; -<# foreach(var x in objInfo.Members.Where(x => x.IsWritable)) { #> - ____result.<#= x.Name #> = __<#= x.Name #>__; -<# } #> -<#if(objInfo.HasIMessagePackSerializationCallbackReceiver && objInfo.NeedsCastOnAfter) { #> - ((IMessagePackSerializationCallbackReceiver)____result).OnAfterDeserialize(); -<# } else if(objInfo.HasIMessagePackSerializationCallbackReceiver) { #> - ____result.OnAfterDeserialize(); -<# } #> - return ____result; - } - } - -<# } #> -} - -#pragma warning restore 168 -#pragma warning restore 414 -#pragma warning restore 618 -#pragma warning restore 612 \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/Generator/ResolverTemplate.cs b/src/MessagePack.CodeGenerator/Generator/ResolverTemplate.cs deleted file mode 100644 index 0e7d5d82..00000000 --- a/src/MessagePack.CodeGenerator/Generator/ResolverTemplate.cs +++ /dev/null @@ -1,455 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// このコードはツールによって生成されました。 -// ランタイム バージョン: 15.0.0.0 -// -// このファイルへの変更は、正しくない動作の原因になる可能性があり、 -// コードが再生成されると失われます。 -// -// ------------------------------------------------------------------------------ -namespace MessagePack.CodeGenerator.Generator -{ - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System; - - /// - /// Class to produce the template output - /// - - #line 1 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public partial class ResolverTemplate : ResolverTemplateBase - { -#line hidden - /// - /// Create the template output - /// - public virtual string TransformText() - { - this.Write("#pragma warning disable 618\r\n#pragma warning disable 612\r\n#pragma warning disable" + - " 414\r\n#pragma warning disable 168\r\n\r\nnamespace "); - - #line 11 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - - #line default - #line hidden - this.Write("\r\n{\r\n using System;\r\n using MessagePack;\r\n\r\n public class "); - - #line 16 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); - - #line default - #line hidden - this.Write(" : global::MessagePack.IFormatterResolver\r\n {\r\n public static readonly " + - "global::MessagePack.IFormatterResolver Instance = new "); - - #line 18 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); - - #line default - #line hidden - this.Write("();\r\n\r\n "); - - #line 20 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); - - #line default - #line hidden - this.Write(@"() - { - - } - - public global::MessagePack.Formatters.IMessagePackFormatter GetFormatter() - { - return FormatterCache.formatter; - } - - static class FormatterCache - { - public static readonly global::MessagePack.Formatters.IMessagePackFormatter formatter; - - static FormatterCache() - { - var f = "); - - #line 36 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); - - #line default - #line hidden - this.Write(@"GetFormatterHelper.GetFormatter(typeof(T)); - if (f != null) - { - formatter = (global::MessagePack.Formatters.IMessagePackFormatter)f; - } - } - } - } - - internal static class "); - - #line 45 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); - - #line default - #line hidden - this.Write("GetFormatterHelper\r\n {\r\n static readonly global::System.Collections.Gen" + - "eric.Dictionary lookup;\r\n\r\n static "); - - #line 49 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(ResolverName)); - - #line default - #line hidden - this.Write("GetFormatterHelper()\r\n {\r\n lookup = new global::System.Collecti" + - "ons.Generic.Dictionary("); - - #line 51 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(registerInfos.Length)); - - #line default - #line hidden - this.Write(")\r\n {\r\n"); - - #line 53 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - for(var i = 0; i < registerInfos.Length; i++) { var x = registerInfos[i]; - - #line default - #line hidden - this.Write(" {typeof("); - - #line 54 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.FullName)); - - #line default - #line hidden - this.Write("), "); - - #line 54 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(i)); - - #line default - #line hidden - this.Write(" },\r\n"); - - #line 55 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - } - - #line default - #line hidden - this.Write(" };\r\n }\r\n\r\n internal static object GetFormatter(Type t)\r" + - "\n {\r\n int key;\r\n if (!lookup.TryGetValue(t, out key" + - ")) return null;\r\n\r\n switch (key)\r\n {\r\n"); - - #line 66 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - for(var i = 0; i < registerInfos.Length; i++) { var x = registerInfos[i]; - - #line default - #line hidden - this.Write(" case "); - - #line 67 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(i)); - - #line default - #line hidden - this.Write(": return new "); - - #line 67 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(x.FormatterName.StartsWith("global::") ? x.FormatterName: (!string.IsNullOrEmpty(FormatterNamespace) ? FormatterNamespace + "." : FormatterNamespace) + x.FormatterName)); - - #line default - #line hidden - this.Write("();\r\n"); - - #line 68 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\ResolverTemplate.tt" - } - - #line default - #line hidden - this.Write(" default: return null;\r\n }\r\n }\r\n }\r\n}\r\n\r\n#pra" + - "gma warning restore 168\r\n#pragma warning restore 414\r\n#pragma warning restore 61" + - "8\r\n#pragma warning restore 612"); - return this.GenerationEnvironment.ToString(); - } - } - - #line default - #line hidden - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public class ResolverTemplateBase - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - protected System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} diff --git a/src/MessagePack.CodeGenerator/Generator/ResolverTemplate.tt b/src/MessagePack.CodeGenerator/Generator/ResolverTemplate.tt deleted file mode 100644 index a7511a36..00000000 --- a/src/MessagePack.CodeGenerator/Generator/ResolverTemplate.tt +++ /dev/null @@ -1,78 +0,0 @@ -<#@ template language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -#pragma warning disable 618 -#pragma warning disable 612 -#pragma warning disable 414 -#pragma warning disable 168 - -namespace <#= Namespace #> -{ - using System; - using MessagePack; - - public class <#= ResolverName #> : global::MessagePack.IFormatterResolver - { - public static readonly global::MessagePack.IFormatterResolver Instance = new <#= ResolverName #>(); - - <#= ResolverName #>() - { - - } - - public global::MessagePack.Formatters.IMessagePackFormatter GetFormatter() - { - return FormatterCache.formatter; - } - - static class FormatterCache - { - public static readonly global::MessagePack.Formatters.IMessagePackFormatter formatter; - - static FormatterCache() - { - var f = <#= ResolverName #>GetFormatterHelper.GetFormatter(typeof(T)); - if (f != null) - { - formatter = (global::MessagePack.Formatters.IMessagePackFormatter)f; - } - } - } - } - - internal static class <#= ResolverName #>GetFormatterHelper - { - static readonly global::System.Collections.Generic.Dictionary lookup; - - static <#= ResolverName #>GetFormatterHelper() - { - lookup = new global::System.Collections.Generic.Dictionary(<#= registerInfos.Length #>) - { -<# for(var i = 0; i < registerInfos.Length; i++) { var x = registerInfos[i]; #> - {typeof(<#= x.FullName #>), <#= i #> }, -<# } #> - }; - } - - internal static object GetFormatter(Type t) - { - int key; - if (!lookup.TryGetValue(t, out key)) return null; - - switch (key) - { -<# for(var i = 0; i < registerInfos.Length; i++) { var x = registerInfos[i]; #> - case <#= i #>: return new <#= x.FormatterName.StartsWith("global::") ? x.FormatterName: (!string.IsNullOrEmpty(FormatterNamespace) ? FormatterNamespace + "." : FormatterNamespace) + x.FormatterName#>(); -<# } #> - default: return null; - } - } - } -} - -#pragma warning restore 168 -#pragma warning restore 414 -#pragma warning restore 618 -#pragma warning restore 612 \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/Generator/TemplatePartials.cs b/src/MessagePack.CodeGenerator/Generator/TemplatePartials.cs deleted file mode 100644 index 03d60a20..00000000 --- a/src/MessagePack.CodeGenerator/Generator/TemplatePartials.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MessagePack.CodeGenerator.Generator -{ - public partial class FormatterTemplate - { - public string Namespace; - public ObjectSerializationInfo[] objectSerializationInfos; - } - - public partial class ResolverTemplate - { - public string Namespace; - public string FormatterNamespace { get; set; } - public string ResolverName = "GeneratedResolver"; - public IResolverRegisterInfo[] registerInfos; - } - public partial class EnumTemplate - { - public string Namespace; - public EnumSerializationInfo[] enumSerializationInfos; - } - - public partial class UnionTemplate - { - public string Namespace; - public UnionSerializationInfo[] unionSerializationInfos; - } -} diff --git a/src/MessagePack.CodeGenerator/Generator/UnionTemplate.cs b/src/MessagePack.CodeGenerator/Generator/UnionTemplate.cs deleted file mode 100644 index 9b29e901..00000000 --- a/src/MessagePack.CodeGenerator/Generator/UnionTemplate.cs +++ /dev/null @@ -1,584 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// このコードはツールによって生成されました。 -// ランタイム バージョン: 15.0.0.0 -// -// このファイルへの変更は、正しくない動作の原因になる可能性があり、 -// コードが再生成されると失われます。 -// -// ------------------------------------------------------------------------------ -namespace MessagePack.CodeGenerator.Generator -{ - using System.Linq; - using System.Text; - using System.Collections.Generic; - using System; - - /// - /// Class to produce the template output - /// - - #line 1 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public partial class UnionTemplate : UnionTemplateBase - { -#line hidden - /// - /// Create the template output - /// - public virtual string TransformText() - { - this.Write("#pragma warning disable 618\r\n#pragma warning disable 612\r\n#pragma warning disable" + - " 414\r\n#pragma warning disable 168\r\n\r\nnamespace "); - - #line 11 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); - - #line default - #line hidden - this.Write("\r\n{\r\n using System;\r\n using System.Collections.Generic;\r\n using MessageP" + - "ack;\r\n\r\n"); - - #line 17 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - foreach(var info in unionSerializationInfos) { - - #line default - #line hidden - this.Write(" public sealed class "); - - #line 18 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.Name)); - - #line default - #line hidden - this.Write("Formatter : global::MessagePack.Formatters.IMessagePackFormatter<"); - - #line 18 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(">\r\n {\r\n readonly Dictionary> " + - "typeToKeyAndJumpMap;\r\n readonly Dictionary keyToJumpMap;\r\n\r\n " + - " public "); - - #line 23 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.Name)); - - #line default - #line hidden - this.Write("Formatter()\r\n {\r\n this.typeToKeyAndJumpMap = new Dictionary>("); - - #line 25 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.SubTypes.Length)); - - #line default - #line hidden - this.Write(", global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default)\r\n " + - " {\r\n"); - - #line 27 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; - - #line default - #line hidden - this.Write(" { typeof("); - - #line 28 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(item.Type)); - - #line default - #line hidden - this.Write(").TypeHandle, new KeyValuePair("); - - #line 28 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(item.Key)); - - #line default - #line hidden - this.Write(", "); - - #line 28 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(i)); - - #line default - #line hidden - this.Write(") },\r\n"); - - #line 29 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - } - - #line default - #line hidden - this.Write(" };\r\n this.keyToJumpMap = new Dictionary("); - - #line 31 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.SubTypes.Length)); - - #line default - #line hidden - this.Write(")\r\n {\r\n"); - - #line 33 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; - - #line default - #line hidden - this.Write(" { "); - - #line 34 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(item.Key)); - - #line default - #line hidden - this.Write(", "); - - #line 34 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(i)); - - #line default - #line hidden - this.Write(" },\r\n"); - - #line 35 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - } - - #line default - #line hidden - this.Write(" };\r\n }\r\n\r\n public int Serialize(ref byte[] bytes, int o" + - "ffset, "); - - #line 39 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(@" value, global::MessagePack.IFormatterResolver formatterResolver) - { - KeyValuePair keyValuePair; - if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair)) - { - var startOffset = offset; - offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, 2); - offset += MessagePackBinary.WriteInt32(ref bytes, offset, keyValuePair.Key); - switch (keyValuePair.Value) - { -"); - - #line 49 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; - - #line default - #line hidden - this.Write(" case "); - - #line 50 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(i)); - - #line default - #line hidden - this.Write(":\r\n offset += formatterResolver.GetFormatterWithVerify<"); - - #line 51 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(item.Type)); - - #line default - #line hidden - this.Write(">().Serialize(ref bytes, offset, ("); - - #line 51 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(item.Type)); - - #line default - #line hidden - this.Write(")value, formatterResolver);\r\n break;\r\n"); - - #line 53 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - } - - #line default - #line hidden - this.Write(" default:\r\n break;\r\n }\r\n" + - "\r\n return offset - startOffset;\r\n }\r\n\r\n ret" + - "urn MessagePackBinary.WriteNil(ref bytes, offset);\r\n }\r\n \r\n " + - " public "); - - #line 64 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(@" Deserialize(byte[] bytes, int offset, global::MessagePack.IFormatterResolver formatterResolver, out int readSize) - { - if (MessagePackBinary.IsNil(bytes, offset)) - { - readSize = 1; - return null; - } - - var startOffset = offset; - - if (MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize) != 2) - { - throw new InvalidOperationException(""Invalid Union data was detected. Type:"); - - #line 76 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(@"""); - } - offset += readSize; - - var key = MessagePackBinary.ReadInt32(bytes, offset, out readSize); - offset += readSize; - - if (!this.keyToJumpMap.TryGetValue(key, out key)) - { - key = -1; - } - - "); - - #line 88 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(" result = null;\r\n switch (key)\r\n {\r\n"); - - #line 91 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; - - #line default - #line hidden - this.Write(" case "); - - #line 92 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(i)); - - #line default - #line hidden - this.Write(":\r\n result = ("); - - #line 93 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(info.FullName)); - - #line default - #line hidden - this.Write(")formatterResolver.GetFormatterWithVerify<"); - - #line 93 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - this.Write(this.ToStringHelper.ToStringWithCulture(item.Type)); - - #line default - #line hidden - this.Write(">().Deserialize(bytes, offset, formatterResolver, out readSize);\r\n " + - " offset += readSize;\r\n break;\r\n"); - - #line 96 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - } - - #line default - #line hidden - this.Write(@" default: - offset += MessagePackBinary.ReadNextBlock(bytes, offset); - break; - } - - readSize = offset - startOffset; - - return result; - } - } - -"); - - #line 108 "C:\Users\y.kawai\Documents\neuecc\MessagePack-CSharp\src\MessagePack.CodeGenerator\Generator\UnionTemplate.tt" - } - - #line default - #line hidden - this.Write("\r\n}\r\n\r\n#pragma warning restore 168\r\n#pragma warning restore 414\r\n#pragma warning " + - "restore 618\r\n#pragma warning restore 612"); - return this.GenerationEnvironment.ToString(); - } - } - - #line default - #line hidden - #region Base class - /// - /// Base class for this transformation - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "15.0.0.0")] - public class UnionTemplateBase - { - #region Fields - private global::System.Text.StringBuilder generationEnvironmentField; - private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField; - private global::System.Collections.Generic.List indentLengthsField; - private string currentIndentField = ""; - private bool endsWithNewline; - private global::System.Collections.Generic.IDictionary sessionField; - #endregion - #region Properties - /// - /// The string builder that generation-time code is using to assemble generated output - /// - protected System.Text.StringBuilder GenerationEnvironment - { - get - { - if ((this.generationEnvironmentField == null)) - { - this.generationEnvironmentField = new global::System.Text.StringBuilder(); - } - return this.generationEnvironmentField; - } - set - { - this.generationEnvironmentField = value; - } - } - /// - /// The error collection for the generation process - /// - public System.CodeDom.Compiler.CompilerErrorCollection Errors - { - get - { - if ((this.errorsField == null)) - { - this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection(); - } - return this.errorsField; - } - } - /// - /// A list of the lengths of each indent that was added with PushIndent - /// - private System.Collections.Generic.List indentLengths - { - get - { - if ((this.indentLengthsField == null)) - { - this.indentLengthsField = new global::System.Collections.Generic.List(); - } - return this.indentLengthsField; - } - } - /// - /// Gets the current indent we use when adding lines to the output - /// - public string CurrentIndent - { - get - { - return this.currentIndentField; - } - } - /// - /// Current transformation session - /// - public virtual global::System.Collections.Generic.IDictionary Session - { - get - { - return this.sessionField; - } - set - { - this.sessionField = value; - } - } - #endregion - #region Transform-time helpers - /// - /// Write text directly into the generated output - /// - public void Write(string textToAppend) - { - if (string.IsNullOrEmpty(textToAppend)) - { - return; - } - // If we're starting off, or if the previous text ended with a newline, - // we have to append the current indent first. - if (((this.GenerationEnvironment.Length == 0) - || this.endsWithNewline)) - { - this.GenerationEnvironment.Append(this.currentIndentField); - this.endsWithNewline = false; - } - // Check if the current text ends with a newline - if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture)) - { - this.endsWithNewline = true; - } - // This is an optimization. If the current indent is "", then we don't have to do any - // of the more complex stuff further down. - if ((this.currentIndentField.Length == 0)) - { - this.GenerationEnvironment.Append(textToAppend); - return; - } - // Everywhere there is a newline in the text, add an indent after it - textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField)); - // If the text ends with a newline, then we should strip off the indent added at the very end - // because the appropriate indent will be added when the next time Write() is called - if (this.endsWithNewline) - { - this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length)); - } - else - { - this.GenerationEnvironment.Append(textToAppend); - } - } - /// - /// Write text directly into the generated output - /// - public void WriteLine(string textToAppend) - { - this.Write(textToAppend); - this.GenerationEnvironment.AppendLine(); - this.endsWithNewline = true; - } - /// - /// Write formatted text directly into the generated output - /// - public void Write(string format, params object[] args) - { - this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Write formatted text directly into the generated output - /// - public void WriteLine(string format, params object[] args) - { - this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args)); - } - /// - /// Raise an error - /// - public void Error(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - this.Errors.Add(error); - } - /// - /// Raise a warning - /// - public void Warning(string message) - { - System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError(); - error.ErrorText = message; - error.IsWarning = true; - this.Errors.Add(error); - } - /// - /// Increase the indent - /// - public void PushIndent(string indent) - { - if ((indent == null)) - { - throw new global::System.ArgumentNullException("indent"); - } - this.currentIndentField = (this.currentIndentField + indent); - this.indentLengths.Add(indent.Length); - } - /// - /// Remove the last indent that was added with PushIndent - /// - public string PopIndent() - { - string returnValue = ""; - if ((this.indentLengths.Count > 0)) - { - int indentLength = this.indentLengths[(this.indentLengths.Count - 1)]; - this.indentLengths.RemoveAt((this.indentLengths.Count - 1)); - if ((indentLength > 0)) - { - returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength)); - this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength)); - } - } - return returnValue; - } - /// - /// Remove any indentation - /// - public void ClearIndent() - { - this.indentLengths.Clear(); - this.currentIndentField = ""; - } - #endregion - #region ToString Helpers - /// - /// Utility class to produce culture-oriented representation of an object as a string. - /// - public class ToStringInstanceHelper - { - private System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture; - /// - /// Gets or sets format provider to be used by ToStringWithCulture method. - /// - public System.IFormatProvider FormatProvider - { - get - { - return this.formatProviderField ; - } - set - { - if ((value != null)) - { - this.formatProviderField = value; - } - } - } - /// - /// This is called from the compile/run appdomain to convert objects within an expression block to a string - /// - public string ToStringWithCulture(object objectToConvert) - { - if ((objectToConvert == null)) - { - throw new global::System.ArgumentNullException("objectToConvert"); - } - System.Type t = objectToConvert.GetType(); - System.Reflection.MethodInfo method = t.GetMethod("ToString", new System.Type[] { - typeof(System.IFormatProvider)}); - if ((method == null)) - { - return objectToConvert.ToString(); - } - else - { - return ((string)(method.Invoke(objectToConvert, new object[] { - this.formatProviderField }))); - } - } - } - private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper(); - /// - /// Helper to produce culture-oriented representation of an object as a string - /// - public ToStringInstanceHelper ToStringHelper - { - get - { - return this.toStringHelperField; - } - } - #endregion - } - #endregion -} diff --git a/src/MessagePack.CodeGenerator/Generator/UnionTemplate.tt b/src/MessagePack.CodeGenerator/Generator/UnionTemplate.tt deleted file mode 100644 index e1578f89..00000000 --- a/src/MessagePack.CodeGenerator/Generator/UnionTemplate.tt +++ /dev/null @@ -1,115 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -#pragma warning disable 618 -#pragma warning disable 612 -#pragma warning disable 414 -#pragma warning disable 168 - -namespace <#= Namespace #> -{ - using System; - using System.Collections.Generic; - using MessagePack; - -<# foreach(var info in unionSerializationInfos) { #> - public sealed class <#= info.Name #>Formatter : global::MessagePack.Formatters.IMessagePackFormatter<<#= info.FullName #>> - { - readonly Dictionary> typeToKeyAndJumpMap; - readonly Dictionary keyToJumpMap; - - public <#= info.Name #>Formatter() - { - this.typeToKeyAndJumpMap = new Dictionary>(<#= info.SubTypes.Length #>, global::MessagePack.Internal.RuntimeTypeHandleEqualityComparer.Default) - { -<# for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; #> - { typeof(<#= item.Type #>).TypeHandle, new KeyValuePair(<#= item.Key #>, <#= i #>) }, -<# } #> - }; - this.keyToJumpMap = new Dictionary(<#= info.SubTypes.Length #>) - { -<# for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; #> - { <#= item.Key #>, <#= i #> }, -<# } #> - }; - } - - public int Serialize(ref byte[] bytes, int offset, <#= info.FullName #> value, global::MessagePack.IFormatterResolver formatterResolver) - { - KeyValuePair keyValuePair; - if (value != null && this.typeToKeyAndJumpMap.TryGetValue(value.GetType().TypeHandle, out keyValuePair)) - { - var startOffset = offset; - offset += MessagePackBinary.WriteFixedArrayHeaderUnsafe(ref bytes, offset, 2); - offset += MessagePackBinary.WriteInt32(ref bytes, offset, keyValuePair.Key); - switch (keyValuePair.Value) - { -<# for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; #> - case <#= i #>: - offset += formatterResolver.GetFormatterWithVerify<<#= item.Type #>>().Serialize(ref bytes, offset, (<#= item.Type #>)value, formatterResolver); - break; -<# } #> - default: - break; - } - - return offset - startOffset; - } - - return MessagePackBinary.WriteNil(ref bytes, offset); - } - - public <#= info.FullName #> Deserialize(byte[] bytes, int offset, global::MessagePack.IFormatterResolver formatterResolver, out int readSize) - { - if (MessagePackBinary.IsNil(bytes, offset)) - { - readSize = 1; - return null; - } - - var startOffset = offset; - - if (MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize) != 2) - { - throw new InvalidOperationException("Invalid Union data was detected. Type:<#= info.FullName #>"); - } - offset += readSize; - - var key = MessagePackBinary.ReadInt32(bytes, offset, out readSize); - offset += readSize; - - if (!this.keyToJumpMap.TryGetValue(key, out key)) - { - key = -1; - } - - <#= info.FullName #> result = null; - switch (key) - { -<# for(var i = 0; i < info.SubTypes.Length; i++) { var item = info.SubTypes[i]; #> - case <#= i #>: - result = (<#= info.FullName #>)formatterResolver.GetFormatterWithVerify<<#= item.Type #>>().Deserialize(bytes, offset, formatterResolver, out readSize); - offset += readSize; - break; -<# } #> - default: - offset += MessagePackBinary.ReadNextBlock(bytes, offset); - break; - } - - readSize = offset - startOffset; - - return result; - } - } - -<# } #> - -} - -#pragma warning restore 168 -#pragma warning restore 414 -#pragma warning restore 618 -#pragma warning restore 612 \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/MessagePack.CodeGenerator.csproj b/src/MessagePack.CodeGenerator/MessagePack.CodeGenerator.csproj deleted file mode 100644 index 6bc31cd2..00000000 --- a/src/MessagePack.CodeGenerator/MessagePack.CodeGenerator.csproj +++ /dev/null @@ -1,57 +0,0 @@ - - - Exe - mpc - net461 - true - - - - - - - - - - - - - UnionTemplate.tt - True - True - - - True - True - EnumTemplate.tt - - - True - True - FormatterTemplate.tt - - - True - True - ResolverTemplate.tt - - - - - TextTemplatingFilePreprocessor - UnionTemplate.cs - - - TextTemplatingFilePreprocessor - EnumTemplate.cs - - - TextTemplatingFilePreprocessor - FormatterTemplate.cs - - - TextTemplatingFilePreprocessor - ResolverTemplate.cs - - - diff --git a/src/MessagePack.CodeGenerator/Mono.Options/Options.cs b/src/MessagePack.CodeGenerator/Mono.Options/Options.cs deleted file mode 100644 index 486b3ca8..00000000 --- a/src/MessagePack.CodeGenerator/Mono.Options/Options.cs +++ /dev/null @@ -1,1463 +0,0 @@ -// -// Options.cs -// -// Authors: -// Jonathan Pryor -// Federico Di Gregorio -// Rolf Bjarne Kvinge -// -// Copyright (C) 2008 Novell (http://www.novell.com) -// Copyright (C) 2009 Federico Di Gregorio. -// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -// Compile With: -// gmcs -debug+ -r:System.Core Options.cs -o:NDesk.Options.dll -// gmcs -debug+ -d:LINQ -r:System.Core Options.cs -o:NDesk.Options.dll -// -// The LINQ version just changes the implementation of -// OptionSet.Parse(IEnumerable), and confers no semantic changes. - -// -// A Getopt::Long-inspired option parsing library for C#. -// -// NDesk.Options.OptionSet is built upon a key/value table, where the -// key is a option format string and the value is a delegate that is -// invoked when the format string is matched. -// -// Option format strings: -// Regex-like BNF Grammar: -// name: .+ -// type: [=:] -// sep: ( [^{}]+ | '{' .+ '}' )? -// aliases: ( name type sep ) ( '|' name type sep )* -// -// Each '|'-delimited name is an alias for the associated action. If the -// format string ends in a '=', it has a required value. If the format -// string ends in a ':', it has an optional value. If neither '=' or ':' -// is present, no value is supported. `=' or `:' need only be defined on one -// alias, but if they are provided on more than one they must be consistent. -// -// Each alias portion may also end with a "key/value separator", which is used -// to split option values if the option accepts > 1 value. If not specified, -// it defaults to '=' and ':'. If specified, it can be any character except -// '{' and '}' OR the *string* between '{' and '}'. If no separator should be -// used (i.e. the separate values should be distinct arguments), then "{}" -// should be used as the separator. -// -// Options are extracted either from the current option by looking for -// the option name followed by an '=' or ':', or is taken from the -// following option IFF: -// - The current option does not contain a '=' or a ':' -// - The current option requires a value (i.e. not a Option type of ':') -// -// The `name' used in the option format string does NOT include any leading -// option indicator, such as '-', '--', or '/'. All three of these are -// permitted/required on any named option. -// -// Option bundling is permitted so long as: -// - '-' is used to start the option group -// - all of the bundled options are a single character -// - at most one of the bundled options accepts a value, and the value -// provided starts from the next character to the end of the string. -// -// This allows specifying '-a -b -c' as '-abc', and specifying '-D name=value' -// as '-Dname=value'. -// -// Option processing is disabled by specifying "--". All options after "--" -// are returned by OptionSet.Parse() unchanged and unprocessed. -// -// Unprocessed options are returned from OptionSet.Parse(). -// -// Examples: -// int verbose = 0; -// OptionSet p = new OptionSet () -// .Add ("v", v => ++verbose) -// .Add ("name=|value=", v => Console.WriteLine (v)); -// p.Parse (new string[]{"-v", "--v", "/v", "-name=A", "/name", "B", "extra"}); -// -// The above would parse the argument string array, and would invoke the -// lambda expression three times, setting `verbose' to 3 when complete. -// It would also print out "A" and "B" to standard output. -// The returned array would contain the string "extra". -// -// C# 3.0 collection initializers are supported and encouraged: -// var p = new OptionSet () { -// { "h|?|help", v => ShowHelp () }, -// }; -// -// System.ComponentModel.TypeConverter is also supported, allowing the use of -// custom data types in the callback type; TypeConverter.ConvertFromString() -// is used to convert the value option to an instance of the specified -// type: -// -// var p = new OptionSet () { -// { "foo=", (Foo f) => Console.WriteLine (f.ToString ()) }, -// }; -// -// Random other tidbits: -// - Boolean options (those w/o '=' or ':' in the option format string) -// are explicitly enabled if they are followed with '+', and explicitly -// disabled if they are followed with '-': -// string a = null; -// var p = new OptionSet () { -// { "a", s => a = s }, -// }; -// p.Parse (new string[]{"-a"}); // sets v != null -// p.Parse (new string[]{"-a+"}); // sets v != null -// p.Parse (new string[]{"-a-"}); // sets v == null -// - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Globalization; -using System.IO; -using System.Runtime.Serialization; -using System.Security.Permissions; -using System.Text; -using System.Text.RegularExpressions; - -#if LINQ -using System.Linq; -#endif - -#if TEST -using NDesk.Options; -#endif - -#if NDESK_OPTIONS -namespace NDesk.Options -#else -namespace Mono.Options -#endif -{ - static class StringCoda - { - - public static IEnumerable WrappedLines(string self, params int[] widths) - { - IEnumerable w = widths; - return WrappedLines(self, w); - } - - public static IEnumerable WrappedLines(string self, IEnumerable widths) - { - if (widths == null) - throw new ArgumentNullException("widths"); - return CreateWrappedLinesIterator(self, widths); - } - - private static IEnumerable CreateWrappedLinesIterator(string self, IEnumerable widths) - { - if (string.IsNullOrEmpty(self)) - { - yield return string.Empty; - yield break; - } - using (IEnumerator ewidths = widths.GetEnumerator()) - { - bool? hw = null; - int width = GetNextWidth(ewidths, int.MaxValue, ref hw); - int start = 0, end; - do - { - end = GetLineEnd(start, width, self); - char c = self[end - 1]; - if (char.IsWhiteSpace(c)) - --end; - bool needContinuation = end != self.Length && !IsEolChar(c); - string continuation = ""; - if (needContinuation) - { - --end; - continuation = "-"; - } - string line = self.Substring(start, end - start) + continuation; - yield return line; - start = end; - if (char.IsWhiteSpace(c)) - ++start; - width = GetNextWidth(ewidths, width, ref hw); - } while (start < self.Length); - } - } - - private static int GetNextWidth(IEnumerator ewidths, int curWidth, ref bool? eValid) - { - if (!eValid.HasValue || (eValid.HasValue && eValid.Value)) - { - curWidth = (eValid = ewidths.MoveNext()).Value ? ewidths.Current : curWidth; - // '.' is any character, - is for a continuation - const string minWidth = ".-"; - if (curWidth < minWidth.Length) - throw new ArgumentOutOfRangeException("widths", - string.Format("Element must be >= {0}, was {1}.", minWidth.Length, curWidth)); - return curWidth; - } - // no more elements, use the last element. - return curWidth; - } - - private static bool IsEolChar(char c) - { - return !char.IsLetterOrDigit(c); - } - - private static int GetLineEnd(int start, int length, string description) - { - int end = System.Math.Min(start + length, description.Length); - int sep = -1; - for (int i = start; i < end; ++i) - { - if (description[i] == '\n') - return i + 1; - if (IsEolChar(description[i])) - sep = i + 1; - } - if (sep == -1 || end == description.Length) - return end; - return sep; - } - } - - public class OptionValueCollection : IList, IList - { - - List values = new List(); - OptionContext c; - - internal OptionValueCollection(OptionContext c) - { - this.c = c; - } - - #region ICollection - void ICollection.CopyTo(Array array, int index) { (values as ICollection).CopyTo(array, index); } - bool ICollection.IsSynchronized { get { return (values as ICollection).IsSynchronized; } } - object ICollection.SyncRoot { get { return (values as ICollection).SyncRoot; } } - #endregion - - #region ICollection - public void Add(string item) { values.Add(item); } - public void Clear() { values.Clear(); } - public bool Contains(string item) { return values.Contains(item); } - public void CopyTo(string[] array, int arrayIndex) { values.CopyTo(array, arrayIndex); } - public bool Remove(string item) { return values.Remove(item); } - public int Count { get { return values.Count; } } - public bool IsReadOnly { get { return false; } } - #endregion - - #region IEnumerable - IEnumerator IEnumerable.GetEnumerator() { return values.GetEnumerator(); } - #endregion - - #region IEnumerable - public IEnumerator GetEnumerator() { return values.GetEnumerator(); } - #endregion - - #region IList - int IList.Add(object value) { return (values as IList).Add(value); } - bool IList.Contains(object value) { return (values as IList).Contains(value); } - int IList.IndexOf(object value) { return (values as IList).IndexOf(value); } - void IList.Insert(int index, object value) { (values as IList).Insert(index, value); } - void IList.Remove(object value) { (values as IList).Remove(value); } - void IList.RemoveAt(int index) { (values as IList).RemoveAt(index); } - bool IList.IsFixedSize { get { return false; } } - object IList.this[int index] { get { return this[index]; } set { (values as IList)[index] = value; } } - #endregion - - #region IList - public int IndexOf(string item) { return values.IndexOf(item); } - public void Insert(int index, string item) { values.Insert(index, item); } - public void RemoveAt(int index) { values.RemoveAt(index); } - - private void AssertValid(int index) - { - if (c.Option == null) - throw new InvalidOperationException("OptionContext.Option is null."); - if (index >= c.Option.MaxValueCount) - throw new ArgumentOutOfRangeException("index"); - if (c.Option.OptionValueType == OptionValueType.Required && - index >= values.Count) - throw new OptionException(string.Format( - c.OptionSet.MessageLocalizer("Missing required value for option '{0}'."), c.OptionName), - c.OptionName); - } - - public string this[int index] - { - get - { - AssertValid(index); - return index >= values.Count ? null : values[index]; - } - set - { - values[index] = value; - } - } - #endregion - - public List ToList() - { - return new List(values); - } - - public string[] ToArray() - { - return values.ToArray(); - } - - public override string ToString() - { - return string.Join(", ", values.ToArray()); - } - } - - public class OptionContext - { - private Option option; - private string name; - private int index; - private OptionSet set; - private OptionValueCollection c; - - public OptionContext(OptionSet set) - { - this.set = set; - this.c = new OptionValueCollection(this); - } - - public Option Option - { - get { return option; } - set { option = value; } - } - - public string OptionName - { - get { return name; } - set { name = value; } - } - - public int OptionIndex - { - get { return index; } - set { index = value; } - } - - public OptionSet OptionSet - { - get { return set; } - } - - public OptionValueCollection OptionValues - { - get { return c; } - } - } - - public enum OptionValueType - { - None, - Optional, - Required, - } - - public abstract class Option - { - string prototype, description; - string[] names; - OptionValueType type; - int count; - string[] separators; - bool hidden; - - protected Option(string prototype, string description) - : this(prototype, description, 1, false) - { - } - - protected Option(string prototype, string description, int maxValueCount) - : this(prototype, description, maxValueCount, false) - { - } - - protected Option(string prototype, string description, int maxValueCount, bool hidden) - { - if (prototype == null) - throw new ArgumentNullException("prototype"); - if (prototype.Length == 0) - throw new ArgumentException("Cannot be the empty string.", "prototype"); - if (maxValueCount < 0) - throw new ArgumentOutOfRangeException("maxValueCount"); - - this.prototype = prototype; - this.description = description; - this.count = maxValueCount; - this.names = (this is OptionSet.Category) - // append GetHashCode() so that "duplicate" categories have distinct - // names, e.g. adding multiple "" categories should be valid. - ? new[] { prototype + this.GetHashCode() } - : prototype.Split('|'); - - if (this is OptionSet.Category) - return; - - this.type = ParsePrototype(); - this.hidden = hidden; - - if (this.count == 0 && type != OptionValueType.None) - throw new ArgumentException( - "Cannot provide maxValueCount of 0 for OptionValueType.Required or " + - "OptionValueType.Optional.", - "maxValueCount"); - if (this.type == OptionValueType.None && maxValueCount > 1) - throw new ArgumentException( - string.Format("Cannot provide maxValueCount of {0} for OptionValueType.None.", maxValueCount), - "maxValueCount"); - if (Array.IndexOf(names, "<>") >= 0 && - ((names.Length == 1 && this.type != OptionValueType.None) || - (names.Length > 1 && this.MaxValueCount > 1))) - throw new ArgumentException( - "The default option handler '<>' cannot require values.", - "prototype"); - } - - public string Prototype { get { return prototype; } } - public string Description { get { return description; } } - public OptionValueType OptionValueType { get { return type; } } - public int MaxValueCount { get { return count; } } - public bool Hidden { get { return hidden; } } - - public string[] GetNames() - { - return (string[])names.Clone(); - } - - public string[] GetValueSeparators() - { - if (separators == null) - return new string[0]; - return (string[])separators.Clone(); - } - - protected static T Parse(string value, OptionContext c) - { - Type tt = typeof(T); - bool nullable = tt.IsValueType && tt.IsGenericType && - !tt.IsGenericTypeDefinition && - tt.GetGenericTypeDefinition() == typeof(Nullable<>); - Type targetType = nullable ? tt.GetGenericArguments()[0] : typeof(T); - TypeConverter conv = TypeDescriptor.GetConverter(targetType); - T t = default(T); - try - { - if (value != null) - t = (T)conv.ConvertFromString(value); - } - catch (Exception e) - { - throw new OptionException( - string.Format( - c.OptionSet.MessageLocalizer("Could not convert string `{0}' to type {1} for option `{2}'."), - value, targetType.Name, c.OptionName), - c.OptionName, e); - } - return t; - } - - internal string[] Names { get { return names; } } - internal string[] ValueSeparators { get { return separators; } } - - static readonly char[] NameTerminator = new char[] { '=', ':' }; - - private OptionValueType ParsePrototype() - { - char type = '\0'; - List seps = new List(); - for (int i = 0; i < names.Length; ++i) - { - string name = names[i]; - if (name.Length == 0) - throw new ArgumentException("Empty option names are not supported.", "prototype"); - - int end = name.IndexOfAny(NameTerminator); - if (end == -1) - continue; - names[i] = name.Substring(0, end); - if (type == '\0' || type == name[end]) - type = name[end]; - else - throw new ArgumentException( - string.Format("Conflicting option types: '{0}' vs. '{1}'.", type, name[end]), - "prototype"); - AddSeparators(name, end, seps); - } - - if (type == '\0') - return OptionValueType.None; - - if (count <= 1 && seps.Count != 0) - throw new ArgumentException( - string.Format("Cannot provide key/value separators for Options taking {0} value(s).", count), - "prototype"); - if (count > 1) - { - if (seps.Count == 0) - this.separators = new string[] { ":", "=" }; - else if (seps.Count == 1 && seps[0].Length == 0) - this.separators = null; - else - this.separators = seps.ToArray(); - } - - return type == '=' ? OptionValueType.Required : OptionValueType.Optional; - } - - private static void AddSeparators(string name, int end, ICollection seps) - { - int start = -1; - for (int i = end + 1; i < name.Length; ++i) - { - switch (name[i]) - { - case '{': - if (start != -1) - throw new ArgumentException( - string.Format("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - start = i + 1; - break; - case '}': - if (start == -1) - throw new ArgumentException( - string.Format("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - seps.Add(name.Substring(start, i - start)); - start = -1; - break; - default: - if (start == -1) - seps.Add(name[i].ToString()); - break; - } - } - if (start != -1) - throw new ArgumentException( - string.Format("Ill-formed name/value separator found in \"{0}\".", name), - "prototype"); - } - - public void Invoke(OptionContext c) - { - OnParseComplete(c); - c.OptionName = null; - c.Option = null; - c.OptionValues.Clear(); - } - - protected abstract void OnParseComplete(OptionContext c); - - public override string ToString() - { - return Prototype; - } - } - - public abstract class ArgumentSource - { - - protected ArgumentSource() - { - } - - public abstract string[] GetNames(); - public abstract string Description { get; } - public abstract bool GetArguments(string value, out IEnumerable replacement); - - public static IEnumerable GetArgumentsFromFile(string file) - { - return GetArguments(File.OpenText(file), true); - } - - public static IEnumerable GetArguments(TextReader reader) - { - return GetArguments(reader, false); - } - - // Cribbed from mcs/driver.cs:LoadArgs(string) - static IEnumerable GetArguments(TextReader reader, bool close) - { - try - { - StringBuilder arg = new StringBuilder(); - - string line; - while ((line = reader.ReadLine()) != null) - { - int t = line.Length; - - for (int i = 0; i < t; i++) - { - char c = line[i]; - - if (c == '"' || c == '\'') - { - char end = c; - - for (i++; i < t; i++) - { - c = line[i]; - - if (c == end) - break; - arg.Append(c); - } - } - else if (c == ' ') - { - if (arg.Length > 0) - { - yield return arg.ToString(); - arg.Length = 0; - } - } - else - arg.Append(c); - } - if (arg.Length > 0) - { - yield return arg.ToString(); - arg.Length = 0; - } - } - } - finally - { - if (close) - reader.Close(); - } - } - } - - public class ResponseFileSource : ArgumentSource - { - - public override string[] GetNames() - { - return new string[] { "@file" }; - } - - public override string Description - { - get { return "Read response file for more options."; } - } - - public override bool GetArguments(string value, out IEnumerable replacement) - { - if (string.IsNullOrEmpty(value) || !value.StartsWith("@")) - { - replacement = null; - return false; - } - replacement = ArgumentSource.GetArgumentsFromFile(value.Substring(1)); - return true; - } - } - - [Serializable] - public class OptionException : Exception - { - private string option; - - public OptionException() - { - } - - public OptionException(string message, string optionName) - : base(message) - { - this.option = optionName; - } - - public OptionException(string message, string optionName, Exception innerException) - : base(message, innerException) - { - this.option = optionName; - } - - protected OptionException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - this.option = info.GetString("OptionName"); - } - - public string OptionName - { - get { return this.option; } - } - - [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("OptionName", option); - } - } - - public delegate void OptionAction(TKey key, TValue value); - - public class OptionSet : KeyedCollection - { - public OptionSet() - : this(delegate (string f) { return f; }) - { - } - - public OptionSet(Converter localizer) - { - this.localizer = localizer; - this.roSources = new ReadOnlyCollection(sources); - } - - Converter localizer; - - public Converter MessageLocalizer - { - get { return localizer; } - } - - List sources = new List(); - ReadOnlyCollection roSources; - - public ReadOnlyCollection ArgumentSources - { - get { return roSources; } - } - - - protected override string GetKeyForItem(Option item) - { - if (item == null) - throw new ArgumentNullException("option"); - if (item.Names != null && item.Names.Length > 0) - return item.Names[0]; - // This should never happen, as it's invalid for Option to be - // constructed w/o any names. - throw new InvalidOperationException("Option has no names!"); - } - - [Obsolete("Use KeyedCollection.this[string]")] - protected Option GetOptionForName(string option) - { - if (option == null) - throw new ArgumentNullException("option"); - try - { - return base[option]; - } - catch (KeyNotFoundException) - { - return null; - } - } - - protected override void InsertItem(int index, Option item) - { - base.InsertItem(index, item); - AddImpl(item); - } - - protected override void RemoveItem(int index) - { - Option p = Items[index]; - base.RemoveItem(index); - // KeyedCollection.RemoveItem() handles the 0th item - for (int i = 1; i < p.Names.Length; ++i) - { - Dictionary.Remove(p.Names[i]); - } - } - - protected override void SetItem(int index, Option item) - { - base.SetItem(index, item); - AddImpl(item); - } - - private void AddImpl(Option option) - { - if (option == null) - throw new ArgumentNullException("option"); - List added = new List(option.Names.Length); - try - { - // KeyedCollection.InsertItem/SetItem handle the 0th name. - for (int i = 1; i < option.Names.Length; ++i) - { - Dictionary.Add(option.Names[i], option); - added.Add(option.Names[i]); - } - } - catch (Exception) - { - foreach (string name in added) - Dictionary.Remove(name); - throw; - } - } - - public OptionSet Add(string header) - { - if (header == null) - throw new ArgumentNullException("header"); - Add(new Category(header)); - return this; - } - - internal sealed class Category : Option - { - - // Prototype starts with '=' because this is an invalid prototype - // (see Option.ParsePrototype(), and thus it'll prevent Category - // instances from being accidentally used as normal options. - public Category(string description) - : base("=:Category:= " + description, description) - { - } - - protected override void OnParseComplete(OptionContext c) - { - throw new NotSupportedException("Category.OnParseComplete should not be invoked."); - } - } - - - public new OptionSet Add(Option option) - { - base.Add(option); - return this; - } - - sealed class ActionOption : Option - { - Action action; - - public ActionOption(string prototype, string description, int count, Action action) - : this(prototype, description, count, action, false) - { - } - - public ActionOption(string prototype, string description, int count, Action action, bool hidden) - : base(prototype, description, count, hidden) - { - if (action == null) - throw new ArgumentNullException("action"); - this.action = action; - } - - protected override void OnParseComplete(OptionContext c) - { - action(c.OptionValues); - } - } - - public OptionSet Add(string prototype, Action action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, Action action) - { - return Add(prototype, description, action, false); - } - - public OptionSet Add(string prototype, string description, Action action, bool hidden) - { - if (action == null) - throw new ArgumentNullException("action"); - Option p = new ActionOption(prototype, description, 1, - delegate (OptionValueCollection v) { action(v[0]); }, hidden); - base.Add(p); - return this; - } - - public OptionSet Add(string prototype, OptionAction action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, OptionAction action) - { - return Add(prototype, description, action, false); - } - - public OptionSet Add(string prototype, string description, OptionAction action, bool hidden) - { - if (action == null) - throw new ArgumentNullException("action"); - Option p = new ActionOption(prototype, description, 2, - delegate (OptionValueCollection v) { action(v[0], v[1]); }, hidden); - base.Add(p); - return this; - } - - sealed class ActionOption : Option - { - Action action; - - public ActionOption(string prototype, string description, Action action) - : base(prototype, description, 1) - { - if (action == null) - throw new ArgumentNullException("action"); - this.action = action; - } - - protected override void OnParseComplete(OptionContext c) - { - action(Parse(c.OptionValues[0], c)); - } - } - - sealed class ActionOption : Option - { - OptionAction action; - - public ActionOption(string prototype, string description, OptionAction action) - : base(prototype, description, 2) - { - if (action == null) - throw new ArgumentNullException("action"); - this.action = action; - } - - protected override void OnParseComplete(OptionContext c) - { - action( - Parse(c.OptionValues[0], c), - Parse(c.OptionValues[1], c)); - } - } - - public OptionSet Add(string prototype, Action action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, Action action) - { - return Add(new ActionOption(prototype, description, action)); - } - - public OptionSet Add(string prototype, OptionAction action) - { - return Add(prototype, null, action); - } - - public OptionSet Add(string prototype, string description, OptionAction action) - { - return Add(new ActionOption(prototype, description, action)); - } - - public OptionSet Add(ArgumentSource source) - { - if (source == null) - throw new ArgumentNullException("source"); - sources.Add(source); - return this; - } - - protected virtual OptionContext CreateOptionContext() - { - return new OptionContext(this); - } - - public List Parse(IEnumerable arguments) - { - if (arguments == null) - throw new ArgumentNullException("arguments"); - OptionContext c = CreateOptionContext(); - c.OptionIndex = -1; - bool process = true; - List unprocessed = new List(); - Option def = Contains("<>") ? this["<>"] : null; - ArgumentEnumerator ae = new ArgumentEnumerator(arguments); - foreach (string argument in ae) - { - ++c.OptionIndex; - if (argument == "--") - { - process = false; - continue; - } - if (!process) - { - Unprocessed(unprocessed, def, c, argument); - continue; - } - if (AddSource(ae, argument)) - continue; - if (!Parse(argument, c)) - Unprocessed(unprocessed, def, c, argument); - } - if (c.Option != null) - c.Option.Invoke(c); - return unprocessed; - } - - class ArgumentEnumerator : IEnumerable - { - List> sources = new List>(); - - public ArgumentEnumerator(IEnumerable arguments) - { - sources.Add(arguments.GetEnumerator()); - } - - public void Add(IEnumerable arguments) - { - sources.Add(arguments.GetEnumerator()); - } - - public IEnumerator GetEnumerator() - { - do - { - IEnumerator c = sources[sources.Count - 1]; - if (c.MoveNext()) - yield return c.Current; - else - { - c.Dispose(); - sources.RemoveAt(sources.Count - 1); - } - } while (sources.Count > 0); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - - bool AddSource(ArgumentEnumerator ae, string argument) - { - foreach (ArgumentSource source in sources) - { - IEnumerable replacement; - if (!source.GetArguments(argument, out replacement)) - continue; - ae.Add(replacement); - return true; - } - return false; - } - - private static bool Unprocessed(ICollection extra, Option def, OptionContext c, string argument) - { - if (def == null) - { - extra.Add(argument); - return false; - } - c.OptionValues.Add(argument); - c.Option = def; - c.Option.Invoke(c); - return false; - } - - private readonly Regex ValueOption = new Regex( - @"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$"); - - protected bool GetOptionParts(string argument, out string flag, out string name, out string sep, out string value) - { - if (argument == null) - throw new ArgumentNullException("argument"); - - flag = name = sep = value = null; - Match m = ValueOption.Match(argument); - if (!m.Success) - { - return false; - } - flag = m.Groups["flag"].Value; - name = m.Groups["name"].Value; - if (m.Groups["sep"].Success && m.Groups["value"].Success) - { - sep = m.Groups["sep"].Value; - value = m.Groups["value"].Value; - } - return true; - } - - protected virtual bool Parse(string argument, OptionContext c) - { - if (c.Option != null) - { - ParseValue(argument, c); - return true; - } - - string f, n, s, v; - if (!GetOptionParts(argument, out f, out n, out s, out v)) - return false; - - Option p; - if (Contains(n)) - { - p = this[n]; - c.OptionName = f + n; - c.Option = p; - switch (p.OptionValueType) - { - case OptionValueType.None: - c.OptionValues.Add(n); - c.Option.Invoke(c); - break; - case OptionValueType.Optional: - case OptionValueType.Required: - ParseValue(v, c); - break; - } - return true; - } - // no match; is it a bool option? - if (ParseBool(argument, n, c)) - return true; - // is it a bundled option? - if (ParseBundledValue(f, string.Concat(n + s + v), c)) - return true; - - return false; - } - - private void ParseValue(string option, OptionContext c) - { - if (option != null) - foreach (string o in c.Option.ValueSeparators != null - ? option.Split(c.Option.ValueSeparators, c.Option.MaxValueCount - c.OptionValues.Count, StringSplitOptions.None) - : new string[] { option }) - { - c.OptionValues.Add(o); - } - if (c.OptionValues.Count == c.Option.MaxValueCount || - c.Option.OptionValueType == OptionValueType.Optional) - c.Option.Invoke(c); - else if (c.OptionValues.Count > c.Option.MaxValueCount) - { - throw new OptionException(localizer(string.Format( - "Error: Found {0} option values when expecting {1}.", - c.OptionValues.Count, c.Option.MaxValueCount)), - c.OptionName); - } - } - - private bool ParseBool(string option, string n, OptionContext c) - { - Option p; - string rn; - if (n.Length >= 1 && (n[n.Length - 1] == '+' || n[n.Length - 1] == '-') && - Contains((rn = n.Substring(0, n.Length - 1)))) - { - p = this[rn]; - string v = n[n.Length - 1] == '+' ? option : null; - c.OptionName = option; - c.Option = p; - c.OptionValues.Add(v); - p.Invoke(c); - return true; - } - return false; - } - - private bool ParseBundledValue(string f, string n, OptionContext c) - { - if (f != "-") - return false; - for (int i = 0; i < n.Length; ++i) - { - Option p; - string opt = f + n[i].ToString(); - string rn = n[i].ToString(); - if (!Contains(rn)) - { - if (i == 0) - return false; - throw new OptionException(string.Format(localizer( - "Cannot bundle unregistered option '{0}'."), opt), opt); - } - p = this[rn]; - switch (p.OptionValueType) - { - case OptionValueType.None: - Invoke(c, opt, n, p); - break; - case OptionValueType.Optional: - case OptionValueType.Required: - { - string v = n.Substring(i + 1); - c.Option = p; - c.OptionName = opt; - ParseValue(v.Length != 0 ? v : null, c); - return true; - } - default: - throw new InvalidOperationException("Unknown OptionValueType: " + p.OptionValueType); - } - } - return true; - } - - private static void Invoke(OptionContext c, string name, string value, Option option) - { - c.OptionName = name; - c.Option = option; - c.OptionValues.Add(value); - option.Invoke(c); - } - - private const int OptionWidth = 29; - private const int Description_FirstWidth = 80 - OptionWidth; - private const int Description_RemWidth = 80 - OptionWidth - 2; - - public void WriteOptionDescriptions(TextWriter o) - { - foreach (Option p in this) - { - int written = 0; - - if (p.Hidden) - continue; - - Category c = p as Category; - if (c != null) - { - WriteDescription(o, p.Description, "", 80, 80); - continue; - } - - if (!WriteOptionPrototype(o, p, ref written)) - continue; - - if (written < OptionWidth) - o.Write(new string(' ', OptionWidth - written)); - else - { - o.WriteLine(); - o.Write(new string(' ', OptionWidth)); - } - - WriteDescription(o, p.Description, new string(' ', OptionWidth + 2), - Description_FirstWidth, Description_RemWidth); - } - - foreach (ArgumentSource s in sources) - { - string[] names = s.GetNames(); - if (names == null || names.Length == 0) - continue; - - int written = 0; - - Write(o, ref written, " "); - Write(o, ref written, names[0]); - for (int i = 1; i < names.Length; ++i) - { - Write(o, ref written, ", "); - Write(o, ref written, names[i]); - } - - if (written < OptionWidth) - o.Write(new string(' ', OptionWidth - written)); - else - { - o.WriteLine(); - o.Write(new string(' ', OptionWidth)); - } - - WriteDescription(o, s.Description, new string(' ', OptionWidth + 2), - Description_FirstWidth, Description_RemWidth); - } - } - - void WriteDescription(TextWriter o, string value, string prefix, int firstWidth, int remWidth) - { - bool indent = false; - foreach (string line in GetLines(localizer(GetDescription(value)), firstWidth, remWidth)) - { - if (indent) - o.Write(prefix); - o.WriteLine(line); - indent = true; - } - } - - bool WriteOptionPrototype(TextWriter o, Option p, ref int written) - { - string[] names = p.Names; - - int i = GetNextOptionIndex(names, 0); - if (i == names.Length) - return false; - - if (names[i].Length == 1) - { - Write(o, ref written, " -"); - Write(o, ref written, names[0]); - } - else - { - Write(o, ref written, " --"); - Write(o, ref written, names[0]); - } - - for (i = GetNextOptionIndex(names, i + 1); - i < names.Length; i = GetNextOptionIndex(names, i + 1)) - { - Write(o, ref written, ", "); - Write(o, ref written, names[i].Length == 1 ? "-" : "--"); - Write(o, ref written, names[i]); - } - - if (p.OptionValueType == OptionValueType.Optional || - p.OptionValueType == OptionValueType.Required) - { - if (p.OptionValueType == OptionValueType.Optional) - { - Write(o, ref written, localizer("[")); - } - Write(o, ref written, localizer("=" + GetArgumentName(0, p.MaxValueCount, p.Description))); - string sep = p.ValueSeparators != null && p.ValueSeparators.Length > 0 - ? p.ValueSeparators[0] - : " "; - for (int c = 1; c < p.MaxValueCount; ++c) - { - Write(o, ref written, localizer(sep + GetArgumentName(c, p.MaxValueCount, p.Description))); - } - if (p.OptionValueType == OptionValueType.Optional) - { - Write(o, ref written, localizer("]")); - } - } - return true; - } - - static int GetNextOptionIndex(string[] names, int i) - { - while (i < names.Length && names[i] == "<>") - { - ++i; - } - return i; - } - - static void Write(TextWriter o, ref int n, string s) - { - n += s.Length; - o.Write(s); - } - - private static string GetArgumentName(int index, int maxIndex, string description) - { - if (description == null) - return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); - string[] nameStart; - if (maxIndex == 1) - nameStart = new string[] { "{0:", "{" }; - else - nameStart = new string[] { "{" + index + ":" }; - for (int i = 0; i < nameStart.Length; ++i) - { - int start, j = 0; - do - { - start = description.IndexOf(nameStart[i], j); - } while (start >= 0 && j != 0 ? description[j++ - 1] == '{' : false); - if (start == -1) - continue; - int end = description.IndexOf("}", start); - if (end == -1) - continue; - return description.Substring(start + nameStart[i].Length, end - start - nameStart[i].Length); - } - return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1); - } - - private static string GetDescription(string description) - { - if (description == null) - return string.Empty; - StringBuilder sb = new StringBuilder(description.Length); - int start = -1; - for (int i = 0; i < description.Length; ++i) - { - switch (description[i]) - { - case '{': - if (i == start) - { - sb.Append('{'); - start = -1; - } - else if (start < 0) - start = i + 1; - break; - case '}': - if (start < 0) - { - if ((i + 1) == description.Length || description[i + 1] != '}') - throw new InvalidOperationException("Invalid option description: " + description); - ++i; - sb.Append("}"); - } - else - { - sb.Append(description.Substring(start, i - start)); - start = -1; - } - break; - case ':': - if (start < 0) - goto default; - start = i + 1; - break; - default: - if (start < 0) - sb.Append(description[i]); - break; - } - } - return sb.ToString(); - } - - private static IEnumerable GetLines(string description, int firstWidth, int remWidth) - { - return StringCoda.WrappedLines(description, firstWidth, remWidth); - } - } -} - diff --git a/src/MessagePack.CodeGenerator/Program.cs b/src/MessagePack.CodeGenerator/Program.cs deleted file mode 100644 index c53d9b91..00000000 --- a/src/MessagePack.CodeGenerator/Program.cs +++ /dev/null @@ -1,179 +0,0 @@ -using MessagePack.CodeGenerator.Generator; -using Mono.Options; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MessagePack.CodeGenerator -{ - class CommandlineArguments - { - public string InputPath { get; private set; } - public string OutputPath { get; private set; } - public List ConditionalSymbols { get; private set; } - public string ResolverName { get; private set; } - public string NamespaceRoot { get; private set; } - public bool IsUseMap { get; private set; } - - public bool IsParsed { get; set; } - - public CommandlineArguments(string[] args) - { - ConditionalSymbols = new List(); - NamespaceRoot = "MessagePack"; - ResolverName = "GeneratedResolver"; - IsUseMap = false; - - var option = new OptionSet() - { - { "i|input=", "[required]Input path of analyze csproj", x => { InputPath = x; } }, - { "o|output=", "[required]Output file path", x => { OutputPath = x; } }, - { "c|conditionalsymbol=", "[optional, default=empty]conditional compiler symbol", x => { ConditionalSymbols.AddRange(x.Split(',')); } }, - { "r|resolvername=", "[optional, default=GeneratedResolver]Set resolver name", x => { ResolverName = x; } }, - { "n|namespace=", "[optional, default=MessagePack]Set namespace root name", x => { NamespaceRoot = x; } }, - { "m|usemapmode", "[optional, default=false]Force use map mode serialization", x => { IsUseMap = true; } }, - }; - if (args.Length == 0) - { - goto SHOW_HELP; - } - else - { - option.Parse(args); - - if (InputPath == null || OutputPath == null) - { - Console.WriteLine("Invalid Argument:" + string.Join(" ", args)); - Console.WriteLine(); - goto SHOW_HELP; - } - - IsParsed = true; - return; - } - - SHOW_HELP: - Console.WriteLine("mpc arguments help:"); - option.WriteOptionDescriptions(Console.Out); - IsParsed = false; - } - - public string GetNamespaceDot() - { - return string.IsNullOrWhiteSpace(NamespaceRoot) ? "" : NamespaceRoot + "."; - } - } - - - class Program - { - static void Main(string[] args) - { - var cmdArgs = new CommandlineArguments(args); - if (!cmdArgs.IsParsed) - { - return; - } - - // Generator Start... - - var sw = Stopwatch.StartNew(); - Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath); - - var collector = new TypeCollector(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap); - - Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); - Console.WriteLine(); - - sw.Restart(); - Console.WriteLine("Method Collect Start"); - - var (objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect(); - - Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); - - Console.WriteLine("Output Generation Start"); - sw.Restart(); - - var objectFormatterTemplates = objectInfo - .GroupBy(x => x.Namespace) - .Select(x => new FormatterTemplate() - { - Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), - objectSerializationInfos = x.ToArray(), - }) - .ToArray(); - - var enumFormatterTemplates = enumInfo - .GroupBy(x => x.Namespace) - .Select(x => new EnumTemplate() - { - Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), - enumSerializationInfos = x.ToArray() - }) - .ToArray(); - - var unionFormatterTemplates = unionInfo - .GroupBy(x => x.Namespace) - .Select(x => new UnionTemplate() - { - Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), - unionSerializationInfos = x.ToArray() - }) - .ToArray(); - - var resolverTemplate = new ResolverTemplate() - { - Namespace = cmdArgs.GetNamespaceDot() + "Resolvers", - FormatterNamespace = cmdArgs.GetNamespaceDot() + "Formatters", - ResolverName = cmdArgs.ResolverName, - registerInfos = genericInfo.Cast().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray() - }; - - var sb = new StringBuilder(); - sb.AppendLine(resolverTemplate.TransformText()); - sb.AppendLine(); - foreach (var item in enumFormatterTemplates) - { - var text = item.TransformText(); - sb.AppendLine(text); - } - sb.AppendLine(); - foreach (var item in unionFormatterTemplates) - { - var text = item.TransformText(); - sb.AppendLine(text); - } - sb.AppendLine(); - foreach (var item in objectFormatterTemplates) - { - var text = item.TransformText(); - sb.AppendLine(text); - } - - Output(cmdArgs.OutputPath, sb.ToString()); - - Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); - } - - static void Output(string path, string text) - { - path = path.Replace("global::", ""); - - const string prefix = "[Out]"; - Console.WriteLine(prefix + path); - - var fi = new FileInfo(path); - if (!fi.Directory.Exists) - { - fi.Directory.Create(); - } - - System.IO.File.WriteAllText(path, text, Encoding.UTF8); - } - } -} diff --git a/src/MessagePack.CodeGenerator/Utils/EnvironmentHelper.cs b/src/MessagePack.CodeGenerator/Utils/EnvironmentHelper.cs deleted file mode 100644 index 4ed1f638..00000000 --- a/src/MessagePack.CodeGenerator/Utils/EnvironmentHelper.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using Microsoft.Build.MSBuildLocator; - -namespace MessagePack.CodeGenerator -{ - internal static class EnvironmentHelper - { - /// - /// Setup the environment in order MSBuild to work - /// - public static void Setup() - { - if (IsMono) - { - SetupMsBuildPath(() => - { - return GetMonoMsBuildPath(monoDir => - { - Environment.SetEnvironmentVariable("MSBuildExtensionsPath", - Path.Combine(monoDir, "xbuild")); - }); - }); - return; - } - var vsInstallDir = Environment.GetEnvironmentVariable("VSINSTALLDIR"); - if (string.IsNullOrEmpty(vsInstallDir) || !Directory.Exists(vsInstallDir)) - { - var instance = MSBuildLocator.QueryVisualStudioInstances() - .OrderByDescending(o => o.Version) - .FirstOrDefault(); - if (instance != null) - { - MSBuildLocator.RegisterInstance(instance); - } - else - { - throw new InvalidOperationException( - "Visual Studio installation directory was not found. " + - "Install Visual Studio or set the environment variable VSINSTALLDIR"); - } - Environment.SetEnvironmentVariable("VSINSTALLDIR", instance.VisualStudioRootPath); - } - } - - public static bool IsMono => Type.GetType("Mono.Runtime") != null; - - public static bool IsNetCore => - RuntimeInformation.FrameworkDescription.StartsWith(".NET Core"); // .NET Core 4.6.00001.0 - - public static bool IsNetFramework => - RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework"); // .NET Framework 4.7.2115.0 - - // On Mono RuntimeInformation.IsOSPlatform will always retrun true for Windows - public static bool IsWindows => Path.DirectorySeparatorChar == '\\'; - - public static string GetConfigurationFilePath() - { - var name = AppDomain.CurrentDomain.FriendlyName; - // On .NET Core FriendlyName as only the assembly name without the extension - if (IsNetCore) - { - name += ".dll"; - } - name += ".config"; - var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name); - return File.Exists(path) ? path : null; - } - - public static string GetNetCoreMsBuildPath() - { - // Get the sdk path by using the .NET Core runtime assembly location - // Default locations: - // Windows -> C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.0.0\System.Private.CoreLib.dllz - // Linux -> /usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0/System.Private.CoreLib.dll - // OSX -> /usr/local/share/dotnet/shared/Microsoft.NETCore.App/2.0.0/System.Private.CoreLib.dll - // MSBuild.dll is then located: - // Windows -> C:\Program Files\dotnet\sdk\2.0.0\MSBuild.dll - // Linux -> /usr/share/dotnet/sdk/2.0.0/MSBuild.dll - // OSX -> /usr/local/share/dotnet/sdk/2.0.0/MSBuild.dll - - var assembly = typeof(System.Runtime.GCSettings).Assembly; - var assemblyDirectory = Path.GetDirectoryName(assembly.Location); - var directoryInfo = new DirectoryInfo(assemblyDirectory); - var netCoreVersion = directoryInfo.Name; // e.g. 2.0.0 - // Get the dotnet folder - var dotnetFolder = directoryInfo.Parent.Parent.Parent.FullName; - // MSBuild should be located at dotnet/sdk/{version}/MSBuild.dll - var msBuildPath = Path.Combine(dotnetFolder, "sdk", netCoreVersion, "MSBuild.dll"); - return File.Exists(msBuildPath) ? msBuildPath : null; - } - - public static string GetMonoMsBuildPath(Action monoDirectoryAction = null) - { - // Get the sdk path by using the Mono runtime assembly location - // Default locations: - // Windows -> C:\Program Files (x86)\Mono\lib\mono\4.5\mscorlib.dll - // Linux -> /usr/lib/mono/4.5/mscorlib.dll - // OSX -> /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/4.5/mscorlib.dll - // MSBuild.dll is then located: - // Windows -> C:\Program Files (x86)\Mono\lib\mono\msbuild\15.0\bin\MSBuild.dll - // Linux -> /usr/lib/mono/msbuild/15.0/bin/MSBuild.dll - // OSX -> /Library/Frameworks/Mono.framework/Versions/5.2.0/lib/mono/msbuild/15.0/bin/MSBuild.dll - - var assembly = typeof(System.Runtime.GCSettings).Assembly; - var assemblyDirectory = Path.GetDirectoryName(assembly.Location); - var directoryInfo = new DirectoryInfo(assemblyDirectory).Parent; // get mono directory - monoDirectoryAction?.Invoke(directoryInfo.FullName); - var msBuildPath = Path.Combine(directoryInfo.FullName, "msbuild", "15.0", "bin", "MSBuild.dll"); - return File.Exists(msBuildPath) ? msBuildPath : null; - } - - private static void SetupMsBuildPath(Func getMsBuildPathFunc) - { - var msbuildPath = Environment.GetEnvironmentVariable("MSBUILD_EXE_PATH"); - if (!string.IsNullOrEmpty(msbuildPath) && File.Exists(msbuildPath)) - { - return; - } - msbuildPath = getMsBuildPathFunc(); - if (msbuildPath == null) - { - throw new InvalidOperationException( - "Environment variable MSBUILD_EXE_PATH is not set or is set incorrectly. " + - "Please set MSBUILD_EXE_PATH to point at MSBuild.dll."); - } - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildPath); - } - } -} \ No newline at end of file diff --git a/src/MessagePack.CodeGenerator/Utils/RoslynExtensions.cs b/src/MessagePack.CodeGenerator/Utils/RoslynExtensions.cs deleted file mode 100644 index d243d9ae..00000000 --- a/src/MessagePack.CodeGenerator/Utils/RoslynExtensions.cs +++ /dev/null @@ -1,190 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.MSBuild; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; - -namespace MessagePack.CodeGenerator -{ - // Utility and Extension methods for Roslyn - internal static class RoslynExtensions - { - public static async Task GetCompilationFromProject(string csprojPath, params string[] preprocessorSymbols) - { - // fucking workaround of resolve reference... - var externalReferences = new List(); - { - var locations = new List(); - locations.Add(typeof(object).Assembly.Location); // mscorlib - locations.Add(typeof(System.Linq.Enumerable).Assembly.Location); // core - - var xElem = XElement.Load(csprojPath); - var ns = xElem.Name.Namespace; - - var csProjRoot = Path.GetDirectoryName(csprojPath); - var framworkRoot = Path.GetDirectoryName(typeof(object).Assembly.Location); - - foreach (var item in xElem.Descendants(ns + "Reference")) - { - var hintPath = item.Element(ns + "HintPath")?.Value; - if (hintPath == null) - { - var path = Path.Combine(framworkRoot, item.Attribute("Include").Value + ".dll"); - locations.Add(path); - } - else - { - locations.Add(Path.Combine(csProjRoot, hintPath)); - } - } - - foreach (var item in locations.Distinct()) - { - if (File.Exists(item)) - { - externalReferences.Add(MetadataReference.CreateFromFile(item)); - } - } - } - - EnvironmentHelper.Setup(); - - var workspace = MSBuildWorkspace.Create(); - workspace.WorkspaceFailed += Workspace_WorkspaceFailed; - - var project = await workspace.OpenProjectAsync(csprojPath).ConfigureAwait(false); - project = project.AddMetadataReferences(externalReferences); // workaround:) - project = project.WithParseOptions((project.ParseOptions as CSharpParseOptions).WithPreprocessorSymbols(preprocessorSymbols)); - - var compilation = await project.GetCompilationAsync().ConfigureAwait(false); - return compilation; - } - - private static void Workspace_WorkspaceFailed(object sender, WorkspaceDiagnosticEventArgs e) - { - Console.WriteLine(e.Diagnostic.ToString()); - // throw new Exception(e.Diagnostic.ToString()); - } - - public static IEnumerable GetNamedTypeSymbols(this Compilation compilation) - { - foreach (var syntaxTree in compilation.SyntaxTrees) - { - var semModel = compilation.GetSemanticModel(syntaxTree); - - foreach (var item in syntaxTree.GetRoot() - .DescendantNodes() - .Select(x => semModel.GetDeclaredSymbol(x)) - .Where(x => x != null)) - { - var namedType = item as INamedTypeSymbol; - if (namedType != null) - { - yield return namedType; - } - } - } - } - - public static IEnumerable EnumerateBaseType(this ITypeSymbol symbol) - { - var t = symbol.BaseType; - while (t != null) - { - yield return t; - t = t.BaseType; - } - } - - public static AttributeData FindAttribute(this IEnumerable attributeDataList, string typeName) - { - return attributeDataList - .Where(x => x.AttributeClass.ToDisplayString() == typeName) - .FirstOrDefault(); - } - - public static AttributeData FindAttributeShortName(this IEnumerable attributeDataList, string typeName) - { - return attributeDataList - .Where(x => x.AttributeClass.Name == typeName) - .FirstOrDefault(); - } - - public static AttributeData FindAttributeIncludeBasePropertyShortName(this IPropertySymbol property, string typeName) - { - do - { - var data = FindAttributeShortName(property.GetAttributes(), typeName); - if (data != null) return data; - property = property.OverriddenProperty; - } while (property != null); - - return null; - } - - public static AttributeSyntax FindAttribute(this BaseTypeDeclarationSyntax typeDeclaration, SemanticModel model, string typeName) - { - return typeDeclaration.AttributeLists - .SelectMany(x => x.Attributes) - .Where(x => model.GetTypeInfo(x).Type?.ToDisplayString() == typeName) - .FirstOrDefault(); - } - - public static INamedTypeSymbol FindBaseTargetType(this ITypeSymbol symbol, string typeName) - { - return symbol.EnumerateBaseType() - .Where(x => x.OriginalDefinition?.ToDisplayString() == typeName) - .FirstOrDefault(); - } - - public static object GetSingleNamedArgumentValue(this AttributeData attribute, string key) - { - foreach (var item in attribute.NamedArguments) - { - if (item.Key == key) - { - return item.Value.Value; - } - } - - return null; - } - - public static bool IsNullable(this INamedTypeSymbol symbol) - { - if (symbol.IsGenericType) - { - if (symbol.ConstructUnboundGenericType().ToDisplayString() == "T?") - { - return true; - } - } - return false; - } - - public static IEnumerable GetAllMembers(this ITypeSymbol symbol) - { - var t = symbol; - while (t != null) - { - foreach (var item in t.GetMembers()) - { - yield return item; - } - t = t.BaseType; - } - } - - public static IEnumerable GetAllInterfaceMembers(this ITypeSymbol symbol) - { - return symbol.GetMembers() - .Concat(symbol.AllInterfaces.SelectMany(x => x.GetMembers())); - } - } -} diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Shims/Reflection.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Shims/Reflection.cs index bf475d55..e41c6747 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Shims/Reflection.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Shims/Reflection.cs @@ -9,7 +9,7 @@ using System.Text; namespace System.Reflection { -#if !NET_4_6 +#if !NET_4_6 && !NET_STANDARD_2_0 public class TypeInfo { @@ -200,7 +200,7 @@ namespace System.Reflection public static class ReflectionExtensions { -#if !NET_4_6 +#if !NET_4_6 && !NET_STANDARD_2_0 public static TypeInfo GetTypeInfo(this Type type) { @@ -267,6 +267,7 @@ namespace System.Reflection #else + public static bool IsConstructedGenericType(this TypeInfo type) { return type.IsConstructedGenericType; diff --git a/src/MessagePack.UnityClient/MessagePack.UnityClient.sln b/src/MessagePack.UnityClient/MessagePack.UnityClient.sln index 536df589..fcd35ef0 100644 --- a/src/MessagePack.UnityClient/MessagePack.UnityClient.sln +++ b/src/MessagePack.UnityClient/MessagePack.UnityClient.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagePack.UnityClient", "Assembly-CSharp.csproj", "{57B7A568-FAC6-6E41-92BE-735D1F0B6CFA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{57B7A568-FAC6-6E41-92BE-735D1F0B6CFA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/MessagePack.UnityClient/ProjectSettings/PresetManager.asset b/src/MessagePack.UnityClient/ProjectSettings/PresetManager.asset index 32989d0e..e58f57ce 100644 Binary files a/src/MessagePack.UnityClient/ProjectSettings/PresetManager.asset and b/src/MessagePack.UnityClient/ProjectSettings/PresetManager.asset differ diff --git a/src/MessagePack.UnityClient/ProjectSettings/ProjectSettings.asset b/src/MessagePack.UnityClient/ProjectSettings/ProjectSettings.asset index 7411f1c5..b055d76d 100644 Binary files a/src/MessagePack.UnityClient/ProjectSettings/ProjectSettings.asset and b/src/MessagePack.UnityClient/ProjectSettings/ProjectSettings.asset differ diff --git a/src/MessagePack.UnityClient/ProjectSettings/ProjectVersion.txt b/src/MessagePack.UnityClient/ProjectSettings/ProjectVersion.txt index 29eae9e0..46a9098b 100644 --- a/src/MessagePack.UnityClient/ProjectSettings/ProjectVersion.txt +++ b/src/MessagePack.UnityClient/ProjectSettings/ProjectVersion.txt @@ -1 +1 @@ -m_EditorVersion: 2018.1.6f1 +m_EditorVersion: 2018.3.0b7 diff --git a/src/MessagePack.UnityClient/ProjectSettings/UnityConnectSettings.asset b/src/MessagePack.UnityClient/ProjectSettings/UnityConnectSettings.asset index b68818aa..7b5665a0 100644 Binary files a/src/MessagePack.UnityClient/ProjectSettings/UnityConnectSettings.asset and b/src/MessagePack.UnityClient/ProjectSettings/UnityConnectSettings.asset differ diff --git a/src/MessagePack.UnityClient/ProjectSettings/VFXManager.asset b/src/MessagePack.UnityClient/ProjectSettings/VFXManager.asset new file mode 100644 index 00000000..066e7908 Binary files /dev/null and b/src/MessagePack.UnityClient/ProjectSettings/VFXManager.asset differ diff --git a/src/MessagePack.UniversalCodeGenerator/CodeAnalysis/TypeCollector.cs b/src/MessagePack.UniversalCodeGenerator/CodeAnalysis/TypeCollector.cs index e51ebf70..6dd4a42c 100644 --- a/src/MessagePack.UniversalCodeGenerator/CodeAnalysis/TypeCollector.cs +++ b/src/MessagePack.UniversalCodeGenerator/CodeAnalysis/TypeCollector.cs @@ -327,7 +327,7 @@ namespace MessagePack.CodeGenerator var unionAttrs = type.GetAttributes().Where(x => x.AttributeClass == typeReferences.UnionAttribute).Select(x => x.ConstructorArguments).ToArray(); if (unionAttrs.Length == 0) { - throw new MessagePackGeneratorResolveFailedException("Serialization Type must mark UnionAttribute." + " type: " + type.Name); + throw new MessagePackGeneratorResolveFailedException("Serialization Type must mark UnionAttribute." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); } // 0, Int 1, SubType @@ -466,7 +466,7 @@ namespace MessagePack.CodeGenerator var contractAttr = type.GetAttributes().FirstOrDefault(x => x.AttributeClass == typeReferences.MessagePackObjectAttribute); if (contractAttr == null) { - throw new MessagePackGeneratorResolveFailedException("Serialization Object must mark MessagePackObjectAttribute." + " type: " + type.Name); + throw new MessagePackGeneratorResolveFailedException("Serialization Object must mark MessagePackObjectAttribute." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); } var isIntKey = true; @@ -546,11 +546,11 @@ namespace MessagePack.CodeGenerator if (!member.IsReadable && !member.IsWritable) continue; var key = item.GetAttributes().FirstOrDefault(x => x.AttributeClass == typeReferences.KeyAttribute)?.ConstructorArguments[0]; - if (key == null) throw new MessagePackGeneratorResolveFailedException("all public members must mark KeyAttribute or IgnoreMemberAttribute." + " type: " + type.Name + " member:" + item.Name); + if (key == null) throw new MessagePackGeneratorResolveFailedException("all public members must mark KeyAttribute or IgnoreMemberAttribute." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); var intKey = (key.Value.Value is int) ? (int)key.Value.Value : (int?)null; var stringKey = (key.Value.Value is string) ? (string)key.Value.Value : (string)null; - if (intKey == null && stringKey == null) throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.Name + " member:" + item.Name); + if (intKey == null && stringKey == null) throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); if (searchFirst) { @@ -561,21 +561,21 @@ namespace MessagePack.CodeGenerator { if ((isIntKey && intKey == null) || (!isIntKey && stringKey == null)) { - throw new MessagePackGeneratorResolveFailedException("all members key type must be same." + " type: " + type.Name + " member:" + item.Name); + throw new MessagePackGeneratorResolveFailedException("all members key type must be same." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); } } if (isIntKey) { member.IntKey = (int)intKey; - if (intMemebrs.ContainsKey(member.IntKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); + if (intMemebrs.ContainsKey(member.IntKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); intMemebrs.Add(member.IntKey, member); } else { member.StringKey = (string)stringKey; - if (stringMembers.ContainsKey(member.StringKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); + if (stringMembers.ContainsKey(member.StringKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); member.IntKey = hiddenIntKey++; stringMembers.Add(member.StringKey, member); @@ -602,11 +602,11 @@ namespace MessagePack.CodeGenerator if (!member.IsReadable && !member.IsWritable) continue; var key = item.GetAttributes().FirstOrDefault(x => x.AttributeClass == typeReferences.KeyAttribute)?.ConstructorArguments[0]; - if (key == null) throw new MessagePackGeneratorResolveFailedException("all public members must mark KeyAttribute or IgnoreMemberAttribute." + " type: " + type.Name + " member:" + item.Name); + if (key == null) throw new MessagePackGeneratorResolveFailedException("all public members must mark KeyAttribute or IgnoreMemberAttribute." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); var intKey = (key.Value.Value is int) ? (int)key.Value.Value : (int?)null; var stringKey = (key.Value.Value is string) ? (string)key.Value.Value : (string)null; - if (intKey == null && stringKey == null) throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.Name + " member:" + item.Name); + if (intKey == null && stringKey == null) throw new MessagePackGeneratorResolveFailedException("both IntKey and StringKey are null." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); if (searchFirst) { @@ -624,14 +624,14 @@ namespace MessagePack.CodeGenerator if (isIntKey) { member.IntKey = (int)intKey; - if (intMemebrs.ContainsKey(member.IntKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); + if (intMemebrs.ContainsKey(member.IntKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); intMemebrs.Add(member.IntKey, member); } else { member.StringKey = (string)stringKey; - if (stringMembers.ContainsKey(member.StringKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.Name + " member:" + item.Name); + if (stringMembers.ContainsKey(member.StringKey)) throw new MessagePackGeneratorResolveFailedException("key is duplicated, all members key must be unique." + " type: " + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " member:" + item.Name); member.IntKey = hiddenIntKey++; stringMembers.Add(member.StringKey, member); @@ -658,7 +658,7 @@ namespace MessagePack.CodeGenerator } // struct allows null ctor - if (ctor == null && isClass) throw new MessagePackGeneratorResolveFailedException("can't find public constructor. type:" + type.Name); + if (ctor == null && isClass) throw new MessagePackGeneratorResolveFailedException("can't find public constructor. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); var constructorParameters = new List(); if (ctor != null) @@ -688,7 +688,7 @@ namespace MessagePack.CodeGenerator } else { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.Name + " parameterIndex:" + ctorParamIndex + " paramterType:" + item.Type.Name); + throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterIndex:" + ctorParamIndex + " paramterType:" + item.Type.Name); } } } @@ -701,7 +701,7 @@ namespace MessagePack.CodeGenerator } else { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.Name + " parameterIndex:" + ctorParamIndex); + throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterIndex:" + ctorParamIndex); } } } @@ -720,7 +720,7 @@ namespace MessagePack.CodeGenerator } else { - throw new MessagePackGeneratorResolveFailedException("duplicate matched constructor parameter name:" + type.Name + " parameterName:" + item.Name + " paramterType:" + item.Type.Name); + throw new MessagePackGeneratorResolveFailedException("duplicate matched constructor parameter name:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterName:" + item.Name + " paramterType:" + item.Type.Name); } } @@ -738,7 +738,7 @@ namespace MessagePack.CodeGenerator } else { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.Name + " parameterName:" + item.Name + " paramterType:" + item.Type.Name); + throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, parameterType mismatch. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterName:" + item.Name + " paramterType:" + item.Type.Name); } } } @@ -751,7 +751,7 @@ namespace MessagePack.CodeGenerator } else { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.Name + " parameterName:" + item.Name); + throw new MessagePackGeneratorResolveFailedException("can't find matched constructor parameter, index not found. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + " parameterName:" + item.Name); } } } @@ -761,7 +761,7 @@ namespace MessagePack.CodeGenerator if (ctor == null) { - throw new MessagePackGeneratorResolveFailedException("can't find matched constructor. type:" + type.Name); + throw new MessagePackGeneratorResolveFailedException("can't find matched constructor. type:" + type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); } } diff --git a/src/MessagePack.UniversalCodeGenerator/MessagePack.UniversalCodeGenerator.csproj b/src/MessagePack.UniversalCodeGenerator/MessagePack.UniversalCodeGenerator.csproj index 286628a8..6367ff55 100644 --- a/src/MessagePack.UniversalCodeGenerator/MessagePack.UniversalCodeGenerator.csproj +++ b/src/MessagePack.UniversalCodeGenerator/MessagePack.UniversalCodeGenerator.csproj @@ -3,6 +3,8 @@ Exe netcoreapp2.1 + mpc + MessagePack.CodeGenerator MessagePack.UniversalCodeGenerator.ruleset diff --git a/src/MessagePack.UniversalCodeGenerator/Program.cs b/src/MessagePack.UniversalCodeGenerator/Program.cs index c53d9b91..10744797 100644 --- a/src/MessagePack.UniversalCodeGenerator/Program.cs +++ b/src/MessagePack.UniversalCodeGenerator/Program.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Text; -using System.Threading.Tasks; namespace MessagePack.CodeGenerator { @@ -56,7 +55,7 @@ namespace MessagePack.CodeGenerator return; } - SHOW_HELP: + SHOW_HELP: Console.WriteLine("mpc arguments help:"); option.WriteOptionDescriptions(Console.Out); IsParsed = false; @@ -71,93 +70,102 @@ namespace MessagePack.CodeGenerator class Program { - static void Main(string[] args) + static int Main(string[] args) { - var cmdArgs = new CommandlineArguments(args); - if (!cmdArgs.IsParsed) + try { - return; - } - - // Generator Start... - - var sw = Stopwatch.StartNew(); - Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath); - - var collector = new TypeCollector(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap); - - Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); - Console.WriteLine(); - - sw.Restart(); - Console.WriteLine("Method Collect Start"); - - var (objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect(); - - Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); - - Console.WriteLine("Output Generation Start"); - sw.Restart(); - - var objectFormatterTemplates = objectInfo - .GroupBy(x => x.Namespace) - .Select(x => new FormatterTemplate() + var cmdArgs = new CommandlineArguments(args); + if (!cmdArgs.IsParsed) { - Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), - objectSerializationInfos = x.ToArray(), - }) - .ToArray(); + return 0; + } - var enumFormatterTemplates = enumInfo - .GroupBy(x => x.Namespace) - .Select(x => new EnumTemplate() + // Generator Start... + + var sw = Stopwatch.StartNew(); + Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath); + + var collector = new TypeCollector(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap); + + Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); + Console.WriteLine(); + + sw.Restart(); + Console.WriteLine("Method Collect Start"); + + var (objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect(); + + Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); + + Console.WriteLine("Output Generation Start"); + sw.Restart(); + + var objectFormatterTemplates = objectInfo + .GroupBy(x => x.Namespace) + .Select(x => new FormatterTemplate() + { + Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), + objectSerializationInfos = x.ToArray(), + }) + .ToArray(); + + var enumFormatterTemplates = enumInfo + .GroupBy(x => x.Namespace) + .Select(x => new EnumTemplate() + { + Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), + enumSerializationInfos = x.ToArray() + }) + .ToArray(); + + var unionFormatterTemplates = unionInfo + .GroupBy(x => x.Namespace) + .Select(x => new UnionTemplate() + { + Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), + unionSerializationInfos = x.ToArray() + }) + .ToArray(); + + var resolverTemplate = new ResolverTemplate() { - Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), - enumSerializationInfos = x.ToArray() - }) - .ToArray(); + Namespace = cmdArgs.GetNamespaceDot() + "Resolvers", + FormatterNamespace = cmdArgs.GetNamespaceDot() + "Formatters", + ResolverName = cmdArgs.ResolverName, + registerInfos = genericInfo.Cast().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray() + }; - var unionFormatterTemplates = unionInfo - .GroupBy(x => x.Namespace) - .Select(x => new UnionTemplate() + var sb = new StringBuilder(); + sb.AppendLine(resolverTemplate.TransformText()); + sb.AppendLine(); + foreach (var item in enumFormatterTemplates) { - Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), - unionSerializationInfos = x.ToArray() - }) - .ToArray(); + var text = item.TransformText(); + sb.AppendLine(text); + } + sb.AppendLine(); + foreach (var item in unionFormatterTemplates) + { + var text = item.TransformText(); + sb.AppendLine(text); + } + sb.AppendLine(); + foreach (var item in objectFormatterTemplates) + { + var text = item.TransformText(); + sb.AppendLine(text); + } - var resolverTemplate = new ResolverTemplate() - { - Namespace = cmdArgs.GetNamespaceDot() + "Resolvers", - FormatterNamespace = cmdArgs.GetNamespaceDot() + "Formatters", - ResolverName = cmdArgs.ResolverName, - registerInfos = genericInfo.Cast().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray() - }; + Output(cmdArgs.OutputPath, sb.ToString()); - var sb = new StringBuilder(); - sb.AppendLine(resolverTemplate.TransformText()); - sb.AppendLine(); - foreach (var item in enumFormatterTemplates) - { - var text = item.TransformText(); - sb.AppendLine(text); + Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); + return 0; } - sb.AppendLine(); - foreach (var item in unionFormatterTemplates) + catch (Exception ex) { - var text = item.TransformText(); - sb.AppendLine(text); + Console.WriteLine("Unhandled Error:" + ex); + return 1; } - sb.AppendLine(); - foreach (var item in objectFormatterTemplates) - { - var text = item.TransformText(); - sb.AppendLine(text); - } - - Output(cmdArgs.OutputPath, sb.ToString()); - - Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); } static void Output(string path, string text) diff --git a/src/MessagePack.UniversalCodeGenerator/Utils/ProcessUtil.cs b/src/MessagePack.UniversalCodeGenerator/Utils/ProcessUtil.cs new file mode 100644 index 00000000..d3b819cd --- /dev/null +++ b/src/MessagePack.UniversalCodeGenerator/Utils/ProcessUtil.cs @@ -0,0 +1,130 @@ +using System.Diagnostics; +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace MessagePack.CodeGenerator +{ + internal static class ProcessUtil + { + public static async Task ExecuteProcessAsync(string fileName, string args, Stream stdout, Stream stderr, TextReader stdin, CancellationToken ct = default(CancellationToken)) + { + var psi = new ProcessStartInfo(fileName, args); + psi.UseShellExecute = false; + psi.CreateNoWindow = true; + psi.RedirectStandardError = stderr != null; + psi.RedirectStandardOutput = stdout != null; + psi.RedirectStandardInput = stdin != null; + using (var proc = new Process()) + using (var cts = new CancellationTokenSource()) + using (var exitedct = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct)) + { + proc.StartInfo = psi; + proc.EnableRaisingEvents = true; + proc.Exited += (sender, ev) => + { + cts.Cancel(); + }; + if (!proc.Start()) + { + throw new InvalidOperationException($"failed to start process(fileName = {fileName}, args = {args})"); + } + int exitCode = 0; + await Task.WhenAll( + Task.Run(() => + { + exitCode = StdinTask(proc, stdin, exitedct, cts); + if(exitCode < 0) + { + proc.Dispose(); + } + }) + , + Task.Run(async () => + { + if (stdout != null) + { + await RedirectOutputTask(proc.StandardOutput.BaseStream, stdout, exitedct.Token, "stdout"); + } + }) + , + Task.Run(async () => + { + if (stderr != null) + { + await RedirectOutputTask(proc.StandardError.BaseStream, stderr, exitedct.Token, "stderr"); + } + }) + ); + if(exitCode >= 0) + { + return proc.ExitCode; + } + else + { + return -1; + } + } + } + static int StdinTask(Process proc, TextReader stdin, CancellationTokenSource exitedct, CancellationTokenSource cts) + { + if (stdin != null) + { + while (!exitedct.Token.IsCancellationRequested) + { + var l = stdin.ReadLine(); + if (l == null) + { + break; + } + proc.StandardInput.WriteLine(l); + } + proc.StandardInput.Dispose(); + } + exitedct.Token.WaitHandle.WaitOne(); + if (cts.IsCancellationRequested) + { + proc.WaitForExit(); + var exitCode = proc.ExitCode; + return exitCode; + } + else + { + proc.StandardOutput.Dispose(); + proc.StandardError.Dispose(); + proc.Kill(); + return -1; + } + } + + static async Task RedirectOutputTask(Stream procStdout, Stream stdout, CancellationToken ct, string suffix) + { + if (stdout != null) + { + var buf = new byte[1024]; + while (!ct.IsCancellationRequested) + { + try + { + var bytesread = await procStdout.ReadAsync(buf, 0, 1024, ct).ConfigureAwait(false); + if(bytesread <= 0) + { + break; + } + stdout.Write(buf, 0, bytesread); + } + catch(NullReferenceException) + { + break; + } + catch(ObjectDisposedException) + { + break; + } + } + } + } + + } +} \ No newline at end of file diff --git a/src/MessagePack.UniversalCodeGenerator/Utils/RoslynExtensions.cs b/src/MessagePack.UniversalCodeGenerator/Utils/RoslynExtensions.cs index 7dbc826f..da80520c 100644 --- a/src/MessagePack.UniversalCodeGenerator/Utils/RoslynExtensions.cs +++ b/src/MessagePack.UniversalCodeGenerator/Utils/RoslynExtensions.cs @@ -17,6 +17,103 @@ namespace MessagePack.CodeGenerator // Utility and Extension methods for Roslyn internal static class RoslynExtensions { + static (string fname, string args) GetBuildCommandLine(string csprojPath, string tempPath, bool useDotNet) + { + string fname = "dotnet"; + const string tasks = "ResolveAssemblyReferencesDesignTime;ResolveProjectReferencesDesignTime;ResolveComReferencesDesignTime;Compile"; + // from Buildalyzer implementation + // https://github.com/daveaglick/Buildalyzer/blob/b42d2e3ba1b3673a8133fb41e72b507b01bce1d6/src/Buildalyzer/Environment/BuildEnvironment.cs#L86-L96 + Dictionary properties = new Dictionary() + { + {"IntermediateOutputPath", tempPath}, + {"ProviderCommandLineArgs", "true"}, + {"GenerateResourceMSBuildArchitecture", "CurrentArchitecture"}, + {"DesignTimeBuild", "true"}, + {"BuildProjectReferences","false"}, + {"SkipCompilerExecution","true"}, + {"DisableRarCache", "true"}, + {"AutoGenerateBindingRedirects", "false"}, + {"CopyBuildOutputToOutputDirectory", "false"}, + {"CopyOutputSymbolsToOutputDirectory", "false"}, + {"SkipCopyBuildProduct", "true"}, + {"AddModules", "false"}, + {"UseCommonOutputDirectory", "true"}, + {"GeneratePackageOnBuild", "false"}, + {"RunPostBuildEvent", "false"}, + {"SolutionDir", new FileInfo(csprojPath).FullName} + }; + var propargs = string.Join(" ", properties.Select(kv => $"/p:{kv.Key}=\"{kv.Value}\"")); + // how to determine whether command should be executed('dotnet msbuild' or 'msbuild')? + if (useDotNet) + { + fname = "dotnet"; + return (fname, $"msbuild \"{csprojPath}\" /t:{tasks} {propargs} /bl:\"{Path.Combine(tempPath, "build.binlog")}\" /v:n"); + } + else + { + fname = "msbuild"; + return (fname, $"\"{csprojPath}\" /t:{tasks} {propargs} /bl:\"{Path.Combine(tempPath, "build.binlog")}\" /v:n"); + } + } + static async Task TryExecute(string csprojPath, string tempPath, bool useDotNet) + { + // executing build command with output binary log + var (fname, args) = GetBuildCommandLine(csprojPath, tempPath, useDotNet); + try + { + using (var stdout = new MemoryStream()) + using (var stderr = new MemoryStream()) + { + var exitCode = await ProcessUtil.ExecuteProcessAsync(fname, args, stdout, stderr, null).ConfigureAwait(false); + if (exitCode == 0) + { + return true; + } + else + { + // write process output to stdout and stderr when error. + using (var stdout2 = new MemoryStream(stdout.ToArray())) + using (var stderr2 = new MemoryStream(stderr.ToArray())) + using (var consoleStdout = Console.OpenStandardOutput()) + using (var consoleStderr = Console.OpenStandardError()) + { + await stdout2.CopyToAsync(consoleStdout).ConfigureAwait(false); + await stderr2.CopyToAsync(consoleStderr).ConfigureAwait(false); + } + return false; + } + } + } + catch (Exception e) + { + Console.WriteLine($"exception occured(fname={fname}, args={args}):{e}"); + return false; + } + } + static async Task GetAnalyzerResults(AnalyzerManager analyzerManager, string csprojPath, params string[] preprocessorSymbols) + { + var tempPath = Path.Combine(new FileInfo(csprojPath).Directory.FullName, "__buildtemp"); + try + { + if (!await TryExecute(csprojPath, tempPath, true).ConfigureAwait(false)) + { + Console.WriteLine("execute `dotnet msbuild` failed, retry with `msbuild`"); + if (!await TryExecute(csprojPath, tempPath, false).ConfigureAwait(false)) + { + throw new Exception("failed to build project"); + } + } + // get results of analysis from binarylog + return analyzerManager.Analyze(Path.Combine(tempPath, "build.binlog")).ToArray(); + } + finally + { + if (Directory.Exists(tempPath)) + { + Directory.Delete(tempPath, true); + } + } + } public static async Task GetCompilationFromProject(string csprojPath, params string[] preprocessorSymbols) { var analyzerOptions = new AnalyzerManagerOptions(); @@ -26,7 +123,7 @@ namespace MessagePack.CodeGenerator var projectAnalyzer = manager.GetProject(csprojPath); // addproj // projectAnalyzer.AddBuildLogger(new Microsoft.Build.Logging.ConsoleLogger(Microsoft.Build.Framework.LoggerVerbosity.Minimal)); - var workspace = manager.GetWorkspaceWithPreventBuildEvent(); + var workspace = await manager.GetWorkspaceWithPreventBuildEventAsync().ConfigureAwait(false); workspace.WorkspaceFailed += WorkSpaceFailed; var project = workspace.CurrentSolution.Projects.First(); @@ -43,36 +140,20 @@ namespace MessagePack.CodeGenerator Console.WriteLine(e); } - public static AdhocWorkspace GetWorkspaceWithPreventBuildEvent(this AnalyzerManager manager) + // WIP function for getting Roslyn's workspace from csproj + public static async Task GetWorkspaceWithPreventBuildEventAsync(this AnalyzerManager manager) { - // info article: https://qiita.com/skitoy4321/items/9edfb094549f5167a57f var projPath = manager.Projects.First().Value.ProjectFile.Path; - var tempPath = Path.Combine(new FileInfo(projPath).Directory.FullName, "__buildtemp") + System.IO.Path.DirectorySeparatorChar; - - var envopts = new EnvironmentOptions(); - // "Clean" and "Build" is listed in default - // Modify to designtime system https://github.com/dotnet/project-system/blob/master/docs/design-time-builds.md#targets-that-run-during-design-time-builds - // that prevent Pre/PostBuildEvent - - envopts.TargetsToBuild.Clear(); - // Clean should not use(if use pre/post build, dll was deleted). - // envopts.TargetsToBuild.Add("Clean"); - envopts.TargetsToBuild.Add("ResolveAssemblyReferencesDesignTime"); - envopts.TargetsToBuild.Add("ResolveProjectReferencesDesignTime"); - envopts.TargetsToBuild.Add("ResolveComReferencesDesignTime"); - envopts.TargetsToBuild.Add("Compile"); - envopts.GlobalProperties["IntermediateOutputPath"] = tempPath; - try + var ws = new AdhocWorkspace(); + foreach (var result in await GetAnalyzerResults(manager, projPath)) { - return GetWorkspace(manager, envopts); - } - finally - { - if (Directory.Exists(tempPath)) + // getting only successful build + if (result.Succeeded) { - Directory.Delete(tempPath, true); + result.AddToWorkspace(ws); } } + return ws; } public static AdhocWorkspace GetWorkspace(this AnalyzerManager manager, EnvironmentOptions envOptions) diff --git a/src/MessagePack/Internal/AutomataDictionary.cs b/src/MessagePack/Internal/AutomataDictionary.cs index 41436a3f..c3dde0ec 100644 --- a/src/MessagePack/Internal/AutomataDictionary.cs +++ b/src/MessagePack/Internal/AutomataDictionary.cs @@ -172,11 +172,15 @@ namespace MessagePack.Internal // IL Emit +#if !NET_STANDARD_2_0 + public void EmitMatch(ILGenerator il, LocalBuilder p, LocalBuilder rest, LocalBuilder key, Action> onFound, Action onNotFound) { root.EmitSearchNext(il, p, rest, key, onFound, onNotFound); } +#endif + class AutomataNode : IComparable { static readonly AutomataNode[] emptyNodes = new AutomataNode[0]; @@ -334,6 +338,8 @@ namespace MessagePack.Internal } } +#if !NET_STANDARD_2_0 + // SearchNext(ref byte* p, ref int rest, ref ulong key) public void EmitSearchNext(ILGenerator il, LocalBuilder p, LocalBuilder rest, LocalBuilder key, Action> onFound, Action onNotFound) { @@ -453,6 +459,8 @@ namespace MessagePack.Internal EmitSearchNextCore(il, p, rest, key, onFound, onNotFound, r, r.Length); } } + +#endif } } @@ -466,6 +474,8 @@ namespace MessagePack.Internal #if !NETSTANDARD +#if !NET_STANDARD_2_0 + static MethodInfo dynamicGetKeyMethod; static readonly object gate = new object(); static DynamicAssembly dynamicAssembly; @@ -679,7 +689,9 @@ namespace MessagePack.Internal return dynamicGetKeyMethod; } - + +#endif + #endif #if NETSTANDARD || NETFRAMEWORK diff --git a/src/MessagePack/Internal/DynamicAssembly.cs b/src/MessagePack/Internal/DynamicAssembly.cs index 575f47e3..cb309554 100644 --- a/src/MessagePack/Internal/DynamicAssembly.cs +++ b/src/MessagePack/Internal/DynamicAssembly.cs @@ -1,4 +1,5 @@ #if !UNITY_WSA +#if !NET_STANDARD_2_0 using System; using System.Reflection; @@ -74,4 +75,5 @@ namespace MessagePack.Internal } } +#endif #endif \ No newline at end of file diff --git a/src/MessagePack/Internal/ILGeneratorExtensions.cs b/src/MessagePack/Internal/ILGeneratorExtensions.cs index f2e7eb66..2ce4f963 100644 --- a/src/MessagePack/Internal/ILGeneratorExtensions.cs +++ b/src/MessagePack/Internal/ILGeneratorExtensions.cs @@ -1,4 +1,5 @@ #if !UNITY_WSA +#if !NET_STANDARD_2_0 using System; using System.Linq; @@ -390,4 +391,5 @@ namespace MessagePack.Internal } +#endif #endif \ No newline at end of file diff --git a/src/MessagePack/Resolvers/ContractlessReflectionObjectResolver.cs b/src/MessagePack/Resolvers/ContractlessReflectionObjectResolver.cs index 88c531b2..472af7a9 100644 --- a/src/MessagePack/Resolvers/ContractlessReflectionObjectResolver.cs +++ b/src/MessagePack/Resolvers/ContractlessReflectionObjectResolver.cs @@ -8,296 +8,298 @@ using System.Text; namespace MessagePack.Resolvers { - public static class ContractlessReflectionObjectResolver - { - // TODO:CamelCase Option? AllowPrivate? - public static readonly IFormatterResolver Default = new DefaultResolver(); - public static readonly IFormatterResolver Contractless = new ContractlessResolver(); - public static readonly IFormatterResolver ContractlessForceStringKey = new ContractlessForceStringResolver(); + // MEMO: Not completely implemented. - class DefaultResolver : IFormatterResolver - { - const bool ForceStringKey = false; - const bool Contractless = false; - const bool AllowPrivate = false; + //public static class ContractlessReflectionObjectResolver + //{ + // // TODO:CamelCase Option? AllowPrivate? + // public static readonly IFormatterResolver Default = new DefaultResolver(); + // public static readonly IFormatterResolver Contractless = new ContractlessResolver(); + // public static readonly IFormatterResolver ContractlessForceStringKey = new ContractlessForceStringResolver(); - public IMessagePackFormatter GetFormatter() - { - return Cache.formatter; - } + // class DefaultResolver : IFormatterResolver + // { + // const bool ForceStringKey = false; + // const bool Contractless = false; + // const bool AllowPrivate = false; - static class Cache - { - public static readonly IMessagePackFormatter formatter; + // public IMessagePackFormatter GetFormatter() + // { + // return Cache.formatter; + // } - static Cache() - { - var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); - if (metaInfo != null) - { - formatter = new ReflectionObjectFormatter(metaInfo); - } - } - } - } + // static class Cache + // { + // public static readonly IMessagePackFormatter formatter; - class ContractlessResolver : IFormatterResolver - { - const bool ForceStringKey = false; - const bool Contractless = true; - const bool AllowPrivate = false; + // static Cache() + // { + // var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); + // if (metaInfo != null) + // { + // formatter = new ReflectionObjectFormatter(metaInfo); + // } + // } + // } + // } - public IMessagePackFormatter GetFormatter() - { - return Cache.formatter; - } + // class ContractlessResolver : IFormatterResolver + // { + // const bool ForceStringKey = false; + // const bool Contractless = true; + // const bool AllowPrivate = false; - static class Cache - { - public static readonly IMessagePackFormatter formatter; + // public IMessagePackFormatter GetFormatter() + // { + // return Cache.formatter; + // } - static Cache() - { - var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); - if (metaInfo != null) - { - formatter = new ReflectionObjectFormatter(metaInfo); - } - } - } - } + // static class Cache + // { + // public static readonly IMessagePackFormatter formatter; - class ContractlessForceStringResolver : IFormatterResolver - { - const bool ForceStringKey = true; - const bool Contractless = true; - const bool AllowPrivate = false; + // static Cache() + // { + // var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); + // if (metaInfo != null) + // { + // formatter = new ReflectionObjectFormatter(metaInfo); + // } + // } + // } + // } - public IMessagePackFormatter GetFormatter() - { - return Cache.formatter; - } + // class ContractlessForceStringResolver : IFormatterResolver + // { + // const bool ForceStringKey = true; + // const bool Contractless = true; + // const bool AllowPrivate = false; - static class Cache - { - public static readonly IMessagePackFormatter formatter; + // public IMessagePackFormatter GetFormatter() + // { + // return Cache.formatter; + // } - static Cache() - { - var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); - if (metaInfo != null) - { - formatter = new ReflectionObjectFormatter(metaInfo); - } - } - } - } + // static class Cache + // { + // public static readonly IMessagePackFormatter formatter; - } + // static Cache() + // { + // var metaInfo = ObjectSerializationInfo.CreateOrNull(typeof(T), ForceStringKey, Contractless, AllowPrivate); + // if (metaInfo != null) + // { + // formatter = new ReflectionObjectFormatter(metaInfo); + // } + // } + // } + // } + + //} - public class ReflectionObjectFormatter : IMessagePackFormatter - { - readonly ObjectSerializationInfo metaInfo; + //public class ReflectionObjectFormatter : IMessagePackFormatter + //{ + // readonly ObjectSerializationInfo metaInfo; - // for write - readonly byte[][] writeMemberNames; - readonly ObjectSerializationInfo.EmittableMember[] writeMembers; + // // for write + // readonly byte[][] writeMemberNames; + // readonly ObjectSerializationInfo.EmittableMember[] writeMembers; - // for read - readonly int[] constructorParameterIndexes; - readonly AutomataDictionary mapMemberDictionary; - readonly ObjectSerializationInfo.EmittableMember[] readMembers; + // // for read + // readonly int[] constructorParameterIndexes; + // readonly AutomataDictionary mapMemberDictionary; + // readonly ObjectSerializationInfo.EmittableMember[] readMembers; - internal ReflectionObjectFormatter(ObjectSerializationInfo metaInfo) - { - this.metaInfo = metaInfo; + // internal ReflectionObjectFormatter(ObjectSerializationInfo metaInfo) + // { + // this.metaInfo = metaInfo; - // for write - { - var memberNameList = new List(metaInfo.Members.Length); - var emmitableMemberList = new List(metaInfo.Members.Length); - foreach (var item in metaInfo.Members) - { - if (item.IsWritable) - { - emmitableMemberList.Add(item); - memberNameList.Add(Encoding.UTF8.GetBytes(item.Name)); - } - } - this.writeMemberNames = memberNameList.ToArray(); - this.writeMembers = emmitableMemberList.ToArray(); - } - // for read - { - var automata = new AutomataDictionary(); - var emmitableMemberList = new List(metaInfo.Members.Length); - int index = 0; - foreach (var item in metaInfo.Members) - { - if (item.IsReadable) - { - emmitableMemberList.Add(item); - automata.Add(item.Name, index++); - } - } - this.readMembers = emmitableMemberList.ToArray(); - this.mapMemberDictionary = automata; - } - } + // // for write + // { + // var memberNameList = new List(metaInfo.Members.Length); + // var emmitableMemberList = new List(metaInfo.Members.Length); + // foreach (var item in metaInfo.Members) + // { + // if (item.IsWritable) + // { + // emmitableMemberList.Add(item); + // memberNameList.Add(Encoding.UTF8.GetBytes(item.Name)); + // } + // } + // this.writeMemberNames = memberNameList.ToArray(); + // this.writeMembers = emmitableMemberList.ToArray(); + // } + // // for read + // { + // var automata = new AutomataDictionary(); + // var emmitableMemberList = new List(metaInfo.Members.Length); + // int index = 0; + // foreach (var item in metaInfo.Members) + // { + // if (item.IsReadable) + // { + // emmitableMemberList.Add(item); + // automata.Add(item.Name, index++); + // } + // } + // this.readMembers = emmitableMemberList.ToArray(); + // this.mapMemberDictionary = automata; + // } + // } - public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver) - { - // reduce generic method size, avoid write code in type. - if (metaInfo.IsIntKey) - { - return ReflectionObjectFormatterHelper.WriteArraySerialize(metaInfo, writeMembers, ref bytes, offset, value, formatterResolver); - } - else - { - return ReflectionObjectFormatterHelper.WriteMapSerialize(metaInfo, writeMembers, writeMemberNames, ref bytes, offset, value, formatterResolver); - } - } + // public int Serialize(ref byte[] bytes, int offset, T value, IFormatterResolver formatterResolver) + // { + // // reduce generic method size, avoid write code in type. + // if (metaInfo.IsIntKey) + // { + // return ReflectionObjectFormatterHelper.WriteArraySerialize(metaInfo, writeMembers, ref bytes, offset, value, formatterResolver); + // } + // else + // { + // return ReflectionObjectFormatterHelper.WriteMapSerialize(metaInfo, writeMembers, writeMemberNames, ref bytes, offset, value, formatterResolver); + // } + // } - public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) - { - return (T)ReflectionObjectFormatterHelper.Deserialize(metaInfo, readMembers, constructorParameterIndexes, mapMemberDictionary, bytes, offset, formatterResolver, out readSize); - } - } + // public T Deserialize(byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) + // { + // return (T)ReflectionObjectFormatterHelper.Deserialize(metaInfo, readMembers, constructorParameterIndexes, mapMemberDictionary, bytes, offset, formatterResolver, out readSize); + // } + //} - internal static class ReflectionObjectFormatterHelper - { - internal static int WriteArraySerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) - { - var startOffset = offset; + //internal static class ReflectionObjectFormatterHelper + //{ + // internal static int WriteArraySerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) + // { + // var startOffset = offset; - offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, writeMembers.Length); - foreach (var item in metaInfo.Members) - { - if (item == null) - { - offset += MessagePackBinary.WriteNil(ref bytes, offset); - } - else - { - var memberValue = item.ReflectionLoadValue(value); - offset += MessagePackSerializer.NonGeneric.Serialize(item.Type, ref bytes, offset, memberValue, formatterResolver); - } - } + // offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, writeMembers.Length); + // foreach (var item in metaInfo.Members) + // { + // if (item == null) + // { + // offset += MessagePackBinary.WriteNil(ref bytes, offset); + // } + // else + // { + // var memberValue = item.ReflectionLoadValue(value); + // offset += MessagePackSerializer.NonGeneric.Serialize(item.Type, ref bytes, offset, memberValue, formatterResolver); + // } + // } - return offset - startOffset; - } + // return offset - startOffset; + // } - internal static int WriteMapSerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, byte[][] memberNames, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) - { - var startOffset = offset; + // internal static int WriteMapSerialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] writeMembers, byte[][] memberNames, ref byte[] bytes, int offset, object value, IFormatterResolver formatterResolver) + // { + // var startOffset = offset; - offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, writeMembers.Length); + // offset += MessagePackBinary.WriteMapHeader(ref bytes, offset, writeMembers.Length); - for (int i = 0; i < writeMembers.Length; i++) - { - offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, memberNames[i]); - var memberValue = writeMembers[i].ReflectionLoadValue(value); - offset += MessagePackSerializer.NonGeneric.Serialize(writeMembers[i].Type, ref bytes, offset, memberValue, formatterResolver); - } + // for (int i = 0; i < writeMembers.Length; i++) + // { + // offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, memberNames[i]); + // var memberValue = writeMembers[i].ReflectionLoadValue(value); + // offset += MessagePackSerializer.NonGeneric.Serialize(writeMembers[i].Type, ref bytes, offset, memberValue, formatterResolver); + // } - return offset - startOffset; - } + // return offset - startOffset; + // } - internal static object Deserialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] readMembers, int[] constructorParameterIndexes, AutomataDictionary mapMemberDictionary, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) - { - var startOffset = offset; - object[] parameters = null; + // internal static object Deserialize(ObjectSerializationInfo metaInfo, ObjectSerializationInfo.EmittableMember[] readMembers, int[] constructorParameterIndexes, AutomataDictionary mapMemberDictionary, byte[] bytes, int offset, IFormatterResolver formatterResolver, out int readSize) + // { + // var startOffset = offset; + // object[] parameters = null; - var headerType = MessagePackBinary.GetMessagePackType(bytes, offset); - if (headerType == MessagePackType.Nil) - { - readSize = 1; - return null; - } - else if (headerType == MessagePackType.Array) - { - var arraySize = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); - offset += readSize; + // var headerType = MessagePackBinary.GetMessagePackType(bytes, offset); + // if (headerType == MessagePackType.Nil) + // { + // readSize = 1; + // return null; + // } + // else if (headerType == MessagePackType.Array) + // { + // var arraySize = MessagePackBinary.ReadArrayHeader(bytes, offset, out readSize); + // offset += readSize; - // ReadValues - parameters = new object[arraySize]; - for (int i = 0; i < arraySize; i++) - { - var info = readMembers[i]; - if (info != null) - { - parameters[i] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); - offset += readSize; - } - else - { - offset += MessagePackBinary.ReadNextBlock(bytes, offset); - } - } - } - else if (headerType == MessagePackType.Map) - { - var mapSize = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); - offset += readSize; + // // ReadValues + // parameters = new object[arraySize]; + // for (int i = 0; i < arraySize; i++) + // { + // var info = readMembers[i]; + // if (info != null) + // { + // parameters[i] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); + // offset += readSize; + // } + // else + // { + // offset += MessagePackBinary.ReadNextBlock(bytes, offset); + // } + // } + // } + // else if (headerType == MessagePackType.Map) + // { + // var mapSize = MessagePackBinary.ReadMapHeader(bytes, offset, out readSize); + // offset += readSize; - // ReadValues - parameters = new object[mapSize]; - for (int i = 0; i < mapSize; i++) - { - var rawPropName = MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); - offset += readSize; + // // ReadValues + // parameters = new object[mapSize]; + // for (int i = 0; i < mapSize; i++) + // { + // var rawPropName = MessagePackBinary.ReadStringSegment(bytes, offset, out readSize); + // offset += readSize; - int index; - if (mapMemberDictionary.TryGetValue(rawPropName.Array, rawPropName.Offset, rawPropName.Count, out index)) - { - var info = readMembers[index]; - parameters[index] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); - offset += readSize; - } - else - { - offset += MessagePackBinary.ReadNextBlock(bytes, offset); - } - } - } - else - { - throw new InvalidOperationException("Invalid MessagePackType:" + MessagePackCode.ToFormatName(bytes[offset])); - } + // int index; + // if (mapMemberDictionary.TryGetValue(rawPropName.Array, rawPropName.Offset, rawPropName.Count, out index)) + // { + // var info = readMembers[index]; + // parameters[index] = MessagePackSerializer.NonGeneric.Deserialize(info.Type, bytes, offset, formatterResolver, out readSize); + // offset += readSize; + // } + // else + // { + // offset += MessagePackBinary.ReadNextBlock(bytes, offset); + // } + // } + // } + // else + // { + // throw new InvalidOperationException("Invalid MessagePackType:" + MessagePackCode.ToFormatName(bytes[offset])); + // } - // CreateObject - object result = null; - if (constructorParameterIndexes.Length == 0) - { - result = Activator.CreateInstance(metaInfo.Type); - } - else - { - var args = new object[constructorParameterIndexes.Length]; - for (int i = 0; i < constructorParameterIndexes.Length; i++) - { - args[i] = parameters[constructorParameterIndexes[i]]; - } + // // CreateObject + // object result = null; + // if (constructorParameterIndexes.Length == 0) + // { + // result = Activator.CreateInstance(metaInfo.Type); + // } + // else + // { + // var args = new object[constructorParameterIndexes.Length]; + // for (int i = 0; i < constructorParameterIndexes.Length; i++) + // { + // args[i] = parameters[constructorParameterIndexes[i]]; + // } - result = Activator.CreateInstance(metaInfo.Type, args); - } + // result = Activator.CreateInstance(metaInfo.Type, args); + // } - // SetMembers - for (int i = 0; i < readMembers.Length; i++) - { - var info = readMembers[i]; - if (info != null) - { - info.ReflectionStoreValue(result, parameters[i]); - } - } + // // SetMembers + // for (int i = 0; i < readMembers.Length; i++) + // { + // var info = readMembers[i]; + // if (info != null) + // { + // info.ReflectionStoreValue(result, parameters[i]); + // } + // } - readSize = offset - startOffset; - return result; - } - } + // readSize = offset - startOffset; + // return result; + // } + //} } #endif \ No newline at end of file diff --git a/src/MessagePack/Resolvers/DynamicEnumResolver.cs b/src/MessagePack/Resolvers/DynamicEnumResolver.cs index 3d41ef1e..550e349b 100644 --- a/src/MessagePack/Resolvers/DynamicEnumResolver.cs +++ b/src/MessagePack/Resolvers/DynamicEnumResolver.cs @@ -1,4 +1,5 @@ #if !UNITY_WSA +#if !NET_STANDARD_2_0 using System; using MessagePack.Formatters; @@ -119,4 +120,5 @@ namespace MessagePack.Resolvers } } +#endif #endif \ No newline at end of file diff --git a/src/MessagePack/Resolvers/DynamicObjectResolver.cs b/src/MessagePack/Resolvers/DynamicObjectResolver.cs index 94803900..e18cc1c4 100644 --- a/src/MessagePack/Resolvers/DynamicObjectResolver.cs +++ b/src/MessagePack/Resolvers/DynamicObjectResolver.cs @@ -1,4 +1,5 @@ #if !UNITY_WSA +#if !NET_STANDARD_2_0 using System; using System.Linq; @@ -1802,29 +1803,29 @@ typeof(int), typeof(int) }); } } - public object ReflectionLoadValue(object value) - { - if (IsProperty) - { - return PropertyInfo.GetValue(value, null); - } - else - { - return FieldInfo.GetValue(value); - } - } + //public object ReflectionLoadValue(object value) + //{ + // if (IsProperty) + // { + // return PropertyInfo.GetValue(value, null); + // } + // else + // { + // return FieldInfo.GetValue(value); + // } + //} - public void ReflectionStoreValue(object obj, object value) - { - if (IsProperty) - { - PropertyInfo.SetValue(obj, value, null); - } - else - { - FieldInfo.SetValue(obj, value); - } - } + //public void ReflectionStoreValue(object obj, object value) + //{ + // if (IsProperty) + // { + // PropertyInfo.SetValue(obj, value, null); + // } + // else + // { + // FieldInfo.SetValue(obj, value); + // } + //} } } @@ -1838,4 +1839,5 @@ typeof(int), typeof(int) }); } } +#endif #endif \ No newline at end of file diff --git a/src/MessagePack/Resolvers/DynamicUnionResolver.cs b/src/MessagePack/Resolvers/DynamicUnionResolver.cs index 60e4d7a6..46ae3902 100644 --- a/src/MessagePack/Resolvers/DynamicUnionResolver.cs +++ b/src/MessagePack/Resolvers/DynamicUnionResolver.cs @@ -11,6 +11,7 @@ using System.Threading; namespace MessagePack.Resolvers { #if !UNITY_WSA +#if !NET_STANDARD_2_0 /// /// UnionResolver by dynamic code generation. @@ -477,6 +478,7 @@ namespace MessagePack.Resolvers } } +#endif #endif } @@ -512,4 +514,5 @@ namespace MessagePack.Internal } } -} \ No newline at end of file +} + diff --git a/src/MessagePack/Resolvers/StandardResolver.cs b/src/MessagePack/Resolvers/StandardResolver.cs index f2f707d2..dfc8230d 100644 --- a/src/MessagePack/Resolvers/StandardResolver.cs +++ b/src/MessagePack/Resolvers/StandardResolver.cs @@ -182,7 +182,7 @@ namespace MessagePack.Internal MessagePack.Unity.UnityResolver.Instance, #endif -#if !ENABLE_IL2CPP && !UNITY_WSA +#if !ENABLE_IL2CPP && !UNITY_WSA && !NET_STANDARD_2_0 DynamicEnumResolver.Instance, // Try Enum DynamicGenericResolver.Instance, // Try Array, Tuple, Collection @@ -197,7 +197,7 @@ namespace MessagePack.Internal static readonly IFormatterResolver[] resolvers = StandardResolverHelper.DefaultResolvers.Concat(new IFormatterResolver[] { -#if !ENABLE_IL2CPP && !UNITY_WSA +#if !ENABLE_IL2CPP && !UNITY_WSA && !NET_STANDARD_2_0 DynamicObjectResolver.Instance, // Try Object #endif }).ToArray(); @@ -236,7 +236,7 @@ namespace MessagePack.Internal static readonly IFormatterResolver[] resolvers = StandardResolverHelper.DefaultResolvers.Concat(new IFormatterResolver[] { -#if !ENABLE_IL2CPP && !UNITY_WSA +#if !ENABLE_IL2CPP && !UNITY_WSA && !NET_STANDARD_2_0 DynamicObjectResolver.Instance, // Try Object DynamicContractlessObjectResolver.Instance, // Serializes keys as strings #endif @@ -277,7 +277,7 @@ namespace MessagePack.Internal static readonly IFormatterResolver[] resolvers = StandardResolverHelper.DefaultResolvers.Concat(new IFormatterResolver[] { -#if !ENABLE_IL2CPP && !UNITY_WSA +#if !ENABLE_IL2CPP && !UNITY_WSA && !NET_STANDARD_2_0 DynamicObjectResolverAllowPrivate.Instance, // Try Object #endif }).ToArray(); @@ -316,7 +316,7 @@ namespace MessagePack.Internal static readonly IFormatterResolver[] resolvers = StandardResolverHelper.DefaultResolvers.Concat(new IFormatterResolver[] { -#if !ENABLE_IL2CPP && !UNITY_WSA +#if !ENABLE_IL2CPP && !UNITY_WSA && !NET_STANDARD_2_0 DynamicObjectResolverAllowPrivate.Instance, // Try Object DynamicContractlessObjectResolverAllowPrivate.Instance, // Serializes keys as strings #endif diff --git a/tests/MessagePack.AspNetCoreMvcFormatter.Tests/AspNetCoreMvcFormatterTest.cs b/tests/MessagePack.AspNetCoreMvcFormatter.Tests/AspNetCoreMvcFormatterTest.cs new file mode 100644 index 00000000..d666959b --- /dev/null +++ b/tests/MessagePack.AspNetCoreMvcFormatter.Tests/AspNetCoreMvcFormatterTest.cs @@ -0,0 +1,360 @@ +using System; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MessagePack.AspNetCoreMvcFormatter; +using MessagePack.Resolvers; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.Primitives; +using Microsoft.Net.Http.Headers; +using Moq; +using Newtonsoft.Json; +using Xunit; + +namespace MessagePack.Tests.ExtensionTests +{ + public class AspNetCoreMvcFormatterTest + { + private const string MsgPackContentType = "application/x-msgpack"; + + [Fact] + public async Task MessagePackFormatter() + { + var person = new User + { + UserId = 1, + FullName = "John Denver", + Age = 35, + Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + }; + + var messagePackBinary = MessagePackSerializer.Serialize(person); + + // OutputFormatter + var outputFormatterContext = GetOutputFormatterContext(person, typeof(User), MsgPackContentType); + var outputFormatter = new MessagePackOutputFormatter(StandardResolver.Instance); + + outputFormatter.CanWriteResult(outputFormatterContext).IsTrue(); + + await outputFormatter.WriteAsync(outputFormatterContext); + + var body = outputFormatterContext.HttpContext.Response.Body; + + Assert.NotNull(body); + body.Position = 0; + + using (var ms = new MemoryStream()) + { + body.CopyTo(ms); + Assert.Equal(messagePackBinary, ms.ToArray()); + } + + // InputFormatter + var httpContext = new DefaultHttpContext(); + httpContext.Features.Set(new TestResponseFeature()); + httpContext.Request.Body = new NonSeekableReadStream(messagePackBinary); + httpContext.Request.ContentType = MsgPackContentType; + + var inputFormatterContext = CreateInputFormatterContext(typeof(User), httpContext); + + var inputFormatter = new MessagePackInputFormatter(); + + inputFormatter.CanRead(inputFormatterContext).IsTrue(); + + var result = await inputFormatter.ReadAsync(inputFormatterContext); + + Assert.False(result.HasError); + + var userModel = Assert.IsType(result.Model); + userModel.IsStructuralEqual(person); + } + + [Fact] + public void MessagePackFormatterCanNotRead() + { + var person = new User(); + + // OutputFormatter + var outputFormatterContext = GetOutputFormatterContext(person, typeof(User), "application/json"); + var outputFormatter = new MessagePackOutputFormatter(StandardResolver.Instance); + + outputFormatter.CanWriteResult(outputFormatterContext).IsFalse(); + + // InputFormatter + var httpContext = new DefaultHttpContext(); + httpContext.Features.Set(new TestResponseFeature()); + httpContext.Request.Body = new NonSeekableReadStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(person))); + httpContext.Request.ContentType = "application/json"; + + var inputFormatterContext = CreateInputFormatterContext(typeof(User), httpContext); + + var inputFormatter = new MessagePackInputFormatter(); + + inputFormatter.CanRead(inputFormatterContext).IsFalse(); + } + + [Fact] + public async Task LZ4MessagePackFormatter() + { + var person = new User + { + UserId = 1, + FullName = "John Denver", + Age = 35, + Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." + }; + + var messagePackBinary = MessagePackSerializer.Serialize(person); + var lz4MessagePackBinary = LZ4MessagePackSerializer.Serialize(person); + + // OutputFormatter + var outputFormatterContext = GetOutputFormatterContext(person, typeof(User), MsgPackContentType); + var outputFormatter = new LZ4MessagePackOutputFormatter(StandardResolver.Instance); + await outputFormatter.WriteAsync(outputFormatterContext); + var body = outputFormatterContext.HttpContext.Response.Body; + + Assert.NotNull(body); + body.Position = 0; + + using (var ms = new MemoryStream()) + { + body.CopyTo(ms); + var binary = ms.ToArray(); + + binary.IsNot(messagePackBinary); + binary.Is(lz4MessagePackBinary); + } + + // InputFormatter + var httpContext = new DefaultHttpContext(); + httpContext.Features.Set(new TestResponseFeature()); + httpContext.Request.Body = new NonSeekableReadStream(messagePackBinary); + httpContext.Request.ContentType = MsgPackContentType; + + var inputFormatterContext = CreateInputFormatterContext(typeof(User), httpContext); + + var inputFormatter = new LZ4MessagePackInputFormatter(); + + var result = await inputFormatter.ReadAsync(inputFormatterContext); + + Assert.False(result.HasError); + + var userModel = Assert.IsType(result.Model); + userModel.IsStructuralEqual(person); + } + + [Fact] + public void LZ4MessagePackFormatterCanNotRead() + { + var person = new User(); + + // OutputFormatter + var outputFormatterContext = GetOutputFormatterContext(person, typeof(User), "application/json"); + var outputFormatter = new LZ4MessagePackOutputFormatter(StandardResolver.Instance); + + outputFormatter.CanWriteResult(outputFormatterContext).IsFalse(); + + // InputFormatter + var httpContext = new DefaultHttpContext(); + httpContext.Features.Set(new TestResponseFeature()); + httpContext.Request.Body = new NonSeekableReadStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(person))); + httpContext.Request.ContentType = "application/json"; + + var inputFormatterContext = CreateInputFormatterContext(typeof(User), httpContext); + + var inputFormatter = new LZ4MessagePackInputFormatter(); + + inputFormatter.CanRead(inputFormatterContext).IsFalse(); + } + + /// + /// JsonOutputFormatterTests.cs#L453 + /// + private static OutputFormatterWriteContext GetOutputFormatterContext( + object outputValue, + Type outputType, + string contentType = "application/xml; charset=utf-8", + MemoryStream responseStream = null) + { + var mediaTypeHeaderValue = MediaTypeHeaderValue.Parse(contentType); + + var actionContext = GetActionContext(mediaTypeHeaderValue, responseStream); + return new OutputFormatterWriteContext( + actionContext.HttpContext, + new TestHttpResponseStreamWriterFactory().CreateWriter, + outputType, + outputValue) + { + ContentType = new StringSegment(contentType), + }; + } + + /// + /// JsonOutputFormatterTests.cs#L472 + /// + private static ActionContext GetActionContext( + MediaTypeHeaderValue contentType, + MemoryStream responseStream = null) + { + var request = new Mock(); + var headers = new HeaderDictionary(); + request.Setup(r => r.ContentType).Returns(contentType.ToString()); + request.SetupGet(r => r.Headers).Returns(headers); + headers[HeaderNames.AcceptCharset] = contentType.Charset.ToString(); + var response = new Mock(); + response.SetupGet(f => f.Body).Returns(responseStream ?? new MemoryStream()); + var httpContext = new Mock(); + httpContext.SetupGet(c => c.Request).Returns(request.Object); + httpContext.SetupGet(c => c.Response).Returns(response.Object); + return new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); + } + + /// + /// JsonInputFormatterTest.cs#L717 + /// + private InputFormatterContext CreateInputFormatterContext( + Type modelType, + HttpContext httpContext, + string modelName = null, + bool treatEmptyInputAsDefaultValue = false) + { + var provider = new EmptyModelMetadataProvider(); + var metadata = provider.GetMetadataForType(modelType); + + return new InputFormatterContext( + httpContext, + modelName: modelName ?? string.Empty, + modelState: new ModelStateDictionary(), + metadata: metadata, + readerFactory: new TestHttpRequestStreamReaderFactory().CreateReader, + treatEmptyInputAsDefaultValue: treatEmptyInputAsDefaultValue); + } + + /// + /// JsonInputFormatterTest.cs#L791 + /// + private class TestResponseFeature : HttpResponseFeature + { + public override void OnCompleted(Func callback, object state) + { + // do not do anything + } + } + + /// + /// TestHttpResponseStreamWriterFactory.cs + /// + private class TestHttpResponseStreamWriterFactory : IHttpResponseStreamWriterFactory + { + private const int DefaultBufferSize = 16 * 1024; + + public TextWriter CreateWriter(Stream stream, Encoding encoding) + { + return new HttpResponseStreamWriter(stream, encoding, DefaultBufferSize); + } + } + + /// + /// TestHttpRequestStreamReaderFactory.cs + /// + private class TestHttpRequestStreamReaderFactory : IHttpRequestStreamReaderFactory + { + public TextReader CreateReader(Stream stream, Encoding encoding) + { + return new HttpRequestStreamReader(stream, encoding); + } + } + + /// + /// NonSeekableReadableStream.cs + /// + private class NonSeekableReadStream : Stream + { + private Stream _inner; + + public NonSeekableReadStream(byte[] data) + : this(new MemoryStream(data)) + { + } + + public NonSeekableReadStream(Stream inner) + { + _inner = inner; + } + + public override bool CanRead => _inner.CanRead; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length + { + get { throw new NotSupportedException(); } + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override void Flush() + { + throw new NotImplementedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + count = Math.Max(count, 1); + return _inner.Read(buffer, offset, count); + } + + public override Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + count = Math.Max(count, 1); + return _inner.ReadAsync(buffer, offset, count, cancellationToken); + } + } + } + + [MessagePackObject] + public class User + { + [Key(0)] + public int UserId { get; set; } + + [Key(1)] + public string FullName { get; set; } + + [Key(2)] + public int Age { get; set; } + + [Key(3)] + public string Description { get; set; } + } +} diff --git a/tests/MessagePack.AspNetCoreMvcFormatter.Tests/MessagePack.AspNetCoreMvcFormatter.Tests.csproj b/tests/MessagePack.AspNetCoreMvcFormatter.Tests/MessagePack.AspNetCoreMvcFormatter.Tests.csproj new file mode 100644 index 00000000..3f019869 --- /dev/null +++ b/tests/MessagePack.AspNetCoreMvcFormatter.Tests/MessagePack.AspNetCoreMvcFormatter.Tests.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp2.1 + + false + + + + + + + + + + + + + + +