Use fully qualified name of the source type instead of adding usings if necessary.
This commit is contained in:
parent
aced7d749d
commit
0ad89b0d6b
|
@ -11,8 +11,11 @@ namespace MapTo
|
||||||
{
|
{
|
||||||
internal abstract class MappingContext
|
internal abstract class MappingContext
|
||||||
{
|
{
|
||||||
|
private readonly List<string> _ignoredNamespaces;
|
||||||
|
|
||||||
protected MappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
|
protected MappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
|
||||||
{
|
{
|
||||||
|
_ignoredNamespaces = new();
|
||||||
Diagnostics = ImmutableArray<Diagnostic>.Empty;
|
Diagnostics = ImmutableArray<Diagnostic>.Empty;
|
||||||
Usings = ImmutableArray.Create("System", Constants.RootNamespace);
|
Usings = ImmutableArray.Create("System", Constants.RootNamespace);
|
||||||
SourceGenerationOptions = sourceGenerationOptions;
|
SourceGenerationOptions = sourceGenerationOptions;
|
||||||
|
@ -77,7 +80,10 @@ namespace MapTo
|
||||||
|
|
||||||
protected void AddUsingIfRequired(bool condition, string? ns)
|
protected void AddUsingIfRequired(bool condition, string? ns)
|
||||||
{
|
{
|
||||||
if (condition && ns is not null && ns != TypeSyntax.GetNamespace() && !Usings.Contains(ns))
|
if (condition && ns is not null &&
|
||||||
|
ns != TypeSyntax.GetNamespace() &&
|
||||||
|
!_ignoredNamespaces.Contains(ns) &&
|
||||||
|
!Usings.Contains(ns))
|
||||||
{
|
{
|
||||||
Usings = Usings.Add(ns);
|
Usings = Usings.Add(ns);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +151,6 @@ namespace MapTo
|
||||||
}
|
}
|
||||||
|
|
||||||
AddUsingIfRequired(propertyType);
|
AddUsingIfRequired(propertyType);
|
||||||
AddUsingIfRequired(sourceTypeSymbol);
|
|
||||||
AddUsingIfRequired(enumerableTypeArgumentType);
|
AddUsingIfRequired(enumerableTypeArgumentType);
|
||||||
AddUsingIfRequired(mappedSourcePropertyType);
|
AddUsingIfRequired(mappedSourcePropertyType);
|
||||||
|
|
||||||
|
@ -155,8 +160,8 @@ namespace MapTo
|
||||||
converterFullyQualifiedName,
|
converterFullyQualifiedName,
|
||||||
converterParameters.ToImmutableArray(),
|
converterParameters.ToImmutableArray(),
|
||||||
sourceProperty.Name,
|
sourceProperty.Name,
|
||||||
mappedSourcePropertyType?.Name,
|
ToQualifiedDisplayName(mappedSourcePropertyType),
|
||||||
enumerableTypeArgumentType?.Name);
|
ToQualifiedDisplayName(enumerableTypeArgumentType));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool TryGetMapTypeConverter(ISymbol property, IPropertySymbol sourceProperty, out string? converterFullyQualifiedName,
|
protected bool TryGetMapTypeConverter(ISymbol property, IPropertySymbol sourceProperty, out string? converterFullyQualifiedName,
|
||||||
|
@ -171,7 +176,7 @@ namespace MapTo
|
||||||
}
|
}
|
||||||
|
|
||||||
var typeConverterAttribute = property.GetAttribute(MapTypeConverterAttributeTypeSymbol);
|
var typeConverterAttribute = property.GetAttribute(MapTypeConverterAttributeTypeSymbol);
|
||||||
if (!(typeConverterAttribute?.ConstructorArguments.First().Value is INamedTypeSymbol converterTypeSymbol))
|
if (typeConverterAttribute?.ConstructorArguments.First().Value is not INamedTypeSymbol converterTypeSymbol)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -248,6 +253,9 @@ namespace MapTo
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sourceTypeNamespace = sourceTypeSymbol.ContainingNamespace.ToDisplayString();
|
||||||
|
_ignoredNamespaces.Add(sourceTypeNamespace);
|
||||||
|
|
||||||
var typeIdentifierName = TypeSyntax.GetIdentifierName();
|
var typeIdentifierName = TypeSyntax.GetIdentifierName();
|
||||||
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
||||||
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
|
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
|
||||||
|
@ -260,7 +268,6 @@ namespace MapTo
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddUsingIfRequired(sourceTypeSymbol);
|
|
||||||
AddUsingIfRequired(mappedProperties.Any(p => p.IsEnumerable), "System.Linq");
|
AddUsingIfRequired(mappedProperties.Any(p => p.IsEnumerable), "System.Linq");
|
||||||
|
|
||||||
return new MappingModel(
|
return new MappingModel(
|
||||||
|
@ -269,7 +276,7 @@ namespace MapTo
|
||||||
TypeSyntax.Modifiers,
|
TypeSyntax.Modifiers,
|
||||||
TypeSyntax.Keyword.Text,
|
TypeSyntax.Keyword.Text,
|
||||||
typeIdentifierName,
|
typeIdentifierName,
|
||||||
sourceTypeSymbol.ContainingNamespace.ToString(),
|
sourceTypeNamespace,
|
||||||
sourceTypeIdentifierName,
|
sourceTypeIdentifierName,
|
||||||
sourceTypeSymbol.ToDisplayString(),
|
sourceTypeSymbol.ToDisplayString(),
|
||||||
mappedProperties,
|
mappedProperties,
|
||||||
|
@ -316,5 +323,16 @@ namespace MapTo
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string? ToQualifiedDisplayName(ISymbol? typeSymbol)
|
||||||
|
{
|
||||||
|
if (typeSymbol is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeNamespace = typeSymbol.ContainingNamespace.ToDisplayString();
|
||||||
|
return _ignoredNamespaces.Contains(typeNamespace) ? typeSymbol.ToDisplayString() : typeSymbol.Name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,7 +34,7 @@ namespace MapTo
|
||||||
bool GenerateSecondaryConstructor
|
bool GenerateSecondaryConstructor
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
public string SourceType => SourceTypeIdentifierName == TypeIdentifierName ? SourceTypeFullName : SourceTypeIdentifierName;
|
public string SourceType => SourceTypeFullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal record SourceGenerationOptions(
|
internal record SourceGenerationOptions(
|
||||||
|
|
|
@ -172,6 +172,142 @@ namespace SaleModel
|
||||||
diagnostics.ShouldBeSuccessful();
|
diagnostics.ShouldBeSuccessful();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(SameSourceAndDestinationTypeNameData))]
|
||||||
|
public void When_SourceAndDestinationNamesAreTheSame_Should_MapAccordingly(string source, LanguageVersion languageVersion)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
source = source.Trim();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var (_, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions, languageVersion: languageVersion);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
diagnostics.ShouldBeSuccessful();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<object> SameSourceAndDestinationTypeNameData => new List<object>
|
||||||
|
{
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
@"
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
public class TypeName { public int Prop2 { get; set; } }
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Test2
|
||||||
|
{
|
||||||
|
using MapTo;
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.TypeName))]
|
||||||
|
public partial class TypeName
|
||||||
|
{
|
||||||
|
[MapProperty(SourcePropertyName=""Prop2"")]
|
||||||
|
public int Prop1 { get; set; }
|
||||||
|
}
|
||||||
|
}",
|
||||||
|
LanguageVersion.CSharp7_3
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
@"
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
public record TypeName(int Prop2);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Test2
|
||||||
|
{
|
||||||
|
using MapTo;
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.TypeName))]
|
||||||
|
public partial record TypeName([MapProperty(SourcePropertyName=""Prop2"")] int Prop1);
|
||||||
|
}",
|
||||||
|
LanguageVersion.CSharp9
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
@"
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public class SourceType2 { public int Id { get; set; } }
|
||||||
|
public class SourceType
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public List<SourceType2> Prop1 { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Test2
|
||||||
|
{
|
||||||
|
using MapTo;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.SourceType2))]
|
||||||
|
public partial class SourceType2 { public int Id { get; set; } }
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.SourceType))]
|
||||||
|
public partial class SourceType
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public IReadOnlyList<SourceType2> Prop1 { get; set; }
|
||||||
|
}
|
||||||
|
}",
|
||||||
|
LanguageVersion.CSharp7_3
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
@"
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public record SourceType(int Id, List<SourceType2> Prop1);
|
||||||
|
public record SourceType2(int Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Test2
|
||||||
|
{
|
||||||
|
using MapTo;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.SourceType2))]
|
||||||
|
public partial record SourceType2(int Id);
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.SourceType))]
|
||||||
|
public partial record SourceType(int Id, IReadOnlyList<SourceType2> Prop1);
|
||||||
|
}",
|
||||||
|
LanguageVersion.CSharp9
|
||||||
|
},
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
@"
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
public record SourceType1(int Id);
|
||||||
|
public record SourceType2(int Id, List<SourceType1> Prop1);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
using MapTo;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.SourceType1))]
|
||||||
|
public partial record SourceType3(int Id);
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.SourceType2))]
|
||||||
|
public partial record SourceType4(int Id, IReadOnlyList<SourceType3> Prop1);
|
||||||
|
}",
|
||||||
|
LanguageVersion.CSharp9
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(VerifyMappedTypesData))]
|
[MemberData(nameof(VerifyMappedTypesData))]
|
||||||
public void VerifyMappedTypes(string[] sources, LanguageVersion languageVersion)
|
public void VerifyMappedTypes(string[] sources, LanguageVersion languageVersion)
|
||||||
|
|
Loading…
Reference in New Issue