コード例 #1
0
        public override SignatureHelpState?GetCurrentArgumentState(
            SyntaxNode root,
            int position,
            ISyntaxFactsService syntaxFacts,
            TextSpan currentSpan,
            CancellationToken cancellationToken
            )
        {
            if (
                TryGetConstructorInitializer(
                    root,
                    position,
                    syntaxFacts,
                    SignatureHelpTriggerReason.InvokeSignatureHelpCommand,
                    cancellationToken,
                    out var expression
                    ) &&
                currentSpan.Start
                == SignatureHelpUtilities.GetSignatureHelpSpan(expression.ArgumentList).Start
                )
            {
                return(SignatureHelpUtilities.GetSignatureHelpState(
                           expression.ArgumentList,
                           position
                           ));
            }

            return(null);
        }
コード例 #2
0
        protected override async Task <SignatureHelpItems> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!TryGetObjectCreationExpression(root, position, document.GetLanguageService <ISyntaxFactsService>(), triggerInfo.TriggerReason, cancellationToken, out var objectCreationExpression))
            {
                return(null);
            }

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

            if (!(semanticModel.GetTypeInfo(objectCreationExpression, cancellationToken).Type is INamedTypeSymbol type))
            {
                return(null);
            }

            var within = semanticModel.GetEnclosingNamedType(position, cancellationToken);

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

            var anonymousTypeDisplayService           = document.GetLanguageService <IAnonymousTypeDisplayService>();
            var documentationCommentFormattingService = document.GetLanguageService <IDocumentationCommentFormattingService>();
            var textSpan    = SignatureHelpUtilities.GetSignatureHelpSpan(objectCreationExpression.ArgumentList);
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            var(items, selectedItem) = type.TypeKind == TypeKind.Delegate
                ? GetDelegateTypeConstructors(objectCreationExpression, semanticModel, anonymousTypeDisplayService, type, cancellationToken)
                : GetNormalTypeConstructors(document, objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, type, within, cancellationToken);

            return(CreateSignatureHelpItems(items, textSpan,
                                            GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem));
        }
コード例 #3
0
        protected override async Task <SignatureHelpItems> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!TryGetInitializerExpression(root, position, document.GetLanguageService <ISyntaxFactsService>(), triggerInfo.TriggerReason, cancellationToken, out var initializerExpression))
            {
                return(null);
            }

            var addMethods = await CommonSignatureHelpUtilities.GetCollectionInitializerAddMethodsAsync(
                document, initializerExpression, cancellationToken).ConfigureAwait(false);

            if (addMethods.IsDefaultOrEmpty)
            {
                return(null);
            }

            var textSpan    = SignatureHelpUtilities.GetSignatureHelpSpan(initializerExpression);
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            return(CreateCollectionInitializerSignatureHelpItems(addMethods.Select(s =>
                                                                                   ConvertMethodGroupMethod(document, s, initializerExpression.OpenBraceToken.SpanStart, semanticModel)).ToList(),
                                                                 textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken)));
        }
