ProxyBaseClasses (#27)

This commit is contained in:
Stef Heyenrath
2022-02-01 18:49:01 +01:00
committed by GitHub
parent 649ed89bb6
commit f9664e0564
45 changed files with 1305 additions and 836 deletions
@@ -1,85 +1,91 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using ProxyInterfaceSourceGenerator.Extensions;
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver
namespace ProxyInterfaceSourceGenerator.SyntaxReceiver;
internal class ProxySyntaxReceiver : ISyntaxReceiver
{
internal class ProxySyntaxReceiver : ISyntaxReceiver
private static readonly string[] Modifiers = { "public", "partial" };
public IDictionary<InterfaceDeclarationSyntax, ProxyData> CandidateInterfaces { get; } = new Dictionary<InterfaceDeclarationSyntax, ProxyData>();
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
private static readonly string[] Modifiers = new[] { "public", "partial" };
public IDictionary<InterfaceDeclarationSyntax, ProxyData> CandidateInterfaces { get; } = new Dictionary<InterfaceDeclarationSyntax, ProxyData>();
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
if (syntaxNode is InterfaceDeclarationSyntax interfaceDeclarationSyntax && TryGet(interfaceDeclarationSyntax, out var data))
{
if (syntaxNode is InterfaceDeclarationSyntax interfaceDeclarationSyntax && TryGet(interfaceDeclarationSyntax, out var data))
{
CandidateInterfaces.Add(interfaceDeclarationSyntax, data);
}
}
private static bool TryGet(InterfaceDeclarationSyntax interfaceDeclarationSyntax, [NotNullWhen(true)] out ProxyData? data)
{
data = null;
if (interfaceDeclarationSyntax.Modifiers.Select(m => m.ToString()).Except(Modifiers).Count() != 0)
{
// InterfaceDeclarationSyntax should be "public" and "partial"
return false;
}
var attributeLists = interfaceDeclarationSyntax.AttributeLists.FirstOrDefault(x => x.Attributes.Any(a => a.Name.ToString().Equals("ProxyInterfaceGenerator.Proxy")));
if (attributeLists is null)
{
return false;
}
var argumentList = attributeLists.Attributes.FirstOrDefault()?.ArgumentList;
if (argumentList is null)
{
return false;
}
var usings = new List<string>();
string ns = string.Empty;
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out NamespaceDeclarationSyntax? namespaceDeclarationSyntax))
{
ns = namespaceDeclarationSyntax.Name.ToString();
usings.Add(ns);
}
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out CompilationUnitSyntax? cc))
{
foreach (var @using in cc.Usings)
{
usings.Add(@using.Name.ToString());
}
}
string rawTypeName = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type.ToString();
data = new
(
ns,
interfaceDeclarationSyntax.Identifier.ToString(),
rawTypeName,
ConvertTypeName(rawTypeName),
usings,
false //bool.Parse(argumentList.Arguments[1].Expression.GetText().ToString())
);
return true;
}
private static string ConvertTypeName(string typeName)
{
return !(typeName.Contains('<') && typeName.Contains('>')) ?
typeName :
$"{typeName.Replace("<", string.Empty).Replace(">", string.Empty).Replace(",", string.Empty).Trim()}`{typeName.Count(c => c == ',') + 1}";
CandidateInterfaces.Add(interfaceDeclarationSyntax, data);
}
}
private static bool TryGet(InterfaceDeclarationSyntax interfaceDeclarationSyntax, [NotNullWhen(true)] out ProxyData? data)
{
data = null;
if (interfaceDeclarationSyntax.Modifiers.Select(m => m.ToString()).Except(Modifiers).Count() != 0)
{
// InterfaceDeclarationSyntax should be "public" and "partial"
return false;
}
var attributeLists = interfaceDeclarationSyntax.AttributeLists.FirstOrDefault(x => x.Attributes.Any(a => a.Name.ToString().Equals("ProxyInterfaceGenerator.Proxy")));
if (attributeLists is null)
{
return false;
}
var argumentList = attributeLists.Attributes.FirstOrDefault()?.ArgumentList;
if (argumentList is null)
{
return false;
}
var usings = new List<string>();
string ns = string.Empty;
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out NamespaceDeclarationSyntax? namespaceDeclarationSyntax))
{
ns = namespaceDeclarationSyntax.Name.ToString();
usings.Add(ns);
}
if (SyntaxNodeUtils.TryGetParentSyntax(interfaceDeclarationSyntax, out CompilationUnitSyntax? cc))
{
foreach (var @using in cc.Usings)
{
usings.Add(@using.Name.ToString());
}
}
string rawTypeName = ((TypeOfExpressionSyntax)argumentList.Arguments[0].Expression).Type.ToString();
bool proxyAllClasses;
try
{
proxyAllClasses = bool.Parse(((LiteralExpressionSyntax)argumentList.Arguments[1].Expression).ToString());
}
catch
{
proxyAllClasses = false;
}
data = new
(
ns,
interfaceDeclarationSyntax.Identifier.ToString(),
rawTypeName,
ConvertTypeName(rawTypeName),
usings,
proxyAllClasses
);
return true;
}
private static string ConvertTypeName(string typeName)
{
return !(typeName.Contains('<') && typeName.Contains('>')) ?
typeName :
$"{typeName.Replace("<", string.Empty).Replace(">", string.Empty).Replace(",", string.Empty).Trim()}`{typeName.Count(c => c == ',') + 1}";
}
}