private async Task AddDocuments(MSProject msProject, Project project) { // Handle all documents in project foreach (var msDocument in msProject.Documents) { await AddNamespaces(project, msDocument); } }
/// <summary> /// Generates a new dependency solution based on opened solution /// </summary> /// <returns></returns> public async Task <Solution> GenerateDependencyTree() { var solution = new Solution(); ResetTmpStorage(); // TODO: Handle all parallel to improve performance foreach (var msProject in (await GetCurrentSolution()).Projects) { var referencedProjectIds = msProject.ProjectReferences.Select(x => x.ProjectId).ToList(); var project = new Project(Guid.NewGuid(), msProject.Id, msProject.Name); _projectToProjectMapping.Add(project, referencedProjectIds); await AddDocuments(msProject, project); solution.Projects.Add(project); } MapReferences(solution); return(solution); }
private async Task AddNamespaces(Project project, MSDocument msDocument) { // We use the syntax tree to find all declareded classes inside this dockument var syntaxRoot = await msDocument.GetSyntaxRootAsync(); // We need the semanic model to query some informations of nodes var semanticModel = await msDocument.GetSemanticModelAsync(); var referencedNamespaces = GetRelatedNamespaces(syntaxRoot, semanticModel); // Use the syntax tree to get all namepace definitions inside var namespaces = syntaxRoot.DescendantNodesAndSelf().OfType <NamespaceDeclarationSyntax>(); foreach (var namespaceDeclarationSyntax in namespaces) { // Get the symbol for namespace from model to get full name of namespace var namespaceSymbol = semanticModel.GetDeclaredSymbol(namespaceDeclarationSyntax); var namespaceName = namespaceSymbol.ToDisplayString(SymbolDisplayFormat.CSharpErrorMessageFormat); // Check for exisiting namespace var @namespace = project.Namespaces.FirstOrDefault(x => x.Name.Equals(namespaceName)); if (@namespace == null) { @namespace = new Namespace(Guid.NewGuid(), namespaceName, project); project.Namespaces.Add(@namespace); _namespaceToNamespaceMapping.Add(@namespace, referencedNamespaces); } else { _namespaceToNamespaceMapping[@namespace] = _namespaceToNamespaceMapping[@namespace] .Union(referencedNamespaces).ToList(); } // Use the syntax tree to get all classes declarations inside var classes = namespaceDeclarationSyntax.DescendantNodes().OfType <ClassDeclarationSyntax>(); // Handle each class declaration inside the namespace foreach (var classDeclaration in classes) { var symbol = semanticModel.GetDeclaredSymbol(classDeclaration); var baseList = classDeclaration.BaseList; var referencedClasses = GetReturnType(baseList, semanticModel); CreateClass(classDeclaration, symbol, @namespace, referencedClasses, referencedNamespaces, semanticModel, msDocument.FilePath); } // Use the syntax tree to get all interface declations inside var interfaces = namespaceDeclarationSyntax.DescendantNodes().OfType <InterfaceDeclarationSyntax>(); foreach (var interfaceDeclaration in interfaces) { var symbol = semanticModel.GetDeclaredSymbol(interfaceDeclaration); var baseList = interfaceDeclaration.BaseList; var referencedClasses = GetReturnType(baseList, semanticModel); CreateClass(interfaceDeclaration, symbol, @namespace, referencedClasses, referencedNamespaces, semanticModel, msDocument.FilePath); } } }