コード例 #4
0
        protected override async Task <SignatureHelpItems> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!TryGetConstructorInitializer(root, position, document.GetLanguageService <ISyntaxFactsService>(), triggerInfo.TriggerReason, cancellationToken, out var constructorInitializer))
            {
                return(null);
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var within = semanticModel.GetEnclosingNamedType(position, cancellationToken);

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

            if (within.TypeKind != TypeKind.Struct && within.TypeKind != TypeKind.Class)
            {
                return(null);
            }

            var type = constructorInitializer.Kind() == SyntaxKind.BaseConstructorInitializer
                ? within.BaseType
                : within;

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

            var currentConstructor = semanticModel.GetDeclaredSymbol(constructorInitializer.Parent);

            var symbolDisplayService   = document.GetLanguageService <ISymbolDisplayService>();
            var accessibleConstructors = type.InstanceConstructors
                                         .WhereAsArray(c => c.IsAccessibleWithin(within) && !c.Equals(currentConstructor))
                                         .WhereAsArray(c => c.IsEditorBrowsable(document.ShouldHideAdvancedMembers(), semanticModel.Compilation))
                                         .Sort(symbolDisplayService, semanticModel, constructorInitializer.SpanStart);

            if (!accessibleConstructors.Any())
            {
                return(null);
            }

            var anonymousTypeDisplayService           = document.GetLanguageService <IAnonymousTypeDisplayService>();
            var documentationCommentFormattingService = document.GetLanguageService <IDocumentationCommentFormattingService>();
            var textSpan    = SignatureHelpUtilities.GetSignatureHelpSpan(constructorInitializer.ArgumentList);
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            var symbolInfo   = semanticModel.GetSymbolInfo(constructorInitializer, cancellationToken);
            var selectedItem = TryGetSelectedIndex(accessibleConstructors, symbolInfo);

            return(CreateSignatureHelpItems(accessibleConstructors.SelectAsArray(c =>
                                                                                 Convert(c, constructorInitializer.ArgumentList.OpenParenToken, semanticModel, symbolDisplayService, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(),
                                            textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem));
        }
コード例 #5
0
 internal static TextSpan GetTextSpan(SyntaxToken openBracket)
 {
     Contract.ThrowIfFalse(
         openBracket.Parent is BracketedArgumentListSyntax &&
         (
             openBracket.Parent.Parent is ElementAccessExpressionSyntax ||
             openBracket.Parent.Parent is ElementBindingExpressionSyntax
         )
         );
     return(SignatureHelpUtilities.GetSignatureHelpSpan(
                (BracketedArgumentListSyntax)openBracket.Parent
                ));
 }
コード例 #6
0
 protected virtual TextSpan GetTextSpan(
     SyntaxToken genericIdentifier,
     SyntaxToken lessThanToken
     )
 {
     Contract.ThrowIfFalse(
         lessThanToken.Parent is TypeArgumentListSyntax &&
         lessThanToken.Parent.Parent is GenericNameSyntax
         );
     return(SignatureHelpUtilities.GetSignatureHelpSpan(
                ((GenericNameSyntax)lessThanToken.Parent.Parent).TypeArgumentList
                ));
 }
コード例 #7
0
        public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken)
        {
            ExpressionSyntax expression;
            SyntaxToken      openBracket;

            if (!TryGetElementAccessExpression(
                    root,
                    position,
                    syntaxFacts,
                    SignatureHelpTriggerReason.InvokeSignatureHelpCommand,
                    cancellationToken,
                    out expression,
                    out openBracket) ||
                currentSpan.Start != expression.SpanStart)
            {
                return(null);
            }

            // If the user is actively typing, it's likely that we're in a broken state and the
            // syntax tree will be incorrect.  Because of this we need to synthesize a new
            // bracketed argument list so we can correctly map the cursor to the current argument
            // and then we need to account for this and offset the position check accordingly.
            int offset;
            BracketedArgumentListSyntax argumentList;
            var newBracketedArgumentList = SyntaxFactory.ParseBracketedArgumentList(openBracket.Parent.ToString());

            if (expression.Parent is ConditionalAccessExpressionSyntax)
            {
                // The typed code looks like: <expression>?[
                var conditional    = (ConditionalAccessExpressionSyntax)expression.Parent;
                var elementBinding = SyntaxFactory.ElementBindingExpression(newBracketedArgumentList);
                var conditionalAccessExpression = SyntaxFactory.ConditionalAccessExpression(expression, elementBinding);
                offset       = expression.SpanStart - conditionalAccessExpression.SpanStart;
                argumentList = ((ElementBindingExpressionSyntax)conditionalAccessExpression.WhenNotNull).ArgumentList;
            }
            else
            {
                // The typed code looks like:
                //   <expression>[
                // or
                //   <identifier>?[
                ElementAccessExpressionSyntax elementAccessExpression = SyntaxFactory.ElementAccessExpression(expression, newBracketedArgumentList);
                offset       = expression.SpanStart - elementAccessExpression.SpanStart;
                argumentList = elementAccessExpression.ArgumentList;
            }

            position -= offset;
            return(SignatureHelpUtilities.GetSignatureHelpState(argumentList, position));
        }
コード例 #8
0
        protected override async Task <SignatureHelpItems> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!TryGetAttributeExpression(root, position, document.GetLanguageService <ISyntaxFactsService>(), triggerInfo.TriggerReason, cancellationToken, out var attribute))
            {
                return(null);
            }

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

            var attributeType = semanticModel.GetTypeInfo(attribute, cancellationToken).Type as INamedTypeSymbol;

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

            var within = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);

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

            var symbolDisplayService   = document.GetLanguageService <ISymbolDisplayService>();
            var accessibleConstructors = attributeType.InstanceConstructors
                                         .WhereAsArray(c => c.IsAccessibleWithin(within))
                                         .FilterToVisibleAndBrowsableSymbols(document.ShouldHideAdvancedMembers(), semanticModel.Compilation)
                                         .Sort(symbolDisplayService, semanticModel, attribute.SpanStart);

            if (!accessibleConstructors.Any())
            {
                return(null);
            }

            var anonymousTypeDisplayService   = document.GetLanguageService <IAnonymousTypeDisplayService>();
            var documentationCommentFormatter = document.GetLanguageService <IDocumentationCommentFormattingService>();
            var textSpan    = SignatureHelpUtilities.GetSignatureHelpSpan(attribute.ArgumentList);
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            var symbolInfo   = semanticModel.GetSymbolInfo(attribute, cancellationToken);
            var selectedItem = TryGetSelectedIndex(accessibleConstructors, symbolInfo);

            return(CreateSignatureHelpItems(accessibleConstructors.Select(c =>
                                                                          Convert(c, within, attribute, semanticModel, symbolDisplayService, anonymousTypeDisplayService, documentationCommentFormatter, cancellationToken)).ToList(),
                                            textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem));
        }
