diff --git a/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs b/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs index 615eca1074..d3022b3d07 100644 --- a/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs +++ b/src/Riok.Mapperly/Descriptors/MappingBuilders/EnumerableMappingBuilder.cs @@ -40,8 +40,8 @@ public static class EnumerableMappingBuilder if (elementMapping == null) return null; - if (TryBuildCastMapping(ctx, elementMapping) is { } implicitMapping) - return implicitMapping; + if (TryBuildCastMapping(ctx, elementMapping) is { } castMapping) + return castMapping; if (TryBuildFastConversion(ctx, elementMapping) is { } fastLoopMapping) return fastLoopMapping; @@ -149,7 +149,9 @@ ForEachAddEnumerableExistingTargetMapping CreateForEach(string methodName) || !ctx.CollectionInfos!.Source.CountIsKnown || ctx.CollectionInfos.Target.CollectionType == CollectionType.None ) + { return null; + } // if target is a list or type implemented by list if (ctx.CollectionInfos.Target.CollectionType is CollectionType.List or CollectionType.ICollection or CollectionType.IList) @@ -185,15 +187,15 @@ or CollectionType.IEnumerable return null; // upgrade nullability of element type - var targetValue = ((INamedTypeSymbol)ctx.CollectionInfos!.Target.Type.OriginalDefinition).Construct(elementMapping.TargetType); - var targetCollection = ctx.Types.Get(typeof(List<>)).Construct(elementMapping.TargetType); + var targetType = ((INamedTypeSymbol)ctx.CollectionInfos!.Target.Type.OriginalDefinition).Construct(elementMapping.TargetType); + var targetTypeToInstantiate = ctx.Types.Get(typeof(List<>)).Construct(elementMapping.TargetType); return new ForEachAddEnumerableMapping( ctx.Source, - targetValue, + targetType, elementMapping, AddMethodName, - targetCollection, + targetTypeToInstantiate, ctx.CollectionInfos.Source.CountPropertyName ); } @@ -206,11 +208,11 @@ private static NewInstanceMapping BuildArrayToArrayMapping(MappingBuilderContext if (!elementMapping.IsSynthetic) { // upgrade nullability of element type - var targetValue = + var targetType = ctx.CollectionInfos!.Target.CollectionType == CollectionType.Array ? ctx.Types.GetArrayType(elementMapping.TargetType) : ((INamedTypeSymbol)ctx.Target).ConstructedFrom.Construct(elementMapping.TargetType); - return new ArrayForMapping(ctx.Source, targetValue, elementMapping, elementMapping.TargetType); + return new ArrayForMapping(ctx.Source, targetType, elementMapping, elementMapping.TargetType); } return ctx.MapperConfiguration.UseDeepCloning @@ -225,14 +227,14 @@ private static NewInstanceMapping BuildArrayToArrayMapping(MappingBuilderContext return null; // upgrade nullability of element type - var targetValue = + var targetType = ctx.CollectionInfos!.Target.CollectionType == CollectionType.Array ? ctx.Types.GetArrayType(elementMapping.TargetType) : ((INamedTypeSymbol)ctx.Target).ConstructedFrom.Construct(elementMapping.TargetType); return new ArrayForEachMapping( ctx.Source, - targetValue, + targetType, elementMapping, elementMapping.TargetType, ctx.CollectionInfos.Source.CountPropertyName! diff --git a/src/Riok.Mapperly/Descriptors/Mappings/INewInstanceObjectMemberMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/INewInstanceObjectMemberMapping.cs index b57aa6fc8b..26e1e8ef2c 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/INewInstanceObjectMemberMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/INewInstanceObjectMemberMapping.cs @@ -5,7 +5,7 @@ namespace Riok.Mapperly.Descriptors.Mappings; /// /// An object mapping creating the target instance via a new() call. /// -public interface INewInstanceObjectMemberMapping : IMapping +public interface INewInstanceObjectMemberMapping : INewInstanceMapping { void AddConstructorParameterMapping(ConstructorParameterMapping mapping); diff --git a/src/Riok.Mapperly/Descriptors/Mappings/INewValueTupleMapping.cs b/src/Riok.Mapperly/Descriptors/Mappings/INewValueTupleMapping.cs index 95e25e465c..695a5adfba 100644 --- a/src/Riok.Mapperly/Descriptors/Mappings/INewValueTupleMapping.cs +++ b/src/Riok.Mapperly/Descriptors/Mappings/INewValueTupleMapping.cs @@ -5,7 +5,7 @@ namespace Riok.Mapperly.Descriptors.Mappings; /// /// A tuple mapping creating the target instance via a tuple expression (eg. (A: 10, B: 20)). /// -public interface INewValueTupleMapping : IMapping +public interface INewValueTupleMapping : INewInstanceMapping { void AddConstructorParameterMapping(ValueTupleConstructorParameterMapping mapping); } diff --git a/src/Riok.Mapperly/Helpers/CompilationExtensions.cs b/src/Riok.Mapperly/Helpers/CompilationExtensions.cs index 62c3a9becb..e994a07f31 100644 --- a/src/Riok.Mapperly/Helpers/CompilationExtensions.cs +++ b/src/Riok.Mapperly/Helpers/CompilationExtensions.cs @@ -58,7 +58,10 @@ internal static class CompilationExtensions return type; #else + // RS0030 banned api: GetTypesByMetadataName is not supported for Roslyn < 4.4 +#pragma warning disable RS0030 return compilation.GetTypeByMetadataName(fullyQualifiedMetadataName); +#pragma warning restore RS0030 #endif } diff --git a/src/Riok.Mapperly/Helpers/FieldSymbolEqualityComparer.cs b/src/Riok.Mapperly/Helpers/FieldSymbolEqualityComparer.cs index c69ee920b7..dd8d24582a 100644 --- a/src/Riok.Mapperly/Helpers/FieldSymbolEqualityComparer.cs +++ b/src/Riok.Mapperly/Helpers/FieldSymbolEqualityComparer.cs @@ -4,5 +4,5 @@ namespace Riok.Mapperly.Helpers; internal static class FieldSymbolEqualityComparer { - public static IEqualityComparer Default = SymbolEqualityComparer.Default; + public static readonly IEqualityComparer Default = SymbolEqualityComparer.Default; } diff --git a/test/Riok.Mapperly.Tests/Mapping/UserMethodTest.cs b/test/Riok.Mapperly.Tests/Mapping/UserMethodTest.cs index f2fef9e530..b8ffc43b47 100644 --- a/test/Riok.Mapperly.Tests/Mapping/UserMethodTest.cs +++ b/test/Riok.Mapperly.Tests/Mapping/UserMethodTest.cs @@ -15,43 +15,45 @@ public Task WithNamespaceShouldWork() [Fact] public Task InstanceMapperShouldEmitDiagnosticForPartialStaticMethods() { - var source = - @" -using System; -using System.Collections.Generic; -using Riok.Mapperly.Abstractions; - -[Mapper] -public partial class MyMapper -{ - public static object StaticToObject(string s); + var source = TestSourceBuilder.CSharp( + """ + using System; + using System.Collections.Generic; + using Riok.Mapperly.Abstractions; - public partial object InstanceToObject(string s); -} -"; + [Mapper] + public partial class MyMapper + { + public static object StaticToObject(string s); + + public partial object InstanceToObject(string s); + } + """ + ); return TestHelper.VerifyGenerator(source); } [Fact] public Task InstanceMapperShouldSupportUserDefinedStaticMethods() { - var source = - @" -using System; -using System.Collections.Generic; -using Riok.Mapperly.Abstractions; - -[Mapper] -public partial class MyMapper -{ - public static int StaticMapper(int s) => s; + var source = TestSourceBuilder.CSharp( + """ + using System; + using System.Collections.Generic; + using Riok.Mapperly.Abstractions; - public partial B Map(A s); -} + [Mapper] + public partial class MyMapper + { + public static int MapInt(int s) => s; + + public partial B Map(A s); + } -public record A(int Value); -public record B(int Value); -"; + public record A(int Value); + public record B(int Value); + """ + ); return TestHelper.VerifyGenerator(source); } @@ -59,7 +61,10 @@ public record B(int Value); public Task InstanceMapperShouldUseStaticExistingTargetMethod() { var source = TestSourceBuilder.MapperWithBodyAndTypes( - "partial B Map(A s);" + "static void StaticMapper(List src, List dst) { }", + """ + partial B Map(A s);" + static void MapList(List src, List dst) { } + """, "class A { public List Value { get; set; } }", "public class B { public List Value { get; } }" ); diff --git a/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldSupportUserDefinedStaticMethods#MyMapper.g.verified.cs b/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldSupportUserDefinedStaticMethods#MyMapper.g.verified.cs index 37d13cee80..bf2b767370 100644 --- a/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldSupportUserDefinedStaticMethods#MyMapper.g.verified.cs +++ b/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldSupportUserDefinedStaticMethods#MyMapper.g.verified.cs @@ -5,7 +5,7 @@ public partial class MyMapper { public partial global::B Map(global::A s) { - var target = new global::B(StaticMapper(s.Value)); + var target = new global::B(MapInt(s.Value)); return target; } -} \ No newline at end of file +} diff --git a/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldUseStaticExistingTargetMethod#Mapper.g.verified.cs b/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldUseStaticExistingTargetMethod#Mapper.g.verified.cs index 37b82dce36..820b7aec2d 100644 --- a/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldUseStaticExistingTargetMethod#Mapper.g.verified.cs +++ b/test/Riok.Mapperly.Tests/_snapshots/UserMethodTest.InstanceMapperShouldUseStaticExistingTargetMethod#Mapper.g.verified.cs @@ -6,7 +6,7 @@ public partial class Mapper private partial global::B Map(global::A s) { var target = new global::B(); - StaticMapper(s.Value, target.Value); + MapList(s.Value, target.Value); return target; } -} \ No newline at end of file +}