Переделано написание инвокеров

This commit is contained in:
2025-03-27 17:41:16 +03:00
parent c4d9a54942
commit 22d627cf9c
4 changed files with 50 additions and 25 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Example.Backend
[SharedObjectSingleton] [SharedObjectSingleton]
public class PrinterFactory : IPrinterFactory public class PrinterFactory : IPrinterFactory
{ {
private List<IPrinter> _printers = new List<IPrinter>(); private readonly List<IPrinter> _printers = new();
public IPrinter Create(string printerName) public IPrinter Create(string printerName)
{ {
+18
View File
@@ -13,6 +13,24 @@ namespace mROA.Codegen
private readonly List<IMethodInvoker> _methods = new () { private readonly List<IMethodInvoker> _methods = new () {
<!I invoker r sep invokerSep><!D invokerSep>, <!I invoker r sep invokerSep><!D invokerSep>,
<!D> <!D>
<!T asyncInvoker>
new mROA.Implementation.AsyncMethodInvoker
{
IsVoid = <!L isVoid>,
ReturnType = typeof(<!L returnType>),
ParameterTypes = new Type[] { <!L parametersType> },
SuitableType = typeof(<!L suitableType>),
Invoking = (i, parameters, special, post) => <!L funcInvoking>,
}<!T>
<!T syncInvoker>
new mROA.Implementation.MethodInvoker
{
IsVoid = <!L isVoid>,
ReturnType = typeof(<!L returnType>),
ParameterTypes = new Type[] { <!L parametersType> },
SuitableType = typeof(<!L suitableType>),
Invoking = (i, parameters, special) => <!L funcInvoking>,
}<!T>
}; };
public IMethodInvoker GetMethod(int id) public IMethodInvoker GetMethod(int id)
+2
View File
@@ -55,5 +55,7 @@ namespace mROA.CodegenTools
{ {
Parts.Add(new DefineTemplateSection(text, tag, this)); Parts.Add(new DefineTemplateSection(text, tag, this));
} }
public void AddDefine(string tag, object value) => AddDefine(tag, value.ToString());
} }
} }
+28 -23
View File
@@ -80,8 +80,6 @@ namespace mROA.Codegen
private void GenerateCode(GeneratorExecutionContext context, Compilation compilation, private void GenerateCode(GeneratorExecutionContext context, Compilation compilation,
ImmutableArray<InterfaceDeclarationSyntax> classes) ImmutableArray<InterfaceDeclarationSyntax> classes)
{ {
List<IMethodSymbol> totalMethods = new List<IMethodSymbol>(); List<IMethodSymbol> totalMethods = new List<IMethodSymbol>();
@@ -215,7 +213,8 @@ namespace mROA.Codegen
InterfaceTemplate.AddDefine("name", classSymbol.Name); InterfaceTemplate.AddDefine("name", classSymbol.Name);
InterfaceTemplate.AddDefine("namespace", classSymbol.ContainingNamespace.ToDisplayString()); InterfaceTemplate.AddDefine("namespace", classSymbol.ContainingNamespace.ToDisplayString());
var singleEventBinder = new List<string>(events.Count); var singleEventBinder = new List<string>(events.Count);
var objectBinderTemplate = (TemplateDocument)((InnerTemplateSection)BinderTemplate["objectBinderTemplate"]).InnerTemplate.Clone(); var objectBinderTemplate =
(TemplateDocument)((InnerTemplateSection)BinderTemplate["objectBinderTemplate"]).InnerTemplate.Clone();
for (int i = 0; i < events.Count; i++) for (int i = 0; i < events.Count; i++)
{ {
var currentEvent = events[i]; var currentEvent = events[i];
@@ -228,6 +227,7 @@ namespace mROA.Codegen
GenerateEventCode(currentEvent, invokers, classSymbol); GenerateEventCode(currentEvent, invokers, classSymbol);
GenerateBinderCode(currentEvent, invokers, classSymbol, objectBinderTemplate); GenerateBinderCode(currentEvent, invokers, classSymbol, objectBinderTemplate);
} }
objectBinderTemplate.AddDefine("type", classSymbol.ToDisplayString()); objectBinderTemplate.AddDefine("type", classSymbol.ToDisplayString());
var partialInterface = InterfaceTemplate.Compile(); var partialInterface = InterfaceTemplate.Compile();
var binder = objectBinderTemplate.Compile(); var binder = objectBinderTemplate.Compile();
@@ -377,23 +377,26 @@ namespace mROA.Codegen
} }
if (isAsync) if (isAsync)
backend = $@"new mROA.Implementation.AsyncMethodInvoker {
{level}{{ var invokerTemplate = (TemplateDocument)((InnerTemplateSection)MethodRepoTemplate["asyncInvoker"]).InnerTemplate.Clone();
{level} IsVoid = {isVoid.ToString().ToLower()}, invokerTemplate.AddDefine("isVoid", isVoid.ToString().ToLower());
{(isVoid ? String.Empty : (level + "\t" + "ReturnType = typeof(" + ExtractTaskType(method.ReturnType)) + "),")} invokerTemplate.AddDefine("returnType", ExtractTaskType(method.ReturnType));
{level} ParameterTypes = new Type[] {{ {parameterTypes} }}, invokerTemplate.AddDefine("parametersType", parameterTypes);
{level} SuitableType = typeof({baseInterace.ToDisplayString()}), invokerTemplate.AddDefine("suitableType", baseInterace.ToDisplayString());
{level} Invoking = (i, parameters, special, post) => {funcInvoking}, invokerTemplate.AddDefine("funcInvoking", funcInvoking);
{level}}}"; backend = invokerTemplate.Compile();
}
else else
backend = $@"new mROA.Implementation.MethodInvoker {
{level}{{ var invokerTemplate = (TemplateDocument)((InnerTemplateSection)MethodRepoTemplate["syncInvoker"]).InnerTemplate.Clone();
{level} IsVoid = {isVoid.ToString().ToLower()}, invokerTemplate.AddDefine("isVoid", isVoid.ToString().ToLower());
{level} ReturnType = typeof({method.ReturnType.ToDisplayString()}), invokerTemplate.AddDefine("returnType", isVoid ? "void" : method.ReturnType.ToDisplayString());
{level} ParameterTypes = new Type[] {{ {parameterTypes} }}, invokerTemplate.AddDefine("parametersType", parameterTypes);
{level} SuitableType = typeof({baseInterace.ToDisplayString()}), invokerTemplate.AddDefine("suitableType", baseInterace.ToDisplayString());
{level} Invoking = (i, parameters, special) => {funcInvoking} invokerTemplate.AddDefine("funcInvoking", funcInvoking);
{level}}}"; backend = invokerTemplate.Compile();
}
MethodRepoTemplate.Insert("invoker", backend); MethodRepoTemplate.Insert("invoker", backend);
invokers.Add(backend); invokers.Add(backend);
@@ -402,7 +405,8 @@ namespace mROA.Codegen
private void GenerateBinderCode(IEventSymbol eventSymbol, List<string> invokers, INamedTypeSymbol baseType, private void GenerateBinderCode(IEventSymbol eventSymbol, List<string> invokers, INamedTypeSymbol baseType,
TemplateDocument document) TemplateDocument document)
{ {
var eventBinderTemplate = (TemplateDocument)((InnerTemplateSection)document["eventBinderTemplate"]!).InnerTemplate.Clone(); var eventBinderTemplate =
(TemplateDocument)((InnerTemplateSection)document["eventBinderTemplate"]!).InnerTemplate.Clone();
var index = invokers.Count - 1; var index = invokers.Count - 1;
var parameters = (eventSymbol.Type as INamedTypeSymbol)!.TypeArguments.ToList(); var parameters = (eventSymbol.Type as INamedTypeSymbol)!.TypeArguments.ToList();
@@ -421,7 +425,6 @@ namespace mROA.Codegen
{ {
callFilter = $"\n\r\t\t\tif(ownerId == p{requestIndex}.OwnerId) return;"; callFilter = $"\n\r\t\t\tif(ownerId == p{requestIndex}.OwnerId) return;";
eventBinderTemplate.AddDefine("callFilter", callFilter); eventBinderTemplate.AddDefine("callFilter", callFilter);
} }
eventBinderTemplate.AddDefine("type", baseType.ToDisplayString()); eventBinderTemplate.AddDefine("type", baseType.ToDisplayString());
@@ -533,7 +536,8 @@ namespace mROA.Codegen
var parameterTypes = string.Join(", ", var parameterTypes = string.Join(", ",
$"{string.Join(", ", method.Parameters.Select(p => $"typeof({p.Type.ToDisplayString()})"))}"); $"{string.Join(", ", method.Parameters.Select(p => $"typeof({p.Type.ToDisplayString()})"))}");
var parameterInserts = string.Join(", ", var parameterInserts = string.Join(", ",
method.Parameters.Take(method.Parameters.Length - 1).Select(p => Caster(p.Type, "parameters[" + method.Parameters.IndexOf(p) + "]"))); method.Parameters.Take(method.Parameters.Length - 1).Select(p =>
Caster(p.Type, "parameters[" + method.Parameters.IndexOf(p) + "]")));
var valueInsert = Caster(method.Parameters.Last().Type, var valueInsert = Caster(method.Parameters.Last().Type,
"parameters[" + (method.Parameters.Length - 1) + "]"); "parameters[" + (method.Parameters.Length - 1) + "]");
@@ -578,7 +582,8 @@ namespace mROA.Codegen
private string ExtractTaskType(ITypeSymbol taskType) private string ExtractTaskType(ITypeSymbol taskType)
{ {
return (taskType as INamedTypeSymbol).TypeArguments[0].ToDisplayString(); var generics = ((INamedTypeSymbol)taskType).TypeArguments;
return generics.Length == 0 ? "void" : generics[0].ToDisplayString();
} }
private bool ContainsSOIAttribute(SyntaxList<AttributeListSyntax> attributes, GeneratorExecutionContext context, private bool ContainsSOIAttribute(SyntaxList<AttributeListSyntax> attributes, GeneratorExecutionContext context,