private (IMethodSymbol, Compilation) GetMapMethod(string code)
        {
            var compilation = CompilationUtility.Compile(code);
            var method      = (IMethodSymbol)compilation.GetSymbolsWithName("Map", SymbolFilter.Member).Single();

            return(method, compilation);
        }
        public void TestGenerateMetadataFromAssemblyWithReferences()
        {
            var compilation       = CompilationUtility.CreateCompilationFromAssembly(TupleAssemblyFiles.Concat(TupleReferencesFiles));
            var referenceAssembly = CompilationUtility.GetAssemblyFromAssemblyComplation(compilation, TupleAssemblyFiles).Select(s => s.assembly).ToList();

            var output = GenerateYamlMetadata(compilation, referenceAssembly[0]);
            var @class = output.Items[0].Items[0];

            Assert.NotNull(@class);
            Assert.Equal("XmlTasks", @class.DisplayNames[SyntaxLanguage.CSharp]);
            Assert.Equal("XmlTasks", @class.DisplayNamesWithType[SyntaxLanguage.CSharp]);
            Assert.Equal("TupleLibrary.XmlTasks", @class.DisplayQualifiedNames[SyntaxLanguage.CSharp]);

            {
                var method = @class.Items.Single(i => i.Name == "TupleLibrary.XmlTasks.ToNamespace(System.String,System.String)");
                Assert.Equal("ToNamespace(String, String)", method.DisplayNames[SyntaxLanguage.CSharp]);
                Assert.Equal("XmlTasks.ToNamespace(String, String)", method.DisplayNamesWithType[SyntaxLanguage.CSharp]);
                Assert.Equal("TupleLibrary.XmlTasks.ToNamespace(System.String, System.String)", method.DisplayQualifiedNames[SyntaxLanguage.CSharp]);

                Assert.Equal("public (string prefix, string uri) ToNamespace(string prefix, string uri)", method.Syntax.Content[SyntaxLanguage.CSharp]);
            }

            {
                var method = @class.Items.Single(i => i.Name == "TupleLibrary.XmlTasks.XmlPeek(System.String,System.ValueTuple{System.String,System.String}[])");
                Assert.Equal("XmlPeek(String, (String prefix, String uri)[])", method.DisplayNames[SyntaxLanguage.CSharp]);
                Assert.Equal("XmlTasks.XmlPeek(String, (String prefix, String uri)[])", method.DisplayNamesWithType[SyntaxLanguage.CSharp]);
                Assert.Equal("TupleLibrary.XmlTasks.XmlPeek(System.String, System.ValueTuple<System.String, System.String>[])", method.DisplayQualifiedNames[SyntaxLanguage.CSharp]);

                Assert.Equal("public string XmlPeek(string xpath, params (string prefix, string uri)[] namespaces)", method.Syntax.Content[SyntaxLanguage.CSharp]);
            }
        }
        private (MethodDeclarationSyntax, SemanticModel) GetMapMethodDeclaration(string code)
        {
            var compilation   = CompilationUtility.Compile(code);
            var syntaxTree    = compilation.SyntaxTrees.Single();
            var semanticModel = compilation.GetSemanticModel(syntaxTree);

            var methodDeclarationSyntax = syntaxTree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().Single();

            return(methodDeclarationSyntax, semanticModel);
        }
        public void TestGenerateMetadataFromAssembly()
        {
            var compilation       = CompilationUtility.CreateCompilationFromAssembly(AssemblyFiles);
            var referenceAssembly = CompilationUtility.GetAssemblyFromAssemblyComplation(compilation);

            var output = GenerateYamlMetadata(compilation, referenceAssembly[1]);
            var @class = output.Items[0].Items[2];

            Assert.NotNull(@class);
            Assert.Equal("Cat<T, K>", @class.DisplayNames.First().Value);
            Assert.Equal("Cat<T, K>", @class.DisplayNamesWithType.First().Value);
            Assert.Equal("CatLibrary.Cat<T, K>", @class.DisplayQualifiedNames.First().Value);
        }
        public void TestGenerateMetadataFromAssembly()
        {
            var compilation       = CompilationUtility.CreateCompilationFromAssembly(AssemblyFiles);
            var referenceAssembly = CompilationUtility.GetAssemblyFromAssemblyComplation(compilation, AssemblyFiles).Select(s => s.assembly).ToList();

            {
                var output = GenerateYamlMetadata(compilation, referenceAssembly[1]);
                var @class = output.Items[0].Items[2];
                Assert.NotNull(@class);
                Assert.Equal("Cat<T, K>", @class.DisplayNames.First().Value);
                Assert.Equal("Cat<T, K>", @class.DisplayNamesWithType.First().Value);
                Assert.Equal("CatLibrary.Cat<T, K>", @class.DisplayQualifiedNames.First().Value);
            }

            {
                var output = GenerateYamlMetadata(compilation, referenceAssembly[2]);
                var @class = output.Items[0].Items[0];
                Assert.NotNull(@class);
                Assert.Equal("CarLibrary2.Cat2", @class.Name);
                Assert.Equal(new[] { "System.Object", "CatLibrary.Cat{CatLibrary.Dog{System.String},System.Int32}" }, @class.Inheritance);
            }
        }
