Beispiel #1
0
        private async Task <IEnumerable <CompletionItem> > GetSnippetCompletionItemsAsync(Workspace workspace, SemanticModel semanticModel, int position, bool isPreProcessorContext, CancellationToken cancellationToken)
        {
            var service = _snippetInfoService ?? workspace.Services.GetLanguageServices(semanticModel.Language).GetService <ISnippetInfoService>();

            if (service == null)
            {
                return(SpecializedCollections.EmptyEnumerable <CompletionItem>());
            }

            var snippets = service.GetSnippetsIfAvailable();

            if (isPreProcessorContext)
            {
                snippets = snippets.Where(snippet => snippet.Shortcut.StartsWith("#"));
            }

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

            return(snippets.Select(snippet => new CompletionItem(
                                       this,
                                       displayText: isPreProcessorContext?snippet.Shortcut.Substring(1) : snippet.Shortcut,
                                           sortText: isPreProcessorContext ? snippet.Shortcut.Substring(1) : snippet.Shortcut,
                                           description: (snippet.Title + Environment.NewLine + snippet.Description).ToSymbolDisplayParts(),
                                           filterSpan: CompletionUtilities.GetTextChangeSpan(text, position),
                                           glyph: Glyph.Snippet,
                                           shouldFormatOnCommit: service.ShouldFormatSnippet(snippet))));
        }
Beispiel #2
0
        protected override async Task <IEnumerable <CompletionItem> > GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

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

            var targetToken = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position);

            if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective))
            {
                var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var aliases = compilation.ExternalReferences.SelectMany(r => r.Properties.Aliases).ToSet();

                if (aliases.Any())
                {
                    var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                    var usedAliases = root.ChildNodes().OfType <ExternAliasDirectiveSyntax>().Where(e => !e.Identifier.IsMissing).Select(e => e.Identifier.ValueText);
                    aliases.RemoveRange(usedAliases);
                    aliases.Remove(MetadataReferenceProperties.GlobalAlias);
                    var textChangeSpan = CompletionUtilities.GetTextChangeSpan(await document.GetTextAsync(cancellationToken).ConfigureAwait(false), position);
                    return(aliases.Select(e =>
                                          new CompletionItem(this, e, textChangeSpan, glyph: Glyph.Namespace)));
                }
            }

            return(SpecializedCollections.EmptyEnumerable <CompletionItem>());
        }
Beispiel #3
0
        public override async Task ProduceCompletionListAsync(CompletionListContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

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

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

            var targetToken = tree
                              .FindTokenOnLeftOfPosition(position, cancellationToken)
                              .GetPreviousTokenIfTouchingWord(position);

            if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective))
            {
                var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

                var aliases = compilation.ExternalReferences.SelectMany(r => r.Properties.Aliases).ToSet();

                if (aliases.Any())
                {
                    var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                    var usedAliases = root.ChildNodes().OfType <ExternAliasDirectiveSyntax>()
                                      .Where(e => !e.Identifier.IsMissing)
                                      .Select(e => e.Identifier.ValueText);

                    aliases.RemoveRange(usedAliases);
                    aliases.Remove(MetadataReferenceProperties.GlobalAlias);

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

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

                    foreach (var alias in aliases)
                    {
                        context.AddItem(new CompletionItem(this, alias, filterSpan, glyph: Glyph.Namespace));
                    }
                }
            }
        }
        private async Task <IEnumerable <CompletionItem> > GetNameEqualsItemsAsync(Workspace workspace, SemanticModel semanticModel,
                                                                                   int position, SyntaxToken token, AttributeSyntax attributeSyntax, ISet <string> existingNamedParameters,
                                                                                   CancellationToken cancellationToken)
        {
            var attributeNamedParameters   = GetAttributeNamedParameters(semanticModel, position, attributeSyntax, cancellationToken);
            var unspecifiedNamedParameters = attributeNamedParameters.Where(p => !existingNamedParameters.Contains(p.Name));

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

            return(from p in attributeNamedParameters
                   where !existingNamedParameters.Contains(p.Name)
                   select new CompletionItem(
                       this,
                       p.Name.ToIdentifierToken().ToString() + SpaceEqualsString,
                       CompletionUtilities.GetTextChangeSpan(text, position),
                       CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, token.SpanStart, p),
                       p.GetGlyph(),
                       sortText: p.Name,
                       rules: ItemRules.Instance));
        }
Beispiel #5
0
        private async Task <IEnumerable <CompletionItem> > GetNameColonItemsAsync(
            Workspace workspace, SemanticModel semanticModel, int position, SyntaxToken token, AttributeSyntax attributeSyntax, ISet <string> existingNamedParameters,
            CancellationToken cancellationToken)
        {
            var parameterLists = GetParameterLists(semanticModel, position, attributeSyntax, cancellationToken);

            parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters));

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

            return
                (from pl in parameterLists
                 from p in pl
                 where !existingNamedParameters.Contains(p.Name)
                 select new CSharpCompletionItem(
                     workspace,
                     this,
                     p.Name.ToIdentifierToken().ToString() + ColonString,
                     CompletionUtilities.GetTextChangeSpan(text, position),
                     CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, token.SpanStart, p),
                     p.GetGlyph(),
                     sortText: p.Name));
        }
 private TextSpan GetTextChangeSpan(SourceText text, int position)
 {
     return(CompletionUtilities.GetTextChangeSpan(text, position));
 }
