Добавлена поддержка нескольких параметров в кодген
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user