Esempio n. 6
0
        private ITypeSymbol GetType(string code)
        {
            var compilation = CompilationUtility.Compile(code);

            return((ITypeSymbol)compilation.GetSymbolsWithName("DTO", SymbolFilter.Type).Single());
        }
Esempio n. 7
0
        private async Task SaveAllMembersFromCacheAsync(IEnumerable <string> inputs, string outputFolder, bool forceRebuild)
        {
            var projectCache = new ConcurrentDictionary <string, Project>();
            // Project<=>Documents
            var      documentCache = new ProjectDocumentCache();
            DateTime triggeredTime = DateTime.UtcNow;
            var      solutions     = inputs.Where(s => IsSupportedSolution(s));
            var      projects      = inputs.Where(s => IsSupportedProject(s));

            var sourceFiles = inputs.Where(s => IsSupportedSourceFile(s));

            // Exclude not supported files from inputs
            inputs = solutions.Concat(projects).Concat(sourceFiles);

            // No matter is incremental or not, we have to load solutions into memory
            await solutions.ForEachInParallelAsync(async path =>
            {
                documentCache.AddDocument(path, path);
                var solution = await GetSolutionAsync(path);
                if (solution != null)
                {
                    foreach (var project in solution.Projects)
                    {
                        var filePath = project.FilePath;

                        // If the project is csproj/vbproj, add to project dictionary, otherwise, ignore
                        if (IsSupportedProject(filePath))
                        {
                            projectCache.GetOrAdd(project.FilePath, s => project);
                        }
                        else
                        {
                            var value = string.Join(",", SupportedExtensions);
                            Logger.Log(LogLevel.Warning, $"Project {filePath} inside solution {path} is not supported, supported file extension are: {value}. The project will be ignored.");
                        }
                    }
                }
            }, 60);

            // Load additional projects out if it is not contained in expanded solution
            projects = projects.Except(projectCache.Keys).Distinct();

            await projects.ForEachInParallelAsync(async path =>
            {
                var project = await GetProjectAsync(path);
                if (project != null)
                {
                    projectCache.GetOrAdd(path, s => project);
                }
            }, 60);

            foreach (var item in projectCache)
            {
                var path    = item.Key;
                var project = item.Value;
                documentCache.AddDocument(path, path);
                documentCache.AddDocuments(path, project.Documents.Select(s => s.FilePath));
                documentCache.AddDocuments(path, project.MetadataReferences
                                           .Where(s => s is PortableExecutableReference)
                                           .Select(s => ((PortableExecutableReference)s).FilePath));
            }

            documentCache.AddDocuments(sourceFiles);

            // Incremental check for inputs as a whole:
            var applicationCache = ApplicationLevelCache.Get(inputs);

            if (!forceRebuild)
            {
                BuildInfo buildInfo = applicationCache.GetValidConfig(inputs);
                if (buildInfo != null)
                {
                    IncrementalCheck check = new IncrementalCheck(buildInfo);
                    // 1. Check if sln files/ project files and its contained documents/ source files are modified
                    var projectModified = check.AreFilesModified(documentCache.Documents);

                    if (!projectModified)
                    {
                        // 2. Check if documents/ assembly references are changed in a project
                        // e.g. <Compile Include="*.cs* /> and file added/deleted
                        foreach (var project in projectCache.Values)
                        {
                            var key = project.FilePath.ToNormalizedFullPath();
                            IEnumerable <string> currentContainedFiles = documentCache.GetDocuments(project.FilePath);
                            var previousDocumentCache = new ProjectDocumentCache(buildInfo.ContainedFiles);

                            IEnumerable <string> previousContainedFiles = previousDocumentCache.GetDocuments(project.FilePath);
                            if (previousContainedFiles != null && currentContainedFiles != null)
                            {
                                projectModified = !previousContainedFiles.SequenceEqual(currentContainedFiles);
                            }
                            else
                            {
                                // When one of them is not null, project is modified
                                if (!object.Equals(previousContainedFiles, currentContainedFiles))
                                {
                                    projectModified = true;
                                }
                            }
                            if (projectModified)
                            {
                                break;
                            }
                        }
                    }

                    if (!projectModified)
                    {
                        // Nothing modified, use the result in cache
                        try
                        {
                            CopyFromCachedResult(buildInfo, inputs, outputFolder);
                            return;
                        }
                        catch (Exception e)
                        {
                            Logger.Log(LogLevel.Warning, $"Unable to copy results from cache: {e.Message}. Rebuild starts.");
                        }
                    }
                }
            }

            // Build all the projects to get the output and save to cache
            List <MetadataItem> projectMetadataList = new List <MetadataItem>();

            foreach (var project in projectCache)
            {
                var projectMetadata = await GetProjectMetadataFromCacheAsync(project.Value, outputFolder, documentCache, forceRebuild, _preserveRawInlineComments);

                if (projectMetadata != null)
                {
                    projectMetadataList.Add(projectMetadata);
                }
            }

            var csFiles = sourceFiles.Where(s => IsSupportedCSSourceFile(s));

            if (csFiles.Any())
            {
                var csContent     = string.Join(Environment.NewLine, csFiles.Select(s => File.ReadAllText(s)));
                var csCompilation = CompilationUtility.CreateCompilationFromCsharpCode(csContent);
                if (csCompilation != null)
                {
                    var csMetadata = await GetFileMetadataFromCacheAsync(csFiles, csCompilation, outputFolder, forceRebuild, _preserveRawInlineComments);

                    if (csMetadata != null)
                    {
                        projectMetadataList.Add(csMetadata);
                    }
                }
            }

            var vbFiles = sourceFiles.Where(s => IsSupportedVBSourceFile(s));

            if (vbFiles.Any())
            {
                var vbContent     = string.Join(Environment.NewLine, vbFiles.Select(s => File.ReadAllText(s)));
                var vbCompilation = CompilationUtility.CreateCompilationFromVBCode(vbContent);
                if (vbCompilation != null)
                {
                    var vbMetadata = await GetFileMetadataFromCacheAsync(vbFiles, vbCompilation, outputFolder, forceRebuild, _preserveRawInlineComments);

                    if (vbMetadata != null)
                    {
                        projectMetadataList.Add(vbMetadata);
                    }
                }
            }

            var allMemebers   = MergeYamlProjectMetadata(projectMetadataList);
            var allReferences = MergeYamlProjectReferences(projectMetadataList);

            if (allMemebers == null || allMemebers.Count == 0)
            {
                var value = projectMetadataList.Select(s => s.Name).ToDelimitedString();
                Logger.Log(LogLevel.Warning, $"No metadata is generated for {value}.");
                applicationCache.SaveToCache(inputs, null, triggeredTime, outputFolder, null);
            }
            else
            {
                // TODO: need an intermediate folder? when to clean it up?
                // Save output to output folder
                var outputFiles = ResolveAndExportYamlMetadata(allMemebers, allReferences, outputFolder, _validInput.IndexFileName, _validInput.TocFileName, _validInput.ApiFolderName, _preserveRawInlineComments, _rawInput.ExternalReferences);
                applicationCache.SaveToCache(inputs, documentCache.Cache, triggeredTime, outputFolder, outputFiles);
            }
        }
 public void OneTimeSetUp()
 {
     _compilation = CompilationUtility.Compile("");
 }