public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;
            var semanticModel     = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

            var workspace     = document.Project.Solution.Workspace;
            var syntaxContext = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            if (!syntaxContext.IsAwaitKeywordContext(position))
            {
                return;
            }

            var method = syntaxContext.TargetToken.GetAncestor(node => node.IsAsyncSupportingFunctionSyntax());
            var shouldMakeContainerAsync = method is not null && !method.GetModifiers().Any(SyntaxKind.AsyncKeyword);
            var completionItem           = CommonCompletionItem.Create(
                displayText: SyntaxFacts.GetText(SyntaxKind.AwaitKeyword),
                displayTextSuffix: "",
                rules: CompletionItemRules.Default,
                Glyph.Keyword,
                description: RecommendedKeyword.CreateDisplayParts(SyntaxFacts.GetText(SyntaxKind.AwaitKeyword), string.Empty),
                inlineDescription: shouldMakeContainerAsync ? CSharpFeaturesResources.Make_container_async : null,
                isComplexTextEdit: shouldMakeContainerAsync);

            context.AddItem(completionItem);
        }
        public override async Task ProvideCompletionsAsync(CompletionContext completionContext)
        {
            var document          = completionContext.Document;
            var position          = completionContext.Position;
            var cancellationToken = completionContext.CancellationToken;

            var semanticModel = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var context   = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            var index = GetElementIndex(context);

            if (index == null)
            {
                return;
            }

            var typeInferrer  = document.GetLanguageService <ITypeInferenceService>();
            var inferredTypes = typeInferrer.InferTypes(semanticModel, context.TargetToken.Parent.SpanStart, cancellationToken)
                                .Where(t => t.IsTupleType)
                                .Cast <INamedTypeSymbol>()
                                .ToImmutableArray();

            AddItems(inferredTypes, index.Value, completionContext);
        }
        public override async Task ProvideCompletionsAsync(CompletionContext completionContext)
        {
            try
            {
                var document          = completionContext.Document;
                var position          = completionContext.Position;
                var cancellationToken = completionContext.CancellationToken;

                var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

                var workspace = document.Project.Solution.Workspace;
                var context   = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

                var index = GetElementIndex(context);
                if (index == null)
                {
                    return;
                }

                var typeInferrer  = document.GetLanguageService <ITypeInferenceService>();
                var inferredTypes = typeInferrer.InferTypes(semanticModel, context.TargetToken.Parent.SpanStart, cancellationToken)
                                    .Where(t => t.IsTupleType)
                                    .Cast <INamedTypeSymbol>()
                                    .ToImmutableArray();

                AddItems(inferredTypes, index.Value, completionContext, context.TargetToken.Parent.SpanStart);
            }
            catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e))
            {
                // nop
            }
        }
        public static async Task <SyntaxContext> CreateContextAsync(
            Document document,
            int position,
            bool usePartialSemantic,
            CancellationToken cancellationToken
            )
        {
            // Need regular semantic model because we will use it to get imported namespace symbols. Otherwise we will try to
            // reach outside of the span and ended up with "node not within syntax tree" error from the speculative model.
            // Also we use partial model unless full model is explictly request (e.g. in tests) so that we don't have to wait for all semantics to be computed.
            var semanticModel = usePartialSemantic
                ? await document
                                .GetPartialSemanticModelAsync(cancellationToken)
                                .ConfigureAwait(false)
                : await document
                                .GetRequiredSemanticModelAsync(cancellationToken)
                                .ConfigureAwait(false);

            Contract.ThrowIfNull(semanticModel);
            return(CSharpSyntaxContext.CreateContext(
                       document.Project.Solution.Workspace,
                       semanticModel,
                       position,
                       cancellationToken
                       ));
        }
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
                ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument))
            {
                SourceText text;
                if (!context.Document.TryGetText(out text))
                {
                    text = await context.Document.GetTextAsync();
                }
                var currentChar = text [context.Position - 1];
                if (ctx.TargetToken.Parent == null || !ctx.TargetToken.Parent.IsKind(SyntaxKind.StringLiteralExpression) ||
                    ctx.TargetToken.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument) ||
                    ctx.TargetToken.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.IsKind(SyntaxKind.ArgumentList) ||
                    ctx.TargetToken.Parent.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.Parent.IsKind(SyntaxKind.InvocationExpression))
                {
                    return;
                }
                var formatArgument       = GetFormatItemNumber(document, position);
                var invocationExpression = ctx.TargetToken.Parent.Parent.Parent.Parent as InvocationExpressionSyntax;
                GetFormatCompletionData(context, semanticModel, invocationExpression, formatArgument, currentChar);
            }
        }
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            try
            {
                var document          = context.Document;
                var position          = context.Position;
                var cancellationToken = context.CancellationToken;

                var tree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                if (tree.IsInNonUserCode(position, cancellationToken))
                {
                    return;
                }

                var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

                var syntaxContext = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken);

                if (syntaxContext.IsInTaskLikeTypeContext)
                {
                    return;
                }

                var token = syntaxContext.TargetToken;
                if (token.IsMandatoryNamedParameterPosition())
                {
                    return;
                }

                // Don't show up within member access
                // This previously worked because the type inferrer didn't work
                // in member access expressions.
                // The regular SymbolCompletionProvider will handle completion after .
                if (token.IsKind(SyntaxKind.DotToken))
                {
                    return;
                }

                var typeInferenceService = document.GetLanguageService <ITypeInferenceService>();
                Contract.ThrowIfNull(typeInferenceService, nameof(typeInferenceService));

                var types = typeInferenceService.InferTypes(semanticModel, position, cancellationToken);

                if (types.Length == 0)
                {
                    types = ImmutableArray.Create <ITypeSymbol>(semanticModel.Compilation.ObjectType);
                }

                foreach (var type in types)
                {
                    await HandleSingleTypeAsync(context, semanticModel, token, type, cancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, ErrorSeverity.General))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
        protected override async Task <SyntaxContext> CreateContextAsync(
            Document document, int position, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            return(CSharpSyntaxContext.CreateContext(
                       document.Project.Solution.Workspace, semanticModel, position, cancellationToken));
        }
        protected override async Task <SyntaxContext> CreateContext(Document document, int position, CancellationToken cancellationToken)
        {
            var workspace     = document.Project.Solution.Workspace;
            var span          = new TextSpan(position, 0);
            var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);

            return(CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken));
        }
