diff --git a/src/Build.UnitTests/Collections/OMcollections_tests.cs b/src/Build.UnitTests/Collections/OMcollections_tests.cs index 0421b05453d..a2c9c2ac165 100644 --- a/src/Build.UnitTests/Collections/OMcollections_tests.cs +++ b/src/Build.UnitTests/Collections/OMcollections_tests.cs @@ -16,6 +16,7 @@ using Shouldly; using ObjectModel = System.Collections.ObjectModel; using Xunit; +using Microsoft.Build.BackEnd; namespace Microsoft.Build.UnitTests.OM.Collections { diff --git a/src/Build.UnitTests/Construction/ElementLocation_Tests.cs b/src/Build.UnitTests/Construction/ElementLocation_Tests.cs index 43d62d5c4dd..dd48d7391e5 100644 --- a/src/Build.UnitTests/Construction/ElementLocation_Tests.cs +++ b/src/Build.UnitTests/Construction/ElementLocation_Tests.cs @@ -18,6 +18,7 @@ using System.Reflection; using Xunit; using System.Text; +using Microsoft.Build.BackEnd; namespace Microsoft.Build.UnitTests.Construction { diff --git a/src/Build.UnitTests/Instance/ProjectMetadataInstance_Internal_Tests.cs b/src/Build.UnitTests/Instance/ProjectMetadataInstance_Internal_Tests.cs index 88a009211a3..1611340705b 100644 --- a/src/Build.UnitTests/Instance/ProjectMetadataInstance_Internal_Tests.cs +++ b/src/Build.UnitTests/Instance/ProjectMetadataInstance_Internal_Tests.cs @@ -8,6 +8,7 @@ using Microsoft.Build.Construction; using Microsoft.Build.UnitTests.BackEnd; using Xunit; +using Microsoft.Build.BackEnd; namespace Microsoft.Build.UnitTests.OM.Instance { diff --git a/src/Build.UnitTests/Instance/ProjectPropertyInstance_Internal_Tests.cs b/src/Build.UnitTests/Instance/ProjectPropertyInstance_Internal_Tests.cs index ab9d4e89982..1f8544a3eb4 100644 --- a/src/Build.UnitTests/Instance/ProjectPropertyInstance_Internal_Tests.cs +++ b/src/Build.UnitTests/Instance/ProjectPropertyInstance_Internal_Tests.cs @@ -9,6 +9,7 @@ using Microsoft.Build.Construction; using Microsoft.Build.UnitTests.BackEnd; using Xunit; +using Microsoft.Build.BackEnd; namespace Microsoft.Build.UnitTests.OM.Instance { diff --git a/src/Build.UnitTests/Instance/TaskItem_Tests.cs b/src/Build.UnitTests/Instance/TaskItem_Tests.cs index 24110272103..e387e719ad6 100644 --- a/src/Build.UnitTests/Instance/TaskItem_Tests.cs +++ b/src/Build.UnitTests/Instance/TaskItem_Tests.cs @@ -13,6 +13,7 @@ using Microsoft.Build.Framework; using System.IO; using Xunit; +using Microsoft.Build.BackEnd; namespace Microsoft.Build.UnitTests.OM.Instance { diff --git a/src/Build/BackEnd/BuildManager/RequestedProjectState.cs b/src/Build/BackEnd/BuildManager/RequestedProjectState.cs index e0e300403cf..1df6a64b42b 100644 --- a/src/Build/BackEnd/BuildManager/RequestedProjectState.cs +++ b/src/Build/BackEnd/BuildManager/RequestedProjectState.cs @@ -44,12 +44,12 @@ private static IDictionary> CreateItemMetadataDictionary(in return new Dictionary>(capacity, StringComparer.OrdinalIgnoreCase); } - private static void TranslateMetadataForItem(ref List list, ITranslator translator) + private static void TranslateMetadataForItem(ITranslator translator, ref List list) { translator.Translate(ref list); } - private static void TranslateString(ref string s, ITranslator translator) + private static void TranslateString(ITranslator translator, ref string s) { translator.Translate(ref s); } diff --git a/src/Build/BackEnd/Components/Caching/ConfigCache.cs b/src/Build/BackEnd/Components/Caching/ConfigCache.cs index b6989894a6b..2645a3feba6 100644 --- a/src/Build/BackEnd/Components/Caching/ConfigCache.cs +++ b/src/Build/BackEnd/Components/Caching/ConfigCache.cs @@ -348,8 +348,8 @@ public void Translate(ITranslator translator) { translator.TranslateDictionary( ref _configurations, - (ref int configId, ITranslator aTranslator) => aTranslator.Translate(ref configId), - (ref BuildRequestConfiguration configuration, ITranslator aTranslator) => + (ITranslator aTranslator, ref int configId) => aTranslator.Translate(ref configId), + (ITranslator aTranslator, ref BuildRequestConfiguration configuration) => { if (translator.Mode == TranslationDirection.WriteToStream) { @@ -365,8 +365,8 @@ public void Translate(ITranslator translator) translator.TranslateDictionary( ref _configurationIdsByMetadata, - (ref ConfigurationMetadata configMetadata, ITranslator aTranslator) => aTranslator.Translate(ref configMetadata, ConfigurationMetadata.FactoryForDeserialization), - (ref int configId, ITranslator aTranslator) => aTranslator.Translate(ref configId), + (ITranslator aTranslator, ref ConfigurationMetadata configMetadata) => aTranslator.Translate(ref configMetadata, ConfigurationMetadata.FactoryForDeserialization), + (ITranslator aTranslator, ref int configId) => aTranslator.Translate(ref configId), capacity => new Dictionary(capacity)); } diff --git a/src/Build/BackEnd/Components/Caching/ResultsCache.cs b/src/Build/BackEnd/Components/Caching/ResultsCache.cs index 36e1a24824e..64db389a8ed 100644 --- a/src/Build/BackEnd/Components/Caching/ResultsCache.cs +++ b/src/Build/BackEnd/Components/Caching/ResultsCache.cs @@ -243,8 +243,8 @@ public void Translate(ITranslator translator) translator.TranslateDictionary( ref localReference, - (ref int i, ITranslator aTranslator) => aTranslator.Translate(ref i), - (ref BuildResult result, ITranslator aTranslator) => aTranslator.Translate(ref result), + (ITranslator aTranslator, ref int i) => aTranslator.Translate(ref i), + (ITranslator aTranslator, ref BuildResult result) => aTranslator.Translate(ref result), capacity => new ConcurrentDictionary(Environment.ProcessorCount, capacity)); if (translator.Mode == TranslationDirection.ReadFromStream) diff --git a/src/Build/Instance/ProjectInstance.cs b/src/Build/Instance/ProjectInstance.cs index ac9d3200de3..992fac85f17 100644 --- a/src/Build/Instance/ProjectInstance.cs +++ b/src/Build/Instance/ProjectInstance.cs @@ -2045,13 +2045,13 @@ private void TranslateTargets(ITranslator translator) } // todo move to nested function after c#7 - private static void TranslatorForTargetSpecificDictionaryKey(ref string key, ITranslator translator) + private static void TranslatorForTargetSpecificDictionaryKey(ITranslator translator, ref string key) { translator.Translate(ref key); } // todo move to nested function after c#7 - private static void TranslatorForTargetSpecificDictionaryValue(ref List value, ITranslator translator) + private static void TranslatorForTargetSpecificDictionaryValue(ITranslator translator, ref List value) { translator.Translate(ref value, TargetSpecification.FactoryForDeserialization); } diff --git a/src/Build/Instance/ProjectTaskInstance.cs b/src/Build/Instance/ProjectTaskInstance.cs index 3c5a256de29..98b42dc76ce 100644 --- a/src/Build/Instance/ProjectTaskInstance.cs +++ b/src/Build/Instance/ProjectTaskInstance.cs @@ -390,12 +390,12 @@ void ITranslatable.Translate(ITranslator translator) } } - private static void ParametersKeyTranslator(ref string key, ITranslator translator) + private static void ParametersKeyTranslator(ITranslator translator, ref string key) { translator.Translate(ref key); } - private static void ParametersValueTranslator(ref (string, ElementLocation) value, ITranslator translator) + private static void ParametersValueTranslator(ITranslator translator, ref (string, ElementLocation) value) { if (translator.Mode == TranslationDirection.WriteToStream) { diff --git a/src/Build/Instance/TaskRegistry.cs b/src/Build/Instance/TaskRegistry.cs index 7a83bd9f59b..3d261b4cf46 100644 --- a/src/Build/Instance/TaskRegistry.cs +++ b/src/Build/Instance/TaskRegistry.cs @@ -1707,13 +1707,13 @@ public void Translate(ITranslator translator) } // todo move to nested function after C# 7 - private static void TranslatorForTaskParametersKey(ref string key, ITranslator translator) + private static void TranslatorForTaskParametersKey(ITranslator translator, ref string key) { translator.Translate(ref key); } // todo move to nested function after C# 7 - private static void TranslatorForTaskParameterValue(ref TaskPropertyInfo taskPropertyInfo, ITranslator translator) + private static void TranslatorForTaskParameterValue(ITranslator translator, ref TaskPropertyInfo taskPropertyInfo) { string name = null; string propertyTypeName = null; @@ -1783,13 +1783,13 @@ public void Translate(ITranslator translator) } //todo make nested after C# 7 - void TranslateTaskRegistrationKey(ref RegisteredTaskIdentity taskIdentity, ITranslator translator) + void TranslateTaskRegistrationKey(ITranslator translator, ref RegisteredTaskIdentity taskIdentity) { translator.Translate(ref taskIdentity); } //todo make nested after C# 7 - void TranslateTaskRegistrationValue(ref List taskRecords, ITranslator translator) + void TranslateTaskRegistrationValue(ITranslator translator, ref List taskRecords) { translator.Translate(ref taskRecords, RegisteredTaskRecord.FactoryForDeserialization); } diff --git a/src/Build/Microsoft.Build.csproj b/src/Build/Microsoft.Build.csproj index c70ad9fc654..e848e45cf85 100644 --- a/src/Build/Microsoft.Build.csproj +++ b/src/Build/Microsoft.Build.csproj @@ -137,6 +137,7 @@ + diff --git a/src/MSBuild/MSBuild.csproj b/src/MSBuild/MSBuild.csproj index 75f5ca314aa..2be04303ffd 100644 --- a/src/MSBuild/MSBuild.csproj +++ b/src/MSBuild/MSBuild.csproj @@ -126,6 +126,7 @@ + diff --git a/src/MSBuildTaskHost/MSBuildTaskHost.csproj b/src/MSBuildTaskHost/MSBuildTaskHost.csproj index 2e10ebdd3fd..ade9f4d4b91 100644 --- a/src/MSBuildTaskHost/MSBuildTaskHost.csproj +++ b/src/MSBuildTaskHost/MSBuildTaskHost.csproj @@ -92,6 +92,7 @@ ITranslator.cs + InternalErrorException.cs diff --git a/src/Shared/BinaryTranslator.cs b/src/Shared/BinaryTranslator.cs index 3dce827846d..8456b3a6c21 100644 --- a/src/Shared/BinaryTranslator.cs +++ b/src/Shared/BinaryTranslator.cs @@ -264,14 +264,14 @@ public void Translate(ref List list) /// The list to be translated. /// Factory to deserialize T /// TaskItem type - public void Translate(ref List list, NodePacketValueFactory factory) where T : ITranslatable + public void Translate(ref List list, ObjectTranslator objectTranslator) { IList listAsInterface = list; - Translate(ref listAsInterface, factory, count => new List(count)); + Translate(ref listAsInterface, objectTranslator, count => new List(count)); list = (List) listAsInterface; } - public void Translate(ref IList list, NodePacketValueFactory factory, NodePacketCollectionCreator collectionFactory) where T : ITranslatable where L : IList + public void Translate(ref IList list, ObjectTranslator objectTranslator, NodePacketCollectionCreator collectionFactory) where L : IList { if (!TranslateNullable(list)) { @@ -285,12 +285,7 @@ public void Translate(ref IList list, NodePacketValueFactory factory { T value = default(T); - if (!TranslateNullable(value)) - { - continue; - } - - value = factory(this); + objectTranslator(this, ref value); list.Add(value); } } @@ -444,24 +439,6 @@ public void Translate(ref T value) value.Translate(this); } - /// - /// Translates an object implementing INodePacketTranslatable which does not expose a - /// public parameterless constructor. - /// - /// The reference type. - /// The value to be translated. - /// The factory method used to instantiate values of type T. - public void Translate(ref T value, NodePacketValueFactory factory) - where T : ITranslatable - { - if (!TranslateNullable(value)) - { - return; - } - - value = factory(this); - } - /// /// Translates an array of objects implementing INodePacketTranslatable. /// @@ -491,8 +468,7 @@ public void TranslateArray(ref T[] array) /// The reference type. /// The array to be translated. /// The factory method used to instantiate values of type T. - public void TranslateArray(ref T[] array, NodePacketValueFactory factory) - where T : ITranslatable + public void TranslateArray(ref T[] array, ObjectTranslator objectTranslator) { if (!TranslateNullable(array)) { @@ -504,7 +480,7 @@ public void TranslateArray(ref T[] array, NodePacketValueFactory factory) for (int i = 0; i < count; i++) { - array[i] = factory(this); + objectTranslator(this, ref array[i]); } } @@ -546,8 +522,8 @@ public void TranslateDictionary(ref IDictionary dictionary, Node public void TranslateDictionary( ref IDictionary dictionary, - Translator keyTranslator, - Translator valueTranslator, + ObjectTranslator keyTranslator, + ObjectTranslator valueTranslator, NodePacketCollectionCreator> dictionaryCreator) { if (!TranslateNullable(dictionary)) @@ -561,9 +537,9 @@ public void TranslateDictionary( for (int i = 0; i < count; i++) { K key = default(K); - keyTranslator.Invoke(ref key, this); + keyTranslator(this, ref key); V value = default(V); - valueTranslator(ref value, this); + valueTranslator(this, ref value); dictionary[key] = value; } } @@ -575,8 +551,8 @@ public void TranslateDictionary( /// The dictionary to be translated. /// The comparer used to instantiate the dictionary. /// The factory used to instantiate values in the dictionary. - public void TranslateDictionary(ref Dictionary dictionary, IEqualityComparer comparer, NodePacketValueFactory valueFactory) - where T : class, ITranslatable + public void TranslateDictionary(ref Dictionary dictionary, IEqualityComparer comparer, ObjectTranslator objectTranslator) + where T : class { if (!TranslateNullable(dictionary)) { @@ -591,7 +567,7 @@ public void TranslateDictionary(ref Dictionary dictionary, IEquali string key = null; Translate(ref key); T value = null; - Translate(ref value, valueFactory); + objectTranslator(this, ref value); dictionary[key] = value; } } @@ -603,9 +579,9 @@ public void TranslateDictionary(ref Dictionary dictionary, IEquali /// The reference type for values in the dictionary. /// The dictionary to be translated. /// The factory used to instantiate values in the dictionary. - public void TranslateDictionary(ref D dictionary, NodePacketValueFactory valueFactory) + public void TranslateDictionary(ref D dictionary, ObjectTranslator objectTranslator) where D : IDictionary, new() - where T : class, ITranslatable + where T : class { if (!TranslateNullable(dictionary)) { @@ -620,7 +596,7 @@ public void TranslateDictionary(ref D dictionary, NodePacketValueFactory(ref D dictionary, NodePacketValueFactoryThe dictionary to be translated. /// The factory used to instantiate values in the dictionary. /// The delegate used to instantiate the dictionary. - public void TranslateDictionary(ref D dictionary, NodePacketValueFactory valueFactory, NodePacketCollectionCreator dictionaryCreator) + public void TranslateDictionary(ref D dictionary, ObjectTranslator objectTranslator, NodePacketCollectionCreator dictionaryCreator) where D : IDictionary - where T : class, ITranslatable + where T : class { if (!TranslateNullable(dictionary)) { @@ -650,7 +626,7 @@ public void TranslateDictionary(ref D dictionary, NodePacketValueFactory set) /// The list to be translated. /// factory to create type T /// A TaskItemType - public void Translate(ref List list, NodePacketValueFactory factory) where T : ITranslatable + public void Translate(ref List list, ObjectTranslator objectTranslator) { if (!TranslateNullable(list)) { @@ -876,7 +852,7 @@ public void Translate(ref List list, NodePacketValueFactory factory) wh for (int i = 0; i < count; i++) { T value = list[i]; - Translate(ref value, factory); + objectTranslator(this, ref value); } } @@ -888,7 +864,7 @@ public void Translate(ref List list, NodePacketValueFactory factory) wh /// factory to create the IList /// A TaskItemType /// IList subtype - public void Translate(ref IList list, NodePacketValueFactory factory, NodePacketCollectionCreator collectionFactory) where T : ITranslatable where L : IList + public void Translate(ref IList list, ObjectTranslator objectTranslator, NodePacketCollectionCreator collectionFactory) where L : IList { if (!TranslateNullable(list)) { @@ -901,7 +877,7 @@ public void Translate(ref IList list, NodePacketValueFactory factory for (int i = 0; i < count; i++) { T value = list[i]; - Translate(ref value, factory); + objectTranslator(this, ref value); } } @@ -1016,24 +992,6 @@ public void Translate(ref T value) value.Translate(this); } - /// - /// Translates an object implementing INodePacketTranslatable which does not expose a - /// public parameterless constructor. - /// - /// The reference type. - /// The value to be translated. - /// The factory method used to instantiate values of type T. - public void Translate(ref T value, NodePacketValueFactory factory) - where T : ITranslatable - { - if (!TranslateNullable(value)) - { - return; - } - - value.Translate(this); - } - /// /// Translates a byte array /// @@ -1081,8 +1039,7 @@ public void TranslateArray(ref T[] array) /// The reference type. /// The array to be translated. /// The factory method used to instantiate values of type T. - public void TranslateArray(ref T[] array, NodePacketValueFactory factory) - where T : ITranslatable + public void TranslateArray(ref T[] array, ObjectTranslator objectTranslator) { if (!TranslateNullable(array)) { @@ -1094,7 +1051,7 @@ public void TranslateArray(ref T[] array, NodePacketValueFactory factory) for (int i = 0; i < count; i++) { - array[i].Translate(this); + objectTranslator(this, ref array[i]); } } @@ -1130,8 +1087,8 @@ public void TranslateDictionary(ref IDictionary dictionary, Node public void TranslateDictionary( ref IDictionary dictionary, - Translator keyTranslator, - Translator valueTranslator, + ObjectTranslator keyTranslator, + ObjectTranslator valueTranslator, NodePacketCollectionCreator> collectionCreator) { if (!TranslateNullable(dictionary)) @@ -1145,9 +1102,9 @@ public void TranslateDictionary( foreach (KeyValuePair pair in dictionary) { K key = pair.Key; - keyTranslator.Invoke(ref key, this); + keyTranslator(this, ref key); V value = pair.Value; - valueTranslator.Invoke(ref value, this); + valueTranslator(this, ref value); } } @@ -1158,8 +1115,8 @@ public void TranslateDictionary( /// The dictionary to be translated. /// The comparer used to instantiate the dictionary. /// The factory used to instantiate values in the dictionary. - public void TranslateDictionary(ref Dictionary dictionary, IEqualityComparer comparer, NodePacketValueFactory valueFactory) - where T : class, ITranslatable + public void TranslateDictionary(ref Dictionary dictionary, IEqualityComparer comparer, ObjectTranslator objectTranslator) + where T : class { if (!TranslateNullable(dictionary)) { @@ -1174,7 +1131,7 @@ public void TranslateDictionary(ref Dictionary dictionary, IEquali string key = pair.Key; Translate(ref key); T value = pair.Value; - Translate(ref value, valueFactory); + objectTranslator(this, ref value); } } @@ -1185,9 +1142,9 @@ public void TranslateDictionary(ref Dictionary dictionary, IEquali /// The reference type for values in the dictionary. /// The dictionary to be translated. /// The factory used to instantiate values in the dictionary. - public void TranslateDictionary(ref D dictionary, NodePacketValueFactory valueFactory) + public void TranslateDictionary(ref D dictionary, ObjectTranslator objectTranslator) where D : IDictionary, new() - where T : class, ITranslatable + where T : class { if (!TranslateNullable(dictionary)) { @@ -1202,7 +1159,7 @@ public void TranslateDictionary(ref D dictionary, NodePacketValueFactory(ref D dictionary, NodePacketValueFactoryThe dictionary to be translated. /// The factory used to instantiate values in the dictionary. /// The delegate used to instantiate the dictionary. - public void TranslateDictionary(ref D dictionary, NodePacketValueFactory valueFactory, NodePacketCollectionCreator dictionaryCreator) + public void TranslateDictionary(ref D dictionary, ObjectTranslator objectTranslator, NodePacketCollectionCreator dictionaryCreator) where D : IDictionary - where T : class, ITranslatable + where T : class { if (!TranslateNullable(dictionary)) { @@ -1231,7 +1188,7 @@ public void TranslateDictionary(ref D dictionary, NodePacketValueFactory - /// Delegate for users that want to translate an arbitrary structure that cannot implement (e.g. translating a complex collection) - /// - /// the translator - /// the object to translate - internal delegate void Translator(ref T obj, ITranslator translator); - /// /// An interface representing an object which may be serialized by the node packet serializer. /// diff --git a/src/Shared/ITranslator.cs b/src/Shared/ITranslator.cs index 088ffef172d..7bd5655fee4 100644 --- a/src/Shared/ITranslator.cs +++ b/src/Shared/ITranslator.cs @@ -16,6 +16,13 @@ namespace Microsoft.Build.BackEnd /// The type to be translated. internal delegate T NodePacketValueFactory(ITranslator translator); + /// + /// Delegate for users that want to translate an arbitrary structure that doesn't implement (e.g. translating a complex collection) + /// + /// the translator + /// the object to translate + internal delegate void ObjectTranslator(ITranslator translator, ref T objectToTranslate); + /// /// This delegate is used to create arbitrary collection types for serialization. /// @@ -161,7 +168,7 @@ BinaryWriter Writer /// The list to be translated. /// factory to create type T /// A TaskItemType - void Translate(ref List list, NodePacketValueFactory factory) where T : ITranslatable; + void Translate(ref List list, ObjectTranslator objectTranslator); /// /// Translates a list of T where T implements INodePacketTranslateable using a collection factory @@ -171,7 +178,7 @@ BinaryWriter Writer /// An ITranslatable subtype /// An IList subtype /// factory to create a collection - void Translate(ref IList list, NodePacketValueFactory factory, NodePacketCollectionCreator collectionFactory) where T : ITranslatable where L : IList; + void Translate(ref IList list, ObjectTranslator objectTranslator, NodePacketCollectionCreator collectionFactory) where L : IList; /// /// Translates a DateTime. @@ -240,16 +247,6 @@ BinaryWriter Writer void Translate(ref T value) where T : ITranslatable, new(); - /// - /// Translates an object implementing INodePacketTranslatable which does not expose a - /// public parameterless constructor. - /// - /// The reference type. - /// The value to be translated. - /// The factory method used to instantiate values of type T. - void Translate(ref T value, NodePacketValueFactory factory) - where T : ITranslatable; - /// /// Translates a culture /// @@ -271,13 +268,12 @@ void TranslateArray(ref T[] array) where T : ITranslatable, new(); /// - /// Translates an array of objects implementing INodePacketTranslatable requiring a factory to create. + /// Translates an array of objects. /// /// The reference type. /// The array to be translated. - /// The factory method used to instantiate values of type T. - void TranslateArray(ref T[] array, NodePacketValueFactory factory) - where T : ITranslatable; + /// The delegate method used to translate values of type T. + void TranslateArray(ref T[] array, ObjectTranslator objectTranslator); /// /// Translates a dictionary of { string, string }. @@ -288,7 +284,7 @@ void TranslateArray(ref T[] array, NodePacketValueFactory factory) void TranslateDictionary(ref IDictionary dictionary, NodePacketCollectionCreator> collectionCreator); - void TranslateDictionary(ref IDictionary dictionary, Translator keyTranslator, Translator valueTranslator, NodePacketCollectionCreator> dictionaryCreator); + void TranslateDictionary(ref IDictionary dictionary, ObjectTranslator keyTranslator, ObjectTranslator valueTranslator, NodePacketCollectionCreator> dictionaryCreator); /// /// Translates a dictionary of { string, T }. @@ -297,8 +293,8 @@ void TranslateArray(ref T[] array, NodePacketValueFactory factory) /// The dictionary to be translated. /// The comparer used to instantiate the dictionary. /// The factory used to instantiate values in the dictionary. - void TranslateDictionary(ref Dictionary dictionary, IEqualityComparer comparer, NodePacketValueFactory valueFactory) - where T : class, ITranslatable; + void TranslateDictionary(ref Dictionary dictionary, IEqualityComparer comparer, ObjectTranslator objectTranslator) + where T : class; /// /// Translates a dictionary of { string, T } for dictionaries with public parameterless constructors. @@ -307,9 +303,9 @@ void TranslateDictionary(ref Dictionary dictionary, IEqualityCompa /// The reference type for values in the dictionary. /// The dictionary to be translated. /// The factory used to instantiate values in the dictionary. - void TranslateDictionary(ref D dictionary, NodePacketValueFactory valueFactory) + void TranslateDictionary(ref D dictionary, ObjectTranslator objectTranslator) where D : IDictionary, new() - where T : class, ITranslatable; + where T : class; /// /// Translates a dictionary of { string, T } for dictionaries with public parameterless constructors. @@ -319,9 +315,9 @@ void TranslateDictionary(ref D dictionary, NodePacketValueFactory value /// The dictionary to be translated. /// The factory used to instantiate values in the dictionary. /// A factory used to create the dictionary. - void TranslateDictionary(ref D dictionary, NodePacketValueFactory valueFactory, NodePacketCollectionCreator collectionCreator) + void TranslateDictionary(ref D dictionary, ObjectTranslator objectTranslator, NodePacketCollectionCreator collectionCreator) where D : IDictionary - where T : class, ITranslatable; + where T : class; /// /// Translates the boolean that says whether this value is null or not diff --git a/src/Shared/TranslatorHelpers.cs b/src/Shared/TranslatorHelpers.cs new file mode 100644 index 00000000000..d58e5b42c18 --- /dev/null +++ b/src/Shared/TranslatorHelpers.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Microsoft.Build.BackEnd +{ + internal static class TranslatorHelpers + { + /// + /// Translates an object implementing which does not expose a + /// public parameterless constructor. + /// + /// The reference type. + /// The translator + /// The value to be translated. + /// The factory method used to instantiate values of type T. + public static void Translate( + this ITranslator translator, + ref T instance, + NodePacketValueFactory valueFactory) where T : ITranslatable + { + if (!translator.TranslateNullable(instance)) + { + return; + } + if (translator.Mode == TranslationDirection.ReadFromStream) + { + instance = valueFactory(translator); + } + else + { + instance.Translate(translator); + } + } + + static ObjectTranslator AdaptFactory(NodePacketValueFactory valueFactory) where T : ITranslatable + { + void Translate(ITranslator translator, ref T objectToTranslate) + { + TranslatorHelpers.Translate(translator, ref objectToTranslate, valueFactory); + } + + return Translate; + } + + public static void Translate( + this ITranslator translator, + ref List list, + NodePacketValueFactory valueFactory) where T : class, ITranslatable + { + translator.Translate(ref list, AdaptFactory(valueFactory)); + } + + public static void Translate( + this ITranslator translator, + ref IList list, + NodePacketValueFactory valueFactory, + NodePacketCollectionCreator collectionFactory) where L : IList where T : ITranslatable + { + translator.Translate(ref list, AdaptFactory(valueFactory), collectionFactory); + } + + public static void TranslateArray( + this ITranslator translator, + ref T[] array, + NodePacketValueFactory valueFactory) where T : class, ITranslatable + { + translator.TranslateArray(ref array, AdaptFactory(valueFactory)); + } + + public static void TranslateDictionary( + this ITranslator translator, + ref Dictionary dictionary, + IEqualityComparer comparer, + NodePacketValueFactory valueFactory) where T : class, ITranslatable + { + translator.TranslateDictionary(ref dictionary, comparer, AdaptFactory(valueFactory)); + } + + public static void TranslateDictionary( + this ITranslator translator, + ref D dictionary, + NodePacketValueFactory valueFactory) + where D : IDictionary, new() + where T : class, ITranslatable + { + translator.TranslateDictionary(ref dictionary, AdaptFactory(valueFactory)); + } + + public static void TranslateDictionary( + this ITranslator translator, + ref D dictionary, + NodePacketValueFactory valueFactory, + NodePacketCollectionCreator collectionCreator) + where D : IDictionary + where T : class, ITranslatable + { + translator.TranslateDictionary(ref dictionary, AdaptFactory(valueFactory), collectionCreator); + } + } +}