diff --git a/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/BuilderContext/NewValueTupleExpressionBuilderContext.cs b/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/BuilderContext/NewValueTupleExpressionBuilderContext.cs index 31468863a8..38d0b626f3 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/BuilderContext/NewValueTupleExpressionBuilderContext.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/BuilderContext/NewValueTupleExpressionBuilderContext.cs @@ -20,7 +20,7 @@ public void AddTupleConstructorParameterMapping(ValueTupleConstructorParameterMa // remove the mapping used to map the tuple constructor value.RemoveAll(x => x.Target.Path.Count == 1); - // remove form dictionary if there aren't nested mappings + // remove from dictionary and target members if there aren't any more mappings if (!value.Any()) { MemberConfigsByRootTargetName.Remove(mapping.Parameter.Name); diff --git a/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewValueTupleMappingBodyBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewValueTupleMappingBodyBuilder.cs index b9112ce6c6..5ffdb74621 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewValueTupleMappingBodyBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBodyBuilders/NewValueTupleMappingBodyBuilder.cs @@ -196,9 +196,8 @@ out sourcePath ) return true; - // if standard matching fails, use the underlying field + // if standard matching fails, try to use the positional fields // if source is a tuple compare the underlying field ie, Item1, Item2 - // if source is not a tuple compare top level members if (ctx.Mapping.SourceType.IsTupleType) { if (ctx.Mapping.SourceType is not INamedTypeSymbol namedType) diff --git a/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/IMemberAssignmentMappingContainer.cs b/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/IMemberAssignmentMappingContainer.cs index e4f8cd84d6..ce4274699a 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/IMemberAssignmentMappingContainer.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/IMemberAssignmentMappingContainer.cs @@ -7,8 +7,6 @@ namespace Riok.Mapperly.Descriptors.Mappings.MemberMappings; /// public interface IMemberAssignmentMappingContainer { - bool HasMemberMappings(); - bool HasMemberMapping(IMemberAssignmentMapping mapping); void AddMemberMapping(IMemberAssignmentMapping mapping); diff --git a/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/MemberAssignmentMappingContainer.cs b/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/MemberAssignmentMappingContainer.cs index f3a0b44a2f..87744146f1 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/MemberAssignmentMappingContainer.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/MemberMappings/MemberAssignmentMappingContainer.cs @@ -42,8 +42,6 @@ public void AddMemberMapping(IMemberAssignmentMapping mapping) } } - public bool HasMemberMappings() => _delegateMappings.Any() || _childContainers.Any(x => x.HasMemberMappings()); - public bool HasMemberMapping(IMemberAssignmentMapping mapping) => _delegateMappings.Contains(mapping) || _parent?.HasMemberMapping(mapping) == true; } diff --git a/src/Riok.Mapperly/Descriptors/Mappings/MethodMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/MethodMapping.cs index 0e771ed980..a5852717cc 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/MethodMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/MethodMapping.cs @@ -63,7 +63,7 @@ ITypeSymbol targetType public override ExpressionSyntax Build(TypeMappingBuildContext ctx) => Invocation(MethodName, SourceParameter.WithArgument(ctx.Source), ReferenceHandlerParameter?.WithArgument(ctx.ReferenceHandler)); - public virtual MethodDeclarationSyntax? BuildMethod(SourceEmitterContext ctx) + public virtual MethodDeclarationSyntax BuildMethod(SourceEmitterContext ctx) { var returnType = FullyQualifiedIdentifier(_returnType); diff --git a/src/Riok.Mapperly/Descriptors/Mappings/NewValueTupleExpressionMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/NewValueTupleExpressionMapping.cs index 850bd15976..10cf306f46 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/NewValueTupleExpressionMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/NewValueTupleExpressionMapping.cs @@ -1,7 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Riok.Mapperly.Descriptors.Mappings.MemberMappings; -using Riok.Mapperly.Emit; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; using static Riok.Mapperly.Emit.SyntaxFactoryHelper; @@ -27,12 +26,6 @@ public NewValueTupleExpressionMapping(ITypeSymbol sourceType, ITypeSymbol target public void AddConstructorParameterMapping(ValueTupleConstructorParameterMapping mapping) => _constructorPropertyMappings.Add(mapping); - public override MethodDeclarationSyntax? BuildMethod(SourceEmitterContext ctx) - { - // generate method body if complex mapping otherwise return null - return HasMemberMappings() ? base.BuildMethod(ctx) : null; - } - public override ExpressionSyntax Build(TypeMappingBuildContext ctx) { // generate error if constructor argument don't match @@ -41,15 +34,7 @@ public override ExpressionSyntax Build(TypeMappingBuildContext ctx) return ThrowNotImplementedException().WithLeadingTrivia(TriviaList(Comment(NoMappingComment))); } - // generate method call if it's a complex mapping - if (HasMemberMappings()) - { - return base.Build(ctx); - } - - // (Name:.. ,..); - var ctorArgs = _constructorPropertyMappings.Select(x => x.BuildArgument(ctx, emitFieldName: true)); - return TupleExpression(SeparatedList(ctorArgs)); + return base.Build(ctx); } public override IEnumerable BuildBody(TypeMappingBuildContext ctx) @@ -65,21 +50,12 @@ public override IEnumerable BuildBody(TypeMappingBuildContext c var ctorArgs = _constructorPropertyMappings.Select(x => x.BuildArgument(ctx, emitFieldName: true)); var tupleCreationExpression = TupleExpression(SeparatedList(ctorArgs)); - // return (Name:.. ,..); if not a complex mapping - if (!HasMemberMappings()) - { - yield return ReturnStatement(tupleCreationExpression); - yield break; - } - - // generate // var target = (Name:.. ,..); - // target.Name.Child = ... - // return target var targetVariableName = ctx.NameBuilder.New(TargetVariableName); yield return DeclareLocalVariable(targetVariableName, tupleCreationExpression); // map properties + // target.Name.Child = ... foreach (var expression in BuildBody(ctx, IdentifierName(targetVariableName))) { yield return expression; diff --git a/src/Riok.Mapperly/Descriptors/Mappings/ObjectMemberMethodMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/ObjectMemberMethodMapping.cs index 839ba53d0f..0d5c4510e2 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/ObjectMemberMethodMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/ObjectMemberMethodMapping.cs @@ -19,8 +19,6 @@ protected ObjectMemberMethodMapping(ITypeSymbol sourceType, ITypeSymbol targetTy _mapping = new ObjectMemberExistingTargetMapping(sourceType, targetType); } - public bool HasMemberMappings() => _mapping.HasMemberMappings(); - public bool HasMemberMapping(IMemberAssignmentMapping mapping) => _mapping.HasMemberMapping(mapping); public void AddMemberMapping(IMemberAssignmentMapping mapping) => _mapping.AddMemberMapping(mapping); diff --git a/src/Riok.Mapperly/Descriptors/Mappings/UserMappings/UserDefinedNewInstanceGenericTypeMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/UserMappings/UserDefinedNewInstanceGenericTypeMapping.cs index d7833cb0a8..dc5d36098e 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/UserMappings/UserDefinedNewInstanceGenericTypeMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/UserMappings/UserDefinedNewInstanceGenericTypeMapping.cs @@ -30,8 +30,8 @@ ITypeSymbol objectType public GenericMappingTypeParameters TypeParameters { get; } - public override MethodDeclarationSyntax? BuildMethod(SourceEmitterContext ctx) => - base.BuildMethod(ctx)?.WithTypeParameterList(TypeParameterList(TypeParameters.SourceType, TypeParameters.TargetType)); + public override MethodDeclarationSyntax BuildMethod(SourceEmitterContext ctx) => + base.BuildMethod(ctx).WithTypeParameterList(TypeParameterList(TypeParameters.SourceType, TypeParameters.TargetType)); protected override ExpressionSyntax BuildTargetType() { diff --git a/src/Riok.Mapperly/Emit/SourceEmitter.cs b/src/Riok.Mapperly/Emit/SourceEmitter.cs index ee3bafb6ee..cba4250715 100644 --- a/src/Riok.Mapperly/Emit/SourceEmitter.cs +++ b/src/Riok.Mapperly/Emit/SourceEmitter.cs @@ -1,7 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Riok.Mapperly.Descriptors; -using Riok.Mapperly.Helpers; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; using static Riok.Mapperly.Emit.SyntaxFactoryHelper; @@ -24,7 +23,7 @@ public static CompilationUnitSyntax Build(MapperDescriptor descriptor) private static IEnumerable BuildMembers(MapperDescriptor descriptor, SourceEmitterContext sourceEmitterContext) { - return descriptor.MethodTypeMappings.Select(mapping => mapping.BuildMethod(sourceEmitterContext)).WhereNotNull(); + return descriptor.MethodTypeMappings.Select(mapping => mapping.BuildMethod(sourceEmitterContext)); } private static MemberDeclarationSyntax WrapInClassesAsNeeded(INamedTypeSymbol symbol, MemberDeclarationSyntax syntax) diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs index 89d6ee9a40..5d8fccb952 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/NET_48/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs @@ -35,7 +35,7 @@ public static partial class DeepCloningMapper if (src.TupleValue != null) { - target.TupleValue = (A: src.TupleValue.Value.A, src.TupleValue.Value.Item2); + target.TupleValue = MapToValueTuple(src.TupleValue.Value); } if (src.RecursiveObject != null) @@ -111,6 +111,12 @@ public static partial class DeepCloningMapper return target; } + private static (string A, string) MapToValueTuple((string A, string) source) + { + var target = (A: source.A, source.Item2); + return target; + } + private static global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject MapToInheritanceSubObject(global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject(); @@ -119,4 +125,4 @@ public static partial class DeepCloningMapper return target; } } -} +} \ No newline at end of file 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 7ea17191c5..de959e970b 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 @@ -80,7 +80,7 @@ public partial int ParseableInt(string value) if (testObject.TupleValue != null) { - target.TupleValue = (A: ParseableInt(testObject.TupleValue.Value.A), ParseableInt(testObject.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(testObject.TupleValue.Value); } if (testObject.RecursiveObject != null) @@ -164,7 +164,7 @@ public partial int ParseableInt(string value) if (dto.TupleValue != null) { - target.TupleValue = (A: dto.TupleValue.Value.A.ToString(), dto.TupleValue.Value.Item2.ToString()); + target.TupleValue = MapToValueTuple1(dto.TupleValue.Value); } if (dto.RecursiveObject != null) @@ -255,7 +255,7 @@ public partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Models.Test if (source.TupleValue != null) { - target.TupleValue = (A: ParseableInt(source.TupleValue.Value.A), ParseableInt(source.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(source.TupleValue.Value); } if (source.RecursiveObject != null) @@ -342,6 +342,12 @@ private partial int PrivateDirectInt(int value) return target; } + private (int A, int) MapToValueTuple((string A, string) source) + { + var target = (A: ParseableInt(source.A), ParseableInt(source.Item2)); + return target; + } + private int[] MapToInt32Array(global::System.Span source) { var target = new int[source.Length]; @@ -401,6 +407,12 @@ private string MapToString(global::Riok.Mapperly.IntegrationTests.Models.TestEnu return target; } + private (string A, string) MapToValueTuple1((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2.ToString()); + return target; + } + private global::System.Collections.Generic.IReadOnlyCollection MapToIReadOnlyCollection(global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto[] source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.TestObjectNested[source.Length]; @@ -453,4 +465,4 @@ private string MapToString1(global::Riok.Mapperly.IntegrationTests.Dto.TestEnumD return target; } } -} +} \ No newline at end of file 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 9af3f7e867..7a45e0aea0 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 @@ -79,7 +79,7 @@ public static partial int ParseableInt(string value) if (src.TupleValue != null) { - target.TupleValue = (A: ParseableInt(src.TupleValue.Value.A), ParseableInt(src.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(src.TupleValue.Value); } if (src.RecursiveObject != null) @@ -178,7 +178,7 @@ public static partial int ParseableInt(string value) if (testObject.TupleValue != null) { - target.TupleValue = (A: ParseableInt(testObject.TupleValue.Value.A), ParseableInt(testObject.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(testObject.TupleValue.Value); } if (testObject.RecursiveObject != null) @@ -262,7 +262,7 @@ public static partial int ParseableInt(string value) if (dto.TupleValue != null) { - target.TupleValue = (A: dto.TupleValue.Value.A.ToString(), dto.TupleValue.Value.Item2.ToString()); + target.TupleValue = MapToValueTuple1(dto.TupleValue.Value); } if (dto.RecursiveObject != null) @@ -353,7 +353,7 @@ public static partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Mode if (source.TupleValue != null) { - target.TupleValue = (A: ParseableInt(source.TupleValue.Value.A), ParseableInt(source.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(source.TupleValue.Value); } if (source.RecursiveObject != null) @@ -579,6 +579,12 @@ object x when typeof(TTarget).IsAssignableFrom(typeof(object)) => (TTarget)(obje return target; } + private static (int A, int) MapToValueTuple((string A, string) source) + { + var target = (A: ParseableInt(source.A), ParseableInt(source.Item2)); + return target; + } + private static int[] MapToInt32Array(global::System.Span source) { var target = new int[source.Length]; @@ -638,6 +644,12 @@ private static string MapToString(global::Riok.Mapperly.IntegrationTests.Models. return target; } + private static (string A, string) MapToValueTuple1((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2.ToString()); + return target; + } + private static global::System.Collections.Generic.IReadOnlyCollection MapToIReadOnlyCollection(global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto[] source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.TestObjectNested[source.Length]; @@ -690,4 +702,4 @@ private static string MapToString1(global::Riok.Mapperly.IntegrationTests.Dto.Te return target; } } -} +} \ No newline at end of file diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs index eb9b754ab8..31702ce6af 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs @@ -32,7 +32,7 @@ public static partial class DeepCloningMapper if (src.TupleValue != null) { - target.TupleValue = (A: src.TupleValue.Value.A, src.TupleValue.Value.Item2); + target.TupleValue = MapToValueTuple(src.TupleValue.Value); } if (src.RecursiveObject != null) @@ -110,6 +110,12 @@ public static partial class DeepCloningMapper return target; } + private static (string A, string) MapToValueTuple((string A, string) source) + { + var target = (A: source.A, source.Item2); + return target; + } + private static global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject MapToInheritanceSubObject(global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject(); @@ -118,4 +124,4 @@ public static partial class DeepCloningMapper return target; } } -} +} \ No newline at end of file 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 9d9c49970a..898cd5d1cd 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 @@ -77,7 +77,7 @@ public partial int ParseableInt(string value) if (testObject.TupleValue != null) { - target.TupleValue = (A: ParseableInt(testObject.TupleValue.Value.A), ParseableInt(testObject.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(testObject.TupleValue.Value); } if (testObject.RecursiveObject != null) @@ -160,7 +160,7 @@ public partial int ParseableInt(string value) if (dto.TupleValue != null) { - target.TupleValue = (A: dto.TupleValue.Value.A.ToString(), dto.TupleValue.Value.Item2.ToString()); + target.TupleValue = MapToValueTuple1(dto.TupleValue.Value); } if (dto.RecursiveObject != null) @@ -253,7 +253,7 @@ public partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Models.Test if (source.TupleValue != null) { - target.TupleValue = (A: ParseableInt(source.TupleValue.Value.A), ParseableInt(source.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(source.TupleValue.Value); } if (source.RecursiveObject != null) @@ -342,6 +342,12 @@ private partial int PrivateDirectInt(int value) return target; } + private (int A, int) MapToValueTuple((string A, string) source) + { + var target = (A: ParseableInt(source.A), ParseableInt(source.Item2)); + return target; + } + private int[] MapToInt32Array(global::System.Span source) { var target = new int[source.Length]; @@ -401,6 +407,12 @@ private string MapToString(global::Riok.Mapperly.IntegrationTests.Models.TestEnu return target; } + private (string A, string) MapToValueTuple1((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2.ToString()); + return target; + } + private global::System.Collections.Generic.IReadOnlyCollection MapToIReadOnlyCollection(global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto[] source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.TestObjectNested[source.Length]; @@ -453,4 +465,4 @@ private string MapToString1(global::Riok.Mapperly.IntegrationTests.Dto.TestEnumD return target; } } -} +} \ No newline at end of file diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/ProjectionMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/ProjectionMapperTest.SnapshotGeneratedSource.verified.cs index 256d988549..123c744fc2 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/ProjectionMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_4_OR_LOWER/ProjectionMapperTest.SnapshotGeneratedSource.verified.cs @@ -7,21 +7,14 @@ public static partial class ProjectionMapper public static partial global::System.Linq.IQueryable ProjectToDto(this global::System.Linq.IQueryable q) { #nullable disable - return System.Linq.Queryable.Select(q, x => new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjection(x.CtorValue) - {IntValue = x.IntValue, IntInitOnlyValue = x.IntInitOnlyValue, RequiredValue = x.RequiredValue, StringValue = x.StringValue, RenamedStringValue2 = x.RenamedStringValue, FlatteningIdValue = x.Flattening.IdValue, NullableFlatteningIdValue = x.NullableFlattening != null ? x.NullableFlattening.IdValue : default, NestedNullableIntValue = x.NestedNullable != null ? x.NestedNullable.IntValue : default, NestedNullable = x.NestedNullable != null ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto() - {IntValue = x.NestedNullable.IntValue} : default, NestedNullableTargetNotNullable = x.NestedNullableTargetNotNullable != null ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto() - {IntValue = x.NestedNullableTargetNotNullable.IntValue} : new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto(), StringNullableTargetNotNullable = x.StringNullableTargetNotNullable ?? "", SourceTargetSameObjectType = x.SourceTargetSameObjectType, NullableReadOnlyObjectCollection = x.NullableReadOnlyObjectCollection != null ? global::System.Linq.Enumerable.ToArray(global::System.Linq.Enumerable.Select(x.NullableReadOnlyObjectCollection, x1 => new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto() - {IntValue = x1.IntValue})) : default, EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)x.EnumValue, EnumName = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByName)x.EnumName, EnumRawValue = (byte)x.EnumRawValue, EnumStringValue = (string)x.EnumStringValue.ToString(), EnumReverseStringValue = System.Enum.Parse(x.EnumReverseStringValue, false), SubObject = x.SubObject != null ? new global::Riok.Mapperly.IntegrationTests.Dto.InheritanceSubObjectDto() - {SubIntValue = x.SubObject.SubIntValue, BaseIntValue = x.SubObject.BaseIntValue} : default, DateTimeValueTargetDateOnly = global::System.DateOnly.FromDateTime(x.DateTimeValueTargetDateOnly), DateTimeValueTargetTimeOnly = global::System.TimeOnly.FromDateTime(x.DateTimeValueTargetTimeOnly), ManuallyMapped = MapManual(x.ManuallyMapped)}); + return System.Linq.Queryable.Select(q, x => new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjection(x.CtorValue) { IntValue = x.IntValue, IntInitOnlyValue = x.IntInitOnlyValue, RequiredValue = x.RequiredValue, StringValue = x.StringValue, RenamedStringValue2 = x.RenamedStringValue, FlatteningIdValue = x.Flattening.IdValue, NullableFlatteningIdValue = x.NullableFlattening != null ? x.NullableFlattening.IdValue : default, NestedNullableIntValue = x.NestedNullable != null ? x.NestedNullable.IntValue : default, NestedNullable = x.NestedNullable != null ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto() { IntValue = x.NestedNullable.IntValue } : default, NestedNullableTargetNotNullable = x.NestedNullableTargetNotNullable != null ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto() { IntValue = x.NestedNullableTargetNotNullable.IntValue } : new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto(), StringNullableTargetNotNullable = x.StringNullableTargetNotNullable ?? "", SourceTargetSameObjectType = x.SourceTargetSameObjectType, NullableReadOnlyObjectCollection = x.NullableReadOnlyObjectCollection != null ? global::System.Linq.Enumerable.ToArray(global::System.Linq.Enumerable.Select(x.NullableReadOnlyObjectCollection, x1 => new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto() { IntValue = x1.IntValue })) : default, EnumValue = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByValue)x.EnumValue, EnumName = (global::Riok.Mapperly.IntegrationTests.Dto.TestEnumDtoByName)x.EnumName, EnumRawValue = (byte)x.EnumRawValue, EnumStringValue = (string)x.EnumStringValue.ToString(), EnumReverseStringValue = System.Enum.Parse(x.EnumReverseStringValue, false), SubObject = x.SubObject != null ? new global::Riok.Mapperly.IntegrationTests.Dto.InheritanceSubObjectDto() { SubIntValue = x.SubObject.SubIntValue, BaseIntValue = x.SubObject.BaseIntValue } : default, DateTimeValueTargetDateOnly = global::System.DateOnly.FromDateTime(x.DateTimeValueTargetDateOnly), DateTimeValueTargetTimeOnly = global::System.TimeOnly.FromDateTime(x.DateTimeValueTargetTimeOnly), ManuallyMapped = MapManual(x.ManuallyMapped) }); #nullable enable } public static partial global::System.Linq.IQueryable ProjectToDto(this global::System.Linq.IQueryable q) { #nullable disable - return System.Linq.Queryable.Select(q, x => (global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjectionBaseType)(x is global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjectionTypeA() - {ValueA = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA)x).ValueA, Id = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA)x).Id, BaseValue = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA)x).BaseValue} : x is global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjectionTypeB() - {ValueB = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB)x).ValueB, Id = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB)x).Id, BaseValue = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB)x).BaseValue} : default)); + return System.Linq.Queryable.Select(q, x => (global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjectionBaseType)(x is global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjectionTypeA() { ValueA = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA)x).ValueA, Id = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA)x).Id, BaseValue = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeA)x).BaseValue } : x is global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB ? new global::Riok.Mapperly.IntegrationTests.Dto.TestObjectDtoProjectionTypeB() { ValueB = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB)x).ValueB, Id = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB)x).Id, BaseValue = ((global::Riok.Mapperly.IntegrationTests.Models.TestObjectProjectionTypeB)x).BaseValue } : default)); #nullable enable } @@ -137,4 +130,4 @@ private static string MapToString(global::Riok.Mapperly.IntegrationTests.Models. return target; } } -} +} \ No newline at end of file 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 e77ec8de5d..2c55eef8a3 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 @@ -76,7 +76,7 @@ public static partial int ParseableInt(string value) if (src.TupleValue != null) { - target.TupleValue = (A: ParseableInt(src.TupleValue.Value.A), ParseableInt(src.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(src.TupleValue.Value); } if (src.RecursiveObject != null) @@ -174,7 +174,7 @@ public static partial int ParseableInt(string value) if (testObject.TupleValue != null) { - target.TupleValue = (A: ParseableInt(testObject.TupleValue.Value.A), ParseableInt(testObject.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(testObject.TupleValue.Value); } if (testObject.RecursiveObject != null) @@ -257,7 +257,7 @@ public static partial int ParseableInt(string value) if (dto.TupleValue != null) { - target.TupleValue = (A: dto.TupleValue.Value.A.ToString(), dto.TupleValue.Value.Item2.ToString()); + target.TupleValue = MapToValueTuple1(dto.TupleValue.Value); } if (dto.RecursiveObject != null) @@ -350,7 +350,7 @@ public static partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Mode if (source.TupleValue != null) { - target.TupleValue = (A: ParseableInt(source.TupleValue.Value.A), ParseableInt(source.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(source.TupleValue.Value); } if (source.RecursiveObject != null) @@ -578,6 +578,12 @@ object x when typeof(TTarget).IsAssignableFrom(typeof(object)) => (TTarget)(obje return target; } + private static (int A, int) MapToValueTuple((string A, string) source) + { + var target = (A: ParseableInt(source.A), ParseableInt(source.Item2)); + return target; + } + private static int[] MapToInt32Array(global::System.Span source) { var target = new int[source.Length]; @@ -637,6 +643,12 @@ private static string MapToString(global::Riok.Mapperly.IntegrationTests.Models. return target; } + private static (string A, string) MapToValueTuple1((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2.ToString()); + return target; + } + private static global::System.Collections.Generic.IReadOnlyCollection MapToIReadOnlyCollection(global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto[] source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.TestObjectNested[source.Length]; @@ -689,4 +701,4 @@ private static string MapToString1(global::Riok.Mapperly.IntegrationTests.Dto.Te return target; } } -} +} \ No newline at end of file diff --git a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs index a6c9b1f7c0..e01ee96c3f 100644 --- a/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs +++ b/test/Riok.Mapperly.IntegrationTests/_snapshots/Roslyn_4_5/DeepCloningMapperTest.SnapshotGeneratedSource.verified.cs @@ -35,7 +35,7 @@ public static partial class DeepCloningMapper if (src.TupleValue != null) { - target.TupleValue = (A: src.TupleValue.Value.A, src.TupleValue.Value.Item2); + target.TupleValue = MapToValueTuple(src.TupleValue.Value); } if (src.RecursiveObject != null) @@ -113,6 +113,12 @@ public static partial class DeepCloningMapper return target; } + private static (string A, string) MapToValueTuple((string A, string) source) + { + var target = (A: source.A, source.Item2); + return target; + } + private static global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject MapToInheritanceSubObject(global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.InheritanceSubObject(); @@ -121,4 +127,4 @@ public static partial class DeepCloningMapper return target; } } -} +} \ No newline at end of file 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 5e2b66e277..4bee504932 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 @@ -80,7 +80,7 @@ public partial int ParseableInt(string value) if (testObject.TupleValue != null) { - target.TupleValue = (A: ParseableInt(testObject.TupleValue.Value.A), ParseableInt(testObject.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(testObject.TupleValue.Value); } if (testObject.RecursiveObject != null) @@ -166,7 +166,7 @@ public partial int ParseableInt(string value) if (dto.TupleValue != null) { - target.TupleValue = (A: dto.TupleValue.Value.A.ToString(), dto.TupleValue.Value.Item2.ToString()); + target.TupleValue = MapToValueTuple1(dto.TupleValue.Value); } if (dto.RecursiveObject != null) @@ -259,7 +259,7 @@ public partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Models.Test if (source.TupleValue != null) { - target.TupleValue = (A: ParseableInt(source.TupleValue.Value.A), ParseableInt(source.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(source.TupleValue.Value); } if (source.RecursiveObject != null) @@ -348,6 +348,12 @@ private partial int PrivateDirectInt(int value) return target; } + private (int A, int) MapToValueTuple((string A, string) source) + { + var target = (A: ParseableInt(source.A), ParseableInt(source.Item2)); + return target; + } + private int[] MapToInt32Array(global::System.Span source) { var target = new int[source.Length]; @@ -407,6 +413,12 @@ private string MapToString(global::Riok.Mapperly.IntegrationTests.Models.TestEnu return target; } + private (string A, string) MapToValueTuple1((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2.ToString()); + return target; + } + private global::System.Collections.Generic.IReadOnlyCollection MapToIReadOnlyCollection(global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto[] source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.TestObjectNested[source.Length]; 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 c79d3b0e7c..6298c6bbac 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 @@ -79,7 +79,7 @@ public static partial int ParseableInt(string value) if (src.TupleValue != null) { - target.TupleValue = (A: ParseableInt(src.TupleValue.Value.A), ParseableInt(src.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(src.TupleValue.Value); } if (src.RecursiveObject != null) @@ -180,7 +180,7 @@ public static partial int ParseableInt(string value) if (testObject.TupleValue != null) { - target.TupleValue = (A: ParseableInt(testObject.TupleValue.Value.A), ParseableInt(testObject.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(testObject.TupleValue.Value); } if (testObject.RecursiveObject != null) @@ -266,7 +266,7 @@ public static partial int ParseableInt(string value) if (dto.TupleValue != null) { - target.TupleValue = (A: dto.TupleValue.Value.A.ToString(), dto.TupleValue.Value.Item2.ToString()); + target.TupleValue = MapToValueTuple1(dto.TupleValue.Value); } if (dto.RecursiveObject != null) @@ -359,7 +359,7 @@ public static partial void UpdateDto(global::Riok.Mapperly.IntegrationTests.Mode if (source.TupleValue != null) { - target.TupleValue = (A: ParseableInt(source.TupleValue.Value.A), ParseableInt(source.TupleValue.Value.Item2)); + target.TupleValue = MapToValueTuple(source.TupleValue.Value); } if (source.RecursiveObject != null) @@ -587,6 +587,12 @@ object x when typeof(TTarget).IsAssignableFrom(typeof(object)) => (TTarget)(obje return target; } + private static (int A, int) MapToValueTuple((string A, string) source) + { + var target = (A: ParseableInt(source.A), ParseableInt(source.Item2)); + return target; + } + private static int[] MapToInt32Array(global::System.Span source) { var target = new int[source.Length]; @@ -646,6 +652,12 @@ private static string MapToString(global::Riok.Mapperly.IntegrationTests.Models. return target; } + private static (string A, string) MapToValueTuple1((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2.ToString()); + return target; + } + private static global::System.Collections.Generic.IReadOnlyCollection MapToIReadOnlyCollection(global::Riok.Mapperly.IntegrationTests.Dto.TestObjectNestedDto[] source) { var target = new global::Riok.Mapperly.IntegrationTests.Models.TestObjectNested[source.Length]; @@ -698,4 +710,4 @@ private static string MapToString1(global::Riok.Mapperly.IntegrationTests.Dto.Te return target; } } -} +} \ No newline at end of file diff --git a/test/Riok.Mapperly.Tests/Mapping/ValueTupleTest.cs b/test/Riok.Mapperly.Tests/Mapping/ValueTupleTest.cs index db888bbd63..c3f0122e50 100644 --- a/test/Riok.Mapperly.Tests/Mapping/ValueTupleTest.cs +++ b/test/Riok.Mapperly.Tests/Mapping/ValueTupleTest.cs @@ -19,7 +19,15 @@ public void TupleToTupleWithDeepCloning() { var source = TestSourceBuilder.Mapping("(int, string)", "(int, string)", TestSourceBuilderOptions.WithDeepCloning); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (source.Item1, source.Item2);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (source.Item1, source.Item2); + return target; + """ + ); } [Fact] @@ -27,7 +35,15 @@ public void TupleToDifferentTypeTuple() { var source = TestSourceBuilder.Mapping("(int, string)", "(long, int)"); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return ((long)source.Item1, int.Parse(source.Item2));"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = ((long)source.Item1, int.Parse(source.Item2)); + return target; + """ + ); } [Fact] @@ -35,7 +51,15 @@ public void NamedTupleToTuple() { var source = TestSourceBuilder.Mapping("(int A, string B)", "(int, string)"); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (source.A, source.B);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (source.A, source.B); + return target; + """ + ); } [Fact] @@ -43,7 +67,15 @@ public void TupleToNamedTuple() { var source = TestSourceBuilder.Mapping("(int, string)", "(int A, string B)"); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (A: source.Item1, B: source.Item2);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (A: source.Item1, B: source.Item2); + return target; + """ + ); } [Fact] @@ -59,7 +91,15 @@ public void NamedTupleToNamedTupleWithDeepCloning() { var source = TestSourceBuilder.Mapping("(int A, string B)", "(int A, string B)", TestSourceBuilderOptions.WithDeepCloning); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (A: source.A, B: source.B);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (A: source.A, B: source.B); + return target; + """ + ); } [Fact] @@ -67,7 +107,15 @@ public void NamedTupleToNamedTupleWithPositionalResolve() { var source = TestSourceBuilder.Mapping("(int A, string B)", "(int C, string D)", TestSourceBuilderOptions.WithDeepCloning); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (C: source.A, D: source.B);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (C: source.A, D: source.B); + return target; + """ + ); } [Fact] @@ -79,7 +127,12 @@ public void PartiallyNamedTupleToPartiallyNamedTuple() .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) .Should() .HaveDiagnostic(DiagnosticDescriptors.SourceMemberNotMapped) - .HaveSingleMethodBody("return (A: int.Parse(source.A), source.A);"); + .HaveSingleMethodBody( + """ + var target = (A: int.Parse(source.A), source.A); + return target; + """ + ); } [Fact] @@ -90,7 +143,12 @@ public void TupleToTupleNamedItems() TestHelper .GenerateMapper(source) .Should() - .HaveSingleMethodBody("return (Item2: int.Parse(source.Item2), Item1: source.Item1.ToString());"); + .HaveSingleMethodBody( + """ + var target = (Item2: int.Parse(source.Item2), Item1: source.Item1.ToString()); + return target; + """ + ); } [Fact] @@ -98,7 +156,15 @@ public void TupleNamedItemsToTuple() { var source = TestSourceBuilder.Mapping("(int Item2, string Item1)", "(int, string)"); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (int.Parse(source.Item1), source.Item2.ToString());"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (int.Parse(source.Item1), source.Item2.ToString()); + return target; + """ + ); } [Fact] @@ -154,7 +220,15 @@ public void ClassToTuple() "public class A { public int B { get;set;} public int C {get;set;} }" ); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (B: source.B, C: source.C.ToString());"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (B: source.B, C: source.C.ToString()); + return target; + """ + ); } [Fact] @@ -167,7 +241,15 @@ public void TupleToTupleWithIgnoredSource() """ ); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (source.A, source.B);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (source.A, source.B); + return target; + """ + ); } [Fact] @@ -180,7 +262,15 @@ public void TupleToTupleWithIgnoredSourceByPosition() """ ); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (source.A, source.B);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (source.A, source.B); + return target; + """ + ); } [Fact] @@ -194,7 +284,15 @@ public void ClassToTupleWithIgnoredSource() "public class B { public int Item1 { get;set;} public int A {get;set;} public int Item2 {get;set;} }" ); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (source.Item1, source.Item2);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (source.Item1, source.Item2); + return target; + """ + ); } [Fact] @@ -211,7 +309,12 @@ public void IgnoredNamedSourceWithPositionalShouldDiagnostic() .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) .Should() .HaveDiagnostic(DiagnosticDescriptors.IgnoredSourceMemberNotFound) - .HaveSingleMethodBody("return (source.A, source.B);"); + .HaveSingleMethodBody( + """ + var target = (source.A, source.B); + return target; + """ + ); } [Fact] @@ -228,7 +331,12 @@ public void TupleWithNonExistentIgnoreSourceShouldDiagnostic() .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) .Should() .HaveDiagnostic(DiagnosticDescriptors.IgnoredSourceMemberNotFound) - .HaveSingleMethodBody("return (source.A, source.B);"); + .HaveSingleMethodBody( + """ + var target = (source.A, source.B); + return target; + """ + ); } [Fact] @@ -316,7 +424,12 @@ public void IgnoreTargetWithNonExistentTargetShouldDiagnostic() .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) .Should() .HaveDiagnostic(DiagnosticDescriptors.IgnoredTargetMemberNotFound) - .HaveSingleMethodBody("return (int.Parse(source.Item1), A: source.Item2);"); + .HaveSingleMethodBody( + """ + var target = (int.Parse(source.Item1), A: source.Item2); + return target; + """ + ); } [Fact] @@ -333,7 +446,12 @@ public void IgnoreTargetWithNonExistentPositionalShouldDiagnostic() .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) .Should() .HaveDiagnostic(DiagnosticDescriptors.IgnoredTargetMemberNotFound) - .HaveSingleMethodBody("return (int.Parse(source.Item1), A: source.Item2);"); + .HaveSingleMethodBody( + """ + var target = (int.Parse(source.Item1), A: source.Item2); + return target; + """ + ); } [Fact] @@ -351,7 +469,12 @@ public void TupleToTupleWithMapProperty() .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) .Should() .HaveDiagnostic(DiagnosticDescriptors.SourceMemberNotMapped) - .HaveSingleMethodBody("return (A: source.C, source.Item3);"); + .HaveSingleMethodBody( + """ + var target = (A: source.C, source.Item3); + return target; + """ + ); } [Fact] @@ -429,7 +552,15 @@ public void TupleToValueTuple() { var source = TestSourceBuilder.Mapping("(int A, string B)", "ValueTuple"); - TestHelper.GenerateMapper(source).Should().HaveSingleMethodBody("return (source.A, source.B);"); + TestHelper + .GenerateMapper(source) + .Should() + .HaveSingleMethodBody( + """ + var target = (source.A, source.B); + return target; + """ + ); } [Fact] @@ -502,6 +633,19 @@ public void TupleToTupleWithMapPropertyWithImplicitNameShouldDiagnostic() .HaveDiagnostic(DiagnosticDescriptors.ConfiguredMappingTargetMemberNotFound); } + [Fact] + public Task SimilarTupleMappingShouldCreateSeparateMethods() + { + var source = TestSourceBuilder.MapperWithBody( + """ + partial (string A, string B) Map((int, int) src); + partial (string A, string B) Map((int B, int A) src); + """ + ); + + return TestHelper.VerifyGenerator(source); + } + [Fact] public void TupleMappingDisabledShouldDiagnostic() { diff --git a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapFieldAndNestedTuple#Mapper.g.verified.cs b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapFieldAndNestedTuple#Mapper.g.verified.cs index 9b8a655b42..2bd10c69eb 100644 --- a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapFieldAndNestedTuple#Mapper.g.verified.cs +++ b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapFieldAndNestedTuple#Mapper.g.verified.cs @@ -5,8 +5,14 @@ public partial class Mapper { private partial (string E, (long G, int H) F) Map(((int B, int C) A, string D) source) { - var target = (E: source.D, F: (G: (long)source.A.B, H: source.A.C)); + var target = (E: source.D, F: MapToValueTuple(source.A)); target.F.H = int.Parse(source.D); return target; } -} \ No newline at end of file + + private (long G, int H) MapToValueTuple((int B, int C) source) + { + var target = (G: (long)source.B, H: source.C); + return target; + } +} diff --git a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapNamedNestedTuple#Mapper.g.verified.cs b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapNamedNestedTuple#Mapper.g.verified.cs index 5f8f2d3e76..1e534ad529 100644 --- a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapNamedNestedTuple#Mapper.g.verified.cs +++ b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.MapPropertyShouldMapNamedNestedTuple#Mapper.g.verified.cs @@ -5,8 +5,14 @@ public partial class Mapper { private partial ((int, int D) C, int) Map(((int F, int G), string B) source) { - var target = (C: (source.Item1.F, D: source.Item1.G), int.Parse(source.B)); + var target = (C: MapToValueTuple(source.Item1), int.Parse(source.B)); target.C.D = int.Parse(source.B); return target; } + + private (int, int D) MapToValueTuple((int F, int G) source) + { + var target = (source.F, D: source.G); + return target; + } } diff --git a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.SimilarTupleMappingShouldCreateSeparateMethods#Mapper.g.verified.cs b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.SimilarTupleMappingShouldCreateSeparateMethods#Mapper.g.verified.cs new file mode 100644 index 0000000000..3af7edbdc3 --- /dev/null +++ b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.SimilarTupleMappingShouldCreateSeparateMethods#Mapper.g.verified.cs @@ -0,0 +1,17 @@ +//HintName: Mapper.g.cs +// +#nullable enable +public partial class Mapper +{ + private partial (string A, string B) Map((int, int) src) + { + var target = (A: src.Item1.ToString(), B: src.Item2.ToString()); + return target; + } + + private partial (string A, string B) Map((int B, int A) src) + { + var target = (A: src.A.ToString(), B: src.B.ToString()); + return target; + } +} diff --git a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.TuplePropertyToTupleProperty#Mapper.g.verified.cs b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.TuplePropertyToTupleProperty#Mapper.g.verified.cs index c791967bf4..0c6a2fb5c6 100644 --- a/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.TuplePropertyToTupleProperty#Mapper.g.verified.cs +++ b/test/Riok.Mapperly.Tests/_snapshots/ValueTupleTest.TuplePropertyToTupleProperty#Mapper.g.verified.cs @@ -6,7 +6,13 @@ public partial class Mapper private partial global::B Map(global::A source) { var target = new global::B(); - target.Value = (A: source.Value.A.ToString(), source.Value.Item2); + target.Value = MapToValueTuple(source.Value); return target; } -} \ No newline at end of file + + private (string A, int) MapToValueTuple((int A, int) source) + { + var target = (A: source.A.ToString(), source.Item2); + return target; + } +}