public static SyntaxNode AddImport(
     this IAddImportsService service, Compilation compilation, SyntaxNode root,
     SyntaxNode contextLocation, SyntaxNode newImport, SyntaxGenerator generator, bool placeSystemNamespaceFirst, CancellationToken cancellationToken)
 {
     return(service.AddImports(compilation, root, contextLocation,
                               SpecializedCollections.SingletonEnumerable(newImport), generator, placeSystemNamespaceFirst, cancellationToken));
 }
예제 #2
0
 public static SyntaxNode AddImport(
     this IAddImportsService service, SyntaxNode root, SyntaxNode contextLocation, 
     SyntaxNode newImport, bool placeSystemNamespaceFirst)
 {
     return service.AddImports(root, contextLocation,
         SpecializedCollections.SingletonEnumerable(newImport), placeSystemNamespaceFirst);
 }
예제 #3
0
 public static SyntaxNode AddImport(
     this IAddImportsService service, Compilation compilation, SyntaxNode root,
     SyntaxNode contextLocation, SyntaxNode newImport, SyntaxGenerator generator, AddImportPlacementOptions options,
     CancellationToken cancellationToken)
 {
     return(service.AddImports(compilation, root, contextLocation,
                               SpecializedCollections.SingletonEnumerable(newImport), generator, options, cancellationToken));
 }
예제 #4
0
 public static SyntaxNode AddImport(
     this IAddImportsService service, Compilation compilation, SyntaxNode root,
     SyntaxNode contextLocation, SyntaxNode newImport, SyntaxGenerator generator, CodeGenerationPreferences preferences,
     bool allowInHiddenRegions, CancellationToken cancellationToken)
 {
     return(service.AddImports(compilation, root, contextLocation,
                               SpecializedCollections.SingletonEnumerable(newImport), generator, preferences,
                               allowInHiddenRegions, cancellationToken));
 }
            /// <summary>
            /// Add imports for the namespace specified by <paramref name="names"/>
            /// to the provided <paramref name="containers"/>
            /// </summary>
            private async Task <Document> AddImportsInContainersAsync(
                Document document,
                IAddImportsService addImportService,
                ImmutableArray <SyntaxNode> containers,
                ImmutableArray <string> names,
                bool placeSystemNamespaceFirst,
                CancellationToken cancellationToken)
            {
                // Sort containers based on their span start, to make the result of
                // adding imports deterministic.
                if (containers.Length > 1)
                {
                    containers = containers.Sort(SyntaxNodeSpanStartComparer.Instance);
                }

                var imports = CreateImports(document, names, withFormatterAnnotation: true);

                foreach (var container in containers)
                {
                    // If the container is a namespace declaration, the context we pass to
                    // AddImportService must be a child of the declaration, otherwise the
                    // import will be added to root node instead.
                    var contextLocation = container is TNamespaceDeclarationSyntax
                        ? container.DescendantNodes().First()
                        : container;

                    var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

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

                    root     = addImportService.AddImports(compilation, root, contextLocation, imports, placeSystemNamespaceFirst);
                    document = document.WithSyntaxRoot(root);
                }

                return(document);
            }
예제 #6
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));
        }
예제 #7
0
        private async Task <Document> AddImportDirectivesFromSyntaxesAsync(
            Document document,
            IEnumerable <SyntaxNode> syntaxNodes,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            bool placeSystemNamespaceFirst,
            bool allowInHiddenRegions,
            CancellationToken cancellationToken)
        {
            using var _1 = ArrayBuilder <SyntaxNode> .GetInstance(out var importsToAdd);

            using var _2 = ArrayBuilder <SyntaxNode> .GetInstance(out var nodesToSimplify);

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

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

            var nodesWithExplicitNamespaces = syntaxNodes
                                              .Select(n => (syntaxnode: n, namespaceSymbol: GetExplicitNamespaceSymbol(n, model)))
                                              .Where(x => x.namespaceSymbol != null);

            var addedSymbols = new HashSet <INamespaceSymbol>();

            foreach (var(node, namespaceSymbol) in nodesWithExplicitNamespaces)
            {
                cancellationToken.ThrowIfCancellationRequested();

                nodesToSimplify.Add(node);

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

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

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

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

            if (nodesToSimplify.Count == 0)
            {
                return(document);
            }

            var annotation = new SyntaxAnnotation();

            root = root.ReplaceNodes(
                nodesToSimplify,
                (o, r) => r.WithAdditionalAnnotations(Simplifier.Annotation, annotation));

            var first = root.DescendantNodesAndSelf().First(x => x.HasAnnotation(annotation));
            var last  = root.DescendantNodesAndSelf().Last(x => x.HasAnnotation(annotation));

            var context = first.GetCommonRoot(last);

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

            return(document.WithSyntaxRoot(root));
        }