示例#9
0
        protected override async Task <SyntaxContext> CreateContextAsync(Document document, int position, CancellationToken cancellationToken)
        {
            // Need regular semantic model because we will use it to get imported namespace symbols. Otherwise we will try to
            // reach outside of the span and ended up with "node not within syntax tree" error from the speculative model.
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            return(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken));
        }
示例#10
0
        public static async Task <SyntaxContext> CreateContextAsync(Document document, int position, CancellationToken cancellationToken)
        {
            // Need regular semantic model because we will use it to get imported namespace symbols. Otherwise we will try to
            // reach outside of the span and ended up with "node not within syntax tree" error from the speculative model.
            var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            Contract.ThrowIfNull(semanticModel);
            return(CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken));
        }
示例#11
0
        protected override Task <Tuple <ImmutableArray <ISymbol>, SyntaxContext> > GetRecommendedSymbolsAtPositionWorkerAsync(
            Workspace workspace, SemanticModel semanticModel, int position, OptionSet options, CancellationToken cancellationToken)
        {
            var context = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            var filterOutOfScopeLocals = options.GetOption(RecommendationOptions.FilterOutOfScopeLocals, semanticModel.Language);
            var symbols = GetSymbolsWorker(context, filterOutOfScopeLocals, cancellationToken);

            var hideAdvancedMembers = options.GetOption(RecommendationOptions.HideAdvancedMembers, semanticModel.Language);

            symbols = symbols.FilterToVisibleAndBrowsableSymbols(hideAdvancedMembers, semanticModel.Compilation);

            return(Task.FromResult(Tuple.Create <ImmutableArray <ISymbol>, SyntaxContext>(symbols, context)));
        }
