Ejemplo n.º 1
0
 public TypeNode(TypeNodeKey key, string?filePath, IEnumerable <string> associatedFiles, string fullMetadataName, bool isNestedType, ProjectIdentifier?project)
 {
     Identifier       = key.Identifier;
     FilePath         = filePath;
     FullMetadataName = fullMetadataName;
     IsNestedType     = isNestedType;
     Project          = project;
     AssociatedFiles.AddRange(associatedFiles);
     Key = key;
 }
        private TypeNode GetOrCreateNode(ITypeSymbol symbol, CompilationCache cache)
        {
            var identifier = symbol.ToIdentifier();
            var key        = new TypeNodeKey(identifier);

            if (!_nodes.TryGetValue(key, out var node))
            {
                node = CreateTypeNodeForSymbol(symbol, key, cache);
                AddNode(node);
            }
            return((TypeNode)node);
        }
        private static async Task BuildGraph(NodeGraph graph, CompilationCache compilationCache, IEnumerable <ProjectIdentifier> projects, CancellationToken ct)
        {
            var knownNodes = new Dictionary <TypeIdentifier, TypeNode>();

            foreach (var project in projects)
            {
                var syntaxTrees = await compilationCache.GetSyntaxTreesForProject(project, ct);

                // We use a hashset here because different SyntaxTrees may declare the same symbol (eg partial definitions)
                // Note: it's safe to hash by ITypeSymbol because they're all coming from the same Compilation
                var declaredSymbols = new HashSet <ITypeSymbol>();
                foreach (var syntaxTree in syntaxTrees)
                {
                    if (ct.IsCancellationRequested)
                    {
                        return;
                    }
                    var root = await syntaxTree.GetRootAsync(ct);

                    var semanticModel = await compilationCache.GetSemanticModel(syntaxTree, project, ct);

                    if (semanticModel == null)
                    {
                        continue;
                    }
                    declaredSymbols.UnionWith(graph.GetIncludedSymbolsFromSyntaxRoot(root, semanticModel));
                }

                foreach (var symbol in declaredSymbols)
                {
                    if (ct.IsCancellationRequested)
                    {
                        return;
                    }

                    var node = GetFromKnownNodes(symbol, compilationCache);
                    await foreach (var dependency in symbol.GetTypeDependencies(compilationCache, project, includeExternalMetadata: false, ct))
                    {
                        if (graph.IsSymbolIncluded(dependency))
                        {
                            var dependencyNode = GetFromKnownNodes(dependency, compilationCache);

                            if (node != dependencyNode)
                            {
                                node.AddForwardLink(dependencyNode, GetLinkType(dependency, symbol));
                            }
                        }
                    }
                }

                TypeNode GetFromKnownNodes(ITypeSymbol symbol, CompilationCache cache)
                {
                    var identifier = symbol.ToIdentifier();

                    if (!knownNodes.TryGetValue(identifier, out var node))
                    {
                        var key = new TypeNodeKey(identifier);
                        node = CreateTypeNodeForSymbol(symbol, key, cache);
                        knownNodes[identifier] = node;
                        graph.AddNode(node);
                    }

                    return(node);
                }
            }
        }
        private static TypeNode CreateTypeNodeForSymbol(ITypeSymbol symbol, TypeNodeKey key, CompilationCache cache)
        {
            var associatedFiles = GetAssociatedFiles(symbol);

            return(new TypeNode(key, symbol.GetPreferredDeclaration(), associatedFiles, symbol.GetFullMetadataName(), isNestedType: symbol.ContainingType != null, cache.GetContainingProject(associatedFiles)?.ToIdentifier()));
        }