private static MethodDeclarationSyntax GenerateGetExecutorMember(CodeSchema.CodeFunction codeFunction) { List <string> argumentFetches = new List <string>(); foreach (var argument in codeFunction.Arguments) { argumentFetches.Add($"await oDrive.PushValue<{argument.Type}>({argument.EndpointID}, {argument.Name});"); } var returnType = string.IsNullOrEmpty(codeFunction.ReturnType) ? "Task" : $"Task<{codeFunction.ReturnType}>"; bool hasReturn = !string.IsNullOrEmpty(codeFunction.ReturnType); var parameters = string.Join(",", GetParameterList(codeFunction.Arguments)); var oDriveMethod = hasReturn ? "RequestValue" : "InvokeEndpoint"; // TODO: Figure out why this template is putting the last semicolon on a new line... // TODO: Could parallel the fetches if there are multiple arguments string template = $@" public ExecutionDelegate GetExecutor(IDevice oDrive) {{ return async ({parameters}) => {{ {string.Join(Environment.NewLine, argumentFetches)} {(hasReturn ? "return " : "")} await oDrive.{oDriveMethod}{(hasReturn ? $"<{codeFunction.ReturnType}>" : "")}({codeFunction.EndpointID}); }}; }} "; return(((CompilationUnitSyntax)ParseSyntaxTree(template).GetRoot()).Members[0] as MethodDeclarationSyntax); }
private static MemberDeclarationSyntax GenerateDelegateMember(CodeSchema.CodeFunction codeFunction) { var returnType = string.IsNullOrEmpty(codeFunction.ReturnType) ? "Task" : $"Task<{codeFunction.ReturnType}>"; var parameters = string.Join(",", GetParameterList(codeFunction.Arguments)); string template = $@"public delegate {returnType} ExecutionDelegate({parameters});"; return(((CompilationUnitSyntax)ParseSyntaxTree(template).GetRoot()).Members[0] as MemberDeclarationSyntax); }
public static ClassDeclarationSyntax Generate(CodeSchema.CodeFunction codeFunction) { string methodOrFunction = string.IsNullOrEmpty(codeFunction.ReturnType) ? "Method" : "Function"; string className = $"{codeFunction.Name}{methodOrFunction}"; var classDeclaration = ClassDeclaration(className) .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.PartialKeyword)) .AddBaseListTypes(SimpleBaseType(ParseTypeName($"IExecutableMember<{className}.ExecutionDelegate>"))) .AddMembers(GenerateDelegateMember(codeFunction)) .AddMembers(GenerateGetExecutorMember(codeFunction)); // var currentCode = ((SyntaxNode)classDeclaration).NormalizeWhitespace().ToFullString(); return(classDeclaration); }