Optimized namespace discovery.
This commit is contained in:
parent
bfd6dafe78
commit
9ab0e4eb25
|
@ -11,7 +11,7 @@ namespace MapTo
|
|||
{
|
||||
internal abstract class MappingContext
|
||||
{
|
||||
private readonly List<string> _ignoredNamespaces;
|
||||
private readonly List<SymbolDisplayPart> _ignoredNamespaces;
|
||||
|
||||
protected MappingContext(Compilation compilation, SourceGenerationOptions sourceGenerationOptions, TypeDeclarationSyntax typeSyntax)
|
||||
{
|
||||
|
@ -76,14 +76,14 @@ namespace MapTo
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (condition && ns is not null &&
|
||||
ns != TypeSyntax.GetNamespace() &&
|
||||
!_ignoredNamespaces.Contains(ns) &&
|
||||
!Usings.Contains(ns))
|
||||
if (ns is not null && condition && ns != TypeSyntax.GetNamespace() && !Usings.Contains(ns))
|
||||
{
|
||||
Usings = Usings.Add(ns);
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ namespace MapTo
|
|||
|
||||
return new MappedProperty(
|
||||
property.Name,
|
||||
propertyType.Name,
|
||||
ToQualifiedDisplayName(propertyType) ?? propertyType.Name,
|
||||
converterFullyQualifiedName,
|
||||
converterParameters.ToImmutableArray(),
|
||||
sourceProperty.Name,
|
||||
|
@ -253,8 +253,7 @@ namespace MapTo
|
|||
return null;
|
||||
}
|
||||
|
||||
var sourceTypeNamespace = sourceTypeSymbol.ContainingNamespace.ToDisplayString();
|
||||
_ignoredNamespaces.Add(sourceTypeNamespace);
|
||||
_ignoredNamespaces.Add(sourceTypeSymbol.ContainingNamespace.ToDisplayParts().First());
|
||||
|
||||
var typeIdentifierName = TypeSyntax.GetIdentifierName();
|
||||
var sourceTypeIdentifierName = sourceTypeSymbol.Name;
|
||||
|
@ -276,7 +275,7 @@ namespace MapTo
|
|||
TypeSyntax.Modifiers,
|
||||
TypeSyntax.Keyword.Text,
|
||||
typeIdentifierName,
|
||||
sourceTypeNamespace,
|
||||
sourceTypeSymbol.ContainingNamespace.ToDisplayString(),
|
||||
sourceTypeIdentifierName,
|
||||
sourceTypeSymbol.ToDisplayString(),
|
||||
mappedProperties,
|
||||
|
@ -324,15 +323,18 @@ namespace MapTo
|
|||
return false;
|
||||
}
|
||||
|
||||
private string? ToQualifiedDisplayName(ISymbol? typeSymbol)
|
||||
private string? ToQualifiedDisplayName(ISymbol? symbol)
|
||||
{
|
||||
if (typeSymbol is null)
|
||||
if (symbol is null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var typeNamespace = typeSymbol.ContainingNamespace.ToDisplayString();
|
||||
return _ignoredNamespaces.Contains(typeNamespace) ? typeSymbol.ToDisplayString() : typeSymbol.Name;
|
||||
var containingNamespace = TypeSyntax.GetNamespace();
|
||||
var symbolNamespace = symbol.ContainingNamespace.ToDisplayString();
|
||||
return containingNamespace != symbolNamespace && _ignoredNamespaces.Contains(symbol.ContainingNamespace.ToDisplayParts().First())
|
||||
? symbol.ToDisplayString()
|
||||
: symbol.Name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,15 +108,15 @@ namespace MapTo
|
|||
new object[]
|
||||
{
|
||||
@"
|
||||
namespace Test
|
||||
namespace Test
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class InnerClass { public int Prop1 { get; set; } }
|
||||
public class OuterClass
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public List<InnerClass> InnerProp { get; set; }
|
||||
public class OuterClass
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public List<InnerClass> InnerProp { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,10 +129,10 @@ namespace Test.Models
|
|||
public partial class InnerClass { public int Prop1 { get; set; } }
|
||||
|
||||
[MapFrom(typeof(Test.OuterClass))]
|
||||
public partial class OuterClass
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public IReadOnlyList<InnerClass> InnerProp { get; set; }
|
||||
public partial class OuterClass
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public IReadOnlyList<InnerClass> InnerProp { get; set; }
|
||||
}
|
||||
}
|
||||
",
|
||||
|
@ -155,27 +155,39 @@ namespace Test.Models
|
|||
@"
|
||||
namespace Test
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public record InnerClass(int Prop1);
|
||||
public record OuterClass(int Id, List<InnerClass> InnerProp);
|
||||
public class InnerClass
|
||||
{
|
||||
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
|
||||
{
|
||||
using MapTo;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[MapFrom(typeof(Test.InnerClass))]
|
||||
public partial record InnerClass(int Prop1);
|
||||
public partial record InnerClass(int Id, string Name);
|
||||
|
||||
[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)
|
||||
: 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 (outerClass == null) throw new ArgumentNullException(nameof(outerClass));
|
||||
|
|
|
@ -387,7 +387,7 @@ namespace Test
|
|||
Prop1 = baz.Prop1;
|
||||
Prop2 = baz.Prop2;
|
||||
Prop3 = baz.Prop3;
|
||||
InnerProp1 = context.MapFromWithContext<Test.A, B>(baz.InnerProp1);
|
||||
InnerProp1 = context.MapFromWithContext<A, B>(baz.InnerProp1);
|
||||
}
|
||||
".Trim();
|
||||
|
||||
|
@ -571,11 +571,10 @@ namespace Test.ViewModels2
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Test.ViewModels;
|
||||
|
||||
partial class ManagerViewModel
|
||||
{
|
||||
public ManagerViewModel(Test.Data.Models.Manager manager)
|
||||
public ManagerViewModel(Test.Data.Models.Manager manager)
|
||||
: this(new MappingContext(), manager) { }
|
||||
|
||||
private protected ManagerViewModel(MappingContext context, Test.Data.Models.Manager manager) : base(context, manager)
|
||||
|
@ -586,7 +585,7 @@ namespace Test.ViewModels2
|
|||
context.Register(manager, this);
|
||||
|
||||
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[]>
|
||||
{
|
||||
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]
|
||||
|
@ -444,7 +488,8 @@ public partial record UserViewModel(
|
|||
[MapProperty(SourcePropertyName = nameof(User.Id))]
|
||||
[MapTypeConverter(typeof(UserViewModel.IdConverter))]
|
||||
string Key,
|
||||
DateTimeOffset RegisteredAt)
|
||||
DateTimeOffset RegisteredAt,
|
||||
Profile Profile)
|
||||
{
|
||||
private class IdConverter : ITypeConverter<int, string>
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue