Esempio n. 1
0
        public GenResult RunFawrest(string serviceContractsFolder, string csProjFile)
        {
            var result = new GenResult();

            result.Info($"Starting {DateTime.Now}");
            result.Info($"Scanning {serviceContractsFolder}");
            var serviceContractDefinitions = GetExistingServiceContractDefinitions(serviceContractsFolder, ref result);

            result.Info($"Found {serviceContractDefinitions.Count} to process");

            foreach (var existingServiceContract in serviceContractDefinitions)
            {
                var mcu = existingServiceContract.ExistingServiceContractSyntaxTree.GetCompilationUnitRoot();
                var newCompilationUnit = SyntaxBuilder.BuildAsyncNamespaceCompilationUnit(mcu);

                result.Debug($"new compilation unit: {newCompilationUnit.GetText()}");

                foreach (var namespaceDeclaration in mcu.Members.Where(m => m.Kind() == SyntaxKind.NamespaceDeclaration))
                {
                    var existingNamespaceDecl = (NamespaceDeclarationSyntax)namespaceDeclaration;
                    var newNamespaceDecl      = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(existingNamespaceDecl.Name.ToString()));
                    result.Debug($"new namespace: {newNamespaceDecl.GetText()}");

                    var newTypes = new SyntaxList <MemberDeclarationSyntax>();
                    var interfaceDeclarations = existingNamespaceDecl.Members.Where(m => m.Kind() == SyntaxKind.InterfaceDeclaration).Select(m => m.WithoutTrivia());

                    //if this has the service contract attribute and it matches the file name, its the target we want to harvest
                    // [OperationContract] from.

                    foreach (var interfaceDeclaration in interfaceDeclarations)
                    {
                        var existingInterfaceDecl = (InterfaceDeclarationSyntax)interfaceDeclaration;

                        if (existingInterfaceDecl.IsServiceContract() == false)
                        {
                            continue;
                        }

                        var newInterfaceDecl = SyntaxBuilder.BuildAsyncInterfaceDeclFromSyncInterfaceDecl(existingServiceContract.ServiceContractName,
                                                                                                          existingServiceContract.ServiceContractAsyncName, existingInterfaceDecl, _UseExistingAsBase);
                        result.Debug($"new interface: {newInterfaceDecl.GetText()}");

                        var newClientClassDecl = SyntaxBuilder.BuildClientBaseClassDecl(existingServiceContract.ServiceClientName,
                                                                                        existingServiceContract.ServiceContractAsyncName);
                        result.Debug($"new clientbase : {newClientClassDecl.GetText()}");

                        var interfaceMethodsToAdd   = new SyntaxList <MemberDeclarationSyntax>();
                        var clientClassMethodsToAdd = new SyntaxList <MemberDeclarationSyntax>();

                        foreach (var methodDeclaration in existingInterfaceDecl.Members.Where(m => m.Kind() == SyntaxKind.MethodDeclaration).Select(m => m.WithoutTrivia()))
                        {
                            var existingMethodDecl = (MethodDeclarationSyntax)methodDeclaration;
                            if (existingMethodDecl.IsOperationContract() == false)
                            {
                                continue;
                            }

                            var newInterfaceMethodDecl = SyntaxBuilder.BuildTaskAsyncWrapperForSyncInterfaceMethod(existingMethodDecl);
                            interfaceMethodsToAdd = interfaceMethodsToAdd.Add(newInterfaceMethodDecl);
                            result.Debug($"new interface method decl: {newInterfaceMethodDecl.GetText()}");

                            var newClientClassMethodDeclAsync = SyntaxBuilder.BuildTaskAsyncWrapperForSyncMethod(existingMethodDecl);
                            clientClassMethodsToAdd = clientClassMethodsToAdd.Add(newClientClassMethodDeclAsync);
                            result.Debug($"new client class method async decl: {newClientClassMethodDeclAsync.GetText()}");

                            if (_UseExistingAsBase)
                            {
                                var newClientClassMethodDecl = SyntaxBuilder.BuildSyncMethod(existingMethodDecl);
                                clientClassMethodsToAdd = clientClassMethodsToAdd.Add(newClientClassMethodDecl);
                                result.Debug($"new client class method decl: {newClientClassMethodDecl.GetText()}");
                            }
                        }

                        newInterfaceDecl = newInterfaceDecl.WithMembers(interfaceMethodsToAdd).WithoutTrivia();
                        newTypes         = newTypes.Add(newInterfaceDecl);

                        newClientClassDecl = newClientClassDecl.WithMembers(clientClassMethodsToAdd).WithoutTrivia();
                        newTypes           = newTypes.Add(newClientClassDecl);
                    }
                    newNamespaceDecl = newNamespaceDecl.WithMembers(newTypes).WithoutTrivia();

                    newCompilationUnit = newCompilationUnit.AddMembers(newNamespaceDecl)
                                         .NormalizeWhitespace()
                                         .WithAdditionalAnnotations(Formatter.Annotation);
                    if (newNamespaceDecl.Members.Any())
                    {
                        existingServiceContract.NewServiceContractCompilationUnitSyntax = newCompilationUnit;
                    }
                }
            }

            foreach (var gennedCode in BuildOutputText(serviceContractDefinitions))
            {
                result.AddGeneratedCode(gennedCode.Key, gennedCode.Value);
            }

            AttemptCompilation(csProjFile, ref result, result.GeneratedOutput);

            result.Info($"Completed {DateTime.Now}");
            return(result);
        }