Exemple #1
0
        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)));
        }
Exemple #2
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.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());
        }