protected override async Task <ImmutableArray <ISymbol> > FindDeclarationsAsync( SymbolFilter filter, SearchQuery searchQuery) { var declarations = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( _project, searchQuery, filter, CancellationToken).ConfigureAwait(false); return(declarations.SelectAsArray(d => d.Symbol)); }
private async Task <ImmutableArray <SymbolResult> > GetMatchingTypesAsync( Document document, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var project = document.Project; var syntaxFacts = project.LanguageServices.GetRequiredService <ISyntaxFactsService>(); syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity); var looksGeneric = syntaxFacts.LooksGeneric(node); var symbols = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name, IgnoreCase), SymbolFilter.Type, cancellationToken).ConfigureAwait(false); // also lookup type symbols with the "Attribute" suffix. var inAttributeContext = syntaxFacts.IsAttributeName(node); if (inAttributeContext) { var attributeSymbols = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name + "Attribute", IgnoreCase), SymbolFilter.Type, cancellationToken).ConfigureAwait(false); symbols = symbols.Concat(attributeSymbols); } var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); var hideAdvancedMembers = options.GetOption(CompletionOptions.HideAdvancedMembers); var editorBrowserInfo = new EditorBrowsableInfo(semanticModel.Compilation); var validSymbols = symbols .OfType <INamedTypeSymbol>() .Where(s => IsValidNamedTypeSearchResult(semanticModel, arity, inAttributeContext, looksGeneric, s) && s.IsEditorBrowsable(hideAdvancedMembers, semanticModel.Compilation, editorBrowserInfo)) .ToImmutableArray(); // Check what the current node binds to. If it binds to any symbols, but with // the wrong arity, then we don't want to suggest fully qualifying to the same // type that we're already binding to. That won't address the WrongArity problem. var currentSymbolInfo = semanticModel.GetSymbolInfo(node, cancellationToken); if (currentSymbolInfo.CandidateReason == CandidateReason.WrongArity) { validSymbols = validSymbols.WhereAsArray( s => !currentSymbolInfo.CandidateSymbols.Contains(s)); } return(validSymbols.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.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name, 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; var 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()); }
private async Task <ImmutableArray <SymbolResult> > GetMatchingTypesAsync( Project project, SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var syntaxFacts = project.LanguageServices.GetService <ISyntaxFactsService>(); syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity); var symbolAndProjectIds = await DeclarationFinder.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(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.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(name + "Attribute", this.IgnoreCase), SymbolFilter.Type, cancellationToken).ConfigureAwait(false); symbols = symbols.Concat(attributeSymbolAndProjectIds.SelectAsArray(t => t.Symbol)); } var validSymbols = symbols .OfType <INamedTypeSymbol>() .Where(s => IsValidNamedTypeSearchResult(semanticModel, arity, inAttributeContext, s)) .ToImmutableArray(); // Check what the current node binds to. If it binds to any symbols, but with // the wrong arity, then we don't want to suggest fully qualifying to the same // type that we're already binding to. That won't address the WrongArity problem. var currentSymbolInfo = semanticModel.GetSymbolInfo(node, cancellationToken); if (currentSymbolInfo.CandidateReason == CandidateReason.WrongArity) { validSymbols = validSymbols.WhereAsArray( s => !currentSymbolInfo.CandidateSymbols.Contains(s)); } return(validSymbols.SelectAsArray(s => new SymbolResult(s, weight: TypeWeight))); }
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.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(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.FindAllDeclarationsWithNormalQueryAsync( project, SearchQuery.Create(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))); }