Optimized namespace discovery.
This commit is contained in:
parent
bfd6dafe78
commit
9ab0e4eb25
|
@ -11,7 +11,7 @@ namespace MapTo
|
||||||
{
|
{
|
||||||
internal abstract class MappingContext
|
internal abstract class MappingContext
|
||||||
{
|
{
|
||||||
private readonly List<string> _ignoredNamespaces;
|
private readonly List<SymbolDisplayPart> _ignoredNamespaces;
|
||||||
|
|
||||||
protected MappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
|
protected MappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
|
||||||
{
|
{
|
||||||
|
@ -76,14 +76,14 @@ namespace MapTo
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AddUsingIfRequired(ISymbol? namedTypeSymbol) =>
|
protected void AddUsingIfRequired(ISymbol? namedTypeSymbol) =>
|
||||||
AddUsingIfRequired(namedTypeSymbol?.ContainingNamespace.IsGlobalNamespace == false, namedTypeSymbol?.ContainingNamespace.ToDisplayString());
|
AddUsingIfRequired(namedTypeSymbol?.ContainingNamespace.IsGlobalNamespace == false, namedTypeSymbol?.ContainingNamespace);
|
||||||
|
|
||||||
|
protected void AddUsingIfRequired(bool condition, INamespaceSymbol? ns) =>
|
||||||
|
AddUsingIfRequired(condition && ns is not null && !_ignoredNamespaces.Contains(ns.ToDisplayParts().First()), ns?.ToDisplayString());
|
||||||
|
|
||||||
protected void AddUsingIfRequired(bool condition, string? ns)
|
protected void AddUsingIfRequired(bool condition, string? ns)
|
||||||
{
|
{
|
||||||
if (condition && ns is not null &&
|
if (ns is not null && condition && ns != TypeSyntax.GetNamespace() && !Usings.Contains(ns))
|
||||||
ns != TypeSyntax.GetNamespace() &&
|
|
||||||
!_ignoredNamespaces.Contains(ns) &&
|
|
||||||
!Usings.Contains(ns))
|
|
||||||
{
|
{
|
||||||
Usings = Usings.Add(ns);
|
Usings = Usings.Add(ns);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ namespace MapTo
|
||||||
|
|
||||||
return new MappedProperty(
|
return new MappedProperty(
|
||||||
property.Name,
|
property.Name,
|
||||||
propertyType.Name,
|
ToQualifiedDisplayName(propertyType) ?? propertyType.Name,
|
||||||
converterFullyQualifiedName,
|
converterFullyQualifiedName,
|
||||||
converterParameters.ToImmutableArray(),
|
converterParameters.ToImmutableArray(),
|
||||||
sourceProperty.Name,
|
sourceProperty.Name,
|
||||||
|
@ -253,8 +253,7 @@ namespace MapTo
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sourceTypeNamespace = sourceTypeSymbol.ContainingNamespace.ToDisplayString();
|
_ignoredNamespaces.Add(sourceTypeSymbol.ContainingNamespace.ToDisplayParts().First());
|
||||||
_ignoredNamespaces.Add(sourceTypeNamespace);
|
|
||||||
|
|
||||||
var typeIdentifierName = TypeSyntax.GetIdentifierName();
|
var typeIdentifierName = TypeSyntax.GetIdentifierName();
|
||||||
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
||||||
|
@ -276,7 +275,7 @@ namespace MapTo
|
||||||
TypeSyntax.Modifiers,
|
TypeSyntax.Modifiers,
|
||||||
TypeSyntax.Keyword.Text,
|
TypeSyntax.Keyword.Text,
|
||||||
typeIdentifierName,
|
typeIdentifierName,
|
||||||
sourceTypeNamespace,
|
sourceTypeSymbol.ContainingNamespace.ToDisplayString(),
|
||||||
sourceTypeIdentifierName,
|
sourceTypeIdentifierName,
|
||||||
sourceTypeSymbol.ToDisplayString(),
|
sourceTypeSymbol.ToDisplayString(),
|
||||||
mappedProperties,
|
mappedProperties,
|
||||||
|
@ -324,15 +323,18 @@ namespace MapTo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? ToQualifiedDisplayName(ISymbol? typeSymbol)
|
private string? ToQualifiedDisplayName(ISymbol? symbol)
|
||||||
{
|
{
|
||||||
if (typeSymbol is null)
|
if (symbol is null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var typeNamespace = typeSymbol.ContainingNamespace.ToDisplayString();
|
var containingNamespace = TypeSyntax.GetNamespace();
|
||||||
return _ignoredNamespaces.Contains(typeNamespace) ? typeSymbol.ToDisplayString() : typeSymbol.Name;
|
var symbolNamespace = symbol.ContainingNamespace.ToDisplayString();
|
||||||
|
return containingNamespace != symbolNamespace && _ignoredNamespaces.Contains(symbol.ContainingNamespace.ToDisplayParts().First())
|
||||||
|
? symbol.ToDisplayString()
|
||||||
|
: symbol.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -155,27 +155,39 @@ namespace Test.Models
|
||||||
@"
|
@"
|
||||||
namespace Test
|
namespace Test
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public record InnerClass(int Prop1);
|
public class InnerClass
|
||||||
public record OuterClass(int Id, List<InnerClass> InnerProp);
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OuterClass
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public List<InnerClass> InnerClasses { get; set; }
|
||||||
|
public DateTime? SomeDate { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Test.Models
|
namespace Test.Models
|
||||||
{
|
{
|
||||||
using MapTo;
|
using MapTo;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
[MapFrom(typeof(Test.InnerClass))]
|
[MapFrom(typeof(Test.InnerClass))]
|
||||||
public partial record InnerClass(int Prop1);
|
public partial record InnerClass(int Id, string Name);
|
||||||
|
|
||||||
[MapFrom(typeof(Test.OuterClass))]
|
[MapFrom(typeof(Test.OuterClass))]
|
||||||
public partial record OuterClass(int Id, IReadOnlyList<InnerClass> InnerProp);
|
public partial record OuterClass(int Id, DateTime? SomeDate, IReadOnlyList<InnerClass> InnerClasses);
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
@"
|
@"
|
||||||
private protected OuterClass(MappingContext context, Test.OuterClass outerClass)
|
private protected OuterClass(MappingContext context, Test.OuterClass outerClass)
|
||||||
: this(Id: outerClass.Id, InnerProp: outerClass.InnerProp.Select(context.MapFromWithContext<Test.InnerClass, InnerClass>).ToList())
|
: this(Id: outerClass.Id, SomeDate: outerClass.SomeDate, InnerClasses: outerClass.InnerClasses.Select(context.MapFromWithContext<Test.InnerClass, InnerClass>).ToList())
|
||||||
{
|
{
|
||||||
if (context == null) throw new ArgumentNullException(nameof(context));
|
if (context == null) throw new ArgumentNullException(nameof(context));
|
||||||
if (outerClass == null) throw new ArgumentNullException(nameof(outerClass));
|
if (outerClass == null) throw new ArgumentNullException(nameof(outerClass));
|
||||||
|
|
|
@ -387,7 +387,7 @@ namespace Test
|
||||||
Prop1 = baz.Prop1;
|
Prop1 = baz.Prop1;
|
||||||
Prop2 = baz.Prop2;
|
Prop2 = baz.Prop2;
|
||||||
Prop3 = baz.Prop3;
|
Prop3 = baz.Prop3;
|
||||||
InnerProp1 = context.MapFromWithContext<Test.A, B>(baz.InnerProp1);
|
InnerProp1 = context.MapFromWithContext<A, B>(baz.InnerProp1);
|
||||||
}
|
}
|
||||||
".Trim();
|
".Trim();
|
||||||
|
|
||||||
|
@ -571,7 +571,6 @@ namespace Test.ViewModels2
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Test.ViewModels;
|
|
||||||
|
|
||||||
partial class ManagerViewModel
|
partial class ManagerViewModel
|
||||||
{
|
{
|
||||||
|
@ -586,7 +585,7 @@ namespace Test.ViewModels2
|
||||||
context.Register(manager, this);
|
context.Register(manager, this);
|
||||||
|
|
||||||
Level = manager.Level;
|
Level = manager.Level;
|
||||||
Employees = manager.Employees.Select(context.MapFromWithContext<Test.Data.Models.Employee, EmployeeViewModel>).ToList();
|
Employees = manager.Employees.Select(context.MapFromWithContext<Test.Data.Models.Employee, Test.ViewModels.EmployeeViewModel>).ToList();
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,51 @@ namespace Test
|
||||||
public static IEnumerable<object[]> VerifyMappedTypesData => new List<object[]>
|
public static IEnumerable<object[]> VerifyMappedTypesData => new List<object[]>
|
||||||
{
|
{
|
||||||
new object[] { new[] { MainSourceClass, NestedSourceClass, MainDestinationClass, NestedDestinationClass }, LanguageVersion.CSharp7_3 },
|
new object[] { new[] { MainSourceClass, NestedSourceClass, MainDestinationClass, NestedDestinationClass }, LanguageVersion.CSharp7_3 },
|
||||||
new object[] { new[] { MainSourceRecord, NestedSourceRecord, MainDestinationRecord, NestedDestinationRecord }, LanguageVersion.CSharp9 }
|
new object[] { new[] { MainSourceRecord, NestedSourceRecord, MainDestinationRecord, NestedDestinationRecord }, LanguageVersion.CSharp9 },
|
||||||
|
new object[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
@"
|
||||||
|
namespace Test.Classes.Classes1
|
||||||
|
{
|
||||||
|
public class Class1
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}",
|
||||||
|
@"
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Test.Classes.Classes1;
|
||||||
|
|
||||||
|
namespace Test.Classes.Classes2
|
||||||
|
{
|
||||||
|
public class Class2
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public List<Class1> Genres { get; set; }
|
||||||
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
}
|
||||||
|
}",
|
||||||
|
@"
|
||||||
|
using MapTo;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using TC = Test.Classes;
|
||||||
|
|
||||||
|
namespace Tests.Records
|
||||||
|
{
|
||||||
|
[MapFrom(typeof(Test.Classes.Classes1.Class1))]
|
||||||
|
public partial record Class1(int Id, string Name);
|
||||||
|
|
||||||
|
[MapFrom(typeof(Test.Classes.Classes2.Class2))]
|
||||||
|
public partial record Class2(int Id, IReadOnlyList<Class1> Genres);
|
||||||
|
}"
|
||||||
|
},
|
||||||
|
LanguageVersion.CSharp9
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -444,7 +488,8 @@ public partial record UserViewModel(
|
||||||
[MapProperty(SourcePropertyName = nameof(User.Id))]
|
[MapProperty(SourcePropertyName = nameof(User.Id))]
|
||||||
[MapTypeConverter(typeof(UserViewModel.IdConverter))]
|
[MapTypeConverter(typeof(UserViewModel.IdConverter))]
|
||||||
string Key,
|
string Key,
|
||||||
DateTimeOffset RegisteredAt)
|
DateTimeOffset RegisteredAt,
|
||||||
|
Profile Profile)
|
||||||
{
|
{
|
||||||
private class IdConverter : ITypeConverter<int, string>
|
private class IdConverter : ITypeConverter<int, string>
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue