private async Task <CompletionItem> CreateItemAsync(
            Workspace workspace, SemanticModel semanticModel, int textChangeSpanPosition, ISymbol symbol, SyntaxToken token, CancellationToken cancellationToken)
        {
            int    tokenPosition = token.SpanStart;
            string symbolText    = string.Empty;

            if (symbol is INamespaceOrTypeSymbol && token.IsKind(SyntaxKind.DotToken))
            {
                symbolText = symbol.Name.EscapeIdentifier();

                if (symbol.GetArity() > 0)
                {
                    symbolText += "{";
                    symbolText += string.Join(", ", ((INamedTypeSymbol)symbol).TypeParameters);
                    symbolText += "}";
                }
            }
            else
            {
                symbolText = symbol.ToMinimalDisplayString(semanticModel, tokenPosition, CrefFormat);
                var parameters = symbol.GetParameters().Select(p =>
                {
                    var displayName = p.Type.ToMinimalDisplayString(semanticModel, tokenPosition);

                    if (p.RefKind == RefKind.Out)
                    {
                        return("out " + displayName);
                    }

                    if (p.RefKind == RefKind.Ref)
                    {
                        return("ref " + displayName);
                    }

                    return(displayName);
                });

                var parameterList = !symbol.IsIndexer() ? string.Format("({0})", string.Join(", ", parameters))
                                                        : string.Format("[{0}]", string.Join(", ", parameters));
                symbolText += parameterList;
            }

            var insertionText = symbolText
                                .Replace('<', '{')
                                .Replace('>', '}')
                                .Replace("()", "");

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

            return(new CrefCompletionItem(
                       workspace,
                       completionProvider: this,
                       displayText: insertionText,
                       insertionText: insertionText,
                       textSpan: GetTextChangeSpan(text, textChangeSpanPosition),
                       descriptionFactory: CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, tokenPosition, symbol),
                       glyph: symbol.GetGlyph(),
                       sortText: symbolText));
        }
Exemple #2
0
        public override async Task ProduceCompletionListAsync(CompletionListContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

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

            var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken);

            if (typeAndLocation == null)
            {
                return;
            }

            var initializedType     = typeAndLocation.Item1 as INamedTypeSymbol;
            var initializerLocation = typeAndLocation.Item2;

            if (initializedType == null)
            {
                return;
            }

            if (await IsExclusiveAsync(document, position, cancellationToken).ConfigureAwait(false))
            {
                context.MakeExclusive(true);
            }
            var enclosing = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members.
            IEnumerable <ISymbol> members = semanticModel.LookupSymbols(position, initializedType);

            members = members.Where(m => IsInitializable(m, initializedType) &&
                                    m.CanBeReferencedByName &&
                                    IsLegalFieldOrProperty(m, enclosing) &&
                                    !m.IsImplicitlyDeclared);

            // Filter out those members that have already been typed
            var alreadyTypedMembers  = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken);
            var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name));

            uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation));

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

            var filterSpan = GetTextChangeSpan(text, position);

            foreach (var uninitializedMember in uninitializedMembers)
            {
                context.AddItem(CreateItem(
                                    workspace,
                                    uninitializedMember.Name,
                                    filterSpan,
                                    CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, initializerLocation.SourceSpan.Start, uninitializedMember),
                                    uninitializedMember.GetGlyph()));
            }
        }
Exemple #3
0
        public override async Task <ImmutableArray <SymbolDisplayPart> > GetDescriptionAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            if (this.LazyDescription == null)
            {
                Interlocked.CompareExchange(
                    ref this.LazyDescription,
                    new AsyncLazy <ImmutableArray <SymbolDisplayPart> >(
                        CommonCompletionUtilities.CreateDescriptionFactory(this.Context.Workspace, this.Context.SemanticModel, this.Position, this.Symbols, this.supportedPlatorms), cacheResult: true),
                    null);
            }

            return(await base.GetDescriptionAsync(cancellationToken).ConfigureAwait(false));
        }
        private CompletionItem CreateItem(IMethodSymbol method, int line, TextSpan lineSpan, TextSpan span, SemanticModel semanticModel, DeclarationModifiers modifiers, Document document, SyntaxToken token)
        {
            modifiers = new DeclarationModifiers(method.IsStatic, isUnsafe: method.IsUnsafe(), isPartial: true, isAsync: modifiers.IsAsync);
            var displayText = GetDisplayText(method, semanticModel, span.Start);

            return(new MemberInsertionCompletionItem(
                       this,
                       displayText,
                       span,
                       CommonCompletionUtilities.CreateDescriptionFactory(document.Project.Solution.Workspace, semanticModel, span.Start, method),
                       Glyph.MethodPrivate,
                       modifiers,
                       line,
                       method.GetSymbolKey(),
                       token));
        }
