Add source generator to generate ExecuteAsync overloads

This commit is contained in:
Stone_Red
2025-12-25 19:23:48 +01:00
parent 3e339b2b7a
commit 8211825bef
6 changed files with 108 additions and 1 deletions
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
</ItemGroup>
</Project>
@@ -0,0 +1,76 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Linq;
using System.Text;
namespace RemoteExec.Generators;
[Generator]
public class RemoteExecutorOverloadGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
context.RegisterPostInitializationOutput(ctx =>
{
string source = GenerateOverloads(16);
ctx.AddSource("RemoteExecutor.Overloads.g.cs", SourceText.From(source, Encoding.UTF8));
});
}
private static string GenerateOverloads(int maxArgs)
{
StringBuilder sb = new StringBuilder();
_ = sb.AppendLine("// <auto-generated />");
_ = sb.AppendLine("using System;");
_ = sb.AppendLine("using System.Threading;");
_ = sb.AppendLine("using System.Threading.Tasks;");
_ = sb.AppendLine();
_ = sb.AppendLine("namespace RemoteExec.Client;");
_ = sb.AppendLine();
_ = sb.AppendLine("public partial class RemoteExecutor");
_ = sb.AppendLine("{");
for (int i = 0; i <= maxArgs; i++)
{
// T1, T2, T3...
string typeParams = i == 0 ? "" : string.Join(", ", Enumerable.Range(1, i).Select(n => $"T{n}"));
// T1 arg1, T2 arg2...
string methodParams = i == 0 ? "" : string.Join(", ", Enumerable.Range(1, i).Select(n => $"T{n} arg{n}"));
// arg1, arg2...
string callArgs = i == 0 ? "" : string.Join(", ", Enumerable.Range(1, i).Select(n => $"arg{n}!"));
// Async overloads (Task<TResult>)
string genericBracket = i == 0 ? "<TResult>" : $"<{typeParams}, TResult>";
string funcType = i == 0 ? "Func<Task<TResult>>" : $"Func<{typeParams}, Task<TResult>>";
_ = sb.AppendLine($$"""
/// <summary>Generates a remote execution call for {{i}} async arguments.</summary>
public async Task<TResult> ExecuteAsync{{genericBracket}}(
{{funcType}} @delegate,
{{methodParams}}{{(i > 0 ? ", " : "")}}CancellationToken ct = default)
{
return await ExecuteAsync<{{funcType}}, TResult>(@delegate, ct{{(i > 0 ? ", " : "")}}{{callArgs}});
}
""");
// Sync overloads (Func<TResult>)
string syncFuncType = i == 0 ? "Func<TResult>" : $"Func<{typeParams}, TResult>";
_ = sb.AppendLine($$"""
/// <summary>Generates a remote execution call for {{i}} synchronous arguments.</summary>
public async Task<TResult> ExecuteAsync{{genericBracket}}(
{{syncFuncType}} @delegate,
{{methodParams}}{{(i > 0 ? ", " : "")}}CancellationToken ct = default)
{
return await ExecuteAsync<{{syncFuncType}}, TResult>(@delegate, ct{{(i > 0 ? ", " : "")}}{{callArgs}});
}
""");
}
_ = sb.AppendLine("}");
return sb.ToString();
}
}