Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/aspnet/MessagePack-CSharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2021-12-25 04:02:46 +0300
committerGitHub <noreply@github.com>2021-12-25 04:02:46 +0300
commit0dc9c785e74b50e8b3217988239ed3bf5c0b4e6a (patch)
treeae4b3621d50715e637071715eb2777f957099060
parent5e3b1073fb51df8d70998e02792e83d8d956fdf8 (diff)
parent76f3f651e712f113c25f4593d36cd8a9e73c1a2b (diff)
Merge pull request #1365 from neuecc/master
Merge master to develop
-rw-r--r--sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj3
-rw-r--r--sandbox/DynamicCodeDumper/Program.cs1
-rw-r--r--sandbox/Sandbox/Generated.cs249
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/MessagePack/HashCode.cs2
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSecurity.cs4
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/AttributeFormatterResolver.cs13
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicObjectResolver.cs68
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/ResolverUtilities.cs45
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/Class1.cs7
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DataContractTest.cs4
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DynamicObjectFallbackTest.cs2
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/ExpandoObjectTests.cs4
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackFormatterPerFieldTest.cs135
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs8
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/Tests/Tests.asmdef29
-rw-r--r--src/MessagePackAnalyzer/MessagePackAnalyzer.csproj1
16 files changed, 426 insertions, 149 deletions
diff --git a/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj b/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
index 7c86c1eb..633265af 100644
--- a/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
+++ b/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
@@ -132,6 +132,9 @@
<Compile Include="..\..\src\MessagePack.UnityClient\Assets\Scripts\MessagePack\Resolvers\DynamicUnionResolver.cs">
<Link>Code\DynamicUnionResolver.cs</Link>
</Compile>
+ <Compile Include="..\..\src\MessagePack.UnityClient\Assets\Scripts\MessagePack\Resolvers\ResolverUtilities.cs">
+ <Link>Code\ResolverUtilities.cs</Link>
+ </Compile>
<Compile Include="..\..\src\MessagePack.UnityClient\Assets\Scripts\MessagePack\StringEncoding.cs">
<Link>Code\StringEncoding.cs</Link>
</Compile>
diff --git a/sandbox/DynamicCodeDumper/Program.cs b/sandbox/DynamicCodeDumper/Program.cs
index 14f6199e..0d74db48 100644
--- a/sandbox/DynamicCodeDumper/Program.cs
+++ b/sandbox/DynamicCodeDumper/Program.cs
@@ -44,6 +44,7 @@ namespace DynamicCodeDumper
////DynamicObjectResolver.Instance.GetFormatter<StringKeySerializerTarget>();
////DynamicObjectResolver.Instance.GetFormatter<LongestString>();
IMessagePackFormatter<MyClass> f = DynamicObjectResolverAllowPrivate.Instance.GetFormatter<MyClass>();
+ ////IMessagePackFormatter<MessagePackFormatterFieldUser> f = DynamicObjectResolver.Instance.GetFormatter<MessagePackFormatterFieldUser>();
////DynamicObjectResolver.Instance.GetFormatter<StringKeySerializerTargetBinary>();
////DynamicObjectResolver.Instance.GetFormatter<Callback1>();
////DynamicObjectResolver.Instance.GetFormatter<Callback1_2>();
diff --git a/sandbox/Sandbox/Generated.cs b/sandbox/Sandbox/Generated.cs
index 6db29c4c..64f68f84 100644
--- a/sandbox/Sandbox/Generated.cs
+++ b/sandbox/Sandbox/Generated.cs
@@ -49,7 +49,7 @@ namespace MessagePack.Resolvers
static GeneratedResolverGetFormatterHelper()
{
- lookup = new global::System.Collections.Generic.Dictionary<Type, int>(71)
+ lookup = new global::System.Collections.Generic.Dictionary<Type, int>(72)
{
{ typeof(global::GlobalMyEnum[,]), 0 },
{ typeof(global::GlobalMyEnum[]), 1 },
@@ -72,56 +72,57 @@ namespace MessagePack.Resolvers
{ typeof(global::ComplexModel), 18 },
{ typeof(global::GlobalMan), 19 },
{ typeof(global::Message), 20 },
- { typeof(global::PerfBenchmarkDotNet.StringKeySerializerTarget), 21 },
- { typeof(global::QuestMessageBody), 22 },
- { typeof(global::SharedData.ArrayOptimizeClass), 23 },
- { typeof(global::SharedData.BarClass), 24 },
- { typeof(global::SharedData.Callback1), 25 },
- { typeof(global::SharedData.Callback1_2), 26 },
- { typeof(global::SharedData.Callback2), 27 },
- { typeof(global::SharedData.Callback2_2), 28 },
- { typeof(global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor), 29 },
- { typeof(global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor), 30 },
- { typeof(global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor), 31 },
- { typeof(global::SharedData.DefaultValueStringKeyClassWithExplicitConstructor), 32 },
- { typeof(global::SharedData.DefaultValueStringKeyClassWithoutExplicitConstructor), 33 },
- { typeof(global::SharedData.DefaultValueStringKeyStructWithExplicitConstructor), 34 },
- { typeof(global::SharedData.Empty1), 35 },
- { typeof(global::SharedData.Empty2), 36 },
- { typeof(global::SharedData.EmptyClass), 37 },
- { typeof(global::SharedData.EmptyStruct), 38 },
- { typeof(global::SharedData.FirstSimpleData), 39 },
- { typeof(global::SharedData.FooClass), 40 },
- { typeof(global::SharedData.HolderV0), 41 },
- { typeof(global::SharedData.HolderV1), 42 },
- { typeof(global::SharedData.HolderV2), 43 },
- { typeof(global::SharedData.MyClass), 44 },
- { typeof(global::SharedData.MySubUnion1), 45 },
- { typeof(global::SharedData.MySubUnion2), 46 },
- { typeof(global::SharedData.MySubUnion3), 47 },
- { typeof(global::SharedData.MySubUnion4), 48 },
- { typeof(global::SharedData.NestParent.NestContract), 49 },
- { typeof(global::SharedData.NonEmpty1), 50 },
- { typeof(global::SharedData.NonEmpty2), 51 },
- { typeof(global::SharedData.SimpleIntKeyData), 52 },
- { typeof(global::SharedData.SimpleStringKeyData), 53 },
- { typeof(global::SharedData.SimpleStructIntKeyData), 54 },
- { typeof(global::SharedData.SimpleStructStringKeyData), 55 },
- { typeof(global::SharedData.SubUnionType1), 56 },
- { typeof(global::SharedData.SubUnionType2), 57 },
- { typeof(global::SharedData.UnVersionBlockTest), 58 },
- { typeof(global::SharedData.Vector2), 59 },
- { typeof(global::SharedData.Vector3Like), 60 },
- { typeof(global::SharedData.VectorLike2), 61 },
- { typeof(global::SharedData.Version0), 62 },
- { typeof(global::SharedData.Version1), 63 },
- { typeof(global::SharedData.Version2), 64 },
- { typeof(global::SharedData.VersionBlockTest), 65 },
- { typeof(global::SharedData.VersioningUnion), 66 },
- { typeof(global::SharedData.WithIndexer), 67 },
- { typeof(global::SimpleModel), 68 },
- { typeof(global::StampMessageBody), 69 },
- { typeof(global::TextMessageBody), 70 },
+ { typeof(global::MessagePackFormatterFieldUser), 21 },
+ { typeof(global::PerfBenchmarkDotNet.StringKeySerializerTarget), 22 },
+ { typeof(global::QuestMessageBody), 23 },
+ { typeof(global::SharedData.ArrayOptimizeClass), 24 },
+ { typeof(global::SharedData.BarClass), 25 },
+ { typeof(global::SharedData.Callback1), 26 },
+ { typeof(global::SharedData.Callback1_2), 27 },
+ { typeof(global::SharedData.Callback2), 28 },
+ { typeof(global::SharedData.Callback2_2), 29 },
+ { typeof(global::SharedData.DefaultValueIntKeyClassWithExplicitConstructor), 30 },
+ { typeof(global::SharedData.DefaultValueIntKeyClassWithoutExplicitConstructor), 31 },
+ { typeof(global::SharedData.DefaultValueIntKeyStructWithExplicitConstructor), 32 },
+ { typeof(global::SharedData.DefaultValueStringKeyClassWithExplicitConstructor), 33 },
+ { typeof(global::SharedData.DefaultValueStringKeyClassWithoutExplicitConstructor), 34 },
+ { typeof(global::SharedData.DefaultValueStringKeyStructWithExplicitConstructor), 35 },
+ { typeof(global::SharedData.Empty1), 36 },
+ { typeof(global::SharedData.Empty2), 37 },
+ { typeof(global::SharedData.EmptyClass), 38 },
+ { typeof(global::SharedData.EmptyStruct), 39 },
+ { typeof(global::SharedData.FirstSimpleData), 40 },
+ { typeof(global::SharedData.FooClass), 41 },
+ { typeof(global::SharedData.HolderV0), 42 },
+ { typeof(global::SharedData.HolderV1), 43 },
+ { typeof(global::SharedData.HolderV2), 44 },
+ { typeof(global::SharedData.MyClass), 45 },
+ { typeof(global::SharedData.MySubUnion1), 46 },
+ { typeof(global::SharedData.MySubUnion2), 47 },
+ { typeof(global::SharedData.MySubUnion3), 48 },
+ { typeof(global::SharedData.MySubUnion4), 49 },
+ { typeof(global::SharedData.NestParent.NestContract), 50 },
+ { typeof(global::SharedData.NonEmpty1), 51 },
+ { typeof(global::SharedData.NonEmpty2), 52 },
+ { typeof(global::SharedData.SimpleIntKeyData), 53 },
+ { typeof(global::SharedData.SimpleStringKeyData), 54 },
+ { typeof(global::SharedData.SimpleStructIntKeyData), 55 },
+ { typeof(global::SharedData.SimpleStructStringKeyData), 56 },
+ { typeof(global::SharedData.SubUnionType1), 57 },
+ { typeof(global::SharedData.SubUnionType2), 58 },
+ { typeof(global::SharedData.UnVersionBlockTest), 59 },
+ { typeof(global::SharedData.Vector2), 60 },
+ { typeof(global::SharedData.Vector3Like), 61 },
+ { typeof(global::SharedData.VectorLike2), 62 },
+ { typeof(global::SharedData.Version0), 63 },
+ { typeof(global::SharedData.Version1), 64 },
+ { typeof(global::SharedData.Version2), 65 },
+ { typeof(global::SharedData.VersionBlockTest), 66 },
+ { typeof(global::SharedData.VersioningUnion), 67 },
+ { typeof(global::SharedData.WithIndexer), 68 },
+ { typeof(global::SimpleModel), 69 },
+ { typeof(global::StampMessageBody), 70 },
+ { typeof(global::TextMessageBody), 71 },
};
}
@@ -156,56 +157,57 @@ namespace MessagePack.Resolvers
case 18: return new MessagePack.Formatters.ComplexModelFormatter();
case 19: return new MessagePack.Formatters.GlobalManFormatter();
case 20: return new MessagePack.Formatters.MessageFormatter();
- case 21: return new MessagePack.Formatters.PerfBenchmarkDotNet.StringKeySerializerTargetFormatter();
- case 22: return new MessagePack.Formatters.QuestMessageBodyFormatter();
- case 23: return new MessagePack.Formatters.SharedData.ArrayOptimizeClassFormatter();
- case 24: return new MessagePack.Formatters.SharedData.BarClassFormatter();
- case 25: return new MessagePack.Formatters.SharedData.Callback1Formatter();
- case 26: return new MessagePack.Formatters.SharedData.Callback1_2Formatter();
- case 27: return new MessagePack.Formatters.SharedData.Callback2Formatter();
- case 28: return new MessagePack.Formatters.SharedData.Callback2_2Formatter();
- case 29: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithExplicitConstructorFormatter();
- case 30: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithoutExplicitConstructorFormatter();
- case 31: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyStructWithExplicitConstructorFormatter();
- case 32: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithExplicitConstructorFormatter();
- case 33: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithoutExplicitConstructorFormatter();
- case 34: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyStructWithExplicitConstructorFormatter();
- case 35: return new MessagePack.Formatters.SharedData.Empty1Formatter();
- case 36: return new MessagePack.Formatters.SharedData.Empty2Formatter();
- case 37: return new MessagePack.Formatters.SharedData.EmptyClassFormatter();
- case 38: return new MessagePack.Formatters.SharedData.EmptyStructFormatter();
- case 39: return new MessagePack.Formatters.SharedData.FirstSimpleDataFormatter();
- case 40: return new MessagePack.Formatters.SharedData.FooClassFormatter();
- case 41: return new MessagePack.Formatters.SharedData.HolderV0Formatter();
- case 42: return new MessagePack.Formatters.SharedData.HolderV1Formatter();
- case 43: return new MessagePack.Formatters.SharedData.HolderV2Formatter();
- case 44: return new MessagePack.Formatters.SharedData.MyClassFormatter();
- case 45: return new MessagePack.Formatters.SharedData.MySubUnion1Formatter();
- case 46: return new MessagePack.Formatters.SharedData.MySubUnion2Formatter();
- case 47: return new MessagePack.Formatters.SharedData.MySubUnion3Formatter();
- case 48: return new MessagePack.Formatters.SharedData.MySubUnion4Formatter();
- case 49: return new MessagePack.Formatters.SharedData.NestParent_NestContractFormatter();
- case 50: return new MessagePack.Formatters.SharedData.NonEmpty1Formatter();
- case 51: return new MessagePack.Formatters.SharedData.NonEmpty2Formatter();
- case 52: return new MessagePack.Formatters.SharedData.SimpleIntKeyDataFormatter();
- case 53: return new MessagePack.Formatters.SharedData.SimpleStringKeyDataFormatter();
- case 54: return new MessagePack.Formatters.SharedData.SimpleStructIntKeyDataFormatter();
- case 55: return new MessagePack.Formatters.SharedData.SimpleStructStringKeyDataFormatter();
- case 56: return new MessagePack.Formatters.SharedData.SubUnionType1Formatter();
- case 57: return new MessagePack.Formatters.SharedData.SubUnionType2Formatter();
- case 58: return new MessagePack.Formatters.SharedData.UnVersionBlockTestFormatter();
- case 59: return new MessagePack.Formatters.SharedData.Vector2Formatter();
- case 60: return new MessagePack.Formatters.SharedData.Vector3LikeFormatter();
- case 61: return new MessagePack.Formatters.SharedData.VectorLike2Formatter();
- case 62: return new MessagePack.Formatters.SharedData.Version0Formatter();
- case 63: return new MessagePack.Formatters.SharedData.Version1Formatter();
- case 64: return new MessagePack.Formatters.SharedData.Version2Formatter();
- case 65: return new MessagePack.Formatters.SharedData.VersionBlockTestFormatter();
- case 66: return new MessagePack.Formatters.SharedData.VersioningUnionFormatter();
- case 67: return new MessagePack.Formatters.SharedData.WithIndexerFormatter();
- case 68: return new MessagePack.Formatters.SimpleModelFormatter();
- case 69: return new MessagePack.Formatters.StampMessageBodyFormatter();
- case 70: return new MessagePack.Formatters.TextMessageBodyFormatter();
+ case 21: return new MessagePack.Formatters.MessagePackFormatterFieldUserFormatter();
+ case 22: return new MessagePack.Formatters.PerfBenchmarkDotNet.StringKeySerializerTargetFormatter();
+ case 23: return new MessagePack.Formatters.QuestMessageBodyFormatter();
+ case 24: return new MessagePack.Formatters.SharedData.ArrayOptimizeClassFormatter();
+ case 25: return new MessagePack.Formatters.SharedData.BarClassFormatter();
+ case 26: return new MessagePack.Formatters.SharedData.Callback1Formatter();
+ case 27: return new MessagePack.Formatters.SharedData.Callback1_2Formatter();
+ case 28: return new MessagePack.Formatters.SharedData.Callback2Formatter();
+ case 29: return new MessagePack.Formatters.SharedData.Callback2_2Formatter();
+ case 30: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithExplicitConstructorFormatter();
+ case 31: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyClassWithoutExplicitConstructorFormatter();
+ case 32: return new MessagePack.Formatters.SharedData.DefaultValueIntKeyStructWithExplicitConstructorFormatter();
+ case 33: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithExplicitConstructorFormatter();
+ case 34: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyClassWithoutExplicitConstructorFormatter();
+ case 35: return new MessagePack.Formatters.SharedData.DefaultValueStringKeyStructWithExplicitConstructorFormatter();
+ case 36: return new MessagePack.Formatters.SharedData.Empty1Formatter();
+ case 37: return new MessagePack.Formatters.SharedData.Empty2Formatter();
+ case 38: return new MessagePack.Formatters.SharedData.EmptyClassFormatter();
+ case 39: return new MessagePack.Formatters.SharedData.EmptyStructFormatter();
+ case 40: return new MessagePack.Formatters.SharedData.FirstSimpleDataFormatter();
+ case 41: return new MessagePack.Formatters.SharedData.FooClassFormatter();
+ case 42: return new MessagePack.Formatters.SharedData.HolderV0Formatter();
+ case 43: return new MessagePack.Formatters.SharedData.HolderV1Formatter();
+ case 44: return new MessagePack.Formatters.SharedData.HolderV2Formatter();
+ case 45: return new MessagePack.Formatters.SharedData.MyClassFormatter();
+ case 46: return new MessagePack.Formatters.SharedData.MySubUnion1Formatter();
+ case 47: return new MessagePack.Formatters.SharedData.MySubUnion2Formatter();
+ case 48: return new MessagePack.Formatters.SharedData.MySubUnion3Formatter();
+ case 49: return new MessagePack.Formatters.SharedData.MySubUnion4Formatter();
+ case 50: return new MessagePack.Formatters.SharedData.NestParent_NestContractFormatter();
+ case 51: return new MessagePack.Formatters.SharedData.NonEmpty1Formatter();
+ case 52: return new MessagePack.Formatters.SharedData.NonEmpty2Formatter();
+ case 53: return new MessagePack.Formatters.SharedData.SimpleIntKeyDataFormatter();
+ case 54: return new MessagePack.Formatters.SharedData.SimpleStringKeyDataFormatter();
+ case 55: return new MessagePack.Formatters.SharedData.SimpleStructIntKeyDataFormatter();
+ case 56: return new MessagePack.Formatters.SharedData.SimpleStructStringKeyDataFormatter();
+ case 57: return new MessagePack.Formatters.SharedData.SubUnionType1Formatter();
+ case 58: return new MessagePack.Formatters.SharedData.SubUnionType2Formatter();
+ case 59: return new MessagePack.Formatters.SharedData.UnVersionBlockTestFormatter();
+ case 60: return new MessagePack.Formatters.SharedData.Vector2Formatter();
+ case 61: return new MessagePack.Formatters.SharedData.Vector3LikeFormatter();
+ case 62: return new MessagePack.Formatters.SharedData.VectorLike2Formatter();
+ case 63: return new MessagePack.Formatters.SharedData.Version0Formatter();
+ case 64: return new MessagePack.Formatters.SharedData.Version1Formatter();
+ case 65: return new MessagePack.Formatters.SharedData.Version2Formatter();
+ case 66: return new MessagePack.Formatters.SharedData.VersionBlockTestFormatter();
+ case 67: return new MessagePack.Formatters.SharedData.VersioningUnionFormatter();
+ case 68: return new MessagePack.Formatters.SharedData.WithIndexerFormatter();
+ case 69: return new MessagePack.Formatters.SimpleModelFormatter();
+ case 70: return new MessagePack.Formatters.StampMessageBodyFormatter();
+ case 71: return new MessagePack.Formatters.TextMessageBodyFormatter();
default: return null;
}
}
@@ -1173,6 +1175,51 @@ namespace MessagePack.Formatters
}
}
+ public sealed class MessagePackFormatterFieldUserFormatter : global::MessagePack.Formatters.IMessagePackFormatter<global::MessagePackFormatterFieldUser>
+ {
+ private readonly global::MessagePack.Formatters.NativeDateTimeFormatter __TimestampCustomFormatter__ = new global::MessagePack.Formatters.NativeDateTimeFormatter();
+
+ public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::MessagePackFormatterFieldUser value, global::MessagePack.MessagePackSerializerOptions options)
+ {
+ if (value == null)
+ {
+ writer.WriteNil();
+ return;
+ }
+
+ writer.WriteArrayHeader(1);
+ this.__TimestampCustomFormatter__.Serialize(ref writer, value.Timestamp, options);
+ }
+
+ public global::MessagePackFormatterFieldUser Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options)
+ {
+ if (reader.TryReadNil())
+ {
+ return null;
+ }
+
+ options.Security.DepthStep(ref reader);
+ var length = reader.ReadArrayHeader();
+ var ____result = new global::MessagePackFormatterFieldUser();
+
+ for (int i = 0; i < length; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ ____result.Timestamp = this.__TimestampCustomFormatter__.Deserialize(ref reader, options);
+ break;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+
+ reader.Depth--;
+ return ____result;
+ }
+ }
+
public sealed class QuestMessageBodyFormatter : global::MessagePack.Formatters.IMessagePackFormatter<global::QuestMessageBody>
{
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/HashCode.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/HashCode.cs
index 8d48c08f..79a44fcf 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/HashCode.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/HashCode.cs
@@ -42,7 +42,7 @@ https://raw.githubusercontent.com/Cyan4973/xxHash/5c174cfa4e45a42f94082dc0d4539b
*/
-#if !NETCOREAPP
+#if !(NETCOREAPP || UNITY_2021_2_OR_NEWER)
using System.Collections.Generic;
using System.ComponentModel;
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSecurity.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSecurity.cs
index 2136d125..2b743afa 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSecurity.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/MessagePackSecurity.cs
@@ -334,8 +334,8 @@ namespace MessagePack
value = float.NaN;
}
- long l = *(long*)&value;
- return HashCode.Combine((int)(l >> 32), unchecked((int)l));
+ int l = *(int*)&value;
+ return l;
}
}
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/AttributeFormatterResolver.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/AttributeFormatterResolver.cs
index 00e5b075..8dde36ff 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/AttributeFormatterResolver.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/AttributeFormatterResolver.cs
@@ -1,10 +1,10 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-using System;
-using System.Linq; // require UNITY_2018_3_OR_NEWER
+using System.Linq;
using System.Reflection;
using MessagePack.Formatters;
+using MessagePack.Internal;
namespace MessagePack.Resolvers
{
@@ -49,14 +49,7 @@ namespace MessagePack.Resolvers
formatterType = formatterType.MakeGenericType(typeof(T).GetGenericArguments());
}
- if (attr.Arguments == null)
- {
- Formatter = (IMessagePackFormatter<T>)Activator.CreateInstance(formatterType);
- }
- else
- {
- Formatter = (IMessagePackFormatter<T>)Activator.CreateInstance(formatterType, attr.Arguments);
- }
+ Formatter = (IMessagePackFormatter<T>)ResolverUtilities.ActivateFormatter(formatterType, attr.Arguments);
}
}
}
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicObjectResolver.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicObjectResolver.cs
index 62a34d7a..52b92b0e 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicObjectResolver.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicObjectResolver.cs
@@ -14,6 +14,7 @@ using System.Text.RegularExpressions;
using System.Threading;
using MessagePack.Formatters;
using MessagePack.Internal;
+using MessagePack.Resolvers;
#pragma warning disable SA1403 // File may only contain a single namespace
@@ -110,7 +111,7 @@ namespace MessagePack.Resolvers
return;
}
- Formatter = (IMessagePackFormatter<T>)Activator.CreateInstance(formatterTypeInfo.AsType());
+ Formatter = (IMessagePackFormatter<T>)ResolverUtilities.ActivateFormatter(formatterTypeInfo.AsType());
}
}
}
@@ -495,7 +496,7 @@ namespace MessagePack.Internal
MessagePackFormatterAttribute attr = item.GetMessagePackFormatterAttribute();
if (attr != null)
{
- var formatter = Activator.CreateInstance(attr.FormatterType, attr.Arguments);
+ IMessagePackFormatter formatter = ResolverUtilities.ActivateFormatter(attr.FormatterType, attr.Arguments);
serializeCustomFormatters.Add(formatter);
}
else
@@ -510,7 +511,7 @@ namespace MessagePack.Internal
MessagePackFormatterAttribute attr = item.GetMessagePackFormatterAttribute();
if (attr != null)
{
- var formatter = Activator.CreateInstance(attr.FormatterType, attr.Arguments);
+ IMessagePackFormatter formatter = ResolverUtilities.ActivateFormatter(attr.FormatterType, attr.Arguments);
deserializeCustomFormatters.Add(formatter);
}
else
@@ -626,38 +627,55 @@ namespace MessagePack.Internal
MessagePackFormatterAttribute attr = item.GetMessagePackFormatterAttribute();
if (attr != null)
{
- FieldBuilder f = builder.DefineField(item.Name + "_formatter", attr.FormatterType, FieldAttributes.Private | FieldAttributes.InitOnly);
-
- var bindingFlags = (int)(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ // Verify that the specified formatter implements the required interface.
+ // Doing this now provides a more helpful error message than if we let the CLR throw an EntryPointNotFoundException later.
+ if (!attr.FormatterType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMessagePackFormatter<>) && i.GenericTypeArguments[0].IsEquivalentTo(item.Type)))
+ {
+ throw new MessagePackSerializationException($"{info.Type.FullName}.{item.Name} is declared as type {item.Type.FullName}, but the prescribed {attr.FormatterType.FullName} does not implement IMessagePackFormatter<{item.Type.Name}>.");
+ }
- LocalBuilder attrVar = il.DeclareLocal(typeof(MessagePackFormatterAttribute));
+ FieldBuilder f = builder.DefineField(item.Name + "_formatter", attr.FormatterType, FieldAttributes.Private | FieldAttributes.InitOnly);
- il.Emit(OpCodes.Ldtoken, info.Type);
- il.EmitCall(EmitInfo.GetTypeFromHandle);
- il.Emit(OpCodes.Ldstr, item.Name);
- il.EmitLdc_I4(bindingFlags);
- if (item.IsProperty)
+ // If no args were provided and the formatter implements the singleton pattern, fetch the formatter from the field.
+ if ((attr.Arguments == null || attr.Arguments.Length == 0) && ResolverUtilities.FetchSingletonField(attr.FormatterType) is FieldInfo singletonField)
{
- il.EmitCall(EmitInfo.TypeGetProperty);
+ il.EmitLoadThis();
+ il.EmitLdsfld(singletonField);
}
else
{
- il.EmitCall(EmitInfo.TypeGetField);
- }
+ var bindingFlags = (int)(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- il.EmitTrue();
- il.EmitCall(EmitInfo.GetCustomAttributeMessagePackFormatterAttribute);
- il.EmitStloc(attrVar);
+ LocalBuilder attrVar = il.DeclareLocal(typeof(MessagePackFormatterAttribute));
- il.EmitLoadThis();
+ il.Emit(OpCodes.Ldtoken, info.Type);
+ il.EmitCall(EmitInfo.GetTypeFromHandle);
+ il.Emit(OpCodes.Ldstr, item.Name);
+ il.EmitLdc_I4(bindingFlags);
+ if (item.IsProperty)
+ {
+ il.EmitCall(EmitInfo.TypeGetProperty);
+ }
+ else
+ {
+ il.EmitCall(EmitInfo.TypeGetField);
+ }
- il.EmitLdloc(attrVar);
- il.EmitCall(EmitInfo.MessagePackFormatterAttr.FormatterType);
- il.EmitLdloc(attrVar);
- il.EmitCall(EmitInfo.MessagePackFormatterAttr.Arguments);
- il.EmitCall(EmitInfo.ActivatorCreateInstance);
+ il.EmitTrue();
+ il.EmitCall(EmitInfo.GetCustomAttributeMessagePackFormatterAttribute);
+ il.EmitStloc(attrVar);
+
+ il.EmitLoadThis();
+
+ il.EmitLdloc(attrVar);
+ il.EmitCall(EmitInfo.MessagePackFormatterAttr.FormatterType);
+ il.EmitLdloc(attrVar);
+ il.EmitCall(EmitInfo.MessagePackFormatterAttr.Arguments);
+ il.EmitCall(EmitInfo.ActivatorCreateInstance);
+
+ il.Emit(OpCodes.Castclass, attr.FormatterType);
+ }
- il.Emit(OpCodes.Castclass, attr.FormatterType);
il.Emit(OpCodes.Stfld, f);
dict.Add(item, f);
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/ResolverUtilities.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/ResolverUtilities.cs
new file mode 100644
index 00000000..a6622181
--- /dev/null
+++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/ResolverUtilities.cs
@@ -0,0 +1,45 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Reflection;
+using MessagePack.Formatters;
+
+namespace MessagePack.Internal
+{
+ internal static class ResolverUtilities
+ {
+ internal static IMessagePackFormatter ActivateFormatter(Type formatterType, object[] args = null)
+ {
+ if (args == null || args.Length == 0)
+ {
+ if (formatterType.GetConstructor(Type.EmptyTypes) is ConstructorInfo ctor)
+ {
+ return (IMessagePackFormatter)ctor.Invoke(Array.Empty<object>());
+ }
+ else if (FetchSingletonField(formatterType) is FieldInfo instance)
+ {
+ return (IMessagePackFormatter)instance.GetValue(null);
+ }
+ else
+ {
+ throw new MessagePackSerializationException($"The {formatterType.FullName} formatter has no default constructor nor implements the singleton pattern.");
+ }
+ }
+ else
+ {
+ return (IMessagePackFormatter)Activator.CreateInstance(formatterType, args);
+ }
+ }
+
+ internal static FieldInfo FetchSingletonField(Type formatterType)
+ {
+ if (formatterType.GetField("Instance", BindingFlags.Static | BindingFlags.Public) is FieldInfo fieldInfo && fieldInfo.IsInitOnly)
+ {
+ return fieldInfo;
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Class1.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Class1.cs
index 9d95efa3..3325e3c3 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Class1.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Class1.cs
@@ -1149,6 +1149,13 @@ public class SimpleModel
}
}
+[MessagePackObject]
+public class MessagePackFormatterFieldUser
+{
+ [Key(0), MessagePackFormatter(typeof(NativeDateTimeFormatter))]
+ public DateTime Timestamp { get; set; }
+}
+
namespace PerfBenchmarkDotNet
{
[MessagePackObject(true)]
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DataContractTest.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DataContractTest.cs
index c14649e3..d4defb9e 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DataContractTest.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DataContractTest.cs
@@ -191,6 +191,8 @@ namespace MessagePack.Tests
public bool Equals(Detail other) => other != null && this.B1 == other.B1 && this.B2 == other.B2;
}
+#if !UNITY_2018_3_OR_NEWER
+
[Fact]
public void DataContractSerializerCompatibility()
{
@@ -219,6 +221,8 @@ namespace MessagePack.Tests
Assert.Equal(dcsValue, mpValue);
}
+#endif
+
private static T DataContractSerializerRoundTrip<T>(T value)
{
var ms = new MemoryStream();
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DynamicObjectFallbackTest.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DynamicObjectFallbackTest.cs
index 4ac2331d..a16b9f0b 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DynamicObjectFallbackTest.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/DynamicObjectFallbackTest.cs
@@ -1,7 +1,7 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-#if !ENABLE_IL2CPP
+#if !UNITY_2018_3_OR_NEWER
using System;
using System.Collections.Generic;
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/ExpandoObjectTests.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/ExpandoObjectTests.cs
index 45b17ede..99f3b808 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/ExpandoObjectTests.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/ExpandoObjectTests.cs
@@ -1,6 +1,8 @@
// Copyright (c) All contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#if !UNITY_2018_3_OR_NEWER
+
using System.Dynamic;
using System.Runtime.Serialization;
using MessagePack.Resolvers;
@@ -115,3 +117,5 @@ namespace MessagePack.Tests
}
}
}
+
+#endif
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackFormatterPerFieldTest.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackFormatterPerFieldTest.cs
index 6be33a46..b0dca2c3 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackFormatterPerFieldTest.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/MessagePackFormatterPerFieldTest.cs
@@ -5,16 +5,27 @@ using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using MessagePack.Formatters;
using MessagePack.Resolvers;
using Xunit;
+using Xunit.Abstractions;
namespace MessagePack.Tests
{
public class MessagePackFormatterPerFieldTest
{
+ private readonly ITestOutputHelper logger;
+
+ public MessagePackFormatterPerFieldTest(ITestOutputHelper logger)
+ {
+ this.logger = logger;
+ }
+
[MessagePackObject]
public class MyClass
{
@@ -105,5 +116,129 @@ namespace MessagePack.Tests
r2.MyProperty4.Is("bar");
}
}
+
+ [MessagePackObject]
+ public class BlockFormattedIntegers
+ {
+ [Key(0)] [MessagePackFormatter(typeof(ForceByteBlockFormatter))] public byte UInt8Property { get; set; }
+
+ [Key(1)] [MessagePackFormatter(typeof(ForceUInt16BlockFormatter))] public ushort UInt16Property { get; set; }
+
+ [Key(2)] [MessagePackFormatter(typeof(ForceUInt32BlockFormatter))] public uint UInt32Property { get; set; }
+
+ [Key(3)] [MessagePackFormatter(typeof(ForceUInt64BlockFormatter))] public ulong UInt64Property { get; set; }
+
+ [Key(4)] [MessagePackFormatter(typeof(ForceSByteBlockFormatter))] public sbyte Int8Property { get; set; }
+
+ [Key(5)] [MessagePackFormatter(typeof(ForceInt16BlockFormatter))] public short Int16Property { get; set; }
+
+ [Key(6)] [MessagePackFormatter(typeof(ForceInt32BlockFormatter))] public int Int32Property { get; set; }
+
+ [Key(7)] [MessagePackFormatter(typeof(ForceInt64BlockFormatter))] public long Int64Property { get; set; }
+
+ [Key(8)] [MessagePackFormatter(typeof(NullableForceByteBlockFormatter))] public byte? NullableUInt8Property { get; set; }
+
+ [Key(9)] [MessagePackFormatter(typeof(NullableForceUInt16BlockFormatter))] public ushort? NullableUInt16Property { get; set; }
+
+ [Key(10)] [MessagePackFormatter(typeof(NullableForceUInt32BlockFormatter))] public uint? NullableUInt32Property { get; set; }
+
+ [Key(11)] [MessagePackFormatter(typeof(NullableForceUInt64BlockFormatter))] public ulong? NullableUInt64Property { get; set; }
+
+ [Key(12)] [MessagePackFormatter(typeof(NullableForceSByteBlockFormatter))] public sbyte? NullableInt8Property { get; set; }
+
+ [Key(13)] [MessagePackFormatter(typeof(NullableForceInt16BlockFormatter))] public short? NullableInt16Property { get; set; }
+
+ [Key(14)] [MessagePackFormatter(typeof(NullableForceInt32BlockFormatter))] public int? NullableInt32Property { get; set; }
+
+ [Key(15)] [MessagePackFormatter(typeof(NullableForceInt64BlockFormatter))] public long? NullableInt64Property { get; set; }
+ }
+
+ /// <summary>
+ /// Asserts that every formatter offers the public API required for use by
+ /// <see cref="MessagePackFormatterAttribute"/>.
+ /// </summary>
+ [Fact]
+ public void AllFormattersOfferAreAvailableViaAttribute()
+ {
+ var formatters = (from type in typeof(ForceByteBlockFormatter).Assembly.GetTypes()
+ where typeof(IMessagePackFormatter).IsAssignableFrom(type) && !type.IsAbstract
+ let ctor = GetDefaultConstructor(type)
+ where ctor is object // skip formatters that require special initialization.
+ select new { Type = type, DefaultConstructor = ctor }).ToList();
+ this.logger.WriteLine("Found {0} applicable formatters to check.", formatters.Count);
+
+ Assert.All(formatters, formatter => Assert.True(formatter.DefaultConstructor.IsPublic || UsesSingletonPattern(formatter.Type)));
+ }
+
+ [Fact]
+ public void ForceBlockFormatters()
+ {
+ var block = new BlockFormattedIntegers
+ {
+ UInt8Property = 1,
+ UInt16Property = 2,
+ UInt32Property = 3,
+ UInt64Property = 4,
+
+ Int8Property = 1,
+ Int16Property = 2,
+ Int32Property = 3,
+ Int64Property = 4,
+
+ NullableUInt8Property = 1,
+ NullableUInt16Property = 2,
+ NullableUInt32Property = 3,
+ NullableUInt64Property = 4,
+
+ NullableInt8Property = 1,
+ NullableInt16Property = 2,
+ NullableInt32Property = 3,
+ NullableInt64Property = 4,
+ };
+ byte[] packed = MessagePackSerializer.Serialize(block, MessagePackSerializerOptions.Standard);
+ var reader = new MessagePackReader(packed);
+
+ reader.ReadArrayHeader();
+
+ Assert.Equal(MessagePackCode.UInt8, reader.NextCode);
+ Assert.Equal(1, reader.ReadByte());
+ Assert.Equal(MessagePackCode.UInt16, reader.NextCode);
+ Assert.Equal(2, reader.ReadUInt16());
+ Assert.Equal(MessagePackCode.UInt32, reader.NextCode);
+ Assert.Equal(3u, reader.ReadUInt32());
+ Assert.Equal(MessagePackCode.UInt64, reader.NextCode);
+ Assert.Equal(4u, reader.ReadUInt64());
+
+ Assert.Equal(MessagePackCode.Int8, reader.NextCode);
+ Assert.Equal(1, reader.ReadSByte());
+ Assert.Equal(MessagePackCode.Int16, reader.NextCode);
+ Assert.Equal(2, reader.ReadInt16());
+ Assert.Equal(MessagePackCode.Int32, reader.NextCode);
+ Assert.Equal(3, reader.ReadInt32());
+ Assert.Equal(MessagePackCode.Int64, reader.NextCode);
+ Assert.Equal(4, reader.ReadInt64());
+
+ Assert.Equal(MessagePackCode.UInt8, reader.NextCode);
+ Assert.Equal(1, reader.ReadByte());
+ Assert.Equal(MessagePackCode.UInt16, reader.NextCode);
+ Assert.Equal(2, reader.ReadUInt16());
+ Assert.Equal(MessagePackCode.UInt32, reader.NextCode);
+ Assert.Equal(3u, reader.ReadUInt32());
+ Assert.Equal(MessagePackCode.UInt64, reader.NextCode);
+ Assert.Equal(4u, reader.ReadUInt64());
+
+ Assert.Equal(MessagePackCode.Int8, reader.NextCode);
+ Assert.Equal(1, reader.ReadSByte());
+ Assert.Equal(MessagePackCode.Int16, reader.NextCode);
+ Assert.Equal(2, reader.ReadInt16());
+ Assert.Equal(MessagePackCode.Int32, reader.NextCode);
+ Assert.Equal(3, reader.ReadInt32());
+ Assert.Equal(MessagePackCode.Int64, reader.NextCode);
+ Assert.Equal(4, reader.ReadInt64());
+ }
+
+ private static ConstructorInfo GetDefaultConstructor(Type formatterType) => formatterType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(c => c.GetParameters().Length == 0);
+
+ private static bool UsesSingletonPattern(Type formatterType) => formatterType.GetField("Instance", BindingFlags.Static | BindingFlags.Public)?.IsInitOnly is true;
}
}
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs
index ef9a80b4..f1eee269 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Shims/XUnit.cs
@@ -92,6 +92,14 @@ namespace Xunit
Assert.False(enumerable.GetEnumerator().MoveNext());
}
+ public static void All<T>(IEnumerable<T> collection, Action<T> predicate)
+ {
+ foreach (T item in collection)
+ {
+ predicate(item);
+ }
+ }
+
public static T IsType<T>(object o)
{
NUnit.Framework.Assert.AreEqual(typeof(T), o.GetType());
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Tests.asmdef b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Tests.asmdef
index 9fb3f171..b02d5a89 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/Tests.asmdef
+++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/Tests.asmdef
@@ -1,19 +1,30 @@
{
"name": "MessagePack.Tests",
+ "rootNamespace": "",
"references": [
"MessagePack",
"MessagePack.Annotations",
- "RuntimeUnitTestToolkit"
- ],
- "optionalUnityReferences": [
- "TestAssemblies"
+ "RuntimeUnitTestToolkit",
+ "UnityEngine.TestRunner",
+ "UnityEditor.TestRunner"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,
- "overrideReferences": false,
- "precompiledReferences": [],
- "autoReferenced": true,
- "defineConstraints": [],
- "versionDefines": []
+ "overrideReferences": true,
+ "precompiledReferences": [
+ "System.Memory.dll",
+ "System.Buffers.dll",
+ "System.Threading.Tasks.Extensions.dll",
+ "System.Runtime.CompilerServices.Unsafe.dll",
+ "System.Runtime.Extensions.dll",
+ "nunit.framework.dll",
+ "MsgPack.dll"
+ ],
+ "autoReferenced": false,
+ "defineConstraints": [
+ "UNITY_INCLUDE_TESTS"
+ ],
+ "versionDefines": [],
+ "noEngineReferences": false
} \ No newline at end of file
diff --git a/src/MessagePackAnalyzer/MessagePackAnalyzer.csproj b/src/MessagePackAnalyzer/MessagePackAnalyzer.csproj
index 51952963..5a5a18f8 100644
--- a/src/MessagePackAnalyzer/MessagePackAnalyzer.csproj
+++ b/src/MessagePackAnalyzer/MessagePackAnalyzer.csproj
@@ -11,6 +11,7 @@
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);PackBuildOutputs</TargetsForTfmSpecificContentInPackage>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<IncludeSymbols>false</IncludeSymbols>
+ <DevelopmentDependency>true</DevelopmentDependency>
</PropertyGroup>
<ItemGroup>
<Content Include="tools\*.ps1" Pack="true" PackagePath="tools\" />