private static async Task <MethodDeclarationSyntax> CreateMethodDeclaration(string methodName, string httpVerb, string routeUriTemplate, SeparatedSyntaxList <ParameterSyntax> parameters, BlockSyntax block, string responseType, string serviceType) { var methodSourceCode = $@" /// <summary> /// auto code generated using {serviceType} Service provider class /// </summary> [{httpVerb}, Route(""{routeUriTemplate}"")] [ResponseType(typeof ({responseType}))] public IHttpActionResult {methodName}() {{ }} "; var root = await CodeParser.ConvertToCompilationUnit(methodSourceCode); var method = root .DescendantNodes() .OfType <MethodDeclarationSyntax>() .First(); method = method .WithParameterList(SyntaxFactory.ParameterList(parameters)) .WithBody(block); return(method); }
public static async Task <IDictionary <string, string> > Run(IDictionary <string, Task <WcfClientClassInfo> > wcfClasses) { var codes = new Dictionary <string, string>(); foreach (var wcfClassName in wcfClasses.Keys) { // wcf class info var wcfInfo = await wcfClasses[wcfClassName]; var classNamespace = wcfInfo.ClientNamespace; var className = wcfInfo.ClientClassName; var baseInterfaceName = wcfInfo.ClientBaseInterfaceName; var wcfClientSourceCode = wcfInfo.WcfClientSourceCode; var serviceGenCode = wcfInfo.ServiceGenCode; var wcfServiceClass = wcfInfo.WcfServiceClass; // check if has wcf code or associated service gen code if (!HasSourceCode(className, wcfClientSourceCode, serviceGenCode, codes)) { continue; } // parse wcf & service file code var wcfClientUnit = await CodeParser.ConvertToCompilationUnit(wcfClientSourceCode); var hasWcfClientInterface = wcfClientUnit.DescendantNodes() .OfType <InterfaceDeclarationSyntax>() .Any(); var wcfClientMethods = wcfClientUnit .DescendantNodes() .OfType <MethodDeclarationSyntax>() .ToList(); var serviceGenUnit = await CodeParser.ConvertToCompilationUnit(serviceGenCode); var serviceGenMethods = serviceGenUnit .DescendantNodes() .OfType <MethodDeclarationSyntax>(); var sourceCode = wcfServiceClass.WcfServiceSourceCode; var unitSyntax = await CodeParser.ConvertToCompilationUnit(sourceCode); var wcfServiceMethods = unitSyntax .DescendantNodes() .OfType <MethodDeclarationSyntax>() .ToList(); // create header file comments var headerFileComment = CreateHeaderFileComment(); // create using directives var usingDirectives = CreateUsingDirectives(wcfClientUnit, hasWcfClientInterface); // create base interface var baseInterface = CreateBaseInterface(baseInterfaceName, hasWcfClientInterface); // create methods var methods = await ClientCodeMethodsGenerator.CreateMethods(wcfClientMethods, serviceGenMethods, wcfServiceMethods); // create source code var sourcCode = CreateSourcCode(headerFileComment, usingDirectives, classNamespace, className, baseInterface, methods); // finalize & format generated code var root = await CodeParser.ConvertToCompilationUnit(sourcCode); var code = root .NormalizeWhitespace() .ToFullString(); codes.Add(className, code); } return(codes); }
public static async Task <IDictionary <string, string> > Run(IDictionary <string, Task <WcfServiceClassInfo> > wcfClasses) { var codes = new Dictionary <string, string>(); // create service code files for web api controllers foreach (string wcfClassName in wcfClasses.Keys) { // wcf class info var wcfInfo = await wcfClasses[wcfClassName]; var controllerName = wcfInfo.ControllerName; var controllerNamespace = wcfInfo.ControllerNamespace; var wcfServiceSourceCode = wcfInfo.WcfServiceSourceCode; var wcfMethods = wcfInfo.WcfMethods; var isAsmx = wcfInfo.IsAsmx; // check if has wcf code if (string.IsNullOrEmpty(wcfServiceSourceCode)) { codes.Add(controllerName, wcfServiceSourceCode); continue; } // parse wcf code var wcfUnit = await CodeParser.ConvertToCompilationUnit(wcfServiceSourceCode); // initialize web api code gen var unit = SyntaxFactory.CompilationUnit(); // create using directives for api controller var apiUsings = CreateApiControllerUsings(); // create file header comments var fileHeaderComments = CreateFileHeaderComments(); apiUsings[0] = apiUsings[0].WithUsingKeyword(fileHeaderComments); // create using directives for method parameters // all 'usings directives' from wcf file are added regardless if actually used or not (a bit of a hack) // a better way is to use roslyn's semantic model/analysis to determine which 'usings' are truly used by the method parameters var wcfUsings = wcfUnit.Usings; // add all usings & header comments var usingDirectives = BuildUsingDirectives(apiUsings, wcfUsings); unit = unit.AddUsings(usingDirectives.ToArray()); // create namespace var namespaceDeclaration = CreateNamespaceDeclaration(controllerNamespace); // create field for wcf class instance var fieldDeclaration = CreateFieldDeclaration(wcfClassName); // create class var classDeclaration = CreateClassDeclaration(controllerName); classDeclaration = classDeclaration.AddMembers(fieldDeclaration); // create methods var methodDeclarations = await ServiceCodeMethodsGenerator.CreateMethodDeclarations(controllerName, wcfUnit, wcfMethods, isAsmx); classDeclaration = classDeclaration.AddMembers(methodDeclarations.ToArray()); // finalize & format generated code namespaceDeclaration = namespaceDeclaration.AddMembers(classDeclaration); unit = unit.AddMembers(namespaceDeclaration); var code = unit .NormalizeWhitespace() .ToFullString(); codes.Add(controllerName, code); } return(codes); }