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)); }
public static SyntaxNode AddImport( this IAddImportsService service, SyntaxNode root, SyntaxNode contextLocation, SyntaxNode newImport, bool placeSystemNamespaceFirst) { return service.AddImports(root, contextLocation, SpecializedCollections.SingletonEnumerable(newImport), placeSystemNamespaceFirst); }
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)); }
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); }
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)); }
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)); }