Use fully qualified name of the source type instead of adding usings if necessary.

This commit is contained in:
Mohammadreza Taikandi 2021-07-02 09:12:11 +01:00
parent aced7d749d
commit 0ad89b0d6b
3 changed files with 162 additions and 8 deletions

View File

@ -11,8 +11,11 @@ namespace MapTo
{
internal abstract class MappingContext
{
private readonly List<string> _ignoredNamespaces;
protected MappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
{
_ignoredNamespaces = new();
Diagnostics = ImmutableArray<Diagnostic>.Empty;
Usings = ImmutableArray.Create("System", Constants.RootNamespace);
SourceGenerationOptions = sourceGenerationOptions;
@ -77,7 +80,10 @@ namespace MapTo
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);
}
@ -145,7 +151,6 @@ namespace MapTo
}
AddUsingIfRequired(propertyType);
AddUsingIfRequired(sourceTypeSymbol);
AddUsingIfRequired(enumerableTypeArgumentType);
AddUsingIfRequired(mappedSourcePropertyType);
@ -155,8 +160,8 @@ namespace MapTo
converterFullyQualifiedName,
converterParameters.ToImmutableArray(),
sourceProperty.Name,
mappedSourcePropertyType?.Name,
enumerableTypeArgumentType?.Name);
ToQualifiedDisplayName(mappedSourcePropertyType),
ToQualifiedDisplayName(enumerableTypeArgumentType));
}
protected bool TryGetMapTypeConverter(ISymbol property, IPropertySymbol sourceProperty, out string? converterFullyQualifiedName,
@ -171,7 +176,7 @@ namespace MapTo
}
var typeConverterAttribute = property.GetAttribute(MapTypeConverterAttributeTypeSymbol);
if (!(typeConverterAttribute?.ConstructorArguments.First().Value is INamedTypeSymbol converterTypeSymbol))
if (typeConverterAttribute?.ConstructorArguments.First().Value is not INamedTypeSymbol converterTypeSymbol)
{
return false;
}
@ -248,6 +253,9 @@ namespace MapTo
return null;
}
var sourceTypeNamespace = sourceTypeSymbol.ContainingNamespace.ToDisplayString();
_ignoredNamespaces.Add(sourceTypeNamespace);
var typeIdentifierName = TypeSyntax.GetIdentifierName();
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
var isTypeInheritFromMappedBaseClass = IsTypeInheritFromMappedBaseClass(semanticModel);
@ -260,7 +268,6 @@ namespace MapTo
return null;
}
AddUsingIfRequired(sourceTypeSymbol);
AddUsingIfRequired(mappedProperties.Any(p => p.IsEnumerable), "System.Linq");
return new MappingModel(
@ -269,7 +276,7 @@ namespace MapTo
TypeSyntax.Modifiers,
TypeSyntax.Keyword.Text,
typeIdentifierName,
sourceTypeSymbol.ContainingNamespace.ToString(),
sourceTypeNamespace,
sourceTypeIdentifierName,
sourceTypeSymbol.ToDisplayString(),
mappedProperties,
@ -316,5 +323,16 @@ namespace MapTo
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;
}
}
}

View File

@ -34,7 +34,7 @@ namespace MapTo
bool GenerateSecondaryConstructor
)
{
public string SourceType => SourceTypeIdentifierName == TypeIdentifierName ? SourceTypeFullName : SourceTypeIdentifierName;
public string SourceType => SourceTypeFullName;
}
internal record SourceGenerationOptions(

View File

@ -172,6 +172,142 @@ namespace SaleModel
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]
[MemberData(nameof(VerifyMappedTypesData))]
public void VerifyMappedTypes(string[] sources, LanguageVersion languageVersion)