Skip to content

Commit

Permalink
feat: support MapProperty with nameof for CtorMapping
Browse files Browse the repository at this point in the history
  • Loading branch information
trejjam committed Nov 28, 2023
1 parent 825a853 commit 4451261
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 9 deletions.
Expand Up @@ -13,4 +13,6 @@ public interface INewInstanceBuilderContext<out T> : IMembersBuilderContext<T>
void AddConstructorParameterMapping(ConstructorParameterMapping mapping);

void AddInitMemberMapping(MemberAssignmentMapping mapping);

Dictionary<string, string> MemberConfigsByRootTargetNameCaseInsensitiveMapping { get; }
}
Expand Up @@ -7,11 +7,21 @@ namespace Riok.Mapperly.Descriptors.MappingBodyBuilders.BuilderContext;
/// An implementation of <see cref="INewInstanceBuilderContext{T}"/>.
/// </summary>
/// <typeparam name="T">The type of the mapping.</typeparam>
public class NewInstanceBuilderContext<T>(MappingBuilderContext builderContext, T mapping)
: MembersMappingBuilderContext<T>(builderContext, mapping),
INewInstanceBuilderContext<T>
public class NewInstanceBuilderContext<T> : MembersMappingBuilderContext<T>, INewInstanceBuilderContext<T>
where T : INewInstanceObjectMemberMapping
{
public Dictionary<string, string> MemberConfigsByRootTargetNameCaseInsensitiveMapping { get; }

public NewInstanceBuilderContext(MappingBuilderContext builderContext, T mapping)
: base(builderContext, mapping)
{
MemberConfigsByRootTargetNameCaseInsensitiveMapping = MemberConfigsByRootTargetName.ToDictionary(
x => x.Key,
x => x.Key,
StringComparer.InvariantCultureIgnoreCase
);
}

public void AddInitMemberMapping(MemberAssignmentMapping mapping)
{
SetSourceMemberMapped(mapping.SourcePath);
Expand All @@ -20,7 +30,10 @@ public void AddInitMemberMapping(MemberAssignmentMapping mapping)

public void AddConstructorParameterMapping(ConstructorParameterMapping mapping)
{
MemberConfigsByRootTargetName.Remove(mapping.Parameter.Name);
if (MemberConfigsByRootTargetNameCaseInsensitiveMapping.TryGetValue(mapping.Parameter.Name, out var parameterName))
{
MemberConfigsByRootTargetName.Remove(parameterName);
}
SetSourceMemberMapped(mapping.DelegateMapping.SourcePath);
Mapping.AddConstructorParameterMapping(mapping);
}
Expand Down
Expand Up @@ -8,11 +8,21 @@ namespace Riok.Mapperly.Descriptors.MappingBodyBuilders.BuilderContext;
/// which supports containers (<seealso cref="MembersContainerBuilderContext{T}"/>).
/// </summary>
/// <typeparam name="T"></typeparam>
public class NewInstanceContainerBuilderContext<T>(MappingBuilderContext builderContext, T mapping)
: MembersContainerBuilderContext<T>(builderContext, mapping),
INewInstanceBuilderContext<T>
public class NewInstanceContainerBuilderContext<T> : MembersContainerBuilderContext<T>, INewInstanceBuilderContext<T>
where T : INewInstanceObjectMemberMapping, IMemberAssignmentTypeMapping
{
public Dictionary<string, string> MemberConfigsByRootTargetNameCaseInsensitiveMapping { get; }

public NewInstanceContainerBuilderContext(MappingBuilderContext builderContext, T mapping)
: base(builderContext, mapping)
{
MemberConfigsByRootTargetNameCaseInsensitiveMapping = MemberConfigsByRootTargetName.ToDictionary(
x => x.Key,
x => x.Key,
StringComparer.InvariantCultureIgnoreCase
);
}

public void AddInitMemberMapping(MemberAssignmentMapping mapping)
{
SetSourceMemberMapped(mapping.SourcePath);
Expand All @@ -21,7 +31,10 @@ public void AddInitMemberMapping(MemberAssignmentMapping mapping)

public void AddConstructorParameterMapping(ConstructorParameterMapping mapping)
{
MemberConfigsByRootTargetName.Remove(mapping.Parameter.Name);
if (MemberConfigsByRootTargetNameCaseInsensitiveMapping.TryGetValue(mapping.Parameter.Name, out var parameterName))
{
MemberConfigsByRootTargetName.Remove(parameterName);
}
SetSourceMemberMapped(mapping.DelegateMapping.SourcePath);
Mapping.AddConstructorParameterMapping(mapping);
}
Expand Down
Expand Up @@ -320,7 +320,10 @@ private static void BuildConstructorMapping(INewInstanceBuilderContext<IMapping>
sourcePath = null;
memberConfig = null;

if (!ctx.MemberConfigsByRootTargetName.TryGetValue(parameter.Name, out var memberConfigs))
if (
!ctx.MemberConfigsByRootTargetNameCaseInsensitiveMapping.TryGetValue(parameter.Name, out var parameterName)
|| !ctx.MemberConfigsByRootTargetName.TryGetValue(parameterName, out var memberConfigs)
)
{
return ctx.BuilderContext
.SymbolAccessor
Expand Down
29 changes: 29 additions & 0 deletions test/Riok.Mapperly.Tests/Mapping/CtorTest.cs
Expand Up @@ -79,4 +79,33 @@ public void DeepCloneRecordShouldNotUseCtorMapping()
"""
);
}

[Fact]
public void MapPropertyCtorMapping()
{
var source = TestSourceBuilder.MapperWithBodyAndTypes(
"""
[MapProperty(nameof(A.BId), nameof(B.Id))]
private partial B Map(A source);
""",
"class A { public long BId { get; } }",
"""
class B
{
public long Id { get; }

public B(long id) { Id = id; }
}
"""
);
TestHelper
.GenerateMapper(source)
.Should()
.HaveSingleMethodBody(
"""
var target = new global::B(source.BId);
return target;
"""
);
}
}

0 comments on commit 4451261

Please sign in to comment.