encapsulate template logic
This commit is contained in:
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using mROA.CodegenTools;
|
||||
using mROA.CodegenTools.Reading;
|
||||
|
||||
namespace mROA.Codegen
|
||||
{
|
||||
public class CodeTemplate
|
||||
{
|
||||
private const string MethodRepoTemplateName = "MethodRepo.cstmpl";
|
||||
private const string ProxyTemplateName = "Proxy.cstmpl";
|
||||
private const string RemoteTypeBinderTemplateName = "RemoteTypeBinder.cstmpl";
|
||||
private const string PartialInterfaceTemplateName = "PartialInterface.cstmpl";
|
||||
private const string IndexProviderTemplateName = "IndexProvider.cstmpl";
|
||||
private const string SyncInvokerTag = "syncInvoker";
|
||||
|
||||
private TemplateDocument? _proxy;
|
||||
private TemplateDocument? _indexerProvider;
|
||||
private TemplateDocument? _remoteTypeBinder;
|
||||
private TemplateDocument? _partialInterface;
|
||||
private TemplateDocument? _methodRepo;
|
||||
private TemplateDocument? _methodInvoker;
|
||||
|
||||
public TemplateDocument Proxy => _proxy
|
||||
?? throw new InvalidOperationException();
|
||||
public TemplateDocument IndexerProvider => _indexerProvider
|
||||
?? throw new InvalidOperationException();
|
||||
public TemplateDocument RemoteTypeBinder => _remoteTypeBinder
|
||||
?? throw new InvalidOperationException();
|
||||
public TemplateDocument PartialInterface => _partialInterface
|
||||
?? throw new InvalidOperationException();
|
||||
public TemplateDocument MethodRepo => _methodRepo
|
||||
?? throw new InvalidOperationException();
|
||||
public TemplateDocument MethodInvoker => _methodInvoker
|
||||
?? throw new InvalidOperationException();
|
||||
|
||||
public void LoadTemplates()
|
||||
{
|
||||
_proxy = TemplateReader.FromEmbeddedResource(ProxyTemplateName);
|
||||
_indexerProvider = TemplateReader.FromEmbeddedResource(IndexProviderTemplateName);
|
||||
_remoteTypeBinder = TemplateReader.FromEmbeddedResource(RemoteTypeBinderTemplateName);
|
||||
_partialInterface = TemplateReader.FromEmbeddedResource(PartialInterfaceTemplateName);
|
||||
_methodRepo = TemplateReader.FromEmbeddedResource(MethodRepoTemplateName);
|
||||
|
||||
var innerMethodSection = MethodRepo[SyncInvokerTag] as InnerTemplateSection
|
||||
?? throw new InvalidOperationException();
|
||||
_methodInvoker = innerMethodSection.InnerTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using mROA.CodegenTools;
|
||||
|
||||
namespace mROA.Codegen
|
||||
{
|
||||
public static class TemplateDocumentExtensions
|
||||
{
|
||||
public static TemplateDocument CloneInnerTemplate(this TemplateDocument template, string tag)
|
||||
{
|
||||
var innerTemplate = template[tag] as InnerTemplateSection
|
||||
?? throw new InvalidOperationException();
|
||||
var clone = innerTemplate.InnerTemplate.Clone();
|
||||
return (TemplateDocument)clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using mROA.CodegenTools;
|
||||
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class EventBinderTemplate : TemplateView
|
||||
{
|
||||
private const string CallFilterTag = "callFilter";
|
||||
private const string TypeTag = "type";
|
||||
private const string EventNameTag = "eventName";
|
||||
private const string ParametersDeclarationTag = "parametersDeclaration";
|
||||
private const string CommandIdTag = "commandId";
|
||||
private const string TransferParametersTag = "transferParameters";
|
||||
|
||||
public EventBinderTemplate(TemplateDocument template) : base(template) { }
|
||||
|
||||
public void DefineCallFilter(string value)
|
||||
{
|
||||
Define(CallFilterTag, value);
|
||||
}
|
||||
|
||||
public void DefineType(string value)
|
||||
{
|
||||
Define(TypeTag, value);
|
||||
}
|
||||
|
||||
public void DefineEventName(string value)
|
||||
{
|
||||
Define(EventNameTag, value);
|
||||
}
|
||||
|
||||
public void DefineParametersDeclaration(string value)
|
||||
{
|
||||
Define(ParametersDeclarationTag, value);
|
||||
}
|
||||
|
||||
public void DefineCommandIdTag(string value)
|
||||
{
|
||||
Define(CommandIdTag, value);
|
||||
}
|
||||
|
||||
public void DefineTransferParameters(string value)
|
||||
{
|
||||
Define(TransferParametersTag, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class IndexProviderTemplate : TemplateView
|
||||
{
|
||||
private const string TemplateFile = "IndexProvider.cstmpl";
|
||||
|
||||
private const string NamespaceTag = "namespace";
|
||||
private const string LevelTag = "level";
|
||||
private const string LenTag = "len";
|
||||
private const string IndexSpanTag = "indexSpan";
|
||||
private const string RemoteTypePairTag = "remoteTypePair";
|
||||
|
||||
public IndexProviderTemplate() : base(TemplateFile) { }
|
||||
|
||||
public void DefineNamespace(string value)
|
||||
{
|
||||
Define(NamespaceTag, value);
|
||||
}
|
||||
|
||||
public void DefineLevel(string value)
|
||||
{
|
||||
Define(LevelTag, value);
|
||||
}
|
||||
|
||||
public void DefineLen(string value)
|
||||
{
|
||||
Define(LenTag, value);
|
||||
}
|
||||
|
||||
public void InsertIndexSpan(string value)
|
||||
{
|
||||
Insert(IndexSpanTag, value);
|
||||
}
|
||||
|
||||
public void InsertRemoteTypePair(string value)
|
||||
{
|
||||
Insert(RemoteTypePairTag, value);
|
||||
}
|
||||
|
||||
public bool IsRemoteTypePairInserted()
|
||||
{
|
||||
return Inserted(RemoteTypePairTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using mROA.CodegenTools;
|
||||
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class InvokerTemplate : TemplateView
|
||||
{
|
||||
private const string IsVoidTag = "isVoid";
|
||||
private const string ReturnTypeTag = "returnType";
|
||||
private const string ParametersTypeTag = "parametersType";
|
||||
private const string SuitableTypeTag = "suitableType";
|
||||
private const string FuncInvokingTag = "funcInvoking";
|
||||
private const string IsTrustedTag = "isTrusted";
|
||||
|
||||
public InvokerTemplate(TemplateDocument template) : base(template) { }
|
||||
|
||||
public void DefineIsVoid(string value)
|
||||
{
|
||||
Define(IsVoidTag, value);
|
||||
}
|
||||
|
||||
public void DefineReturnType(string value)
|
||||
{
|
||||
Define(ReturnTypeTag, value);
|
||||
}
|
||||
|
||||
public void DefineParametersType(string value)
|
||||
{
|
||||
Define(ParametersTypeTag, value);
|
||||
}
|
||||
|
||||
public void DefineSuitableType(string value)
|
||||
{
|
||||
Define(SuitableTypeTag, value);
|
||||
}
|
||||
|
||||
public void DefineFuncInvoking(string value)
|
||||
{
|
||||
Define(FuncInvokingTag, value);
|
||||
}
|
||||
|
||||
public void DefineIsTrusted(string value)
|
||||
{
|
||||
Define(IsTrustedTag, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class MethodRepoTemplate : TemplateView
|
||||
{
|
||||
private const string TemplateFile = "MethodRepo.cstmpl";
|
||||
|
||||
private const string SyncInvokerTemplate = "syncInvoker";
|
||||
private const string AsyncInvokerTemplate = "asyncInvoker";
|
||||
|
||||
private const string InvokerTag = "invoke";
|
||||
|
||||
public MethodRepoTemplate() : base(TemplateFile) { }
|
||||
|
||||
public void InsertInvoke(string value)
|
||||
{
|
||||
Insert(InvokerTag, value);
|
||||
}
|
||||
|
||||
public InvokerTemplate CloneInnerSyncInvoker()
|
||||
{
|
||||
var template = CloneInner(SyncInvokerTemplate);
|
||||
return new InvokerTemplate(template);
|
||||
}
|
||||
|
||||
public InvokerTemplate CloneInnerAsyncInvoker()
|
||||
{
|
||||
var template = CloneInner(AsyncInvokerTemplate);
|
||||
return new InvokerTemplate(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using mROA.CodegenTools;
|
||||
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public partial class ObjectBinderTemplate : TemplateView
|
||||
{
|
||||
private const string EventBinderTemplateTag = "eventBinderTemplate";
|
||||
|
||||
private const string TypeTag = "type";
|
||||
private const string EventBinderTag = "eventBinder";
|
||||
|
||||
public ObjectBinderTemplate(TemplateDocument template) : base(template) { }
|
||||
|
||||
public void DefineType(string value)
|
||||
{
|
||||
Define(TypeTag, value);
|
||||
}
|
||||
|
||||
public void InsertEventBinder(string value)
|
||||
{
|
||||
Insert(EventBinderTag, value);
|
||||
}
|
||||
|
||||
public EventBinderTemplate CloneInnerEventBinder()
|
||||
{
|
||||
var template = CloneInner(EventBinderTemplateTag);
|
||||
return new EventBinderTemplate(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class PartialInterfaceTemplate : TemplateView
|
||||
{
|
||||
private const string TemplateFile = "PartialInterface.cstmpl";
|
||||
|
||||
private const string NameTag = "name";
|
||||
private const string NamespaceTag = "namespace";
|
||||
private const string SignatureTag = "signature";
|
||||
|
||||
public PartialInterfaceTemplate() : base(TemplateFile) { }
|
||||
|
||||
public void DefineName(string value)
|
||||
{
|
||||
Define(NameTag, value);
|
||||
}
|
||||
|
||||
public void DefineNamespace(string value)
|
||||
{
|
||||
Define(NamespaceTag, value);
|
||||
}
|
||||
|
||||
public void InsertSignature(string value)
|
||||
{
|
||||
Insert(SignatureTag, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class ProxyTemplate : TemplateView
|
||||
{
|
||||
private const string TemplateFile = "Proxy.cstmpl";
|
||||
|
||||
private const string ClassNameTag = "className";
|
||||
private const string OriginalNameTag = "originalName";
|
||||
private const string NamespaceNameTag= "namespaceName";
|
||||
private const string MethodsTag = "methods";
|
||||
|
||||
public ProxyTemplate() : base(TemplateFile) { }
|
||||
|
||||
public void DefineClassName(string value)
|
||||
{
|
||||
Define(ClassNameTag, value);
|
||||
}
|
||||
|
||||
public void DefineOriginalName(string value)
|
||||
{
|
||||
Define(OriginalNameTag, value);
|
||||
}
|
||||
|
||||
public void DefineNamespaceName(string value)
|
||||
{
|
||||
Define(NamespaceNameTag, value);
|
||||
}
|
||||
|
||||
public void InsertMethods(string value)
|
||||
{
|
||||
Insert(MethodsTag, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public class RemoteTypeBinderTemplate : TemplateView
|
||||
{
|
||||
private const string TemplateFile = "RemoteTypeBinder.cstmpl";
|
||||
|
||||
private const string ObjectBinderTemplateTag = "objectBinderTemplate";
|
||||
private const string EventBinderTag = "eventBinder";
|
||||
|
||||
public RemoteTypeBinderTemplate() : base(TemplateFile) { }
|
||||
|
||||
public ObjectBinderTemplate CloneInnerObjectBinder()
|
||||
{
|
||||
var template = CloneInner(ObjectBinderTemplateTag);
|
||||
return new ObjectBinderTemplate(template);
|
||||
}
|
||||
|
||||
public void InsertEventBinder(string value)
|
||||
{
|
||||
Insert(EventBinderTag, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using mROA.CodegenTools;
|
||||
using mROA.CodegenTools.Reading;
|
||||
|
||||
namespace mROA.Codegen.Templates
|
||||
{
|
||||
public abstract class TemplateView
|
||||
{
|
||||
private readonly TemplateDocument _template;
|
||||
|
||||
protected TemplateView(string templateFile)
|
||||
{
|
||||
_template = TemplateReader.FromEmbeddedResource(templateFile);
|
||||
}
|
||||
|
||||
protected TemplateView(TemplateDocument template)
|
||||
{
|
||||
_template = template;
|
||||
}
|
||||
|
||||
public string Compile()
|
||||
{
|
||||
return _template.Compile();
|
||||
}
|
||||
|
||||
protected void Define(string tag, string value)
|
||||
{
|
||||
_template.AddDefine(tag, value);
|
||||
}
|
||||
|
||||
protected void Insert(string tag, string value)
|
||||
{
|
||||
_template.Insert(tag, value);
|
||||
}
|
||||
|
||||
protected bool Inserted(string tag)
|
||||
{
|
||||
return _template[$"{tag}+"] != null;
|
||||
}
|
||||
|
||||
protected TemplateDocument CloneInner(string tag)
|
||||
{
|
||||
return _template.CloneInnerTemplate(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
-122
@@ -9,7 +9,7 @@ using System.Threading;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using mROA.CodegenTools;
|
||||
using mROA.Codegen.Templates;
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
||||
|
||||
@@ -31,15 +31,11 @@ namespace mROA.Codegen
|
||||
|
||||
private static readonly Predicate<ITypeSymbol> ParameterFilterForType =
|
||||
i => i.Name is "CancellationToken" or "RequestContext";
|
||||
|
||||
private readonly CodeTemplate _codeTemplate = new();
|
||||
|
||||
|
||||
private int _currentInternalCallIndex;
|
||||
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
_codeTemplate.LoadTemplates();
|
||||
|
||||
var syntaxes = context.SyntaxProvider.CreateSyntaxProvider(
|
||||
NodeIsInterfaceWithSharedObjectInterfaceAttribute,
|
||||
TransformToInterfaceDeclarationSyntax);
|
||||
@@ -69,9 +65,15 @@ namespace mROA.Codegen
|
||||
private void GenerateCode(SourceProductionContext context, Compilation compilation,
|
||||
ImmutableArray<InterfaceDeclarationSyntax> classes)
|
||||
{
|
||||
var methodRepoTemplate = new MethodRepoTemplate();
|
||||
var typeBinder = new RemoteTypeBinderTemplate();
|
||||
var indexProviderTemplate = new IndexProviderTemplate();
|
||||
var totalMethods = new List<IMethodSymbol>();
|
||||
|
||||
_codeTemplate.IndexerProvider.AddDefine("namespace", compilation.AssemblyName!);
|
||||
if (compilation.AssemblyName == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
indexProviderTemplate.DefineNamespace(compilation.AssemblyName);
|
||||
var invokers = new List<string>();
|
||||
var declarations = classes.ToList();
|
||||
var apiLevel = 0;
|
||||
@@ -99,7 +101,7 @@ namespace mROA.Codegen
|
||||
|
||||
className = className.TrimStart('I') + "Proxy";
|
||||
|
||||
var classTemplate = (TemplateDocument)_codeTemplate.Proxy.Clone();
|
||||
var proxyTemplate = new ProxyTemplate();
|
||||
var propertiesAccessMethods = new List<(string, IMethodSymbol)>();
|
||||
|
||||
int startInvokers = invokers.Count;
|
||||
@@ -107,11 +109,11 @@ namespace mROA.Codegen
|
||||
switch (method.MethodKind)
|
||||
{
|
||||
case MethodKind.PropertyGet or MethodKind.PropertySet:
|
||||
GeneratePropertyMethod(method, propertiesAccessMethods, invokers,
|
||||
GeneratePropertyMethod(methodRepoTemplate, method, propertiesAccessMethods, invokers,
|
||||
classSymbol);
|
||||
continue;
|
||||
default:
|
||||
GenerateDeclaredMethod(classTemplate, method, invokers, classSymbol);
|
||||
GenerateDeclaredMethod(proxyTemplate, methodRepoTemplate, method, invokers, classSymbol);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -132,43 +134,40 @@ namespace mROA.Codegen
|
||||
impl =
|
||||
$"public {propertySymbol.Type.ToUnityString()} {symbol.Name} {{ {getter.Item1} {setter.Item1} }}";
|
||||
|
||||
classTemplate.Insert("methods", impl);
|
||||
proxyTemplate.InsertMethods(impl);
|
||||
// declaredMethods.Add(impl);
|
||||
break;
|
||||
case IEventSymbol eventSymbol:
|
||||
classTemplate.Insert("methods",
|
||||
$"public event {eventSymbol.Type.ToUnityString()}? {eventSymbol.Name};");
|
||||
proxyTemplate.InsertMethods($"public event {eventSymbol.Type.ToUnityString()}? {eventSymbol.Name};");
|
||||
// declaredMethods.Add(
|
||||
// $"public event {eventSymbol.Type.ToDisplayString()}? {eventSymbol.Name};");
|
||||
break;
|
||||
}
|
||||
|
||||
GenerateEventImplementation(classTemplate, classSymbol, invokers, context);
|
||||
GenerateEventImplementation(proxyTemplate, methodRepoTemplate, typeBinder, classSymbol, invokers, context);
|
||||
var endInvokers = invokers.Count;
|
||||
_codeTemplate.IndexerProvider.Insert("indexSpan",
|
||||
$"{{ typeof({originalName}), new[] {{ {CodegenUtilities.JoinWithComa(Enumerable.Range(startInvokers, endInvokers - startInvokers).Select(i => i.ToString()))} }} }},");
|
||||
classTemplate.AddDefine("className", className);
|
||||
classTemplate.AddDefine("originalName", originalName);
|
||||
classTemplate.AddDefine("namespaceName", namespaceName);
|
||||
indexProviderTemplate.InsertIndexSpan($"{{ typeof({originalName}), new[] {{ {CodegenUtilities.JoinWithComa(Enumerable.Range(startInvokers, endInvokers - startInvokers).Select(i => i.ToString()))} }} }},");
|
||||
proxyTemplate.DefineClassName(className);
|
||||
proxyTemplate.DefineOriginalName(originalName);
|
||||
proxyTemplate.DefineNamespaceName(namespaceName);
|
||||
|
||||
var code = classTemplate.Compile();
|
||||
var code = proxyTemplate.Compile();
|
||||
|
||||
|
||||
// Add the source code to the compilation.
|
||||
#if !DONT_ADD
|
||||
context.AddSource($"{className}.g.cs", SourceText.From(code, Encoding.UTF8));
|
||||
#endif
|
||||
_codeTemplate.IndexerProvider.Insert("remoteTypePair",
|
||||
$"{{ typeof({classSymbol.ToUnityString()}), (id, r, c, indices) => new {namespaceName}.{className}(id, r, c, indices) }}");
|
||||
indexProviderTemplate.InsertRemoteTypePair($"{{ typeof({classSymbol.ToUnityString()}), (id, r, c, indices) => new {namespaceName}.{className}(id, r, c, indices) }}");
|
||||
}
|
||||
|
||||
if (totalMethods.Count != 0)
|
||||
{
|
||||
var coCodegenRepoCode = _codeTemplate.MethodRepo.Compile();
|
||||
_codeTemplate.IndexerProvider.AddDefine("level", apiLevel.ToString());
|
||||
_codeTemplate.IndexerProvider.AddDefine("len", invokers.Count.ToString());
|
||||
var coCodegenRepoCode = methodRepoTemplate.Compile();
|
||||
indexProviderTemplate.DefineLevel(apiLevel.ToString());
|
||||
indexProviderTemplate.DefineLen(invokers.Count.ToString());
|
||||
|
||||
var providerCode = _codeTemplate.IndexerProvider.Compile();
|
||||
var providerCode = indexProviderTemplate.Compile();
|
||||
#if !DONT_ADD
|
||||
context.AddSource("GeneratedInvokersCollection.g.cs",
|
||||
SourceText.From(coCodegenRepoCode, Encoding.UTF8));
|
||||
@@ -177,16 +176,16 @@ namespace mROA.Codegen
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_codeTemplate.IndexerProvider["remoteTypePair+"] != null)
|
||||
if (indexProviderTemplate.IsRemoteTypePairInserted())
|
||||
{
|
||||
var frontendRepoCode = _codeTemplate.RemoteTypeBinder.Compile();
|
||||
var frontendRepoCode = typeBinder.Compile();
|
||||
#if !DONT_ADD
|
||||
context.AddSource("RemoteTypeBinder.g.cs", SourceText.From(frontendRepoCode, Encoding.UTF8));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateEventImplementation(TemplateDocument classTemplate, INamedTypeSymbol classSymbol,
|
||||
private void GenerateEventImplementation(ProxyTemplate proxyTemplate, MethodRepoTemplate methodRepoTemplate, RemoteTypeBinderTemplate remoteTypeBinder, INamedTypeSymbol classSymbol,
|
||||
List<string> invokers, SourceProductionContext context)
|
||||
{
|
||||
var events = classSymbol.AllInterfaces.Add(classSymbol).SelectMany(i => i.GetMembers())
|
||||
@@ -194,28 +193,26 @@ namespace mROA.Codegen
|
||||
if (events.Count == 0)
|
||||
return;
|
||||
|
||||
var interfaceTemplate = (TemplateDocument)_codeTemplate.PartialInterface.Clone();
|
||||
interfaceTemplate.AddDefine("name", classSymbol.Name);
|
||||
interfaceTemplate.AddDefine("namespace", classSymbol.ContainingNamespace.ToDisplayString());
|
||||
var objectBinderTemplate =
|
||||
(TemplateDocument)((InnerTemplateSection)_codeTemplate.RemoteTypeBinder["objectBinderTemplate"]!)
|
||||
.InnerTemplate
|
||||
.Clone();
|
||||
var partialInterfaceTemplate = new PartialInterfaceTemplate();
|
||||
partialInterfaceTemplate.DefineName(classSymbol.Name);
|
||||
partialInterfaceTemplate.DefineNamespace(classSymbol.ContainingNamespace.ToDisplayString());
|
||||
|
||||
var objectBinderTemplate = remoteTypeBinder.CloneInnerObjectBinder();
|
||||
foreach (var currentEvent in events)
|
||||
{
|
||||
var additionalMethod = GenerateMethodExternalCaller(currentEvent, out var signature);
|
||||
classTemplate.Insert("methods", additionalMethod);
|
||||
proxyTemplate.InsertMethods(additionalMethod);
|
||||
|
||||
// declaredMethods.Add(additionalMethod);
|
||||
interfaceTemplate.Insert("signature", signature);
|
||||
GenerateEventCode(currentEvent, invokers, classSymbol);
|
||||
GenerateBinderCode(currentEvent, classSymbol, objectBinderTemplate);
|
||||
partialInterfaceTemplate.InsertSignature(signature);
|
||||
GenerateEventCode(methodRepoTemplate, currentEvent, invokers, classSymbol);
|
||||
GenerateBinderCode(objectBinderTemplate, currentEvent, classSymbol);
|
||||
}
|
||||
|
||||
objectBinderTemplate.AddDefine("type", classSymbol.ToUnityString());
|
||||
var partialInterface = interfaceTemplate.Compile();
|
||||
|
||||
objectBinderTemplate.DefineType(classSymbol.ToUnityString());
|
||||
var partialInterface = partialInterfaceTemplate.Compile();
|
||||
var binder = objectBinderTemplate.Compile();
|
||||
_codeTemplate.RemoteTypeBinder.Insert("eventBinder", binder);
|
||||
remoteTypeBinder.InsertEventBinder(binder);
|
||||
|
||||
#if !DONT_ADD
|
||||
context.AddSource($"{classSymbol.Name}.g.cs", SourceText.From(partialInterface, Encoding.UTF8));
|
||||
@@ -239,7 +236,7 @@ namespace mROA.Codegen
|
||||
return caller;
|
||||
}
|
||||
|
||||
private void GenerateDeclaredMethod(TemplateDocument classTemplate, IMethodSymbol method, List<string> invokers,
|
||||
private void GenerateDeclaredMethod(ProxyTemplate proxyTemplate, MethodRepoTemplate methodRepoTemplate, IMethodSymbol method, List<string> invokers,
|
||||
INamedTypeSymbol baseInterface)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
@@ -311,7 +308,7 @@ namespace mROA.Codegen
|
||||
sb.AppendLine("\t\t\t" + prefix + caller + postfix + ";");
|
||||
|
||||
sb.AppendLine("\t\t}");
|
||||
classTemplate.Insert("methods", sb.ToString());
|
||||
proxyTemplate.InsertMethods(sb.ToString());
|
||||
|
||||
// declaredMethods.Add(sb.ToString());
|
||||
var parameterTypes = string.Join(", ",
|
||||
@@ -356,38 +353,35 @@ namespace mROA.Codegen
|
||||
|
||||
if (isAsync)
|
||||
{
|
||||
var invokerTemplate =
|
||||
(TemplateDocument)((InnerTemplateSection)_codeTemplate.MethodRepo["asyncInvoker"]!).InnerTemplate
|
||||
.Clone();
|
||||
invokerTemplate.AddDefine("isVoid", isVoid.ToString().ToLower());
|
||||
invokerTemplate.AddDefine("returnType", CodegenUtilities.ExtractTaskType(method.ReturnType));
|
||||
invokerTemplate.AddDefine("parametersType", parameterTypes);
|
||||
invokerTemplate.AddDefine("suitableType", baseInterface.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking", funcInvoking);
|
||||
invokerTemplate.AddDefine("isTrusted", (!isUntrusted).ToString().ToLower());
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerAsyncInvoker();
|
||||
invokerTemplate.DefineIsVoid(isVoid.ToString().ToLower());
|
||||
invokerTemplate.DefineReturnType(CodegenUtilities.ExtractTaskType(method.ReturnType));
|
||||
invokerTemplate.DefineParametersType(parameterTypes);
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking(funcInvoking);
|
||||
invokerTemplate.DefineIsTrusted((!isUntrusted).ToString().ToLower());
|
||||
backend = invokerTemplate.Compile();
|
||||
}
|
||||
else
|
||||
{
|
||||
var invokerTemplate = (TemplateDocument)_codeTemplate.MethodInvoker.Clone();
|
||||
invokerTemplate.AddDefine("isVoid", isVoid.ToString().ToLower());
|
||||
invokerTemplate.AddDefine("returnType", isVoid ? "void" : method.ReturnType.ToUnityString());
|
||||
invokerTemplate.AddDefine("parametersType", parameterTypes);
|
||||
invokerTemplate.AddDefine("suitableType", baseInterface.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking", funcInvoking);
|
||||
invokerTemplate.AddDefine("isTrusted", (!isUntrusted).ToString().ToLower());
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerSyncInvoker();
|
||||
invokerTemplate.DefineIsVoid(isVoid.ToString().ToLower());
|
||||
invokerTemplate.DefineReturnType(isVoid ? "void" : method.ReturnType.ToUnityString());
|
||||
invokerTemplate.DefineParametersType(parameterTypes);
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking(funcInvoking);
|
||||
invokerTemplate.DefineIsTrusted((!isUntrusted).ToString().ToLower());
|
||||
backend = invokerTemplate.Compile();
|
||||
}
|
||||
|
||||
_codeTemplate.MethodRepo.Insert("invoker", backend);
|
||||
methodRepoTemplate.InsertInvoke(backend);
|
||||
|
||||
invokers.Add(backend);
|
||||
}
|
||||
|
||||
private void GenerateBinderCode(IEventSymbol eventSymbol, INamedTypeSymbol baseType, TemplateDocument document)
|
||||
private void GenerateBinderCode(ObjectBinderTemplate objectBinderTemplate, IEventSymbol eventSymbol, INamedTypeSymbol baseType)
|
||||
{
|
||||
var eventBinderTemplate =
|
||||
(TemplateDocument)((InnerTemplateSection)document["eventBinderTemplate"]!).InnerTemplate.Clone();
|
||||
var eventBinderTemplate = objectBinderTemplate.CloneInnerEventBinder();
|
||||
|
||||
var index = _currentInternalCallIndex;
|
||||
var parameters = (eventSymbol.Type as INamedTypeSymbol)!.TypeArguments.ToList();
|
||||
@@ -399,25 +393,24 @@ namespace mROA.Codegen
|
||||
var transferParameters = CodegenUtilities.JoinWithComa(parameters.Select(i => (i, pi++))
|
||||
.Where(i => !ParameterFilterForType(i.i))
|
||||
.Select(i => "p" + i.Item2));
|
||||
|
||||
|
||||
var requestIndex = parameters.FindIndex(i => i.Name == "RequestContext");
|
||||
if (requestIndex != -1)
|
||||
{
|
||||
var callFilter = $"\n\r\t\t\tif(ownerId == p{requestIndex}.OwnerId) return;";
|
||||
eventBinderTemplate.AddDefine("callFilter", callFilter);
|
||||
eventBinderTemplate.DefineCallFilter(callFilter);
|
||||
}
|
||||
|
||||
eventBinderTemplate.AddDefine("type", baseType.ToUnityString());
|
||||
eventBinderTemplate.AddDefine("eventName", eventSymbol.Name);
|
||||
eventBinderTemplate.AddDefine("parametersDeclaration", parametersDeclaration);
|
||||
eventBinderTemplate.AddDefine("commandId",
|
||||
$"context.CallIndexProvider.GetIndices(typeof({baseType.ToUnityString()}))[{index}]");
|
||||
eventBinderTemplate.AddDefine("transferParameters", transferParameters);
|
||||
eventBinderTemplate.DefineType(baseType.ToUnityString());
|
||||
eventBinderTemplate.DefineEventName(eventSymbol.Name);
|
||||
eventBinderTemplate.DefineParametersDeclaration(parametersDeclaration);
|
||||
eventBinderTemplate.DefineCommandIdTag($"context.CallIndexProvider.GetIndices(typeof({baseType.ToUnityString()}))[{index}]");
|
||||
eventBinderTemplate.DefineTransferParameters(transferParameters);
|
||||
var eventBinderCode = eventBinderTemplate.Compile();
|
||||
document.Insert("eventBinder", eventBinderCode);
|
||||
objectBinderTemplate.InsertEventBinder(eventBinderCode);
|
||||
}
|
||||
|
||||
private void GenerateEventCode(IEventSymbol eventSymbol, List<string> invokers, ITypeSymbol baseInterface)
|
||||
private void GenerateEventCode(MethodRepoTemplate methodRepoTemplate, IEventSymbol eventSymbol, List<string> invokers, ITypeSymbol baseInterface)
|
||||
{
|
||||
var level = "\t\t\t";
|
||||
|
||||
@@ -453,21 +446,21 @@ namespace mROA.Codegen
|
||||
{level} return null;
|
||||
{level} }}";
|
||||
|
||||
var invokerTemplate = (TemplateDocument)_codeTemplate.MethodInvoker.Clone();
|
||||
invokerTemplate.AddDefine("isVoid", "true");
|
||||
invokerTemplate.AddDefine("returnType", "void");
|
||||
invokerTemplate.AddDefine("parametersType", parameterTypes);
|
||||
invokerTemplate.AddDefine("suitableType", baseInterface.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking", funcInvoking);
|
||||
invokerTemplate.AddDefine("isTrusted", "true");
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerSyncInvoker();
|
||||
invokerTemplate.DefineIsVoid("true");
|
||||
invokerTemplate.DefineReturnType("void");
|
||||
invokerTemplate.DefineParametersType(parameterTypes);
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking(funcInvoking);
|
||||
invokerTemplate.DefineIsTrusted("true");
|
||||
var backend = invokerTemplate.Compile();
|
||||
_codeTemplate.MethodRepo.Insert("invoker", backend);
|
||||
methodRepoTemplate.InsertInvoke(backend);
|
||||
|
||||
invokers.Add(backend);
|
||||
}
|
||||
|
||||
private void GeneratePropertyMethod(IMethodSymbol method,
|
||||
List<(string, IMethodSymbol)> propsCollection, List<string> invokers, INamedTypeSymbol baseInterace)
|
||||
private void GeneratePropertyMethod(MethodRepoTemplate methodRepoTemplate, IMethodSymbol method,
|
||||
List<(string, IMethodSymbol)> propsCollection, List<string> invokers, INamedTypeSymbol baseInterface)
|
||||
{
|
||||
string frontend;
|
||||
string backend;
|
||||
@@ -485,26 +478,25 @@ namespace mROA.Codegen
|
||||
method.Parameters.Select(p =>
|
||||
CodegenUtilities.Caster(p.Type, "parameters[" + method.Parameters.IndexOf(p) + "]")));
|
||||
|
||||
var invokerTemplate = (TemplateDocument)_codeTemplate.MethodInvoker.Clone();
|
||||
invokerTemplate.AddDefine("isVoid", "false");
|
||||
invokerTemplate.AddDefine("returnType", method.ReturnType.ToUnityString());
|
||||
invokerTemplate.AddDefine("parametersType", parameterTypes);
|
||||
invokerTemplate.AddDefine("suitableType", baseInterace.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking",
|
||||
$"(i as {method.ContainingType.ToUnityString()})[{parameterInserts}]");
|
||||
invokerTemplate.AddDefine("isTrusted", "true");
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerSyncInvoker();
|
||||
invokerTemplate.DefineIsVoid("false");
|
||||
invokerTemplate.DefineReturnType(method.ReturnType.ToUnityString());
|
||||
invokerTemplate.DefineParametersType(parameterTypes);
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking($"(i as {method.ContainingType.ToUnityString()})[{parameterInserts}]");
|
||||
invokerTemplate.DefineIsTrusted("true");
|
||||
|
||||
backend = invokerTemplate.Compile();
|
||||
}
|
||||
else
|
||||
{
|
||||
var invokerTemplate = (TemplateDocument)_codeTemplate.MethodInvoker.Clone();
|
||||
invokerTemplate.AddDefine("isVoid", "false");
|
||||
invokerTemplate.AddDefine("returnType", method.ReturnType.ToUnityString());
|
||||
invokerTemplate.AddDefine("suitableType", baseInterace.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking",
|
||||
$"(i as {method.ContainingType.ToUnityString()}).{(method.AssociatedSymbol as IPropertySymbol)!.Name}");
|
||||
invokerTemplate.AddDefine("isTrusted", "true");
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerSyncInvoker();
|
||||
invokerTemplate.DefineIsVoid("false");
|
||||
invokerTemplate.DefineReturnType(method.ReturnType.ToUnityString());
|
||||
invokerTemplate.DefineParametersType("");
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking($"(i as {method.ContainingType.ToUnityString()}).{(method.AssociatedSymbol as IPropertySymbol)!.Name}");
|
||||
invokerTemplate.DefineIsTrusted("true");
|
||||
|
||||
backend = invokerTemplate.Compile();
|
||||
}
|
||||
@@ -527,31 +519,26 @@ namespace mROA.Codegen
|
||||
|
||||
var valueInsert = CodegenUtilities.Caster(method.Parameters.Last().Type,
|
||||
"parameters[" + (method.Parameters.Length - 1) + "]");
|
||||
var invokerTemplate = (TemplateDocument)_codeTemplate.MethodInvoker.Clone();
|
||||
|
||||
|
||||
invokerTemplate.AddDefine("isVoid", "true");
|
||||
invokerTemplate.AddDefine("returnType", method.ReturnType.ToUnityString());
|
||||
invokerTemplate.AddDefine("parametersType", parameterTypes);
|
||||
invokerTemplate.AddDefine("suitableType", baseInterace.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking",
|
||||
$"(i as {method.ContainingType.ToUnityString()})[{parameterInserts}] = {valueInsert}");
|
||||
invokerTemplate.AddDefine("isTrusted", "true");
|
||||
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerSyncInvoker();
|
||||
invokerTemplate.DefineIsVoid("true");
|
||||
invokerTemplate.DefineReturnType(method.ReturnType.ToUnityString());
|
||||
invokerTemplate.DefineParametersType(parameterTypes);
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking($"(i as {method.ContainingType.ToUnityString()})[{parameterInserts}] = {valueInsert}");
|
||||
invokerTemplate.DefineIsTrusted("true");
|
||||
|
||||
backend = invokerTemplate.Compile();
|
||||
}
|
||||
else
|
||||
{
|
||||
var invokerTemplate = (TemplateDocument)_codeTemplate.MethodInvoker.Clone();
|
||||
|
||||
invokerTemplate.AddDefine("isVoid", "true");
|
||||
invokerTemplate.AddDefine("returnType", method.ReturnType.ToUnityString());
|
||||
invokerTemplate.AddDefine("parametersType",
|
||||
$"typeof({method.Parameters.First().Type.ToUnityString()})");
|
||||
invokerTemplate.AddDefine("suitableType", baseInterace.ToUnityString());
|
||||
invokerTemplate.AddDefine("funcInvoking",
|
||||
$"(i as {method.ContainingType.ToUnityString()}).{(method.AssociatedSymbol as IPropertySymbol)!.Name} = {CodegenUtilities.Caster((method.AssociatedSymbol as IPropertySymbol)!.Type, "parameters[0]")}");
|
||||
invokerTemplate.AddDefine("isTrusted", "true");
|
||||
var invokerTemplate = methodRepoTemplate.CloneInnerSyncInvoker();
|
||||
invokerTemplate.DefineIsVoid("true");
|
||||
invokerTemplate.DefineReturnType(method.ReturnType.ToUnityString());
|
||||
invokerTemplate.DefineParametersType($"typeof({method.Parameters.First().Type.ToUnityString()})");
|
||||
invokerTemplate.DefineSuitableType(baseInterface.ToUnityString());
|
||||
invokerTemplate.DefineFuncInvoking($"(i as {method.ContainingType.ToUnityString()}).{(method.AssociatedSymbol as IPropertySymbol)!.Name} = {CodegenUtilities.Caster((method.AssociatedSymbol as IPropertySymbol)!.Type, "parameters[0]")}");
|
||||
invokerTemplate.DefineIsTrusted("true");
|
||||
|
||||
backend = invokerTemplate.Compile();
|
||||
}
|
||||
@@ -561,7 +548,7 @@ namespace mROA.Codegen
|
||||
}
|
||||
|
||||
propsCollection.Add((frontend, method));
|
||||
_codeTemplate.MethodRepo.Insert("invoker", backend);
|
||||
methodRepoTemplate.InsertInvoke(backend);
|
||||
invokers.Add(backend);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user