Exemple #5
0
            private MemberInsertionCompletionItem CreateItem(
                ISymbol symbol, TextSpan textChangeSpan, ISymbolDisplayService symbolDisplayService,
                SemanticModel semanticModel, SyntaxToken startToken, DeclarationModifiers modifiers)
            {
                var position = startToken.SpanStart;

                var displayString = symbolDisplayService.ToMinimalDisplayString(semanticModel, position, symbol, _overrideNameFormat);

                return(new MemberInsertionCompletionItem(_provider,
                                                         displayString,
                                                         textChangeSpan,
                                                         CommonCompletionUtilities.CreateDescriptionFactory(_document.Project.Solution.Workspace, semanticModel, position, symbol),
                                                         symbol.GetGlyph(),
                                                         modifiers,
                                                         _startLineNumber,
                                                         symbol.GetSymbolKey(),
                                                         startToken));
            }
        protected override async Task <IEnumerable <CompletionItem> > GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var workspace     = document.Project.Solution.Workspace;
            var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan(position, 0), cancellationToken).ConfigureAwait(false);

            var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken);

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

            var initializedType     = typeAndLocation.Item1 as INamedTypeSymbol;
            var initializerLocation = typeAndLocation.Item2;

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

            // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members.
            IEnumerable <ISymbol> members = semanticModel.LookupSymbols(position, initializedType);

            members = members.Where(m => IsInitializable(m, initializedType) &&
                                    m.CanBeReferencedByName &&
                                    IsLegalFieldOrProperty(m) &&
                                    !m.IsImplicitlyDeclared);

            // Filter out those members that have already been typed
            var alreadyTypedMembers  = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken);
            var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name));

            uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation));

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

            var changes = GetTextChangeSpan(text, position);

            // Return the members
            return(uninitializedMembers.Select(
                       m => CreateItem(workspace, m.Name, changes,
                                       CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, initializerLocation.SourceSpan.Start, m),
                                       m.GetGlyph())));
        }
        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));
        }
Exemple #8
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));
        }
Exemple #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));
        }
Exemple #10
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;
            }
        }
Exemple #12
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));
            }
        }
        private CompletionItem CreateItem(
            Workspace workspace, SemanticModel semanticModel, ISymbol symbol, SyntaxToken token, TextSpan filterSpan, StringBuilder builder)
        {
            int position = token.SpanStart;

            if (symbol is INamespaceOrTypeSymbol && token.IsKind(SyntaxKind.DotToken))
            {
                // Handle qualified namespace and type names.

                builder.Append(symbol.ToDisplayString(QualifiedCrefFormat));
            }
            else
            {
                // Handle unqualified namespace and type names, or member names.

                builder.Append(symbol.ToMinimalDisplayString(semanticModel, position, CrefFormat));

                var parameters = symbol.GetParameters();
                if (!parameters.IsDefaultOrEmpty)
                {
                    // Note: we intentionally don't add the "params" modifier for any parameters.

                    builder.Append(symbol.IsIndexer() ? '[' : '(');

                    for (int i = 0; i < parameters.Length; i++)
                    {
                        if (i > 0)
                        {
                            builder.Append(", ");
                        }

                        var parameter = parameters[i];

                        if (parameter.RefKind == RefKind.Out)
                        {
                            builder.Append("out ");
                        }
                        else if (parameter.RefKind == RefKind.Ref)
                        {
                            builder.Append("ref ");
                        }

                        builder.Append(parameter.Type.ToMinimalDisplayString(semanticModel, position));
                    }

                    builder.Append(symbol.IsIndexer() ? ']' : ')');
                }
            }

            var symbolText = builder.ToString();

            var insertionText = builder
                                .Replace('<', '{')
                                .Replace('>', '}')
                                .ToString();

            return(new Item(
                       completionProvider: this,
                       displayText: insertionText,
                       insertionText: insertionText,
                       textSpan: filterSpan,
                       descriptionFactory: CommonCompletionUtilities.CreateDescriptionFactory(workspace, semanticModel, position, symbol),
                       glyph: symbol.GetGlyph(),
                       sortText: symbolText));
        }