Fixed generated code when a class extends multiple classes (#38)
* . * . * pnp * ok * compiles * ? * e * set * .ToArray() * n * ... * ok * pnp * . * . * mapster
This commit is contained in:
@@ -26,4 +26,9 @@ internal static class StringExtensions
|
||||
return result.ToString().Replace('-', '_');
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetLastPart(this string fullTypeName)
|
||||
{
|
||||
return fullTypeName.Split('.').LastOrDefault() ?? fullTypeName;
|
||||
}
|
||||
}
|
||||
@@ -31,13 +31,13 @@ internal abstract class BaseGenerator
|
||||
|
||||
protected bool TryFindProxyDataByTypeName(string type, [NotNullWhen(true)] out ProxyData? proxyData)
|
||||
{
|
||||
proxyData = Context.CandidateInterfaces.Values.FirstOrDefault(x => x.FullRawTypeName == type);
|
||||
proxyData = Context.Candidates.Values.FirstOrDefault(x => x.FullRawTypeName == type);
|
||||
if (proxyData != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var ci in Context.CandidateInterfaces.Values)
|
||||
foreach (var ci in Context.Candidates.Values)
|
||||
{
|
||||
foreach (var u in ci.Usings)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
|
||||
|
||||
public IEnumerable<FileData> GenerateFiles()
|
||||
{
|
||||
foreach (var ci in Context.CandidateInterfaces)
|
||||
foreach (var ci in Context.Candidates)
|
||||
{
|
||||
if (TryGenerateFile(ci.Key, ci.Value, out var file))
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ internal partial class ProxyClassesGenerator
|
||||
|
||||
str.AppendLine($" cfg.CreateMap<{replacedType.Key}, {replacedType.Value}>().ConstructUsing({instance} => new {classNameProxy}({instance}));");
|
||||
str.AppendLine($" cfg.CreateMap<{replacedType.Value}, {replacedType.Key}>().ConstructUsing({proxy} => (({classNameProxy}) {proxy})._Instance);");
|
||||
str.AppendLine();
|
||||
}
|
||||
str.AppendLine(" }).CreateMapper();");
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
|
||||
public IEnumerable<FileData> GenerateFiles()
|
||||
{
|
||||
foreach (var ci in Context.CandidateInterfaces)
|
||||
foreach (var ci in Context.Candidates)
|
||||
{
|
||||
if (TryGenerateFile(ci.Value, out var file))
|
||||
{
|
||||
@@ -39,12 +39,30 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
var className = targetClassSymbol.Symbol.ResolveProxyClassName();
|
||||
var constructorName = $"{targetClassSymbol.Symbol.Name}Proxy";
|
||||
|
||||
var extendsProxyClasses = targetClassSymbol.BaseTypes
|
||||
.Join(
|
||||
Context.CandidateInterfaces.Values,
|
||||
namedTypeSymbol => namedTypeSymbol.ToString(),
|
||||
proxyData => proxyData.FullRawTypeName, (_, proxyData) => proxyData
|
||||
).ToList();
|
||||
var extendsProxyClasses = new List<ProxyData>();
|
||||
foreach (var baseType in targetClassSymbol.BaseTypes)
|
||||
{
|
||||
var candidate = Context.Candidates.Values.FirstOrDefault(ci => ci.FullRawTypeName == baseType.ToString());
|
||||
if (candidate is not null)
|
||||
{
|
||||
extendsProxyClasses.Add(candidate);
|
||||
break;
|
||||
}
|
||||
|
||||
// Try to find with usings
|
||||
foreach (var @using in pd.Usings)
|
||||
{
|
||||
candidate = Context.Candidates.Values.FirstOrDefault(ci => $"{@using}.{ci.FullRawTypeName}" == baseType.ToString());
|
||||
if (candidate is not null)
|
||||
{
|
||||
// Update the FullRawTypeName
|
||||
candidate.FullRawTypeName = $"{@using}.{candidate.FullRawTypeName}";
|
||||
|
||||
extendsProxyClasses.Add(candidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileData = new FileData(
|
||||
$"{targetClassSymbol.Symbol.GetFileName()}Proxy.g.cs",
|
||||
@@ -62,12 +80,23 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
string className,
|
||||
string constructorName)
|
||||
{
|
||||
var extends = extendsProxyClasses.Select(e => $"{e.Namespace}.{e.ShortTypeName}Proxy, ").FirstOrDefault() ?? string.Empty;
|
||||
var @base = extendsProxyClasses.Any() ? " : base(instance)" : string.Empty;
|
||||
var @new = extendsProxyClasses.Any() ? "new " : string.Empty;
|
||||
var instanceBaseDefinition = extendsProxyClasses.Any() ? $"public {extendsProxyClasses[0].FullRawTypeName} _InstanceBase {{ get; }}\r\n" : string.Empty;
|
||||
var instanceBaseSet = extendsProxyClasses.Any() ? "_InstanceBase = instance;" : string.Empty;
|
||||
var firstExtends = extendsProxyClasses.FirstOrDefault();
|
||||
var extends = string.Empty;
|
||||
var @base = string.Empty;
|
||||
var @new = string.Empty;
|
||||
var instanceBaseDefinition = string.Empty;
|
||||
var instanceBaseSetter = string.Empty;
|
||||
|
||||
if (firstExtends is not null)
|
||||
{
|
||||
extends = $"{firstExtends.Namespace}.{firstExtends.ShortTypeName}Proxy, ";
|
||||
@base = " : base(instance)";
|
||||
@new = "new ";
|
||||
instanceBaseDefinition = $"public {firstExtends.FullRawTypeName} _Instance{firstExtends.FullRawTypeName.GetLastPart()} {{ get; }}";
|
||||
instanceBaseSetter = $"_Instance{firstExtends.FullRawTypeName.GetLastPart()} = instance;";
|
||||
}
|
||||
|
||||
var @abstract = string.Empty; // targetClassSymbol.Symbol.IsAbstract ? "abstract " : string.Empty;
|
||||
var properties = GeneratePublicProperties(targetClassSymbol, pd.ProxyBaseClasses);
|
||||
var methods = GeneratePublicMethods(targetClassSymbol, pd.ProxyBaseClasses, extendsProxyClasses);
|
||||
var events = GenerateEvents(targetClassSymbol, pd.ProxyBaseClasses);
|
||||
@@ -97,7 +126,7 @@ using System;
|
||||
|
||||
namespace {pd.Namespace}
|
||||
{{
|
||||
public partial class {className} : {extends}{interfaceName}
|
||||
public {@abstract}partial class {className} : {extends}{interfaceName}
|
||||
{{
|
||||
public {@new}{targetClassSymbol.Symbol} _Instance {{ get; }}
|
||||
{instanceBaseDefinition}
|
||||
@@ -111,7 +140,7 @@ namespace {pd.Namespace}
|
||||
public {constructorName}({targetClassSymbol} instance){@base}
|
||||
{{
|
||||
_Instance = instance;
|
||||
{instanceBaseSet}
|
||||
{instanceBaseSetter}
|
||||
|
||||
{configurationForAutoMapper}
|
||||
}}
|
||||
@@ -220,7 +249,7 @@ namespace {pd.Namespace}
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = GetParameterType(ps, out var isReplaced);
|
||||
_ = GetParameterType(ps, out var isReplaced); // TODO : response is not used?
|
||||
if (isReplaced)
|
||||
{
|
||||
normalOrMap = $" = _mapper.Map<{ps.Type}>({ps.GetSanitizedName()})";
|
||||
|
||||
@@ -9,7 +9,7 @@ internal record Context
|
||||
|
||||
// public List<ContextData> GeneratedData { get; } = new List<ContextData>();
|
||||
|
||||
public IDictionary<InterfaceDeclarationSyntax, ProxyData> CandidateInterfaces { get; init; } = default!;
|
||||
public IDictionary<InterfaceDeclarationSyntax, ProxyData> Candidates { get; init; } = default!;
|
||||
|
||||
public Dictionary<string, string> ReplacedTypes { get; } = new();
|
||||
}
|
||||
@@ -5,7 +5,7 @@ internal class ProxyData
|
||||
public string Namespace { get; init; }
|
||||
public string ShortInterfaceName { get; init; }
|
||||
public string FullInterfaceName { get; init; }
|
||||
public string FullRawTypeName { get; init; }
|
||||
public string FullRawTypeName { get; set; }
|
||||
public string ShortTypeName { get; init; }
|
||||
public string FullTypeName { get; init; }
|
||||
public List<string> Usings { get; init; }
|
||||
|
||||
@@ -63,7 +63,7 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
var context = new Context
|
||||
{
|
||||
GeneratorExecutionContext = ctx,
|
||||
CandidateInterfaces = receiver.CandidateInterfaces
|
||||
Candidates = receiver.CandidateInterfaces
|
||||
};
|
||||
|
||||
var attributeData = _proxyAttributeGenerator.GenerateFile();
|
||||
@@ -75,7 +75,7 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
var context = new Context
|
||||
{
|
||||
GeneratorExecutionContext = ctx,
|
||||
CandidateInterfaces = receiver.CandidateInterfaces
|
||||
Candidates = receiver.CandidateInterfaces
|
||||
};
|
||||
|
||||
var partialInterfacesGenerator = new PartialInterfacesGenerator(context, supportsNullable);
|
||||
@@ -90,7 +90,7 @@ internal class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
var context = new Context
|
||||
{
|
||||
GeneratorExecutionContext = ctx,
|
||||
CandidateInterfaces = receiver.CandidateInterfaces
|
||||
Candidates = receiver.CandidateInterfaces
|
||||
};
|
||||
|
||||
var proxyClassesGenerator = new ProxyClassesGenerator(context, supportsNullable);
|
||||
|
||||
@@ -77,7 +77,7 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
{
|
||||
Namespace = ns,
|
||||
ShortInterfaceName = interfaceDeclarationSyntax.Identifier.ToString(),
|
||||
FullInterfaceName = CreateFullBuilderClassName(ns, interfaceDeclarationSyntax), // $"{ns}.{interfaceDeclarationSyntax.Identifier}",
|
||||
FullInterfaceName = CreateFullInterfaceName(ns, interfaceDeclarationSyntax), // $"{ns}.{interfaceDeclarationSyntax.Identifier}",
|
||||
FullRawTypeName = rawTypeName,
|
||||
ShortTypeName = ConvertTypeName(rawTypeName).Split('.').Last(),
|
||||
FullTypeName = ConvertTypeName(rawTypeName),
|
||||
@@ -95,7 +95,7 @@ internal class ProxySyntaxReceiver : ISyntaxReceiver
|
||||
$"{typeName.Replace("<", string.Empty).Replace(">", string.Empty).Replace(",", string.Empty).Trim()}`{typeName.Count(c => c == ',') + 1}";
|
||||
}
|
||||
|
||||
private static string CreateFullBuilderClassName(string ns, BaseTypeDeclarationSyntax classDeclarationSyntax)
|
||||
private static string CreateFullInterfaceName(string ns, BaseTypeDeclarationSyntax classDeclarationSyntax)
|
||||
{
|
||||
return !string.IsNullOrEmpty(ns) ? $"{ns}.{classDeclarationSyntax.Identifier}" : classDeclarationSyntax.Identifier.ToString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user