diff --git a/src/Riok.Mapperly/Symbols/SetterMemberPath.cs b/src/Riok.Mapperly/Symbols/SetterMemberPath.cs index 77e8d06af3..aed864cb9f 100644 --- a/src/Riok.Mapperly/Symbols/SetterMemberPath.cs +++ b/src/Riok.Mapperly/Symbols/SetterMemberPath.cs @@ -34,10 +34,8 @@ public static SetterMemberPath Build(MappingBuilderContext ctx, MemberPath membe private static (IMappableMember, bool) BuildMemberSetter(MappingBuilderContext ctx, IMappableMember member) { - if (ctx.SymbolAccessor.IsDirectlyAccessible(member.MemberSymbol)) - { + if (ctx.SymbolAccessor.IsDirectlyAccessible(member.MemberSymbol) && member.CanSetDirectly) return (member, false); - } if (member.MemberSymbol.Kind == SymbolKind.Field) { diff --git a/test/Riok.Mapperly.Tests/Mapping/UnsafeAccessorTest.cs b/test/Riok.Mapperly.Tests/Mapping/UnsafeAccessorTest.cs index 5a8880b5f0..8685d27117 100644 --- a/test/Riok.Mapperly.Tests/Mapping/UnsafeAccessorTest.cs +++ b/test/Riok.Mapperly.Tests/Mapping/UnsafeAccessorTest.cs @@ -143,6 +143,44 @@ public void ManualUnflattenedPropertyNullablePath() ); } + [Fact] + public void PropertyWithPrivateSetter() + { + var source = TestSourceBuilder.MapperWithBodyAndTypes( + "partial B Map(A source); ", + TestSourceBuilderOptions.WithMemberVisibility(MemberVisibility.All), + "class A { public int Value { get; set; } }", + "class B { public int Value { get; private set; } }" + ); + + TestHelper + .GenerateMapper(source) + .Should() + .HaveMapMethodBody( + """ + var target = new global::B(); + target.SetValue(source.Value); + return target; + """ + ); + } + + [Fact] + public void PropertyWithProtectedSetterWhenDisabledShouldDiagnostic() + { + var source = TestSourceBuilder.MapperWithBodyAndTypes( + "partial B Map(A source);", + TestSourceBuilderOptions.WithMemberVisibility(MemberVisibility.All & ~MemberVisibility.Protected), + "class A { public int Value { get; set; } }", + "class B { public int Value { get; protected set; } }" + ); + + TestHelper + .GenerateMapper(source, TestHelperOptions.AllowDiagnostics) + .Should() + .HaveDiagnostic(DiagnosticDescriptors.CannotMapToReadOnlyMember); + } + [Fact] public Task PrivateField() {