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);
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();
sb.Append(Key).Append(@" = ");
@ -537,10 +542,20 @@ namespace AutoMapProperty
sb.Append("source").Append(prefix).Append(".").Append(Key);
sb.Append(nullable ? "?" : "");
if (!SymbolEqualityComparer.Default.Equals(concreteToType, concreteFromType))
{
var otherCls = otherClasses.FirstOrDefault(x => x.Name == concreteToType.Name);
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
if (ToType.Name.Contains("Set"))
@ -568,7 +583,7 @@ namespace AutoMapProperty
{");
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)
continue;
@ -588,11 +603,11 @@ namespace AutoMapProperty
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)
{
return GeneratePropertyFrom(otherClasses, Key, Value.FromType, Value.ToType, nullable, prefix);
return GeneratePropertyFrom(otherClasses, Key, Value.FromType, Value.ToType, allowProjectors, requiredProjectors, nullable, prefix);
}
else
{
@ -604,6 +619,30 @@ namespace AutoMapProperty
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)
{
var sb = new StringBuilder();
@ -685,6 +724,7 @@ namespace AutoMapProperty
retSb.Append(";");
return retSb.ToString();
}
public static string? GenerateEqualityOperator(string name, ClassToGenerate.MappableTypes Value, string? prefix = null)
{
var prefixedName = prefix == null ? name : prefix + "." + name;
@ -735,6 +775,7 @@ namespace AutoMapProperty
}
sb.Append(@"
using LinqKit;
#nullable enable
#pragma warning disable CS8600
@ -789,7 +830,7 @@ namespace ").Append(classToGenerate.Namespace).Append(@"
{");
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)
continue;
@ -801,19 +842,19 @@ namespace ").Append(classToGenerate.Namespace).Append(@"
return this;
}");
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(@"()
{");
foreach (var prop in classToGenerate.MappableProperties)
{
var property = GenerateCorrectFromProperty(otherClasses, prop.Key, prop.Value, false);
if (property == null)
continue;
public new System.Linq.Expressions.Expression<Func<").Append(classToGenerate.SourceContainer.Identifier).Append(", ").Append(classToGenerate.Name).Append(@">> GetProjectorFrom(System.IServiceProvider providers) {
sb.Append(@"
").Append(property).Append(@",");
");
var (expr, projectors) = GenerateFromExpression(otherClasses, classToGenerate, classToGenerate.SourceContainer.Identifier);
foreach (var projector in projectors.Distinct())
{
sb.Append("var ").Append(GetProjectorName(projector)).Append(@" = new ").Append(projector.Name).Append(@"().GetProjectorFrom(providers);
");
}
sb.Append(expr);
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)=>