/// <summary> /// Searches for types that match the name the user has written. Returns <see cref="SymbolReference"/>s /// to the <see cref="INamespaceSymbol"/>s or <see cref="INamedTypeSymbol"/>s those types are /// contained in. /// </summary> private async Task <ImmutableArray <SymbolReference> > GetReferencesForMatchingTypesAsync(SearchScope searchScope) { searchScope.CancellationToken.ThrowIfCancellationRequested(); if (!_owner.CanAddImportForType(_diagnosticId, _node, out var nameNode)) { return(ImmutableArray <SymbolReference> .Empty); } CalculateContext( nameNode, _syntaxFacts, out var name, out var arity, out var inAttributeContext, out var hasIncompleteParentMember, out var looksGeneric); if (ExpressionBinds(nameNode, checkForExtensionMethods: false, cancellationToken: searchScope.CancellationToken)) { // If the expression bound, there's nothing to do. return(ImmutableArray <SymbolReference> .Empty); } var symbols = await searchScope.FindDeclarationsAsync(name, nameNode, SymbolFilter.Type).ConfigureAwait(false); // also lookup type symbols with the "Attribute" suffix if necessary. if (inAttributeContext) { var attributeSymbols = await searchScope.FindDeclarationsAsync(name + AttributeSuffix, nameNode, SymbolFilter.Type).ConfigureAwait(false); symbols = symbols.AddRange( attributeSymbols.Select(r => r.WithDesiredName(r.DesiredName.GetWithoutAttributeSuffix(isCaseSensitive: false)))); } var typeSymbols = OfType <ITypeSymbol>(symbols); // Only keep symbols which are accessible from the current location. var accessibleTypeSymbols = typeSymbols.WhereAsArray( s => ArityAccessibilityAndAttributeContextAreCorrect( s.Symbol, arity, inAttributeContext, hasIncompleteParentMember, looksGeneric)); // These types may be contained within namespaces, or they may be nested // inside generic types. Record these namespaces/types if it would be // legal to add imports for them. var typesContainedDirectlyInNamespaces = accessibleTypeSymbols.WhereAsArray(s => s.Symbol.ContainingSymbol is INamespaceSymbol); var typesContainedDirectlyInTypes = accessibleTypeSymbols.WhereAsArray(s => s.Symbol.ContainingType != null); var namespaceReferences = GetNamespaceSymbolReferences(searchScope, typesContainedDirectlyInNamespaces.SelectAsArray(r => r.WithSymbol(r.Symbol.ContainingNamespace))); var typeReferences = typesContainedDirectlyInTypes.SelectAsArray( r => searchScope.CreateReference(r.WithSymbol(r.Symbol.ContainingType))); return(namespaceReferences.Concat(typeReferences)); }