示例#12
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace  = document.Project.Solution.Workspace;
            var ctx        = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);
            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return;
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(
                    position,
                    syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position),
                    cancellationToken))
            {
                return;
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return;
            }
            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null || symbolInfo.Symbol.Kind != SymbolKind.Parameter)
            {
                return;
            }
            var within       = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var addedSymbols = new HashSet <string> ();

            foreach (var ano in ma.AncestorsAndSelf().OfType <AnonymousMethodExpressionSyntax> ())
            {
                Analyze(context, model, ma.Expression, within, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
            }

            foreach (var ano in ma.AncestorsAndSelf().OfType <ParenthesizedLambdaExpressionSyntax> ())
            {
                Analyze(context, model, ma.Expression, within, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
            }
        }
示例#13
0
        private void AddKeywords(Workspace workspace, List <CompletionResult> completions, SemanticModel model, int position, bool wantKind, string wordToComplete)
        {
            var context        = CSharpSyntaxContext.CreateContext(workspace, model, position, CancellationToken.None);
            var keywordHandler = new KeywordContextHandler();
            var keywords       = keywordHandler.Get(context, model, position);

            foreach (var keyword in keywords.Where(k => k.IsValidCompletionFor(wordToComplete)))
            {
                completions.Add(new CompletionResult
                {
                    CompletionText = keyword,
                    DisplayText    = keyword,
                    Snippet        = keyword,
                    Kind           = wantKind ? "Keyword" : null
                });
            }
        }
示例#14
0
        public override async Task ProvideCompletionsAsync(CompletionContext completionContext)
        {
            try
            {
                var position          = completionContext.Position;
                var document          = completionContext.Document;
                var cancellationToken = completionContext.CancellationToken;
                var semanticModel     = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(position, 0), cancellationToken).ConfigureAwait(false);

                if (!completionContext.Options.GetOption(CompletionOptions.ShowNameSuggestions, LanguageNames.CSharp))
                {
                    return;
                }

                var context = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken);
                if (context.IsInNonUserCode)
                {
                    return;
                }

                var nameInfo = await NameDeclarationInfo.GetDeclarationInfoAsync(document, position, cancellationToken).ConfigureAwait(false);

                var baseNames = GetBaseNames(semanticModel, nameInfo);
                if (baseNames == default)
                {
                    return;
                }

                var recommendedNames = await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, cancellationToken).ConfigureAwait(false);

                var sortValue = 0;
                foreach (var(name, kind) in recommendedNames)
                {
                    // We've produced items in the desired order, add a sort text to each item to prevent alphabetization
                    completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8")));
                    sortValue++;
                }

                completionContext.SuggestionModeItem = CommonCompletionItem.Create(
                    CSharpFeaturesResources.Name, displayTextSuffix: "", CompletionItemRules.Default);
            }
            catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e))
            {
                // nop
            }
        }
        async void HandleEventHandlerContext()
        {
            var analysisDocument = DocumentContext.AnalysisDocument;

            if (analysisDocument == null)
            {
                return;
            }
            var partialDoc    = analysisDocument.WithFrozenPartialSemantics(default(CancellationToken));
            var semanticModel = await partialDoc.GetSemanticModelAsync(default(CancellationToken));

            var syntaxContext = CSharpSyntaxContext.CreateContext(DocumentContext.RoslynWorkspace, semanticModel, Editor.CaretOffset, default(CancellationToken));

            if (syntaxContext.InferredTypes.Any(t => t.TypeKind == TypeKind.Delegate))
            {
                CompletionWindowManager.HideWindow();
                RunCompletionCommand();
            }
        }
示例#16
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);

            if (ctx.IsPreProcessorExpressionContext)
            {
                var parseOptions = model.SyntaxTree.Options as CSharpParseOptions;
                foreach (var define in parseOptions.PreprocessorSymbolNames)
                {
                    context.AddItem(CompletionItem.Create(define));
                }
            }
        }
示例#17
0
        private static async Task <bool> ShouldShowSpeculativeTCompletionItemAsync(Document document, int position, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return(false);
            }

            // We could be in the middle of a ref/generic/tuple type, instead of a simple T case.
            // If we managed to walk out and get a different SpanStart, we treat it as a simple $$T case.

            var token         = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
            var semanticModel = await document.ReuseExistingSpeculativeModelAsync(token.Parent, cancellationToken).ConfigureAwait(false);

            var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken);

            if (context.IsInTaskLikeTypeContext)
            {
                return(false);
            }

            var spanStart = position;

            while (true)
            {
                var oldSpanStart = spanStart;

                spanStart = WalkOutOfGenericType(syntaxTree, spanStart, semanticModel, cancellationToken);
                spanStart = WalkOutOfTupleType(syntaxTree, spanStart, cancellationToken);
                spanStart = WalkOutOfRefType(syntaxTree, spanStart, cancellationToken);

                if (spanStart == oldSpanStart)
                {
                    break;
                }
            }

            return(IsStartOfSpeculativeTContext(syntaxTree, spanStart, cancellationToken));
        }
示例#18
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);

            var syntaxTree = ctx.SyntaxTree;

            var enclosingType = model.GetEnclosingNamedType(position, cancellationToken);

            if (enclosingType == null)
            {
                return;
            }

            foreach (var type in ctx.InferredTypes)
            {
                if (type.TypeKind != TypeKind.Delegate)
                {
                    continue;
                }


                string delegateName = null;

                if (ctx.TargetToken.IsKind(SyntaxKind.PlusEqualsToken))
                {
                    delegateName = GuessEventHandlerBaseName(ctx.TargetToken.Parent, ctx.ContainingTypeDeclaration);
                }

                AddDelegateHandlers(context, ctx.TargetToken.Parent, model, type, position, delegateName, cancellationToken);
            }
        }
示例#19
0
        private Task CheckResultAsync(string text, int position, bool absent, CSharpParseOptions options, int?matchPriority)
        {
            using var workspace = new TestWorkspace(composition: FeaturesTestCompositions.Features);
            var solution = workspace.CurrentSolution;
            var project  = solution.AddProject("test", "test", LanguageNames.CSharp);
            var document = project.AddDocument("test.cs", text);

            var tree        = SyntaxFactory.ParseSyntaxTree(text, options: options);
            var compilation = CSharpCompilation.Create(
                "test",
                syntaxTrees: new[] { tree },
                references: new[] { TestMetadata.Net451.mscorlib });

            if (tree.IsInNonUserCode(position, CancellationToken.None) && !absent)
            {
                Assert.False(true, "Wanted keyword, but in non-user code position: " + keywordText);
            }

            var semanticModel = compilation.GetSemanticModel(tree);
            var context       = CSharpSyntaxContext.CreateContext(document, semanticModel, position, CancellationToken.None);

            return(CheckResultAsync(absent, position, context, matchPriority));
        }
