public SignatureHelpProduced(RequestSignatureHelp command, IReadOnlyList <SignatureInformation> signatures, int activeSignatureIndex, int activeParameterIndex) : base(command) { if (signatures?.Count >= 1) { // validate if (activeSignatureIndex < 0 || activeSignatureIndex >= signatures?.Count) { throw new ArgumentOutOfRangeException("Active signature must be a valid index.", nameof(activeSignatureIndex)); } if (activeParameterIndex < 0 || (signatures[activeSignatureIndex].Parameters.Count > 0 && activeParameterIndex >= signatures[activeSignatureIndex].Parameters.Count)) { throw new ArgumentOutOfRangeException("Active parameter must be a valid index.", nameof(activeParameterIndex)); } } else { if (activeSignatureIndex != 0) { throw new ArgumentOutOfRangeException("When no signatures are provided, the active signature index must be 0."); } if (activeParameterIndex != 0) { throw new ArgumentOutOfRangeException("When no parameters are provided, the active parameter index must be 0."); } } Signatures = signatures; ActiveSignatureIndex = activeSignatureIndex; ActiveParameterIndex = activeParameterIndex; }
public static async Task <SignatureHelpProduced> GenerateSignatureInformation(Document document, RequestSignatureHelp command, CancellationToken cancellationToken) { var invocation = await GetInvocation(document, command.LinePosition, cancellationToken); if (invocation is null) { return(null); } var activeParameter = 0; // define active parameter by position foreach (var comma in invocation.Separators) { if (comma.Span.Start > invocation.Position) { break; } activeParameter++; } // process all signatures, define active signature by types var signatures = new List <SignatureInformation>(); var bestScore = int.MinValue; var bestScoreIndex = 0; var types = invocation.ArgumentTypes; var methodGroup = invocation.SemanticModel.GetMemberGroup(invocation.Receiver).OfType <IMethodSymbol>(); if (invocation.Receiver is MemberAccessExpressionSyntax) { var throughExpression = ((MemberAccessExpressionSyntax)invocation.Receiver).Expression; var throughSymbol = invocation.SemanticModel.GetSpeculativeSymbolInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsExpression).Symbol; ISymbol throughType = invocation.SemanticModel.GetSpeculativeTypeInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; var includeInstance = (throughSymbol is not null && !(throughSymbol is ITypeSymbol)) || throughExpression is LiteralExpressionSyntax || throughExpression is TypeOfExpressionSyntax; var includeStatic = (throughSymbol is INamedTypeSymbol) || throughType is not null; methodGroup = methodGroup.Where(m => (m.IsStatic && includeStatic) || (!m.IsStatic && includeInstance)); } else if (invocation.Receiver is SimpleNameSyntax && invocation.IsInStaticContext) { methodGroup = methodGroup.Where(m => m.IsStatic || m.MethodKind == MethodKind.LocalFunction); } foreach (var methodOverload in methodGroup) { var signature = BuildSignature(methodOverload); signatures.Add(signature); var score = InvocationScore(methodOverload, types); if (score > bestScore) { bestScore = score; bestScoreIndex = signatures.Count - 1; } } return(new SignatureHelpProduced( command, signatures, bestScoreIndex, activeParameter)); }
private Task <KernelCommandResult> SendSignatureHelpRequest(Kernel kernel, string code, int line, int character) { var command = new RequestSignatureHelp(code, new LinePosition(line, character)); return(kernel.SendAsync(command)); }
public async Task HandleAsync(RequestSignatureHelp command, KernelInvocationContext context) { var document = _workspace.UpdateWorkingDocument(command.Code); var signatureHelp = await SignatureHelpGenerator.GenerateSignatureInformation(document, command); if (signatureHelp is { })
public static SignatureHelpProduced Empty(RequestSignatureHelp command) => new SignatureHelpProduced(command, null, 0, 0);