From 587abbc00560da242d0cd117e85117d0ca1f547a Mon Sep 17 00:00:00 2001 From: Tim M <49349513+TimothyMakkison@users.noreply.github.com> Date: Tue, 18 Apr 2023 18:34:08 +0100 Subject: [PATCH] feat: add support fot `ImmutableDictionary` and `ImmutableSortedDictionary` (#351) --- .../DictionaryMappingBuilder.cs | 29 +++++++ .../EnumerableMappingBuilder.cs | 27 +++--- ...rEachSetDictionaryExistingTargetMapping.cs | 8 +- .../Mappings/LinqDictionaryMapping.cs | 56 +++++++++++++ .../Descriptors/WellKnownTypes.cs | 3 + src/Riok.Mapperly/Helpers/SymbolExtensions.cs | 7 ++ .../BaseMapperTest.cs | 4 +- .../Dto/TestObjectDto.cs | 4 + .../Models/TestObject.cs | 4 + ...pperTest.RunMappingShouldWork.verified.txt | 10 +++ ...erTest.SnapshotGeneratedSource.verified.cs | 6 ++ ...RunExtensionMappingShouldWork.verified.txt | 10 +++ ...pperTest.RunMappingShouldWork.verified.txt | 10 +++ ...erTest.SnapshotGeneratedSource.verified.cs | 8 ++ ...pperTest.RunMappingShouldWork.verified.txt | 10 +++ ...erTest.SnapshotGeneratedSource.verified.cs | 6 ++ ...RunExtensionMappingShouldWork.verified.txt | 10 +++ ...pperTest.RunMappingShouldWork.verified.txt | 10 +++ ...erTest.SnapshotGeneratedSource.verified.cs | 8 ++ ...pperTest.RunMappingShouldWork.verified.txt | 10 +++ ...erTest.SnapshotGeneratedSource.verified.cs | 6 ++ ...RunExtensionMappingShouldWork.verified.txt | 10 +++ ...pperTest.RunMappingShouldWork.verified.txt | 10 +++ ...erTest.SnapshotGeneratedSource.verified.cs | 8 ++ .../Mapping/DictionaryTest.cs | 84 +++++++++++++++++++ .../Mapping/EnumerableTest.cs | 4 +- 26 files changed, 338 insertions(+), 24 deletions(-) create mode 100644 src/Riok.Mapperly/Descriptors/Mappings/LinqDictionaryMapping.cs diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs index f4b86f9a12..c49e1d3189 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/DictionaryMappingBuilder.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Riok.Mapperly.Abstractions; using Riok.Mapperly.Descriptors.Mappings; @@ -11,6 +12,9 @@ public static class DictionaryMappingBuilder { private const string CountPropertyName = nameof(IDictionary.Count); + private const string ToImmutableDictionaryMethodName = nameof(ImmutableDictionary.ToImmutableDictionary); + private const string ToImmutableSortedDictionaryMethodName = nameof(ImmutableSortedDictionary.ToImmutableSortedDictionary); + public static ITypeMapping? TryBuildMapping(MappingBuilderContext ctx) { if (!ctx.IsConversionEnabled(MappingConversionType.Dictionary)) @@ -38,6 +42,11 @@ public static class DictionaryMappingBuilder dictionaryObjectFactory); } + // if target is an immutable dictionary then use LinqDictionaryMapper + var immutableLinqMapping = ResolveImmutableCollectMethod(ctx, keyMapping, valueMapping); + if (immutableLinqMapping != null) + return immutableLinqMapping; + // the target is not a well known dictionary type // it should have a an object factory or a parameterless public ctor if (!ctx.ObjectFactories.TryFindObjectFactory(ctx.Source, ctx.Target, out var objectFactory) && !ctx.Target.HasAccessibleParameterlessConstructor()) @@ -66,6 +75,14 @@ public static class DictionaryMappingBuilder if (BuildKeyValueMapping(ctx) is not var (keyMapping, valueMapping)) return null; + // if target is an immutable dictionary then don't create a foreach loop + if (ctx.Target.OriginalDefinition.ImplementsGeneric(ctx.Types.IImmutableDictionaryT, out _)) + { + ctx.ReportDiagnostic(DiagnosticDescriptors.CannotMapToReadOnlyMember); + return null; + } + + // add values to dictionary by setting key values in a foreach loop return new ForEachSetDictionaryExistingTargetMapping( ctx.Source, ctx.Target, @@ -130,4 +147,16 @@ private static (ITypeSymbol, ITypeSymbol)? GetEnumerableKeyValueTypes(MappingBui return (enumeratedType.TypeArguments[0], enumeratedType.TypeArguments[1]); } + + private static LinqDicitonaryMapping? ResolveImmutableCollectMethod(MappingBuilderContext ctx, ITypeMapping keyMapping, ITypeMapping valueMapping) + { + if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableSortedDictionaryT)) + return new LinqDicitonaryMapping(ctx.Source, ctx.Target, ctx.Types.ImmutableSortedDictionary.GetStaticGenericMethod(ToImmutableSortedDictionaryMethodName)!, keyMapping, valueMapping); + + // if taget is an ImmutableDictionary or implements interface IImmutableDictionary + if (ctx.Target.OriginalDefinition.ImplementsGeneric(ctx.Types.IImmutableDictionaryT, out _)) + return new LinqDicitonaryMapping(ctx.Source, ctx.Target, ctx.Types.ImmutableDictionary.GetStaticGenericMethod(ToImmutableDictionaryMethodName)!, keyMapping, valueMapping); + + return null; + } } diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs index 3341137e62..d83d159847 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs @@ -119,11 +119,11 @@ private static LinqEnumerableMapping BuildLinqMapping( { var collectMethod = collectMethodName == null ? null - : ResolveStaticMethod(ctx.Types.Enumerable, collectMethodName); + : ctx.Types.Enumerable.GetStaticGenericMethod(collectMethodName); var selectMethod = elementMapping.IsSynthetic ? null - : ResolveStaticMethod(ctx.Types.Enumerable, SelectMethodName); + : ctx.Types.Enumerable.GetStaticGenericMethod(SelectMethodName); return new LinqEnumerableMapping(ctx.Source, ctx.Target, elementMapping, selectMethod, collectMethod); } @@ -145,7 +145,7 @@ private static LinqConstructorMapping BuildLinqConstructorMapping( { var selectMethod = elementMapping.IsSynthetic ? null - : ResolveStaticMethod(ctx.Types.Enumerable, SelectMethodName); + : ctx.Types.Enumerable.GetStaticGenericMethod(SelectMethodName); return new LinqConstructorMapping(ctx.Source, ctx.Target, elementMapping, selectMethod); } @@ -210,7 +210,7 @@ private static (bool CanMapWithLinq, string? CollectMethod) ResolveCollectMethod var selectMethod = elementMapping.IsSynthetic ? null - : ResolveStaticMethod(ctx.Types.Enumerable, SelectMethodName); + : ctx.Types.Enumerable.GetStaticGenericMethod(SelectMethodName); return new LinqEnumerableMapping(ctx.Source, ctx.Target, elementMapping, selectMethod, collectMethod); } @@ -218,33 +218,26 @@ private static (bool CanMapWithLinq, string? CollectMethod) ResolveCollectMethod private static IMethodSymbol? ResolveImmutableCollectMethod(MappingBuilderContext ctx) { if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableArrayT)) - return ResolveStaticMethod(ctx.Types.ImmutableArray, ToImmutableArrayMethodName); + return ctx.Types.ImmutableArray.GetStaticGenericMethod(ToImmutableArrayMethodName); if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableListT)) - return ResolveStaticMethod(ctx.Types.ImmutableList, ToImmutableListMethodName); + return ctx.Types.ImmutableList.GetStaticGenericMethod(ToImmutableListMethodName); if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableHashSetT)) - return ResolveStaticMethod(ctx.Types.ImmutableHashSet, ToImmutableHashSetMethodName); + return ctx.Types.ImmutableHashSet.GetStaticGenericMethod(ToImmutableHashSetMethodName); if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableQueueT)) - return ResolveStaticMethod(ctx.Types.ImmutableQueue, CreateRangeQueueMethodName); + return ctx.Types.ImmutableQueue.GetStaticGenericMethod(CreateRangeQueueMethodName); if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableStackT)) - return ResolveStaticMethod(ctx.Types.ImmutableStack, CreateRangeStackMethodName); + return ctx.Types.ImmutableStack.GetStaticGenericMethod(CreateRangeStackMethodName); if (SymbolEqualityComparer.Default.Equals(ctx.Target.OriginalDefinition, ctx.Types.ImmutableSortedSetT)) - return ResolveStaticMethod(ctx.Types.ImmutableSortedSet, ToImmutableSortedSetMethodName); + return ctx.Types.ImmutableSortedSet.GetStaticGenericMethod(ToImmutableSortedSetMethodName); return null; } - private static IMethodSymbol? ResolveStaticMethod(INamedTypeSymbol namedType, string methodName) - { - return namedType.GetMembers(methodName) - .OfType() - .FirstOrDefault(m => m.IsStatic && m.IsGenericMethod); - } - private static ITypeSymbol? GetEnumeratedType(MappingBuilderContext ctx, ITypeSymbol type) { return type.ImplementsGeneric(ctx.Types.IEnumerableT, out var enumerableIntf) diff --git a/src/Riok.Mapperly/Descriptors/Mappings/ExistingTarget/ForEachSetDictionaryExistingTargetMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/ExistingTarget/ForEachSetDictionaryExistingTargetMapping.cs index fe3bf53a20..1a60e2bf91 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/ExistingTarget/ForEachSetDictionaryExistingTargetMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/ExistingTarget/ForEachSetDictionaryExistingTargetMapping.cs @@ -12,8 +12,8 @@ namespace Riok.Mapperly.Descriptors.Mappings.ExistingTarget; public class ForEachSetDictionaryExistingTargetMapping : ExistingTargetMapping { private const string LoopItemVariableName = "item"; - private const string KeyValueKeyPropertyName = nameof(KeyValuePair.Key); - private const string KeyValueValuePropertyName = nameof(KeyValuePair.Value); + private const string KeyPropertyName = nameof(KeyValuePair.Key); + private const string ValuePropertyName = nameof(KeyValuePair.Value); private readonly ITypeMapping _keyMapping; private readonly ITypeMapping _valueMapping; @@ -33,8 +33,8 @@ public override IEnumerable Build(TypeMappingBuildContext ctx, { var loopItemVariableName = ctx.NameBuilder.New(LoopItemVariableName); - var convertedKeyExpression = _keyMapping.Build(ctx.WithSource(MemberAccess(loopItemVariableName, KeyValueKeyPropertyName))); - var convertedValueExpression = _valueMapping.Build(ctx.WithSource(MemberAccess(loopItemVariableName, KeyValueValuePropertyName))); + var convertedKeyExpression = _keyMapping.Build(ctx.WithSource(MemberAccess(loopItemVariableName, KeyPropertyName))); + var convertedValueExpression = _valueMapping.Build(ctx.WithSource(MemberAccess(loopItemVariableName, ValuePropertyName))); var assignment = Assignment( ElementAccess(target, convertedKeyExpression), diff --git a/src/Riok.Mapperly/Descriptors/Mappings/LinqDictionaryMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/LinqDictionaryMapping.cs new file mode 100644 index 0000000000..137f764b2c --- /dev/null +++ b/src/Riok.Mapperly/Descriptors/Mappings/LinqDictionaryMapping.cs @@ -0,0 +1,56 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static Riok.Mapperly.Emit.SyntaxFactoryHelper; + +namespace Riok.Mapperly.Descriptors.Mappings; + +/// +/// Represents an enumerable mapping which works by using linq (select + collect). +/// +public class LinqDicitonaryMapping : TypeMapping +{ + private const string LambdaParamName = "x"; + + private const string KeyPropertyName = nameof(KeyValuePair.Key); + private const string ValuePropertyName = nameof(KeyValuePair.Value); + + private readonly IMethodSymbol _collectMethod; + private readonly ITypeMapping _keyMapping; + private readonly ITypeMapping _valueMapping; + + public LinqDicitonaryMapping( + ITypeSymbol sourceType, + ITypeSymbol targetType, + IMethodSymbol collectMethod, + ITypeMapping keyMapping, + ITypeMapping valueMapping) + : base(sourceType, targetType) + { + _collectMethod = collectMethod; + _keyMapping = keyMapping; + _valueMapping = valueMapping; + } + + public override ExpressionSyntax Build(TypeMappingBuildContext ctx) + { + var lambdaParamName = ctx.NameBuilder.New(LambdaParamName); + + // if key and value types do not change then use a simple call + // ie: source.ToImmutableDictionary(); + if (_keyMapping.IsSynthetic && _valueMapping.IsSynthetic) + return StaticInvocation(_collectMethod, ctx.Source); + + // create expressions mapping the key and value and then create the final expression + // ie: source.ToImmutableDictionary(x => x.Key, x=> (int)x.Value); + var keyMapExpression = _keyMapping.Build(ctx.WithSource(MemberAccess(lambdaParamName, KeyPropertyName))); + var keyExpression = SimpleLambdaExpression(Parameter(Identifier(lambdaParamName))) + .WithExpressionBody(keyMapExpression); + + var valueMapExpression = _valueMapping.Build(ctx.WithSource(MemberAccess(lambdaParamName, ValuePropertyName))); + var valueExpression = SimpleLambdaExpression(Parameter(Identifier(lambdaParamName))) + .WithExpressionBody(valueMapExpression); + + return StaticInvocation(_collectMethod, ctx.Source, keyExpression, valueExpression); + } +} diff --git a/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs b/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs index aee449ed0d..50b67c0acd 100644 --- a/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs +++ b/src/Riok.Mapperly/Descriptors/WellKnownTypes.cs @@ -49,6 +49,7 @@ public class WellKnownTypes private INamedTypeSymbol? _immutableSortedSetT; private INamedTypeSymbol? _immutableDictionary; private INamedTypeSymbol? _immutableDictionaryT; + private INamedTypeSymbol? _iImmutableDictionaryT; private INamedTypeSymbol? _immutableSortedDictionary; private INamedTypeSymbol? _immutableSortedDictionaryT; @@ -98,7 +99,9 @@ internal WellKnownTypes(Compilation compilation) public INamedTypeSymbol ImmutableSortedSet => _immutableSortedSet ??= GetTypeSymbol(typeof(ImmutableSortedSet)); public INamedTypeSymbol ImmutableSortedSetT => _immutableSortedSetT ??= GetTypeSymbol(typeof(ImmutableSortedSet<>)); public INamedTypeSymbol ImmutableDictionary => _immutableDictionary ??= GetTypeSymbol(typeof(ImmutableDictionary)); + public INamedTypeSymbol IImmutableDictionaryT => _iImmutableDictionaryT ??= GetTypeSymbol(typeof(IImmutableDictionary<,>)); public INamedTypeSymbol ImmutableDictionaryT => _immutableDictionaryT ??= GetTypeSymbol(typeof(ImmutableDictionary<,>)); + public INamedTypeSymbol ImmutableSortedDictionary => _immutableSortedDictionary ??= GetTypeSymbol(typeof(ImmutableSortedDictionary)); public INamedTypeSymbol ImmutableSortedDictionaryT => _immutableSortedDictionaryT ??= GetTypeSymbol(typeof(ImmutableSortedDictionary<,>)); diff --git a/src/Riok.Mapperly/Helpers/SymbolExtensions.cs b/src/Riok.Mapperly/Helpers/SymbolExtensions.cs index 16fd50083e..db01ab291e 100644 --- a/src/Riok.Mapperly/Helpers/SymbolExtensions.cs +++ b/src/Riok.Mapperly/Helpers/SymbolExtensions.cs @@ -78,6 +78,13 @@ internal static IEnumerable GetAccessibleMappableMembers(this I .WhereNotNull(); } + internal static IMethodSymbol? GetStaticGenericMethod(this INamedTypeSymbol namedType, string methodName) + { + return namedType.GetMembers(methodName) + .OfType() + .FirstOrDefault(m => m.IsStatic && m.IsGenericMethod); + } + internal static bool ImplementsGeneric( this ITypeSymbol t, INamedTypeSymbol genericInterfaceSymbol, diff --git a/test/Riok.Mapperly.IntegrationTests/BaseMapperTest.cs b/test/Riok.Mapperly.IntegrationTests/BaseMapperTest.cs index 3449e757a0..a1c1a1db08 100644 --- a/test/Riok.Mapperly.IntegrationTests/BaseMapperTest.cs +++ b/test/Riok.Mapperly.IntegrationTests/BaseMapperTest.cs @@ -86,7 +86,9 @@ protected TestObject NewTestObj() ImmutableHashSetValue = ImmutableHashSet.Create("1", "2", "3"), ImmutableQueueValue = ImmutableQueue.Create("1", "2", "3"), ImmutableStackValue = ImmutableStack.Create("1", "2", "3"), - ImmutableSortedSetValue = ImmutableSortedSet.Create("1", "2", "3") + ImmutableSortedSetValue = ImmutableSortedSet.Create("1", "2", "3"), + ImmutableDictionaryValue = new Dictionary() { { "1", "1" }, { "2", "2" }, { "3", "3" } }.ToImmutableDictionary(), + ImmutableSortedDictionaryValue = new Dictionary() { { "1", "1" }, { "2", "2" }, { "3", "3" } }.ToImmutableSortedDictionary(), }; } diff --git a/test/Riok.Mapperly.IntegrationTests/Dto/TestObjectDto.cs b/test/Riok.Mapperly.IntegrationTests/Dto/TestObjectDto.cs index d71a26ec22..17004df464 100644 --- a/test/Riok.Mapperly.IntegrationTests/Dto/TestObjectDto.cs +++ b/test/Riok.Mapperly.IntegrationTests/Dto/TestObjectDto.cs @@ -69,6 +69,10 @@ public TestObjectDto(int ctorValue, int unknownValue = 10, int ctorValue2 = 100) public ImmutableSortedSet ImmutableSortedSetValue { get; set; } = ImmutableSortedSet.Empty; + public ImmutableDictionary ImmutableDictionaryValue { get; set; } = ImmutableDictionary.Empty; + + public ImmutableSortedDictionary ImmutableSortedDictionaryValue { get; set; } = ImmutableSortedDictionary.Empty; + public TestEnumDtoByValue EnumValue { get; set; } public TestEnumDtoByName EnumName { get; set; } diff --git a/test/Riok.Mapperly.IntegrationTests/Models/TestObject.cs b/test/Riok.Mapperly.IntegrationTests/Models/TestObject.cs index e2b24aaffd..941d143abd 100644 --- a/test/Riok.Mapperly.IntegrationTests/Models/TestObject.cs +++ b/test/Riok.Mapperly.IntegrationTests/Models/TestObject.cs @@ -66,6 +66,10 @@ public TestObject(int ctorValue, int unknownValue = 10, int ctorValue2 = 100) public ImmutableSortedSet ImmutableSortedSetValue { get; set; } = ImmutableSortedSet.Empty; + public ImmutableDictionary ImmutableDictionaryValue { get; set; } = ImmutableDictionary.Empty; + + public ImmutableSortedDictionary ImmutableSortedDictionaryValue { get; set; } = ImmutableSortedDictionary.Empty; + public TestEnum EnumValue { get; set; } public TestEnum EnumName { get; set; } diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.RunMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.RunMappingShouldWork.verified.txt index af6e1984a1..122b886cac 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.RunMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.RunMappingShouldWork.verified.txt @@ -98,6 +98,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.SnapshotGeneratedSource.verified.cs index 1792643ef1..67b7919adf 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/MapperTest.SnapshotGeneratedSource.verified.cs @@ -106,6 +106,8 @@ public partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(testObject.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(testObject.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(testObject.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)testObject.EnumValue; target.EnumName = MapToEnumDtoByName(testObject.EnumName); target.EnumRawValue = (byte)testObject.EnumRawValue; @@ -162,6 +164,8 @@ public partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableQueueValue, x5 => x5.ToString())); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableStackValue, x6 => x6.ToString())); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(dto.ImmutableSortedSetValue, x7 => x7.ToString())); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(dto.ImmutableDictionaryValue, x8 => x8.Key.ToString(), x8 => x8.Value.ToString()); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(dto.ImmutableSortedDictionaryValue, x9 => x9.Key.ToString(), x9 => x9.Value.ToString()); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumValue; target.EnumName = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumName; target.EnumRawValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumRawValue; @@ -233,6 +237,8 @@ public partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Models.Test target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(source.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)source.EnumValue; target.EnumName = MapToEnumDtoByName(source.EnumName); target.EnumRawValue = (byte)source.EnumRawValue; diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt index 0733aa3c95..4c217b7de3 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt @@ -93,6 +93,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunMappingShouldWork.verified.txt index d12ee6e21e..537af2a13d 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.RunMappingShouldWork.verified.txt @@ -98,6 +98,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.SnapshotGeneratedSource.verified.cs index af0c369dbf..b5a5623060 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/StaticMapperTest.SnapshotGeneratedSource.verified.cs @@ -98,6 +98,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(src.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(src.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(src.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(src.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(src.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)src.EnumValue; target.EnumName = MapToEnumDtoByName(src.EnumName); target.EnumRawValue = (byte)src.EnumRawValue; @@ -171,6 +173,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(testObject.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(testObject.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(testObject.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)testObject.EnumValue; target.EnumName = MapToEnumDtoByName(testObject.EnumName); target.EnumRawValue = (byte)testObject.EnumRawValue; @@ -227,6 +231,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableQueueValue, x5 => x5.ToString())); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableStackValue, x6 => x6.ToString())); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(dto.ImmutableSortedSetValue, x7 => x7.ToString())); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(dto.ImmutableDictionaryValue, x8 => x8.Key.ToString(), x8 => x8.Value.ToString()); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(dto.ImmutableSortedDictionaryValue, x9 => x9.Key.ToString(), x9 => x9.Value.ToString()); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumValue; target.EnumName = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumName; target.EnumRawValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumRawValue; @@ -298,6 +304,8 @@ public static partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Mode target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(source.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)source.EnumValue; target.EnumName = MapToEnumDtoByName(source.EnumName); target.EnumRawValue = (byte)source.EnumRawValue; diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.RunMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.RunMappingShouldWork.verified.txt index af6e1984a1..122b886cac 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.RunMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.RunMappingShouldWork.verified.txt @@ -98,6 +98,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.SnapshotGeneratedSource.verified.cs index 74c9b83b44..92b4c9a56f 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/MapperTest.SnapshotGeneratedSource.verified.cs @@ -103,6 +103,8 @@ public partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(testObject.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(testObject.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(testObject.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)testObject.EnumValue; target.EnumName = MapToEnumDtoByName(testObject.EnumName); target.EnumRawValue = (byte)testObject.EnumRawValue; @@ -156,6 +158,8 @@ public partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableQueueValue, x5 => x5.ToString())); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableStackValue, x6 => x6.ToString())); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(dto.ImmutableSortedSetValue, x7 => x7.ToString())); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(dto.ImmutableDictionaryValue, x8 => x8.Key.ToString(), x8 => x8.Value.ToString()); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(dto.ImmutableSortedDictionaryValue, x9 => x9.Key.ToString(), x9 => x9.Value.ToString()); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumValue; target.EnumName = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumName; target.EnumRawValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumRawValue; @@ -227,6 +231,8 @@ public partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Models.Test target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(source.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)source.EnumValue; target.EnumName = MapToEnumDtoByName(source.EnumName); target.EnumRawValue = (byte)source.EnumRawValue; diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt index 0733aa3c95..4c217b7de3 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt @@ -93,6 +93,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunMappingShouldWork.verified.txt index d12ee6e21e..537af2a13d 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.RunMappingShouldWork.verified.txt @@ -98,6 +98,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.SnapshotGeneratedSource.verified.cs index 43ba037347..4dc845be43 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/StaticMapperTest.SnapshotGeneratedSource.verified.cs @@ -95,6 +95,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(src.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(src.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(src.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(src.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(src.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)src.EnumValue; target.EnumName = MapToEnumDtoByName(src.EnumName); target.EnumRawValue = (byte)src.EnumRawValue; @@ -165,6 +167,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(testObject.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(testObject.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(testObject.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)testObject.EnumValue; target.EnumName = MapToEnumDtoByName(testObject.EnumName); target.EnumRawValue = (byte)testObject.EnumRawValue; @@ -218,6 +222,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableQueueValue, x5 => x5.ToString())); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableStackValue, x6 => x6.ToString())); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(dto.ImmutableSortedSetValue, x7 => x7.ToString())); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(dto.ImmutableDictionaryValue, x8 => x8.Key.ToString(), x8 => x8.Value.ToString()); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(dto.ImmutableSortedDictionaryValue, x9 => x9.Key.ToString(), x9 => x9.Value.ToString()); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumValue; target.EnumName = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumName; target.EnumRawValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumRawValue; @@ -289,6 +295,8 @@ public static partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Mode target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(source.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)source.EnumValue; target.EnumName = MapToEnumDtoByName(source.EnumName); target.EnumRawValue = (byte)source.EnumRawValue; diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.RunMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.RunMappingShouldWork.verified.txt index af6e1984a1..122b886cac 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.RunMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.RunMappingShouldWork.verified.txt @@ -98,6 +98,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.SnapshotGeneratedSource.verified.cs index e1c48ce260..f22d1448c1 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/MapperTest.SnapshotGeneratedSource.verified.cs @@ -106,6 +106,8 @@ public partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(testObject.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(testObject.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(testObject.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)testObject.EnumValue; target.EnumName = MapToEnumDtoByName(testObject.EnumName); target.EnumRawValue = (byte)testObject.EnumRawValue; @@ -162,6 +164,8 @@ public partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableQueueValue, x5 => x5.ToString())); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableStackValue, x6 => x6.ToString())); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(dto.ImmutableSortedSetValue, x7 => x7.ToString())); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(dto.ImmutableDictionaryValue, x8 => x8.Key.ToString(), x8 => x8.Value.ToString()); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(dto.ImmutableSortedDictionaryValue, x9 => x9.Key.ToString(), x9 => x9.Value.ToString()); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumValue; target.EnumName = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumName; target.EnumRawValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumRawValue; @@ -233,6 +237,8 @@ public partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Models.Test target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(source.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)source.EnumValue; target.EnumName = MapToEnumDtoByName(source.EnumName); target.EnumRawValue = (byte)source.EnumRawValue; diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt index 0733aa3c95..4c217b7de3 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunExtensionMappingShouldWork.verified.txt @@ -93,6 +93,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunMappingShouldWork.verified.txt b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunMappingShouldWork.verified.txt index d12ee6e21e..537af2a13d 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunMappingShouldWork.verified.txt +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.RunMappingShouldWork.verified.txt @@ -98,6 +98,16 @@ 2, 3 ], + ImmutableDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, + ImmutableSortedDictionaryValue: { + 1: 1, + 2: 2, + 3: 3 + }, EnumValue: DtoValue1, EnumName: Value10, EnumRawValue: 20, diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.SnapshotGeneratedSource.verified.cs index e5af523079..63bb2b3dd7 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/StaticMapperTest.SnapshotGeneratedSource.verified.cs @@ -98,6 +98,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(src.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(src.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(src.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(src.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(src.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)src.EnumValue; target.EnumName = MapToEnumDtoByName(src.EnumName); target.EnumRawValue = (byte)src.EnumRawValue; @@ -171,6 +173,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(testObject.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(testObject.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(testObject.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(testObject.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)testObject.EnumValue; target.EnumName = MapToEnumDtoByName(testObject.EnumName); target.EnumRawValue = (byte)testObject.EnumRawValue; @@ -227,6 +231,8 @@ public static partial int ParseableInt(string value) target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableQueueValue, x5 => x5.ToString())); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(dto.ImmutableStackValue, x6 => x6.ToString())); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(dto.ImmutableSortedSetValue, x7 => x7.ToString())); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(dto.ImmutableDictionaryValue, x8 => x8.Key.ToString(), x8 => x8.Value.ToString()); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(dto.ImmutableSortedDictionaryValue, x9 => x9.Key.ToString(), x9 => x9.Value.ToString()); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumValue; target.EnumName = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumName; target.EnumRawValue = (global::Riok.Mapperly.IntegrationTests.Models.TestEnum)dto.EnumRawValue; @@ -298,6 +304,8 @@ public static partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Mode target.ImmutableQueueValue = global::System.Collections.Immutable.ImmutableQueue.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableQueueValue, x6 => ParseableInt(x6))); target.ImmutableStackValue = global::System.Collections.Immutable.ImmutableStack.CreateRange(global::System.Linq.Enumerable.Select(source.ImmutableStackValue, x7 => ParseableInt(x7))); target.ImmutableSortedSetValue = global::System.Collections.Immutable.ImmutableSortedSet.ToImmutableSortedSet(global::System.Linq.Enumerable.Select(source.ImmutableSortedSetValue, x8 => ParseableInt(x8))); + target.ImmutableDictionaryValue = global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source.ImmutableDictionaryValue, x9 => ParseableInt(x9.Key), x9 => ParseableInt(x9.Value)); + target.ImmutableSortedDictionaryValue = global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source.ImmutableSortedDictionaryValue, x10 => ParseableInt(x10.Key), x10 => ParseableInt(x10.Value)); target.EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)source.EnumValue; target.EnumName = MapToEnumDtoByName(source.EnumName); target.EnumRawValue = (byte)source.EnumRawValue; diff --git a/test/Riok.Mapperly.Tests/Mapping/DictionaryTest.cs b/test/Riok.Mapperly.Tests/Mapping/DictionaryTest.cs index 460577824a..2e918ceb60 100644 --- a/test/Riok.Mapperly.Tests/Mapping/DictionaryTest.cs +++ b/test/Riok.Mapperly.Tests/Mapping/DictionaryTest.cs @@ -250,6 +250,90 @@ public void ReadOnlyDictionaryToCustomTypeReadOnlyReadOnlyDictionaryShouldIgnore """); } + [Fact] + public void DictionaryToImmutableDictionary() + { + var source = TestSourceBuilder.Mapping( + "Dictionary", + "System.Collections.Immutable.ImmutableDictionary"); + TestHelper.GenerateMapper(source) + .Should() + .HaveMapMethodBody( + """ + return global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source); + """); + } + + [Fact] + public void DictionaryToImmutableSortedDictionary() + { + var source = TestSourceBuilder.Mapping( + "Dictionary", + "System.Collections.Immutable.ImmutableSortedDictionary"); + TestHelper.GenerateMapper(source) + .Should() + .HaveMapMethodBody( + """ + return global::System.Collections.Immutable.ImmutableSortedDictionary.ToImmutableSortedDictionary(source); + """); + } + + [Fact] + public void DictionaryToImmutableDictionaryExplicitCastedKeyValue() + { + var source = TestSourceBuilder.Mapping( + "Dictionary", + "System.Collections.Immutable.ImmutableDictionary"); + TestHelper.GenerateMapper(source) + .Should() + .HaveMapMethodBody( + """ + return global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source, x => (int)x.Key, x => (int)x.Value); + """); + } + + [Fact] + public void DictionaryToImmutableDictionaryExplicitCastedValue() + { + var source = TestSourceBuilder.Mapping( + "Dictionary", + "System.Collections.Immutable.ImmutableDictionary"); + TestHelper.GenerateMapper(source) + .Should() + .HaveMapMethodBody( + """ + return global::System.Collections.Immutable.ImmutableDictionary.ToImmutableDictionary(source, x => x.Key, x => (int)x.Value); + """); + } + + [Fact] + public void EnumerableToReadOnlyImmutableDictionaryShouldDiagnostic() + { + var source = TestSourceBuilder.Mapping( + "A", + "B", + "class A { public Dictionary Value { get; } }", + "class B { public System.Collections.Immutable.ImmutableDictionary Value { get; } }"); + + TestHelper.GenerateMapper(source, TestHelperOptions.AllowInfoDiagnostics) + .Should() + .HaveDiagnostic(new(DiagnosticDescriptors.CannotMapToReadOnlyMember)); + } + + [Fact] + public void EnumerableToReadOnlyImmutableSortedDictionaryShouldDiagnostic() + { + var source = TestSourceBuilder.Mapping( + "A", + "B", + "class A { public Dictionary Value { get; } }", + "class B { public System.Collections.Immutable.ImmutableSortedDictionary Value { get; } }"); + + TestHelper.GenerateMapper(source, TestHelperOptions.AllowInfoDiagnostics) + .Should() + .HaveDiagnostic(new(DiagnosticDescriptors.CannotMapToReadOnlyMember)); + } + [Fact] public void ReadOnlyDictionaryToReadOnlyDictionaryExistingInstanceShouldIgnore() { diff --git a/test/Riok.Mapperly.Tests/Mapping/EnumerableTest.cs b/test/Riok.Mapperly.Tests/Mapping/EnumerableTest.cs index dd335ef812..e394c6cf16 100644 --- a/test/Riok.Mapperly.Tests/Mapping/EnumerableTest.cs +++ b/test/Riok.Mapperly.Tests/Mapping/EnumerableTest.cs @@ -897,7 +897,7 @@ public void EnumerableToReadOnlyImmutableArrayShouldDiagnostic() "A", "B", "class A { public IEnumerable Value { get; } }", - "class B { public System.Collections.Immutable.ImmutableList Value { get; } }"); + "class B { public System.Collections.Immutable.ImmutableArray Value { get; } }"); TestHelper.GenerateMapper(source, TestHelperOptions.AllowInfoDiagnostics) .Should() @@ -910,7 +910,7 @@ public void EnumerableToReadOnlyImmutableHashSetShouldDiagnostic() var source = TestSourceBuilder.Mapping( "A", "B", - "class A { public IEnumerable Value { get; } }", + "class A { public IEnumerable Value { get; } }", "class B { public System.Collections.Immutable.ImmutableHashSet Value { get; } }"); TestHelper.GenerateMapper(source, TestHelperOptions.AllowInfoDiagnostics)