示例#20
0
        public override async Task ProvideCompletionsAsync(CompletionContext completionContext)
        {
            var position          = completionContext.Position;
            var document          = completionContext.Document;
            var cancellationToken = completionContext.CancellationToken;
            var semanticModel     = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(position, 0), cancellationToken).ConfigureAwait(false);

            var context = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken);

            if (context.IsInNonUserCode)
            {
                return;
            }

            var nameInfo = await NameDeclarationInfo.GetDeclarationInfo(document, position, cancellationToken).ConfigureAwait(false);

            if (!IsValidType(nameInfo.Type))
            {
                return;
            }

            var type             = UnwrapType(nameInfo.Type, semanticModel.Compilation);
            var baseNames        = NameGenerator.GetBaseNames(type);
            var recommendedNames = await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, cancellationToken).ConfigureAwait(false);

            int sortValue = 0;

            foreach (var(name, kind) in recommendedNames)
            {
                // We've produced items in the desired order, add a sort text to each item to prevent alphabetization
                completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8")));
                sortValue++;
            }

            completionContext.SuggestionModeItem = CommonCompletionItem.Create(CSharpFeaturesResources.Name, CompletionItemRules.Default);
        }
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);

            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return;
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(
                    position,
                    syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position),
                    cancellationToken))
            {
                return;
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return;
            }

            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null)
            {
                return;
            }

            var        within       = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var        addedSymbols = new HashSet <string> ();
            SyntaxNode ancestor     = ma.Expression;

            while (ancestor != null)
            {
                // check parent if for direct type check
                var ifStmSyntax = ancestor as IfStatementSyntax;
                if (ifStmSyntax != null)
                {
                    var condition = SkipParens(ifStmSyntax.Condition);
                    if (condition != null && condition.IsKind(SyntaxKind.IsExpression))
                    {
                        var isExpr     = ((BinaryExpressionSyntax)condition);
                        var leftSymbol = model.GetSymbolInfo(isExpr.Left);

                        if (leftSymbol.Symbol == symbolInfo.Symbol)
                        {
                            var type = model.GetTypeInfo(isExpr.Right).Type;
                            if (type != null)
                            {
                                Analyze(context, model, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, addedSymbols, cancellationToken);
                            }
                        }
                    }
                    // skip if else ... if else
                    if (ancestor.Parent is ElseClauseSyntax)
                    {
                        while (ancestor is IfStatementSyntax || ancestor is ElseClauseSyntax)
                        {
                            ancestor = ancestor.Parent;
                        }
                        continue;
                    }
                    goto loop;
                }

                // check parent block if an if is there that checks the type
                var blockSyntax = ancestor as BlockSyntax;
                if (blockSyntax != null)
                {
                    foreach (var ifStmt in blockSyntax.Statements.OfType <IfStatementSyntax> ())
                    {
                        if (ifStmt.Span.End >= ma.Span.Start)
                        {
                            break;
                        }
                        var  condition  = SkipParens(ifStmt.Condition);
                        bool wasNegated = false;
                        if (condition.IsKind(SyntaxKind.LogicalNotExpression))
                        {
                            condition  = SkipParens(((PrefixUnaryExpressionSyntax)condition).Operand);
                            wasNegated = true;
                        }
                        if (condition == null || !condition.IsKind(SyntaxKind.IsExpression))
                        {
                            goto loop;
                        }
                        var stmt = ifStmt.Statement;
                        if (stmt is BlockSyntax)
                        {
                            stmt = ((BlockSyntax)stmt).Statements.LastOrDefault();
                        }
                        if (!wasNegated ||
                            stmt == null ||
                            !stmt.IsKind(SyntaxKind.ReturnStatement) && !stmt.IsKind(SyntaxKind.ContinueStatement) && !stmt.IsKind(SyntaxKind.BreakStatement) && !stmt.IsKind(SyntaxKind.ThrowStatement))
                        {
                            goto loop;
                        }

                        var isExpr     = ((BinaryExpressionSyntax)condition);
                        var leftSymbol = model.GetSymbolInfo(isExpr.Left);
                        if (leftSymbol.Symbol == symbolInfo.Symbol)
                        {
                            var type = model.GetTypeInfo(isExpr.Right).Type;
                            if (type != null)
                            {
                                Analyze(context, model, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, addedSymbols, cancellationToken);
                            }
                        }
                    }
                }

                var binOp = ancestor as BinaryExpressionSyntax;
                if (binOp != null && binOp.IsKind(SyntaxKind.LogicalAndExpression))
                {
                    if (SkipParens(binOp.Left).IsKind(SyntaxKind.IsExpression))
                    {
                        var isExpr     = (BinaryExpressionSyntax)SkipParens(binOp.Left);
                        var leftSymbol = model.GetSymbolInfo(isExpr.Left);

                        if (leftSymbol.Symbol == symbolInfo.Symbol)
                        {
                            var type = model.GetTypeInfo(isExpr.Right).Type;
                            if (type != null)
                            {
                                Analyze(context, model, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, addedSymbols, cancellationToken);
                            }
                        }
                    }
                }

                loop : ancestor = ancestor.Parent;
            }
        }
