diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2020-01-17 08:20:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-17 08:20:54 +0300 |
commit | 983ea3f0a283171538872533e2d3084b2c11478d (patch) | |
tree | 9723f5acf11b8f1d92f7b079bc68db216686d327 | |
parent | 4b8e2a37eb36146f82df6aecf4a60674fd6cda17 (diff) | |
parent | f3b96a3532e012761175c93ff9778cdb6cf75eac (diff) |
Merge pull request #778 from AArnott/fix253
Deserialize mutable collection interfaces with mutable concrete types
7 files changed, 66 insertions, 7 deletions
diff --git a/sandbox/Sandbox/Generated.cs b/sandbox/Sandbox/Generated.cs index e631833f..17463f16 100644 --- a/sandbox/Sandbox/Generated.cs +++ b/sandbox/Sandbox/Generated.cs @@ -135,7 +135,7 @@ namespace MessagePack.Resolvers case 1: return new global::MessagePack.Formatters.ArrayFormatter<global::GlobalMyEnum>(); case 2: return new global::MessagePack.Formatters.ArrayFormatter<global::QuestMessageBody>(); case 3: return new global::MessagePack.Formatters.InterfaceDictionaryFormatter<string, string>(); - case 4: return new global::MessagePack.Formatters.InterfaceListFormatter<global::SimpleModel>(); + case 4: return new global::MessagePack.Formatters.InterfaceListFormatter2<global::SimpleModel>(); case 5: return new global::MessagePack.Formatters.FourDimensionalArrayFormatter<int>(); case 6: return new global::MessagePack.Formatters.ThreeDimensionalArrayFormatter<int>(); case 7: return new global::MessagePack.Formatters.TwoDimensionalArrayFormatter<int>(); diff --git a/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs b/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs index d4c2db8f..ab43574f 100644 --- a/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs +++ b/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs @@ -192,8 +192,8 @@ namespace MessagePackCompiler.CodeAnalysis { "System.Collections.Generic.Stack<>", "global::MessagePack.Formatters.StackFormatter<TREPLACE>" }, { "System.Collections.Generic.HashSet<>", "global::MessagePack.Formatters.HashSetFormatter<TREPLACE>" }, { "System.Collections.ObjectModel.ReadOnlyCollection<>", "global::MessagePack.Formatters.ReadOnlyCollectionFormatter<TREPLACE>" }, - { "System.Collections.Generic.IList<>", "global::MessagePack.Formatters.InterfaceListFormatter<TREPLACE>" }, - { "System.Collections.Generic.ICollection<>", "global::MessagePack.Formatters.InterfaceCollectionFormatter<TREPLACE>" }, + { "System.Collections.Generic.IList<>", "global::MessagePack.Formatters.InterfaceListFormatter2<TREPLACE>" }, + { "System.Collections.Generic.ICollection<>", "global::MessagePack.Formatters.InterfaceCollectionFormatter2<TREPLACE>" }, { "System.Collections.Generic.IEnumerable<>", "global::MessagePack.Formatters.InterfaceEnumerableFormatter<TREPLACE>" }, { "System.Collections.Generic.Dictionary<,>", "global::MessagePack.Formatters.DictionaryFormatter<TREPLACE>" }, { "System.Collections.Generic.IDictionary<,>", "global::MessagePack.Formatters.InterfaceDictionaryFormatter<TREPLACE>" }, diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/CollectionFormatter.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/CollectionFormatter.cs index d617bf01..6aeaec9f 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/CollectionFormatter.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Formatters/CollectionFormatter.cs @@ -7,6 +7,7 @@ using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; @@ -452,6 +453,7 @@ namespace MessagePack.Formatters } } + [Obsolete("Use " + nameof(InterfaceListFormatter2<int>) + " instead.")] public sealed class InterfaceListFormatter<T> : CollectionFormatterBase<T, T[], IList<T>> { protected override void Add(T[] collection, int index, T value, MessagePackSerializerOptions options) @@ -470,6 +472,7 @@ namespace MessagePack.Formatters } } + [Obsolete("Use " + nameof(InterfaceCollectionFormatter2<int>) + " instead.")] public sealed class InterfaceCollectionFormatter<T> : CollectionFormatterBase<T, T[], ICollection<T>> { protected override void Add(T[] collection, int index, T value, MessagePackSerializerOptions options) @@ -488,6 +491,42 @@ namespace MessagePack.Formatters } } + public sealed class InterfaceListFormatter2<T> : CollectionFormatterBase<T, List<T>, IList<T>> + { + protected override void Add(List<T> collection, int index, T value, MessagePackSerializerOptions options) + { + collection.Add(value); + } + + protected override List<T> Create(int count, MessagePackSerializerOptions options) + { + return new List<T>(count); + } + + protected override IList<T> Complete(List<T> intermediateCollection) + { + return intermediateCollection; + } + } + + public sealed class InterfaceCollectionFormatter2<T> : CollectionFormatterBase<T, List<T>, ICollection<T>> + { + protected override void Add(List<T> collection, int index, T value, MessagePackSerializerOptions options) + { + collection.Add(value); + } + + protected override List<T> Create(int count, MessagePackSerializerOptions options) + { + return new List<T>(count); + } + + protected override ICollection<T> Complete(List<T> intermediateCollection) + { + return intermediateCollection; + } + } + public sealed class InterfaceEnumerableFormatter<T> : CollectionFormatterBase<T, T[], IEnumerable<T>> { protected override void Add(T[] collection, int index, T value, MessagePackSerializerOptions options) diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicGenericResolver.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicGenericResolver.cs index 50574b5a..c108ce59 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicGenericResolver.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Resolvers/DynamicGenericResolver.cs @@ -55,8 +55,8 @@ namespace MessagePack.Internal { typeof(Stack<>), typeof(StackFormatter<>) }, { typeof(HashSet<>), typeof(HashSetFormatter<>) }, { typeof(ReadOnlyCollection<>), typeof(ReadOnlyCollectionFormatter<>) }, - { typeof(IList<>), typeof(InterfaceListFormatter<>) }, - { typeof(ICollection<>), typeof(InterfaceCollectionFormatter<>) }, + { typeof(IList<>), typeof(InterfaceListFormatter2<>) }, + { typeof(ICollection<>), typeof(InterfaceCollectionFormatter2<>) }, { typeof(IEnumerable<>), typeof(InterfaceEnumerableFormatter<>) }, { typeof(Dictionary<,>), typeof(DictionaryFormatter<,>) }, { typeof(IDictionary<,>), typeof(InterfaceDictionaryFormatter<,>) }, diff --git a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/CollectionTest.cs b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/CollectionTest.cs index 85797a96..da6b4a72 100644 --- a/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/CollectionTest.cs +++ b/src/MessagePack.UnityClient/Assets/Scripts/Tests/ShareTests/CollectionTest.cs @@ -76,6 +76,22 @@ namespace MessagePack.Tests } [Fact] + public void InterfaceCollectionsAreDeserializedMutable() + { + var list = this.Convert<IList<int>>(new[] { 1, 2, 3 }); + list.Add(4); + Assert.Equal(new[] { 1, 2, 3, 4 }, list); + + var collection = this.Convert<ICollection<int>>(new[] { 1, 2, 3 }); + collection.Add(4); + Assert.Equal(new[] { 1, 2, 3, 4 }, collection); + + var setCollection = this.Convert<ISet<int>>(new HashSet<int> { 1, 2, 3 }); + setCollection.Add(4); + Assert.Equal(new[] { 1, 2, 3, 4 }, setCollection.OrderBy(n => n).ToArray()); + } + + [Fact] public void StackTest() { var stack = new Stack<int>(new[] { 1, 10, 100 }); diff --git a/src/MessagePack/PublicAPI.Unshipped.txt b/src/MessagePack/PublicAPI.Unshipped.txt index 10d47106..2a1ed97c 100644 --- a/src/MessagePack/PublicAPI.Unshipped.txt +++ b/src/MessagePack/PublicAPI.Unshipped.txt @@ -1,4 +1,8 @@ MessagePack.ExtensionHeader.Equals(MessagePack.ExtensionHeader other) -> bool +MessagePack.Formatters.InterfaceCollectionFormatter2<T> +MessagePack.Formatters.InterfaceCollectionFormatter2<T>.InterfaceCollectionFormatter2() -> void +MessagePack.Formatters.InterfaceListFormatter2<T> +MessagePack.Formatters.InterfaceListFormatter2<T>.InterfaceListFormatter2() -> void MessagePack.MessagePackReader.ReadDateTime(MessagePack.ExtensionHeader header) -> System.DateTime MessagePack.MessagePackReader.TryReadArrayHeader(out int count) -> bool MessagePack.MessagePackReader.TryReadExtensionFormatHeader(out MessagePack.ExtensionHeader extensionHeader) -> bool diff --git a/src/MessagePackAnalyzer/TypeCollector.cs b/src/MessagePackAnalyzer/TypeCollector.cs index c66fe788..ebf9944d 100644 --- a/src/MessagePackAnalyzer/TypeCollector.cs +++ b/src/MessagePackAnalyzer/TypeCollector.cs @@ -50,8 +50,8 @@ namespace MessagePackAnalyzer { "System.Collections.Generic.Stack<>", "global::MessagePack.Formatters.StackFormatter<TREPLACE>" }, { "System.Collections.Generic.HashSet<>", "global::MessagePack.Formatters.HashSetFormatter<TREPLACE>" }, { "System.Collections.ObjectModel.ReadOnlyCollection<>", "global::MessagePack.Formatters.ReadOnlyCollectionFormatter<TREPLACE>" }, - { "System.Collections.Generic.IList<>", "global::MessagePack.Formatters.InterfaceListFormatter<TREPLACE>" }, - { "System.Collections.Generic.ICollection<>", "global::MessagePack.Formatters.InterfaceCollectionFormatter<TREPLACE>" }, + { "System.Collections.Generic.IList<>", "global::MessagePack.Formatters.InterfaceListFormatter2<TREPLACE>" }, + { "System.Collections.Generic.ICollection<>", "global::MessagePack.Formatters.InterfaceCollectionFormatter2<TREPLACE>" }, { "System.Collections.Generic.IEnumerable<>", "global::MessagePack.Formatters.InterfaceEnumerableFormatter<TREPLACE>" }, { "System.Collections.Generic.Dictionary<,>", "global::MessagePack.Formatters.DictionaryFormatter<TREPLACE>" }, { "System.Collections.Generic.IDictionary<,>", "global::MessagePack.Formatters.InterfaceDictionaryFormatter<TREPLACE>" }, |