Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions src/ExpressionTranslator/ExpressionTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ private void ResetIndentLevel()
_indentLevel++;
}

private bool IsGeneratedTypeInternal()
{
if (Definitions == null)
return false;

return Definitions.IsInternal ||
Definitions.Implements?.Any(it => !it.GetTypeInfo().IsVisible) == true;
}
Comment on lines +60 to +66

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrerav Have you checked if this has a negative impact on the generation of Extension mappers?

I haven't figured out what's actually going on there yet.

Origin creation logic is absolutely correct for generating class-based mappers. There is no need for implementation or inheritance.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe internal class with proper implementations should be generated even in case MapperAttribute.IsInternal hasn't been specified

I think this statement contradicts the logic of C# itself.
Implemention an internal interface doesn't force a class to be internal, since implementation is not inheritance 😅


public static ExpressionTranslator Create(Expression node, ExpressionDefinitions? definitions = null)
{
var translator = new ExpressionTranslator(definitions);
Expand Down Expand Up @@ -1201,7 +1210,7 @@ public Expression VisitLambda(LambdaExpression node, LambdaType type, string? me
if (type == LambdaType.PublicLambda)
{
var name = methodName ?? "Main";
if (!isInternal)
if (!isInternal && !IsGeneratedTypeInternal())
isInternal = node.ReturnType.GetTypeInfo().IsNotPublic ||
node.Parameters.Any(it => it.Type.GetTypeInfo().IsNotPublic);
WriteModifierNextLine(isInternal ? "internal" : "public");
Expand Down Expand Up @@ -1235,7 +1244,7 @@ public Expression VisitLambda(LambdaExpression node, LambdaType type, string? me
var name = methodName ?? "Main";
if (type == LambdaType.PublicMethod || type == LambdaType.ExtensionMethod)
{
if (!isInternal)
if (!isInternal && !IsGeneratedTypeInternal())
isInternal = node.ReturnType.GetTypeInfo().IsNotPublic ||
node.Parameters.Any(it => it.Type.GetTypeInfo().IsNotPublic);
WriteModifierNextLine(isInternal ? "internal" : "public");
Expand Down Expand Up @@ -1891,10 +1900,7 @@ public override string ToString()
Indent();
}

var isInternal = Definitions.IsInternal;
if (!isInternal)
isInternal = Definitions.Implements?.Any(it =>
!it.GetTypeInfo().IsInterface && !it.GetTypeInfo().IsPublic) ?? false;
var isInternal = IsGeneratedTypeInternal();
WriteModifierNextLine(isInternal ? "internal" : "public");
Write("partial ", Definitions.IsRecordType ? "record " : "class ", Definitions.TypeName);
if (Definitions.IsRecordType && ctorParams?.Count > 0)
Expand Down
10 changes: 10 additions & 0 deletions src/Mapster.Tool.Tests/Mappers/IIssue399Mapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Linq.Expressions;

namespace Mapster.Tool.Tests.Mappers;

[Mapper]
internal interface IIssue399Mapper
{
Expression<Func<Issue399Source, Issue399Destination>> ProjectToDestination { get; }
Issue399Destination Map(Issue399Source source);
}
24 changes: 24 additions & 0 deletions src/Mapster.Tool.Tests/Mappers/Issue399Mapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Linq.Expressions;
using Mapster.Tool.Tests;
using Mapster.Tool.Tests.Mappers;

namespace Mapster.Tool.Tests.Mappers
{
internal partial class Issue399Mapper : IIssue399Mapper
{
public Expression<Func<Issue399Source, Issue399Destination>> ProjectToDestination => p1 => new Issue399Destination()
{
Id = p1.Id,
Name = p1.Name
};
public Issue399Destination Map(Issue399Source p2)
{
return p2 == null ? null : new Issue399Destination()
{
Id = p2.Id,
Name = p2.Name
};
}
}
}
34 changes: 34 additions & 0 deletions src/Mapster.Tool.Tests/WhenMapperInterfaceUsesInternalTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using FluentAssertions;
using Mapster.Tool.Tests.Mappers;

namespace Mapster.Tool.Tests;

/// <summary>
/// Tests for https://github.com/MapsterMapper/Mapster/issues/399
/// </summary>
public class WhenMapperInterfaceUsesInternalTypes : TestBase
{
[Fact]
public void MapperInterfaceImplementationUsesInternalTypes()
{
IIssue399Mapper mapper = new Issue399Mapper();
var source = new Issue399Source { Id = 1, Name = "Test" };

var destination = mapper.Map(source);

destination.Id.Should().Be(source.Id);
destination.Name.Should().Be(source.Name);
}
}

internal class Issue399Source
{
public int Id { get; init; }
public string? Name { get; init; }
}

internal class Issue399Destination
{
public int Id { get; init; }
public string? Name { get; init; }
}
Loading