示例#22
0
 protected override Task <SyntaxContext> CreateContextAsync(Workspace workspace, SemanticModel semanticModel, int position, CancellationToken cancellationToken)
 => Task.FromResult <SyntaxContext>(CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken));
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);

            var tree = ctx.SyntaxTree;

            if (tree.IsInNonUserCode(context.Position, cancellationToken))
            {
                return;
            }

            var token = tree.FindTokenOnLeftOfPosition(context.Position, cancellationToken);

            if (token.IsKind(SyntaxKind.DotToken) || token.IsMandatoryNamedParameterPosition())
            {
                return;
            }

            // check if it's the first parameter and set autoselect == false if a parameterless version exists.
            if (token.IsKind(SyntaxKind.OpenParenToken))
            {
                var parent = token.Parent?.Parent;
                if (parent == null)
                {
                    return;
                }
                var symbolInfo = model.GetSymbolInfo(parent);
                foreach (var symbol in new [] { symbolInfo.Symbol }.Concat(symbolInfo.CandidateSymbols))
                {
                    if (symbol != null && symbol.IsKind(SymbolKind.Method))
                    {
                        if (symbol.GetParameters().Length == 0)
                        {
                            // completionResult.AutoSelect = false;
                            break;
                        }
                    }
                }
            }

            foreach (var _type in ctx.InferredTypes)
            {
                var type = _type;
                if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                {
                    type = type.GetTypeArguments().FirstOrDefault();
                    if (type == null)
                    {
                        continue;
                    }
                }

                if (type.TypeKind != TypeKind.Enum)
                {
                    continue;
                }
                if (!type.IsEditorBrowsable())
                {
                    continue;
                }

                // Does type have any aliases?
                ISymbol alias = await type.FindApplicableAlias(context.Position, model, cancellationToken).ConfigureAwait(false);

                if (!IsReachable(model, type, token.Parent))
                {
                    var pDict         = ImmutableDictionary <string, string> .Empty;
                    var displayString = CSharpAmbience.SafeMinimalDisplayString(type, model, context.Position, SymbolDisplayFormat.CSharpErrorMessageFormat);
                    var item          = CompletionItem.Create(displayString, properties: pDict, tags: tags);
                    context.AddItem(item.WithRules(item.Rules.WithMatchPriority(int.MaxValue)));
                }

                foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol> ())
                {
                    if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic))
                    {
                        var displayString = CSharpAmbience.SafeMinimalDisplayString(alias ?? field.Type, model, context.Position, SymbolDisplayFormat.CSharpErrorMessageFormat) + "." + field.Name;
                        var pDict         = ImmutableDictionary <string, string> .Empty;
                        context.AddItem(CompletionItem.Create(displayString, properties: pDict, tags: tags));
                    }
                }
            }
        }
