Skip to content

Commit

Permalink
fix: don't diagnostic for constructor mappings when no instance can b…
Browse files Browse the repository at this point in the history
…e created but none is needed anyway
  • Loading branch information
latonz authored Feb 16, 2024
1 parent 7429bc7 commit 450d7ca
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using Microsoft.CodeAnalysis;
using Riok.Mapperly.Configuration;
using Riok.Mapperly.Descriptors.Mappings;
using Riok.Mapperly.Descriptors.Mappings.MemberMappings;
using Riok.Mapperly.Symbols;

namespace Riok.Mapperly.Descriptors.MappingBodyBuilders.BuilderContext;
Expand All @@ -13,13 +15,15 @@ public interface IMembersBuilderContext<out T>
{
T Mapping { get; }

void AddDiagnostics();

MappingBuilderContext BuilderContext { get; }

IReadOnlyCollection<string> IgnoredSourceMemberNames { get; }

Dictionary<string, IMappableMember> TargetMembers { get; }

Dictionary<string, List<PropertyMappingConfiguration>> MemberConfigsByRootTargetName { get; }

void AddDiagnostics();

NullMemberMapping BuildNullMemberMapping(MemberPath sourcePath, INewInstanceMapping delegateMapping, ITypeSymbol targetMemberType);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Microsoft.CodeAnalysis;
using Riok.Mapperly.Abstractions;
using Riok.Mapperly.Configuration;
using Riok.Mapperly.Descriptors.Mappings;
using Riok.Mapperly.Descriptors.Mappings.MemberMappings;
using Riok.Mapperly.Diagnostics;
using Riok.Mapperly.Helpers;
using Riok.Mapperly.Symbols;
Expand Down Expand Up @@ -72,6 +74,23 @@ protected MembersMappingBuilderContext(MappingBuilderContext builderContext, T m

public Dictionary<string, List<PropertyMappingConfiguration>> MemberConfigsByRootTargetName { get; }

public NullMemberMapping BuildNullMemberMapping(
MemberPath sourcePath,
INewInstanceMapping delegateMapping,
ITypeSymbol targetMemberType
)
{
var getterSourcePath = GetterMemberPath.Build(BuilderContext, sourcePath);

var nullFallback = NullFallbackValue.Default;
if (!delegateMapping.SourceType.IsNullable() && sourcePath.IsAnyNullable())
{
nullFallback = BuilderContext.GetNullFallbackValue(targetMemberType);
}

return new NullMemberMapping(delegateMapping, getterSourcePath, targetMemberType, nullFallback, !BuilderContext.IsExpression);
}

public void AddDiagnostics()
{
AddUnmatchedIgnoredTargetMembersDiagnostics();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,22 +173,8 @@ private static void BuildInitMemberMapping(
return;
}

var nullFallback = NullFallbackValue.Default;
if (!delegateMapping.SourceType.IsNullable() && sourcePath.IsAnyNullable())
{
nullFallback = ctx.BuilderContext.GetNullFallbackValue(targetMember.Type);
}

var getterSourcePath = GetterMemberPath.Build(ctx.BuilderContext, sourcePath);
var setterTargetPath = SetterMemberPath.Build(ctx.BuilderContext, targetPath);

var memberMapping = new NullMemberMapping(
delegateMapping,
getterSourcePath,
targetMember.Type,
nullFallback,
!ctx.BuilderContext.IsExpression
);
var memberMapping = ctx.BuildNullMemberMapping(sourcePath, delegateMapping, targetMember.Type);
var memberAssignmentMapping = new MemberAssignmentMapping(setterTargetPath, memberMapping);
ctx.AddInitMemberMapping(memberAssignmentMapping);
}
Expand Down Expand Up @@ -298,15 +284,7 @@ private static bool TryBuildConstructorMapping(
return false;
}

var getterSourcePath = GetterMemberPath.Build(ctx.BuilderContext, sourcePath);

var memberMapping = new NullMemberMapping(
delegateMapping,
getterSourcePath,
parameterType,
ctx.BuilderContext.GetNullFallbackValue(parameterType),
!ctx.BuilderContext.IsExpression
);
var memberMapping = ctx.BuildNullMemberMapping(sourcePath, delegateMapping, parameterType);
var ctorMapping = new ConstructorParameterMapping(parameter, memberMapping, skippedOptionalParam);
constructorParameterMappings.Add(ctorMapping);
mappedTargetMemberNames.Add(parameter.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,7 @@ out HashSet<string> mappedTargetMemberNames
return false;
}

var getterSourcePath = GetterMemberPath.Build(ctx.BuilderContext, sourcePath);

var memberMapping = new NullMemberMapping(
delegateMapping,
getterSourcePath,
targetMemberType,
ctx.BuilderContext.GetNullFallbackValue(targetMemberType),
!ctx.BuilderContext.IsExpression
);

var memberMapping = ctx.BuildNullMemberMapping(sourcePath, delegateMapping, targetMemberType);
var ctorMapping = new ValueTupleConstructorParameterMapping(targetMember, memberMapping);
constructorParameterMappings.Add(ctorMapping);
mappedTargetMemberNames.Add(targetMember.Name);
Expand Down
32 changes: 32 additions & 0 deletions test/Riok.Mapperly.Tests/Mapping/ObjectPropertyNullableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -748,4 +748,36 @@ public Task NullableToNullablePropertyWithAnotherNullableToNonNullableMappingSho

return TestHelper.VerifyGenerator(source);
}

[Fact]
public void ClassToRecordNoAccessibleSourceCtorShouldNotDiagnostic()
{
var source = TestSourceBuilder.Mapping(
"A",
"B",
"""
public class A
{
private A(C value)
{
Value = value;
}

public C Value { get; }
}
""",
"public record B(C Value);",
"public record C(string StringValue);"
);

TestHelper
.GenerateMapper(source)
.Should()
.HaveMapMethodBody(
"""
var target = new global::B(source.Value);
return target;
"""
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,29 @@ public Task ClassToClassNullableSourcePathManuallyFlatten()

return TestHelper.VerifyGenerator(source);
}

[Fact]
public Task ClassToRecordNoAccessibleSourceCtorShouldNotDiagnostic()
{
// see https://github.com/riok/mapperly/issues/972
var source = TestSourceBuilder.Mapping(
"System.Linq.IQueryable<A>",
"System.Linq.IQueryable<B>",
"""
public class A
{
private A(C value)
{
Value = value;
}

public C Value { get; }
}
""",
"public record B(C Value);",
"public record C(string StringValue);"
);

return TestHelper.VerifyGenerator(source);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//HintName: Mapper.g.cs
// <auto-generated />
#nullable enable
public partial class Mapper
{
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "0.0.1.0")]
private partial global::System.Linq.IQueryable<global::B> Map(global::System.Linq.IQueryable<global::A> source)
{
#nullable disable
return System.Linq.Queryable.Select(source, x => new global::B(x.Value));
#nullable enable
}
}

0 comments on commit 450d7ca

Please sign in to comment.