Пример #1
0
            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)));
        }
Пример #3
0
        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)));
        }