nested projectors

This commit is contained in:
honzapatCZ 2025-01-12 22:40:54 +01:00
parent 563168239e
commit 74a2e5ea00

View File

@ -521,7 +521,12 @@ namespace AutoMapProperty
sb.Append(method.ContainingType.ToDisplayString()).Append(".").Append(method.Name); sb.Append(method.ContainingType.ToDisplayString()).Append(".").Append(method.Name);
return sb.ToString(); return sb.ToString();
} }
public static string GeneratePropertyFrom(List<ClassToGenerate> otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool nullable = true, string prefix = "")
public static string GetProjectorName(ClassToGenerate cls)
{
return cls.Name.ToLower();
}
public static string GeneratePropertyFrom(List<ClassToGenerate> otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool allowProjectors, List<ClassToGenerate>? requiredProjectors, bool nullable = true, string prefix = "")
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.Append(Key).Append(@" = "); sb.Append(Key).Append(@" = ");
@ -538,8 +543,18 @@ namespace AutoMapProperty
sb.Append(nullable ? "?" : ""); sb.Append(nullable ? "?" : "");
if (!SymbolEqualityComparer.Default.Equals(concreteToType, concreteFromType)) if (!SymbolEqualityComparer.Default.Equals(concreteToType, concreteFromType))
{ {
sb.Append(@".Select(x => (").Append(GetFullString(concreteToType)).Append(@")x)"); var otherCls = otherClasses.FirstOrDefault(x => x.Name == concreteToType.Name);
sb.Append(nullable ? "?" : ""); if (otherCls != null && allowProjectors)
{
sb.Append(@".Select(x => ").Append(GetProjectorName(otherCls)).Append(@".Invoke(x))");
sb.Append(nullable ? "?" : "");
requiredProjectors!.Add(otherCls);
}
else
{
sb.Append(@".Select(x => (").Append(GetFullString(concreteToType)).Append(@")x)");
sb.Append(nullable ? "?" : "");
}
} }
//Add the appropriate ToHashSet or ToSet or ToCollection or ToList //Add the appropriate ToHashSet or ToSet or ToCollection or ToList
@ -568,7 +583,7 @@ namespace AutoMapProperty
{"); {");
foreach (var prop in classToGenerate.MappableProperties) foreach (var prop in classToGenerate.MappableProperties)
{ {
var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false, prefix + "." + Key); var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, allowProjectors, requiredProjectors, false, prefix + "." + Key);
if (property == null) if (property == null)
continue; continue;
@ -588,11 +603,11 @@ namespace AutoMapProperty
return symbol.ToDisplayString(format: displayFormat); return symbol.ToDisplayString(format: displayFormat);
} }
public static string? GenerateCorrectFromProperty(List<ClassToGenerate> otherClasses, string Key, ClassToGenerate.MappableTypes Value, bool nullable = true, string prefix = "") public static string? GenerateCorrectFromProperty(List<ClassToGenerate> otherClasses, string Key, ClassToGenerate.MappableTypes Value, bool allowProjectors, List<ClassToGenerate>? requiredProjectors, bool nullable = true, string prefix = "")
{ {
if (!Value.CustomFrom) if (!Value.CustomFrom)
{ {
return GeneratePropertyFrom(otherClasses, Key, Value.FromType, Value.ToType, nullable, prefix); return GeneratePropertyFrom(otherClasses, Key, Value.FromType, Value.ToType, allowProjectors, requiredProjectors, nullable, prefix);
} }
else else
{ {
@ -604,6 +619,30 @@ namespace AutoMapProperty
return sb.ToString(); return sb.ToString();
} }
} }
private static (string, List<ClassToGenerate>) GenerateFromExpression(List<ClassToGenerate> otherClasses, ClassToGenerate classToGenerate, SyntaxToken sourceName)
{
var projectors = new List<ClassToGenerate>();
var exprSb = new StringBuilder();
exprSb.Append(@"System.Linq.Expressions.Expression<Func<").Append(sourceName).Append(@", ").Append(classToGenerate.Name).Append(@">> expr = (").Append(sourceName).Append(" source)=>new ").Append(classToGenerate.Name).Append(@"()
{");
foreach (var prop in classToGenerate.MappableProperties)
{
var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, true, projectors, false);
if (property == null)
continue;
exprSb.Append(@"
").Append(property).Append(@",");
}
exprSb.Append(@"
};
return expr.Expand();
");
return (exprSb.ToString(), projectors);
}
public static string? GeneratePropertyTo(List<ClassToGenerate> otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool nullable = true) public static string? GeneratePropertyTo(List<ClassToGenerate> otherClasses, string Key, ITypeSymbol FromType, ITypeSymbol ToType, bool nullable = true)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -685,6 +724,7 @@ namespace AutoMapProperty
retSb.Append(";"); retSb.Append(";");
return retSb.ToString(); return retSb.ToString();
} }
public static string? GenerateEqualityOperator(string name, ClassToGenerate.MappableTypes Value, string? prefix = null) public static string? GenerateEqualityOperator(string name, ClassToGenerate.MappableTypes Value, string? prefix = null)
{ {
var prefixedName = prefix == null ? name : prefix + "." + name; var prefixedName = prefix == null ? name : prefix + "." + name;
@ -735,6 +775,7 @@ namespace AutoMapProperty
} }
sb.Append(@" sb.Append(@"
using LinqKit;
#nullable enable #nullable enable
#pragma warning disable CS8600 #pragma warning disable CS8600
@ -789,7 +830,7 @@ namespace ").Append(classToGenerate.Namespace).Append(@"
{"); {");
foreach (var prop in classToGenerate.MappableProperties) foreach (var prop in classToGenerate.MappableProperties)
{ {
var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value); var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false, null);
if (property == null) if (property == null)
continue; continue;
@ -801,19 +842,19 @@ namespace ").Append(classToGenerate.Namespace).Append(@"
return this; return this;
}"); }");
sb.Append(@" sb.Append(@"
public new System.Linq.Expressions.Expression<Func<").Append(classToGenerate.SourceContainer.Identifier).Append(", ").Append(classToGenerate.Name).Append(@">> GetProjectorFrom(System.IServiceProvider providers) => (source)=>new ").Append(classToGenerate.Name).Append(@"() public new System.Linq.Expressions.Expression<Func<").Append(classToGenerate.SourceContainer.Identifier).Append(", ").Append(classToGenerate.Name).Append(@">> GetProjectorFrom(System.IServiceProvider providers) {
{");
foreach (var prop in classToGenerate.MappableProperties) ");
{ var (expr, projectors) = GenerateFromExpression(otherClasses, classToGenerate, classToGenerate.SourceContainer.Identifier);
var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false);
if (property == null)
continue;
sb.Append(@" foreach (var projector in projectors.Distinct())
").Append(property).Append(@","); {
sb.Append("var ").Append(GetProjectorName(projector)).Append(@" = new ").Append(projector.Name).Append(@"().GetProjectorFrom(providers);
");
} }
sb.Append(expr);
sb.Append(@" sb.Append(@"
};"); }");
sb.Append(@" sb.Append(@"
public static new System.Linq.Expressions.Expression<Func<").Append(classToGenerate.Name).Append(@", bool>> EqualExpression(System.IServiceProvider providers,").Append(classToGenerate.SourceContainer.Identifier).Append(@" item1) => (item2)=> public static new System.Linq.Expressions.Expression<Func<").Append(classToGenerate.Name).Append(@", bool>> EqualExpression(System.IServiceProvider providers,").Append(classToGenerate.SourceContainer.Identifier).Append(@" item1) => (item2)=>