示例#24
0
 protected override Task <SyntaxContext> CreateSyntaxContextAsync(Document document, SemanticModel semanticModel, int position, CancellationToken cancellationToken)
 {
     return(Task.FromResult <SyntaxContext>(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken)));
 }
        public override async Task ProvideCompletionsAsync(CompletionContext completionContext)
        {
            try
            {
                var position          = completionContext.Position;
                var document          = completionContext.Document;
                var cancellationToken = completionContext.CancellationToken;
                var semanticModel     = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

                if (!completionContext.CompletionOptions.ShowNameSuggestions)
                {
                    return;
                }

                var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken);
                if (context.IsInNonUserCode)
                {
                    return;
                }

                var nameInfo = await NameDeclarationInfo.GetDeclarationInfoAsync(document, position, cancellationToken).ConfigureAwait(false);

                using var _ = ArrayBuilder <(string name, SymbolKind kind)> .GetInstance(out var result);

                // Suggest names from existing overloads.
                if (nameInfo.PossibleSymbolKinds.Any(k => k.SymbolKind == SymbolKind.Parameter))
                {
                    var(_, partialSemanticModel) = await document.GetPartialSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    if (partialSemanticModel is not null)
                    {
                        AddNamesFromExistingOverloads(context, partialSemanticModel, result, cancellationToken);
                    }
                }

                var baseNames = GetBaseNames(semanticModel, nameInfo);
                if (baseNames != default)
                {
                    await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, result, cancellationToken).ConfigureAwait(false);
                }

                var recommendedNames = result.ToImmutable();

                if (recommendedNames.IsEmpty)
                {
                    return;
                }

                var sortValue = 0;
                foreach (var(name, kind) in recommendedNames)
                {
                    // We've produced items in the desired order, add a sort text to each item to prevent alphabetization
                    completionContext.AddItem(CreateCompletionItem(name, GetGlyph(kind, nameInfo.DeclaredAccessibility), sortValue.ToString("D8")));
                    sortValue++;
                }

                completionContext.SuggestionModeItem = CommonCompletionItem.Create(
                    CSharpFeaturesResources.Name, displayTextSuffix: "", CompletionItemRules.Default);
            }
            catch (Exception e) when(FatalError.ReportAndCatchUnlessCanceled(e, ErrorSeverity.General))
            {
                // nop
            }
        }
        private static async Task <ImmutableArray <CompletionItem> > GetSnippetsForDocumentAsync(
            Document document, int position, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var syntaxFacts   = document.GetRequiredLanguageService <ISyntaxFactsService>();
            var semanticFacts = document.GetRequiredLanguageService <ISemanticFactsService>();

            var root        = syntaxTree.GetRoot(cancellationToken);
            var leftToken   = root.FindTokenOnLeftOfPosition(position, includeDirectives: true);
            var targetToken = leftToken.GetPreviousTokenIfTouchingWord(position);

            if (syntaxFacts.IsInNonUserCode(syntaxTree, position, cancellationToken) ||
                syntaxTree.IsRightOfDotOrArrowOrColonColon(position, targetToken, cancellationToken) ||
                syntaxFacts.GetContainingTypeDeclaration(root, position) is EnumDeclarationSyntax ||
                syntaxTree.IsPossibleTupleContext(leftToken, position))
            {
                return(ImmutableArray <CompletionItem> .Empty);
            }

            var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);

            var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken);

            if (context.IsInTaskLikeTypeContext)
            {
                return(ImmutableArray <CompletionItem> .Empty);
            }

            if (syntaxFacts.IsPreProcessorDirectiveContext(syntaxTree, position, cancellationToken))
            {
                var directive = leftToken.GetAncestor <DirectiveTriviaSyntax>();
                Contract.ThrowIfNull(directive);

                if (!directive.DirectiveNameToken.IsKind(
                        SyntaxKind.IfKeyword,
                        SyntaxKind.RegionKeyword,
                        SyntaxKind.ElseKeyword,
                        SyntaxKind.ElifKeyword,
                        SyntaxKind.ErrorKeyword,
                        SyntaxKind.LineKeyword,
                        SyntaxKind.PragmaKeyword,
                        SyntaxKind.EndIfKeyword,
                        SyntaxKind.UndefKeyword,
                        SyntaxKind.EndRegionKeyword,
                        SyntaxKind.WarningKeyword))
                {
                    return(GetSnippetCompletionItems(
                               document.Project.Solution.Workspace, semanticModel, isPreProcessorContext: true));
                }
            }
            else
            {
                if (semanticFacts.IsGlobalStatementContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsExpressionContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsStatementContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsTypeContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsTypeDeclarationContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsNamespaceContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsNamespaceDeclarationNameContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsMemberDeclarationContext(semanticModel, position, cancellationToken) ||
                    semanticFacts.IsLabelContext(semanticModel, position, cancellationToken))
                {
                    return(GetSnippetCompletionItems(
                               document.Project.Solution.Workspace, semanticModel, isPreProcessorContext: false));
                }
            }

            return(ImmutableArray <CompletionItem> .Empty);
        }
        public override async Task ProduceCompletionListAsync(CompletionListContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var options           = context.Options;
            var cancellationToken = context.CancellationToken;

            var span          = new TextSpan(position, length: 0);
            var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);

            var syntaxTree = semanticModel.SyntaxTree;

            var syntaxFacts   = document.GetLanguageService <ISyntaxFactsService>();
            var semanticFacts = document.GetLanguageService <ISemanticFactsService>();

            if (syntaxFacts.IsInNonUserCode(syntaxTree, position, cancellationToken) ||
                semanticFacts.IsPreProcessorDirectiveContext(semanticModel, position, cancellationToken))
            {
                return;
            }

            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
            {
                return;
            }

            var node = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken)
                       .GetPreviousTokenIfTouchingWord(position)
                       .Parent;

            if (node.Kind() != SyntaxKind.ExplicitInterfaceSpecifier)
            {
                return;
            }

            // Bind the interface name which is to the left of the dot
            var name = ((ExplicitInterfaceSpecifierSyntax)node).Name;

            var symbol = semanticModel.GetSymbolInfo(name, cancellationToken).Symbol as ITypeSymbol;

            if (symbol?.TypeKind != TypeKind.Interface)
            {
                return;
            }

            var members = semanticModel.LookupSymbols(
                position: name.SpanStart,
                container: symbol)
                          .Where(s => !s.IsStatic)
                          .FilterToVisibleAndBrowsableSymbols(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation);

            // We're going to create a entry for each one, including the signature
            var namePosition = name.SpanStart;

            var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, position);

            foreach (var member in members)
            {
                var displayText   = member.ToMinimalDisplayString(semanticModel, namePosition, s_signatureDisplayFormat);
                var insertionText = displayText;

                context.AddItem(new SymbolCompletionItem(
                                    this,
                                    displayText,
                                    insertionText: insertionText,
                                    filterSpan: textChangeSpan,
                                    position: position,
                                    symbols: new List <ISymbol> {
                    member
                },
                                    context: CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken),
                                    rules: ItemRules.Instance));
            }
        }
        async Task <ICompletionDataList> InternalHandleCodeCompletion(CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, int triggerWordLength, CancellationToken token, bool forceSymbolCompletion = false)
        {
            var analysisDocument = DocumentContext.AnalysisDocument;

            if (analysisDocument == null)
            {
                return(EmptyCompletionDataList);
            }


            var        cs = DocumentContext.RoslynWorkspace.Services.GetLanguageServices(LanguageNames.CSharp).GetService <CompletionService> ();
            SourceText sourceText;

            if (!analysisDocument.TryGetText(out sourceText))
            {
                return(EmptyCompletionDataList);
            }

            CompletionTriggerKind kind;

            switch (triggerInfo.CompletionTriggerReason)
            {
            case CompletionTriggerReason.CharTyped:
                kind = CompletionTriggerKind.Insertion;
                if (triggerInfo.TriggerCharacter == '{')
                {
                    return(EmptyCompletionDataList);
                }
                break;

            case CompletionTriggerReason.CompletionCommand:
                kind = CompletionTriggerKind.InvokeAndCommitIfUnique;
                break;

            case CompletionTriggerReason.BackspaceOrDeleteCommand:
                kind = CompletionTriggerKind.Deletion;
                break;

            case CompletionTriggerReason.RetriggerCommand:
                kind = CompletionTriggerKind.InvokeAndCommitIfUnique;
                break;

            default:
                kind = CompletionTriggerKind.Insertion;
                break;
            }
            var triggerSnapshot = Editor.GetPlatformTextBuffer().CurrentSnapshot;
            var trigger         = new CompletionTrigger(kind, triggerInfo.TriggerCharacter.HasValue ? triggerInfo.TriggerCharacter.Value : '\0');

            if (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CharTyped)
            {
                if (!cs.ShouldTriggerCompletion(sourceText, completionContext.TriggerOffset, trigger, null))
                {
                    return(EmptyCompletionDataList);
                }
            }

            completionContext.Trace("C#: Getting completions");
            var customOptions = DocumentContext.RoslynWorkspace.Options
                                .WithChangedOption(CompletionOptions.TriggerOnDeletion, LanguageNames.CSharp, true)
                                .WithChangedOption(CompletionOptions.HideAdvancedMembers, LanguageNames.CSharp, IdeApp.Preferences.CompletionOptionsHideAdvancedMembers)
                                // Roslyn's implementation of this feature doesn't work correctly in old editor
                                .WithChangedOption(CompletionOptions.ShowItemsFromUnimportedNamespaces, LanguageNames.CSharp, false);
            var completionList = await Task.Run(() => cs.GetCompletionsAsync(analysisDocument, Editor.CaretOffset, trigger, options: customOptions, cancellationToken: token)).ConfigureAwait(false);

            completionContext.Trace("C#: Got completions");

            if (completionList == null)
            {
                return(EmptyCompletionDataList);
            }

            var result = new CompletionDataList();

            result.TriggerWordLength = triggerWordLength;
            CSharpCompletionData defaultCompletionData = null;
            bool first = true, addProtocolCompletion = false;

            foreach (var item in completionList.Items)
            {
                if (string.IsNullOrEmpty(item.DisplayText))
                {
                    continue;
                }
                var data = new CSharpCompletionData(analysisDocument, triggerSnapshot, cs, item);
                if (first)
                {
                    first = false;
                    addProtocolCompletion = data.Provider is OverrideCompletionProvider;
                }
                result.Add(data);
                if (item.Rules.MatchPriority > 0)
                {
                    if (defaultCompletionData == null || defaultCompletionData.Rules.MatchPriority < item.Rules.MatchPriority)
                    {
                        defaultCompletionData = data;
                    }
                }
            }

            result.AutoCompleteUniqueMatch = (triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand);

            var partialDoc = analysisDocument.WithFrozenPartialSemantics(token);
            var semanticModel = await partialDoc.GetSemanticModelAsync(token).ConfigureAwait(false);

            var syntaxContext = CSharpSyntaxContext.CreateContext(DocumentContext.RoslynWorkspace, semanticModel, completionContext.TriggerOffset, token);

            if (forceSymbolCompletion || IdeApp.Preferences.AddImportedItemsToCompletionList)
            {
                completionContext.Trace("C#: Adding import completion data");
                AddImportCompletionData(syntaxContext, result, semanticModel, completionContext.TriggerOffset, token);
                completionContext.Trace("C#: Added import completion data");
            }
            if (defaultCompletionData != null)
            {
                result.DefaultCompletionString = defaultCompletionData.DisplayText;
            }

            if (completionList.SuggestionModeItem != null)
            {
                if (completionList.Items.Contains(completionList.SuggestionModeItem))
                {
                    result.DefaultCompletionString = completionList.SuggestionModeItem.DisplayText;
                }
                // if a suggestion mode item is present autoselection is disabled
                // for example in the lambda case the suggestion mode item is '<lambda expression>' which is not part of the completion item list but taggs the completion list as auto select == false.
                result.AutoSelect = false;
            }
            if (triggerInfo.TriggerCharacter == '_' && triggerWordLength == 1)
            {
                result.AutoSelect = false;
            }
            if (triggerInfo.TriggerCharacter == ' ')
            {
                result.AutoCompleteEmptyMatch = true;
            }

            return(result);
        }
