コード例 #1
0
        protected async Task <IDictionary <SyntaxNode, ISet <INamedTypeSymbol> > > GetAllReferencedDefinitionsAsync(
            Compilation compilation,
            IEnumerable <ISymbol> members,
            CancellationToken cancellationToken)
        {
            var namespaceScopeToReferencedDefinitions = new Dictionary <SyntaxNode, ISet <INamedTypeSymbol> >();
            var root = await Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            Func <SyntaxNode, ISet <INamedTypeSymbol> > createSet = _ => new HashSet <INamedTypeSymbol>();

            var annotatedNodes = root.GetAnnotatedNodesAndTokens(SymbolAnnotation.Kind);

            foreach (var annotatedNode in annotatedNodes)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (annotatedNode.GetAnnotations(DoNotAddImportsAnnotation.Kind).Any())
                {
                    continue;
                }

                SyntaxNode namespaceScope = null;
                var        annotations    = annotatedNode.GetAnnotations(SymbolAnnotation.Kind);
                foreach (var annotation in annotations)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    foreach (var namedType in SymbolAnnotation.GetSymbols(annotation, compilation).OfType <INamedTypeSymbol>())
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        if (!IsBuiltIn(namedType))
                        {
                            namespaceScope = namespaceScope ?? this.GetInnermostNamespaceScope(annotatedNode);
                            var referencedDefinitions = namespaceScopeToReferencedDefinitions.GetOrAdd(
                                namespaceScope, createSet);
                            referencedDefinitions.Add(namedType);
                        }
                    }
                }
            }

            return(namespaceScopeToReferencedDefinitions);
        }
コード例 #2
0
        private (ImmutableArray <SyntaxNode> imports, IEnumerable <INamespaceSymbol> namespaceSymbols, SyntaxNode?context) GetImportDirectivesFromAnnotatedNodes(
            IEnumerable <SyntaxNode> syntaxNodes,
            SyntaxNode root,
            SemanticModel model,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            CancellationToken cancellationToken)
        {
            (SyntaxNode first, SyntaxNode last)? nodes = null;
            var importsToAdd = ArrayBuilder <SyntaxNode> .GetInstance();

            var annotatedNodes = syntaxNodes.Where(x => x.HasAnnotations(SymbolAnnotation.Kind));
            var addedSymbols   = new HashSet <INamespaceSymbol>();

            foreach (var annotatedNode in annotatedNodes)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (annotatedNode.GetAnnotations(DoNotAddImportsAnnotation.Kind).Any())
                {
                    continue;
                }

                var annotations = annotatedNode.GetAnnotations(SymbolAnnotation.Kind);
                foreach (var annotation in annotations)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    foreach (var namedType in SymbolAnnotation.GetSymbols(annotation, model.Compilation).OfType <INamedTypeSymbol>())
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        if (namedType.OriginalDefinition.IsSpecialType() || namedType.IsNullable() || namedType.IsTupleType)
                        {
                            continue;
                        }

                        var namespaceSymbol = namedType.ContainingNamespace;
                        if (namespaceSymbol is null || namespaceSymbol.IsGlobalNamespace)
                        {
                            continue;
                        }

                        nodes = (first : nodes?.first ?? annotatedNode, last : annotatedNode);

                        if (addedSymbols.Contains(namespaceSymbol))
                        {
                            continue;
                        }

                        var namespaceSyntax = GenerateNamespaceImportDeclaration(namespaceSymbol, generator);

                        if (addImportsService.HasExistingImport(model.Compilation, root, annotatedNode, namespaceSyntax, generator))
                        {
                            continue;
                        }

                        if (IsInsideNamespace(annotatedNode, namespaceSymbol, model, cancellationToken))
                        {
                            continue;
                        }

                        addedSymbols.Add(namespaceSymbol);
                        importsToAdd.Add(namespaceSyntax);
                    }
                }
            }

            // we don't add simplifier annotations here,
            // since whatever added the symbol annotation probably also added simplifier annotations,
            // and if not they probably didn't for a reason

            return(importsToAdd.ToImmutableAndFree(), addedSymbols, nodes is var(first, last) ? first.GetCommonRoot(last) : null);
        }
コード例 #3
0
        private async Task <Document> AddImportDirectivesFromSymbolAnnotationsAsync(
            Document document,
            IEnumerable <SyntaxNode> syntaxNodes,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            bool placeSystemNamespaceFirst,
            bool allowInHiddenRegions,
            CancellationToken cancellationToken)
        {
            using var _ = PooledDictionary <INamespaceSymbol, SyntaxNode> .GetInstance(out var importToSyntax);

            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var model = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            SyntaxNode?first = null, last = null;
            var        annotatedNodes = syntaxNodes.Where(x => x.HasAnnotations(SymbolAnnotation.Kind));

            foreach (var annotatedNode in annotatedNodes)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (annotatedNode.GetAnnotations(DoNotAddImportsAnnotation.Kind).Any())
                {
                    continue;
                }

                var annotations = annotatedNode.GetAnnotations(SymbolAnnotation.Kind);
                foreach (var annotation in annotations)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    foreach (var namedType in SymbolAnnotation.GetSymbols(annotation, model.Compilation).OfType <INamedTypeSymbol>())
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        if (namedType.OriginalDefinition.IsSpecialType() || namedType.IsNullable() || namedType.IsTupleType)
                        {
                            continue;
                        }

                        var namespaceSymbol = namedType.ContainingNamespace;
                        if (namespaceSymbol is null || namespaceSymbol.IsGlobalNamespace)
                        {
                            continue;
                        }

                        first ??= annotatedNode;
                        last = annotatedNode;

                        if (importToSyntax.ContainsKey(namespaceSymbol))
                        {
                            continue;
                        }

                        var namespaceSyntax = GenerateNamespaceImportDeclaration(namespaceSymbol, generator);
                        if (addImportsService.HasExistingImport(model.Compilation, root, annotatedNode, namespaceSyntax, generator))
                        {
                            continue;
                        }

                        if (IsInsideNamespace(annotatedNode, namespaceSymbol, model, cancellationToken))
                        {
                            continue;
                        }

                        importToSyntax[namespaceSymbol] = namespaceSyntax;
                    }
                }
            }

            if (first == null || last == null || importToSyntax.Count == 0)
            {
                return(document);
            }

            var context = first.GetCommonRoot(last);

            // Find the namespace/compilation-unit we'll be adding all these imports to.
            var importContainer = addImportsService.GetImportContainer(root, context, importToSyntax.First().Value);

            // Now remove any imports we think can cause conflicts in that container.
            var safeImportsToAdd = GetSafeToAddImports(importToSyntax.Keys.ToImmutableArray(), importContainer, model, cancellationToken);

            var importsToAdd = importToSyntax.Where(kvp => safeImportsToAdd.Contains(kvp.Key)).Select(kvp => kvp.Value).ToImmutableArray();

            if (importsToAdd.Length == 0)
            {
                return(document);
            }

            root = addImportsService.AddImports(
                model.Compilation, root, context, importsToAdd, generator,
                placeSystemNamespaceFirst, allowInHiddenRegions, cancellationToken);
            return(document.WithSyntaxRoot(root));
        }