コード例 #9
0
        public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken)
        {
            InvocationExpressionSyntax expression;
            if (TryGetInvocationExpression(
                    root,
                    position,
                    syntaxFacts,
                    SignatureHelpTriggerReason.InvokeSignatureHelpCommand,
                    cancellationToken,
                    out expression) &&
                currentSpan.Start == SignatureHelpUtilities.GetSignatureHelpSpan(expression.ArgumentList).Start)
            {
                return SignatureHelpUtilities.GetSignatureHelpState(expression.ArgumentList, position);
            }

            return null;
        }
コード例 #10
0
        public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken)
        {
            if (!TryGetGenericIdentifier(root, position, syntaxFacts, SignatureHelpTriggerReason.InvokeSignatureHelpCommand, cancellationToken,
                                         out var genericIdentifier, out var lessThanToken))
            {
                return(null);
            }

            if (genericIdentifier.TryParseGenericName(cancellationToken, out var genericName))
            {
                // Because we synthesized the generic name, it will have an index starting at 0
                // instead of at the actual position it's at in the text.  Because of this, we need to
                // offset the position we are checking accordingly.
                var offset = genericIdentifier.SpanStart - genericName.SpanStart;
                position -= offset;
                return(SignatureHelpUtilities.GetSignatureHelpState(genericName.TypeArgumentList, position));
            }

            return(null);
        }
コード例 #11
0
 private bool IsTriggerToken(SyntaxToken token)
 {
     return(SignatureHelpUtilities.IsTriggerParenOrComma <ObjectCreationExpressionSyntax>(token, IsTriggerCharacter));
 }
コード例 #12
0
        protected override async Task <SignatureHelpItems> GetItemsWorkerAsync(Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (!TryGetInvocationExpression(root, position, document.GetLanguageService <ISyntaxFactsService>(), triggerInfo.TriggerReason, cancellationToken, out var invocationExpression))
            {
                return(null);
            }

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

            var within = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);

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

            // get the regular signature help items
            var symbolDisplayService = document.GetLanguageService <ISymbolDisplayService>();
            var methodGroup          = semanticModel.GetMemberGroup(invocationExpression.Expression, cancellationToken)
                                       .OfType <IMethodSymbol>()
                                       .ToImmutableArray()
                                       .FilterToVisibleAndBrowsableSymbols(document.ShouldHideAdvancedMembers(), semanticModel.Compilation);

            // try to bind to the actual method
            var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression, cancellationToken);

            // if the symbol could be bound, replace that item in the symbol list
            if (symbolInfo.Symbol is IMethodSymbol matchedMethodSymbol && matchedMethodSymbol.IsGenericMethod)
            {
                methodGroup = methodGroup.SelectAsArray(m => Equals(matchedMethodSymbol.OriginalDefinition, m) ? matchedMethodSymbol : m);
            }

            methodGroup = methodGroup.Sort(
                symbolDisplayService, semanticModel, invocationExpression.SpanStart);

            var expressionType = semanticModel.GetTypeInfo(invocationExpression.Expression, cancellationToken).Type as INamedTypeSymbol;

            var anonymousTypeDisplayService           = document.GetLanguageService <IAnonymousTypeDisplayService>();
            var documentationCommentFormattingService = document.GetLanguageService <IDocumentationCommentFormattingService>();

            var textSpan    = SignatureHelpUtilities.GetSignatureHelpSpan(invocationExpression.ArgumentList);
            var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>();

            if (methodGroup.Any())
            {
                var(items, selectedItem) =
                    GetMethodGroupItemsAndSelection(invocationExpression, semanticModel, symbolDisplayService, anonymousTypeDisplayService, documentationCommentFormattingService, within, methodGroup, symbolInfo, cancellationToken);

                return(CreateSignatureHelpItems(
                           items,
                           textSpan,
                           GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken),
                           selectedItem));
            }
            else if (expressionType != null && expressionType.TypeKind == TypeKind.Delegate)
            {
                var items = GetDelegateInvokeItems(invocationExpression, semanticModel, symbolDisplayService, anonymousTypeDisplayService,
                                                   documentationCommentFormattingService, within, expressionType, out var selectedItem, cancellationToken);

                return(CreateSignatureHelpItems(items, textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem));
            }
            else
            {
                return(null);
            }
        }
コード例 #13
0
 private bool IsTriggerToken(SyntaxToken token)
 {
     return(SignatureHelpUtilities.IsTriggerParenOrComma <ConstructorInitializerSyntax>(token, IsTriggerCharacter));
 }
コード例 #14
0
 private bool IsTupleExpressionTriggerToken(SyntaxToken token) =>
 SignatureHelpUtilities.IsTriggerParenOrComma <TupleExpressionSyntax>(
     token,
     IsTriggerCharacter
     );