Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private members in other compilation units are not mapped with IncludedMembers = MemberVisibility.All #1458

Open
cs-clarence opened this issue Aug 17, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@cs-clarence
Copy link

Describe the bug
Pubic property with private setter are not mapped even with IncludedMembers = MemberVisibility.All applied

Declaration code
https://dotnetfiddle.net/E4iGqY - reproduction

using System;
using Riok.Mapperly.Abstractions;

public class User(string emailAddress) 
{
	public string EmailAddress { get; private set; } = emailAddress;
}

public record UserUpdateDto(string EmailAddress);

[Mapper(IncludedMembers = MemberVisibility.All)]
public static partial class UserMapper 
{
	static partial void ApplyTo(this UserUpdateDto input, User user);
	
	public static void ApplyUpdates(this UserUpdateDto input, User user) 
	{
		UserMapper.ApplyTo(input, user);
	}
}
					
public class Program
{
	public static void Main()
	{
		var user = new User("user@gmail.com");
		var updates = new UserUpdateDto("new-user@gmail.com");
		
		updates.ApplyUpdates(user);
		
		Console.WriteLine(user.EmailAddress); // still shows user@gmail.com
	}
}

Environment (please complete the following information):

  • Mapperly Version: 3.6.0
  • Nullable reference types: enabled
  • .NET Version: .NET 8.0
  • Target Framework: .NET 8.0
  • Compiler Version: 8.0
@cs-clarence cs-clarence added the bug Something isn't working label Aug 17, 2024
@latonz
Copy link
Contributor

latonz commented Aug 20, 2024

I cannot reproduce this locally and I'm not sure if .NET fiddle runs source generators correctly.
The following works as expected for me:

# in a new empty directory
dotnet new console
dotnet add package Riok.Mapperly -v 3.6.0
# replace content of Program.cs with provided content
dotnet run
# prints new-user@gmail.com as expected...

Do these steps work for you? Can you reproduce the issue in Rider? in VS Code? in VS? on the terminal?

@cs-clarence
Copy link
Author

cs-clarence commented Aug 23, 2024

I cannot reproduce this locally and I'm not sure if .NET fiddle runs source generators correctly. The following works as expected for me:

# in a new empty directory
dotnet new console
dotnet add package Riok.Mapperly -v 3.6.0
# replace content of Program.cs with provided content
dotnet run
# prints new-user@gmail.com as expected...

Do these steps work for you? Can you reproduce the issue in Rider? in VS Code? in VS? on the terminal?

Can confirm this worked, however the minimal reproduction is not complete, my bad. Here is a better one.

I experienced it when the object mapped is in a different project.

The generated code in Rider is:

// <auto-generated />
#nullable enable
public static partial class UserMapper
{
    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
    static partial void ApplyTo(this global::UserUpdateDto input, global::User user)
    {
        user.SetEmailAddress(input.EmailAddress);
    }
}
    
[global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
static file class UnsafeAccessor
{
    [global::System.CodeDom.Compiler.GeneratedCode("Riok.Mapperly", "3.6.0.0")]
    [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method, Name = "set_EmailAddress")]
    public static extern void SetEmailAddress(this global::User target, string value);
}

The generated code seems correct and is the exact same as when the class is contained in the same project. However, when running it, the changes are not applied.

cc @latonz

@latonz
Copy link
Contributor

latonz commented Aug 26, 2024

Thanks for the update, I can reproduce it now.
It seems that PropertySymbol.IsReadOnly is true and PropertySymbol.SetMethod is null. As soon as I find the time I'll investigate further why exactly this is the case... Probably private members are just not visible to other compilation units? It may work in the IDE since these are related compilation units in the IDE.

@teneko
Copy link

teneko commented Oct 17, 2024

Pretty sure public string EmailAddress { get; private set; } = emailAddress; gets normalized from the compiler to:

private string <EmailAddress>k__BackingField = emailAddress;
public string EmailAddress => <EmailAddress>k__BackingField;

@latonz
Copy link
Contributor

latonz commented Oct 19, 2024

We may need to access the backing field directly in this case, instead of going through the setter...

@latonz latonz changed the title Property with private or internal setter are not mapped Private members in other compilation units are not mapped with IncludedMembers = MemberVisibility.All Nov 7, 2024
@7amou3

This comment was marked as outdated.

@latonz

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants