Example #1
0
        private static void AttemptCompilation(string csProjFile, ref GenResult result, ReadOnlyDictionary <string, string> genText)
        {
            if (string.IsNullOrWhiteSpace(csProjFile) == false && File.Exists(csProjFile))
            {
                result.Info($"Using proj file {csProjFile} to determine references");


                var assemblyName = Path.GetRandomFileName();
                var references   = CompilationHelpers.GetMetadataReferences(csProjFile).ToArray();
                result.Debug($"Found {references.Length} references");

                foreach (var genCode in genText)
                {
                    result.Info($"Compiling {genCode.Key}...");
                    var reTree  = CSharpSyntaxTree.ParseText(genCode.Value);
                    var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                                  .WithPlatform(Platform.AnyCpu) //get from proj file
                                  .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);
                    var compilation = CSharpCompilation.Create(assemblyName, new[] { reTree }, references, options);
                    var diags       = compilation.GetDiagnostics();
                    result.Debug($"Compilation complete, found {diags.Length} Diagnostics");

                    result.AddDiags(diags);
                }
            }
            else
            {
                result.Info($"{nameof(csProjFile)} was either not specified or does not exist at path given. Skipping compilation");
            }
        }
Example #2
0
        private static List <InterfaceDefinition> GetExistingServiceContractDefinitions(string serviceContractsFolder, ref GenResult result, List <string> exclusions = null)
        {
            var syncInterfaceFiles = Directory.GetFiles(serviceContractsFolder, "I*.*");
            var interfacesToCreate = new List <InterfaceDefinition>();

            foreach (var syncInterface in syncInterfaceFiles)
            {
                var fi         = new FileInfo(syncInterface);
                var fileName   = fi.Name;
                var isExcluded = exclusions != null && exclusions.Any(e => e.Equals(fileName, StringComparison.OrdinalIgnoreCase));

                if (isExcluded)
                {
                    result.Debug($"Skipping file {syncInterface}");
                    continue;
                }

                var serviceContractName = Path.GetFileNameWithoutExtension(fileName);
                result.Debug($"Building definition for {serviceContractName} from {fileName}");
                var idef = new InterfaceDefinition(serviceContractName, fi.FullName)
                {
                    ExistingServiceContractSyntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(fi.FullName))
                };

                result.Debug($"Info definition {Environment.NewLine} {idef}");


                interfacesToCreate.Add(idef);
            }
            return(interfacesToCreate);
        }
Example #3
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);
        }