Добавлена поддержка нескольких параметров в кодген

This commit is contained in:
2025-03-07 09:01:21 +03:00
parent c802f337c7
commit 8d082d1ed4
9 changed files with 80 additions and 25 deletions
+36 -16
View File
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -20,45 +22,59 @@ namespace mROA.Codegen
private void GenerateCode(GeneratorExecutionContext context, Compilation compilation,
ImmutableArray<InterfaceDeclarationSyntax> classes)
{
// For future
// var asm = Assembly.GetAssembly(typeof(mROASourceGenerator));
// var files = asm.GetManifestResourceNames();
// var test = asm.GetManifestResourceStream("mROA.Codegen.test.tpt");
// var reader = new StreamReader(test);
// var allText = reader.ReadToEnd();
var methods = new List<(string, IMethodSymbol)>();
var frontendContextRepo = new List<string>();
var declarations = classes.ToList().OrderBy(i => i.Identifier.Text).ToList();
foreach (var classDeclarationSyntax in declarations)
{
{
var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
if (semanticModel.GetDeclaredSymbol(classDeclarationSyntax) is not INamedTypeSymbol classSymbol)
continue;
var namespaceName = classSymbol.ContainingNamespace.ToDisplayString();
var className = classDeclarationSyntax.Identifier.Text;
var methodBody = CollectMethods(classSymbol);
var innerMembers = CollectMembers(classSymbol);
var associated = innerMembers.Select(i => i.AssociatedSymbol).Where(i => i != null).Select(i => i!).Distinct(SymbolEqualityComparer.Default).ToList();
var originalName = className;
className = className.TrimStart('I') + "RemoteEndpoint";
var methodsText = new List<string>();
foreach (var method in methodBody)
var remoteEndpointMember = new List<string>();
foreach (var method in innerMembers.OfType<IMethodSymbol>())
{
if (method.MethodKind is MethodKind.EventAdd or MethodKind.EventRemove)
continue;
var index = methods.Count;
methods.Add((namespaceName + "." + originalName, method));
var sb = new StringBuilder();
bool isParametrized;
bool isAsync;
bool isVoid;
List<IParameterSymbol>? parameters;
switch (method.ReturnType)
{
case INamedTypeSymbol namedType:
isAsync = namedType.Name == "Task";
isVoid = isAsync && namedType.TypeParameters.Length == 0 || namedType.Name == "Void";
isParametrized = method.Parameters.Length == 1 && !isAsync ||
method.Parameters.Length == 2 && isAsync;
parameters = method.Parameters.ToList();
parameters.RemoveAll(i => i.Type.Name is "CancellationToken" or "RequestContext");
isParametrized = parameters.Count != 0;
break;
case IArrayTypeSymbol:
isAsync = false;
@@ -77,8 +93,10 @@ namespace mROA.Codegen
var prefix = isAsync ? "await " : "";
var postfix = !isAsync ? (isVoid ? ".Wait()" : ".GetAwaiter().GetResult()") : "";
var parameterLink = isParametrized ? ", " + method.Parameters.First().Name : string.Empty;
var postfix = !isAsync ? isVoid ? ".Wait()" : ".GetAwaiter().GetResult()" : "";
var parameterLink = isParametrized
? ", new object[] {" + string.Join(", ", method.Parameters.Select(i => i.Name)) + "}"
: string.Empty;
var tokenInsert = isAsync
? isParametrized
? ", cancellationToken : " + method.Parameters[1].Name
@@ -97,7 +115,7 @@ namespace mROA.Codegen
sb.AppendLine("\t\t}");
methodsText.Add(sb.ToString());
remoteEndpointMember.Add(sb.ToString());
}
var code = $@"// <auto-generated/>
@@ -116,7 +134,7 @@ namespace {namespaceName}
{{
}}
{string.Join("\r\n\t", methodsText)}
{string.Join("\r\n\t", remoteEndpointMember)}
}}
}}
";
@@ -243,7 +261,8 @@ namespace mROA.Codegen
private bool ContainsSOIAttribute(SyntaxList<AttributeListSyntax> attributes, GeneratorExecutionContext context,
InterfaceDeclarationSyntax interfaceDeclarationSyntax)
{
foreach (var attributeSyntax in attributes.SelectMany(attributeListSyntax => attributeListSyntax.Attributes))
foreach (var attributeSyntax in
attributes.SelectMany(attributeListSyntax => attributeListSyntax.Attributes))
{
if (context.Compilation.GetSemanticModel(interfaceDeclarationSyntax.SyntaxTree)
.GetSymbolInfo(attributeSyntax).Symbol is not IMethodSymbol attributeSymbol)
@@ -259,7 +278,7 @@ namespace mROA.Codegen
return false;
}
private List<IMethodSymbol> CollectMethods(INamedTypeSymbol type)
private List<IMethodSymbol> CollectMembers(INamedTypeSymbol type)
{
var methods = type.GetMembers().OfType<IMethodSymbol>().ToList();
foreach (var inner in type.AllInterfaces)
@@ -267,6 +286,7 @@ namespace mROA.Codegen
methods.AddRange(inner.GetMembers().OfType<IMethodSymbol>());
}
methods.RemoveAll(m => m.Name == "Dispose");
return methods.OrderBy(i => i.Name).ToList();
}
}