Beispiel #7
0
 protected override TextSpan GetTextChangeSpan(SourceText text, int position)
 {
     return(CompletionUtilities.GetTextChangeSpan(text, position));
 }
        private async Task <CompletionItem> GetBuilderAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (triggerInfo.TriggerReason == CompletionTriggerReason.TypeCharCommand)
            {
                var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                if (triggerInfo.IsDebugger)
                {
                    // Aggressive Intellisense in the debugger: always show the builder
                    return(new CompletionItem(this, "", CompletionUtilities.GetTextChangeSpan(text, position), isBuilder: true));
                }

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

                var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
                token = token.GetPreviousTokenIfTouchingWord(position);
                if (token.Kind() == SyntaxKind.None)
                {
                    return(null);
                }

                var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(token.Parent, cancellationToken).ConfigureAwait(false);

                var typeInferrer = document.GetLanguageService <ITypeInferenceService>();

                if (IsLambdaExpression(semanticModel, position, token, typeInferrer, cancellationToken))
                {
                    return(new CompletionItem(this, CSharpFeaturesResources.LambdaExpression,
                                              CompletionUtilities.GetTextChangeSpan(text, position),
                                              CSharpFeaturesResources.AutoselectDisabledDueToPotentialLambdaDeclaration.ToSymbolDisplayParts(),
                                              isBuilder: true));
                }
                else if (IsAnonymousObjectCreation(token))
                {
                    return(new CompletionItem(this, CSharpFeaturesResources.MemberName,
                                              CompletionUtilities.GetTextChangeSpan(text, position),
                                              CSharpFeaturesResources.AutoselectDisabledDueToPossibleExplicitlyNamesAnonTypeMemCreation.ToSymbolDisplayParts(),
                                              isBuilder: true));
                }
                else if (token.IsPreProcessorExpressionContext())
                {
                    return(new CompletionItem(this, "", CompletionUtilities.GetTextChangeSpan(text, position), isBuilder: true));
                }
                else if (IsImplicitArrayCreation(semanticModel, token, position, typeInferrer, cancellationToken))
                {
                    return(new CompletionItem(this, CSharpFeaturesResources.ImplicitArrayCreation,
                                              CompletionUtilities.GetTextChangeSpan(text, position),
                                              CSharpFeaturesResources.AutoselectDisabledDueToPotentialImplicitArray.ToSymbolDisplayParts(),
                                              isBuilder: true));
                }
                else
                {
                    return(token.IsKindOrHasMatchingText(SyntaxKind.FromKeyword) || token.IsKindOrHasMatchingText(SyntaxKind.JoinKeyword)
                        ? new CompletionItem(this, CSharpFeaturesResources.RangeVariable,
                                             CompletionUtilities.GetTextChangeSpan(text, position),
                                             CSharpFeaturesResources.AutoselectDisabledDueToPotentialRangeVariableDecl.ToSymbolDisplayParts(),
                                             isBuilder: true)
                        : null);
                }
            }

            return(null);
        }
Beispiel #9
0
        protected override async Task <IEnumerable <CompletionItem> > GetItemsWorkerAsync(
            Document document, int position, CompletionTriggerInfo triggerInfo,
            CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

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

            var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);

            if (token.IsMandatoryNamedParameterPosition())
            {
                return(null);
            }

            var typeInferenceService = document.GetLanguageService <ITypeInferenceService>();

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

            var type = typeInferenceService.InferType(semanticModel, position,
                                                      objectAsDefault: true,
                                                      cancellationToken: cancellationToken);

            // If we have a Nullable<T>, unwrap it.
            if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
            {
                type = type.GetTypeArguments().FirstOrDefault();

                if (type == null)
                {
                    return(null);
                }
            }

            if (type.TypeKind != TypeKind.Enum)
            {
                type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
                if (type == null)
                {
                    return(null);
                }
            }

            if (!type.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation))
            {
                return(null);
            }

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

            var displayService = document.GetLanguageService <ISymbolDisplayService>();
            var displayText    = alias != null
                ? alias.Name
                : displayService.ToMinimalDisplayString(semanticModel, position, type);

            var workspace = document.Project.Solution.Workspace;
            var text      = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

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

            var item = new CSharpCompletionItem(
                workspace,
                this,
                displayText: displayText,
                filterSpan: textChangeSpan,
                descriptionFactory: CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, position, alias ?? type),
                glyph: (alias ?? type).GetGlyph(),
                preselect: true);

            return(SpecializedCollections.SingletonEnumerable(item));
        }
Beispiel #10
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);
        }