示例#29
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            if (context.Trigger.Character == '\\')
            {
                if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
                    ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument))
                {
                    var argument = ctx.TargetToken.Parent.Parent as ArgumentSyntax;

                    var symbolInfo = semanticModel.GetSymbolInfo(ctx.TargetToken.Parent.Parent.Parent.Parent);
                    if (symbolInfo.Symbol == null)
                    {
                        return;
                    }

                    if (SemanticHighlightingVisitor <string> .IsRegexMatchMethod(symbolInfo))
                    {
                        if (((ArgumentListSyntax)argument.Parent).Arguments [1] != argument)
                        {
                            return;
                        }
                        AddFormatCompletionData(context, argument.Expression.ToString() [0] == '@');
                        return;
                    }
                    if (SemanticHighlightingVisitor <string> .IsRegexConstructor(symbolInfo))
                    {
                        if (((ArgumentListSyntax)argument.Parent).Arguments [0] != argument)
                        {
                            return;
                        }
                        AddFormatCompletionData(context, argument.Expression.ToString() [0] == '@');
                        return;
                    }
                }
            }
            else
            {
                var ma = ctx.TargetToken.Parent as MemberAccessExpressionSyntax;
                if (ma != null)
                {
                    var symbolInfo = semanticModel.GetSymbolInfo(ma.Expression);
                    var typeInfo   = semanticModel.GetTypeInfo(ma.Expression);
                    var type       = typeInfo.Type;
                    if (type != null && type.Name == "Match" && type.ContainingNamespace.GetFullName() == "System.Text.RegularExpressions")
                    {
                        foreach (var grp in GetGroups(ctx, symbolInfo.Symbol))
                        {
                            context.AddItem(FormatItemCompletionProvider.CreateCompletionItem("Groups[\"" + grp + "\"]", null, null));
                        }
                    }
                }
            }
        }
