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)); }
public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (TryGetAttributeExpression(root, position, syntaxFacts, SignatureHelpTriggerReason.InvokeSignatureHelpCommand, cancellationToken, out var expression) && currentSpan.Start == SignatureHelpUtilities.GetSignatureHelpSpan(expression.ArgumentList).Start) { return(SignatureHelpUtilities.GetSignatureHelpState(expression.ArgumentList, position)); } return(null); }
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)); }
public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (!TryGetElementAccessExpression( root, position, syntaxFacts, SignatureHelpTriggerReason.InvokeSignatureHelpCommand, cancellationToken, out var expression, out var 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)); }
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); }
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); var type = semanticModel.GetTypeInfo(objectCreationExpression, cancellationToken).Type as INamedTypeSymbol; if (type == null) { return(null); } var within = semanticModel.GetEnclosingNamedType(position, cancellationToken); if (within == null) { return(null); } var symbolDisplayService = document.GetLanguageService <ISymbolDisplayService>(); 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, symbolDisplayService, anonymousTypeDisplayService, type, within, cancellationToken) : GetNormalTypeConstructors(document, objectCreationExpression, semanticModel, symbolDisplayService, anonymousTypeDisplayService, documentationCommentFormattingService, type, within, cancellationToken); return(CreateSignatureHelpItems(items, textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem)); }
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 => 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); } }
private bool IsTriggerToken(SyntaxToken token) { return(SignatureHelpUtilities.IsTriggerParenOrComma <InvocationExpressionSyntax>(token, IsTriggerCharacter)); }
private bool IsTriggerToken(SyntaxToken token) { return(SignatureHelpUtilities.IsTriggerParenOrComma <ConstructorInitializerSyntax>(token, IsTriggerCharacter)); }
internal static TextSpan GetTextSpan(SyntaxNode expression, SyntaxToken openBracket) { Contract.ThrowIfFalse(openBracket.Parent is BracketedArgumentListSyntax && (openBracket.Parent.Parent is ElementAccessExpressionSyntax || openBracket.Parent.Parent is ElementBindingExpressionSyntax)); return(SignatureHelpUtilities.GetSignatureHelpSpan((BracketedArgumentListSyntax)openBracket.Parent)); }
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)); }