private async Task <ImmutableArray <SymbolResult> > GetMatchingTypesAsync( Project project, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken) { // Can't be on the right hand side of binary expression (like 'dot'). cancellationToken.ThrowIfCancellationRequested(); var syntaxFacts = project.LanguageServices.GetService <ISyntaxFactsService>(); syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity); var symbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsAsync( project, name, this.IgnoreCase, SymbolFilter.Type, cancellationToken).ConfigureAwait(false); var symbols = symbolAndProjectIds.SelectAsArray(t => t.Symbol); // also lookup type symbols with the "Attribute" suffix. var inAttributeContext = syntaxFacts.IsAttributeName(node); if (inAttributeContext) { var attributeSymbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsAsync( project, name + "Attribute", this.IgnoreCase, SymbolFilter.Type, cancellationToken).ConfigureAwait(false); symbols = symbols.Concat(attributeSymbolAndProjectIds.SelectAsArray(t => t.Symbol)); } var accessibleTypeSymbols = symbols .OfType <INamedTypeSymbol>() .Where(s => (arity == 0 || s.GetArity() == arity) && s.IsAccessibleWithin(semanticModel.Compilation.Assembly) && (!inAttributeContext || s.IsAttribute()) && HasValidContainer(s)) .ToImmutableArray(); return(accessibleTypeSymbols.SelectAsArray(s => new SymbolResult(s, weight: TypeWeight))); }
private async Task <ImmutableArray <SymbolResult> > GetMatchingNamespacesAsync( Project project, SemanticModel semanticModel, SyntaxNode simpleName, CancellationToken cancellationToken) { var syntaxFacts = project.LanguageServices.GetService <ISyntaxFactsService>(); if (syntaxFacts.IsAttributeName(simpleName)) { return(ImmutableArray <SymbolResult> .Empty); } syntaxFacts.GetNameAndArityOfSimpleName(simpleName, out var name, out var arityUnused); if (cancellationToken.IsCancellationRequested) { return(ImmutableArray <SymbolResult> .Empty); } var symbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsAsync( project, name, this.IgnoreCase, SymbolFilter.Namespace, cancellationToken).ConfigureAwait(false); var symbols = symbolAndProjectIds.SelectAsArray(t => t.Symbol); // There might be multiple namespaces that this name will resolve successfully in. // Some of them may be 'better' results than others. For example, say you have // Y.Z and Y exists in both X1 and X2 // We'll want to order them such that we prefer the namespace that will correctly // bind Z off of Y as well. string rightName = null; bool isAttributeName = false; if (syntaxFacts.IsLeftSideOfDot(simpleName)) { var rightSide = syntaxFacts.GetRightSideOfDot(simpleName.Parent); syntaxFacts.GetNameAndArityOfSimpleName(rightSide, out rightName, out arityUnused); isAttributeName = syntaxFacts.IsAttributeName(rightSide); } var namespaces = symbols .OfType <INamespaceSymbol>() .Where(n => !n.IsGlobalNamespace && HasAccessibleTypes(n, semanticModel, cancellationToken)) .Select(n => new SymbolResult(n, BindsWithoutErrors(n, rightName, isAttributeName) ? NamespaceWithNoErrorsWeight : NamespaceWithErrorsWeight)); return(namespaces.ToImmutableArray()); }