示例#30
0
        private async Task <IEnumerable <CompletionItem> > GetCompletionsOffOfExplicitInterfaceAsync(
            Document document, SemanticModel semanticModel, int position, NameSyntax name, CancellationToken cancellationToken)
        {
            // Bind the interface name which is to the left of the dot
            var syntaxTree  = semanticModel.SyntaxTree;
            var nameBinding = semanticModel.GetSymbolInfo(name, cancellationToken);
            var context     = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken);

            var symbol = nameBinding.Symbol as ITypeSymbol;

            if (symbol == null || symbol.TypeKind != TypeKind.Interface)
            {
                return(SpecializedCollections.EmptyEnumerable <CompletionItem>());
            }

            var members = semanticModel.LookupSymbols(
                position: name.SpanStart,
                container: symbol)
                          .Where(s => !s.IsStatic)
                          .FilterToVisibleAndBrowsableSymbols(document.ShouldHideAdvancedMembers(), semanticModel.Compilation);

            // We're going to create a entry for each one, including the signature
            var completions = new List <CompletionItem>();

            var signatureDisplayFormat =
                new SymbolDisplayFormat(
                    genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
                    memberOptions:
                    SymbolDisplayMemberOptions.IncludeParameters,
                    parameterOptions:
                    SymbolDisplayParameterOptions.IncludeName |
                    SymbolDisplayParameterOptions.IncludeType |
                    SymbolDisplayParameterOptions.IncludeParamsRefOut,
                    miscellaneousOptions:
                    SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
                    SymbolDisplayMiscellaneousOptions.UseSpecialTypes);

            var namePosition = name.SpanStart;

            var text = await context.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, context.Position);

            foreach (var member in members)
            {
                var displayString = member.ToMinimalDisplayString(semanticModel, namePosition, signatureDisplayFormat);
                var memberCopied  = member;
                var insertionText = displayString;

                completions.Add(new SymbolCompletionItem(
                                    this,
                                    displayString,
                                    insertionText: insertionText,
                                    filterSpan: textChangeSpan,
                                    position: position,
                                    symbols: new List <ISymbol> {
                    member
                },
                                    context: context,
                                    rules: ItemRules.Instance));
            }

            return(completions);
        }