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("// "); _ = 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) string genericBracket = i == 0 ? "" : $"<{typeParams}, TResult>"; string funcType = i == 0 ? "Func>" : $"Func<{typeParams}, Task>"; _ = sb.AppendLine($$""" /// Generates a remote execution call for {{i}} async arguments. public async Task ExecuteAsync{{genericBracket}}( {{funcType}} @delegate, {{methodParams}}{{(i > 0 ? ", " : "")}}CancellationToken ct = default) { return await ExecuteAsync<{{funcType}}, TResult>(@delegate, ct{{(i > 0 ? ", " : "")}}{{callArgs}}); } """); // Sync overloads (Func) string syncFuncType = i == 0 ? "Func" : $"Func<{typeParams}, TResult>"; _ = sb.AppendLine($$""" /// Generates a remote execution call for {{i}} synchronous arguments. public async Task 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(); } }