Beispiel #11
0
        protected override async Task <IEnumerable <CompletionItem> > GetItemsWorkerAsync(
            Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

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

            var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

            token = token.GetPreviousTokenIfTouchingWord(position);

            if (token.Kind() != SyntaxKind.OpenParenToken &&
                token.Kind() != SyntaxKind.OpenBracketToken &&
                token.Kind() != SyntaxKind.CommaToken)
            {
                return(null);
            }

            var argumentList = token.Parent as BaseArgumentListSyntax;

            if (argumentList == null)
            {
                return(null);
            }

            var semanticModel = await document.GetSemanticModelForNodeAsync(argumentList, cancellationToken).ConfigureAwait(false);

            var parameterLists = GetParameterLists(semanticModel, position, argumentList.Parent, cancellationToken);

            if (parameterLists == null)
            {
                return(null);
            }

            var existingNamedParameters = GetExistingNamedParameters(argumentList, position);

            parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters));

            var unspecifiedParameters = parameterLists.SelectMany(pl => pl)
                                        .Where(p => !existingNamedParameters.Contains(p.Name))
                                        .Distinct(this);

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

            return(unspecifiedParameters.Select(
                       p =>
            {
                // Note: the filter text does not include the ':'.  We want to ensure that if
                // the user types the name exactly (up to the colon) that it is selected as an
                // exact match.
                var workspace = document.Project.Solution.Workspace;
                var escaped = p.Name.ToIdentifierToken().ToString();
                return new CompletionItem(
                    this,
                    escaped + ColonString,
                    CompletionUtilities.GetTextChangeSpan(text, position),
                    CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, token.SpanStart, p),
                    p.GetGlyph(),
                    sortText: p.Name,
                    filterText: escaped,
                    rules: ItemRules.Instance);
            }));
        }
        public override async Task ProduceCompletionListAsync(CompletionListContext context)
        {
            try
            {
                var document          = context.Document;
                var position          = context.Position;
                var options           = context.Options;
                var cancellationToken = context.CancellationToken;

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

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

                var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
                if (token.IsMandatoryNamedParameterPosition())
                {
                    return;
                }

                var typeInferenceService = document.GetLanguageService <ITypeInferenceService>();

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

                var type = typeInferenceService.InferType(semanticModel, position,
                                                          objectAsDefault: true,
                                                          cancellationToken: cancellationToken);

                // If we have a Nullable<T>, unwrap it.
                if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                {
                    type = type.GetTypeArguments().FirstOrDefault();

                    if (type == null)
                    {
                        return;
                    }
                }

                if (type.TypeKind != TypeKind.Enum)
                {
                    type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
                    if (type == null)
                    {
                        return;
                    }
                }

                if (!type.IsEditorBrowsable(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation))
                {
                    return;
                }

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

                var displayService = document.GetLanguageService <ISymbolDisplayService>();
                var displayText    = alias != null
                    ? alias.Name
                    : displayService.ToMinimalDisplayString(semanticModel, position, type);

                var workspace = document.Project.Solution.Workspace;
                var text      = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

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

                var item = new CompletionItem(
                    this,
                    displayText: displayText,
                    filterSpan: textChangeSpan,
                    descriptionFactory: CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, position, alias ?? type),
                    glyph: (alias ?? type).GetGlyph(),
                    preselect: true,
                    rules: ItemRules.Instance);

                context.AddItem(item);
            }
            catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
 protected override TextSpan GetTextChangeSpan(SourceText text, int position)
 {
     // We can just defer to the standard text span algorithm.
     return(CompletionUtilities.GetTextChangeSpan(text, position));
 }
Beispiel #14
0
        public override async Task ProduceCompletionListAsync(CompletionListContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

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

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

            if (!token.IsKind(SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.CommaToken))
            {
                return;
            }

            var argumentList = token.Parent as BaseArgumentListSyntax;

            if (argumentList == null)
            {
                return;
            }

            var semanticModel = await document.GetSemanticModelForNodeAsync(argumentList, cancellationToken).ConfigureAwait(false);

            var parameterLists = GetParameterLists(semanticModel, position, argumentList.Parent, cancellationToken);

            if (parameterLists == null)
            {
                return;
            }

            var existingNamedParameters = GetExistingNamedParameters(argumentList, position);

            parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters));

            var unspecifiedParameters = parameterLists.SelectMany(pl => pl)
                                        .Where(p => !existingNamedParameters.Contains(p.Name))
                                        .Distinct(this);

            if (!unspecifiedParameters.Any())
            {
                return;
            }

            if (token.IsMandatoryNamedParameterPosition())
            {
                context.MakeExclusive(true);
            }

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

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

            var workspace = document.Project.Solution.Workspace;

            foreach (var parameter in unspecifiedParameters)
            {
                // Note: the filter text does not include the ':'.  We want to ensure that if
                // the user types the name exactly (up to the colon) that it is selected as an
                // exact match.
                var escapedName = parameter.Name.ToIdentifierToken().ToString();

                context.AddItem(new CompletionItem(
                                    this,
                                    escapedName + ColonString,
                                    filterSpan,
                                    CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, token.SpanStart, parameter),
                                    parameter.GetGlyph(),
                                    sortText: parameter.Name,
                                    filterText: escapedName,
                                    rules: ItemRules.Instance));
            }
        }
        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));
            }
        }