| 1 | using Microsoft.CodeAnalysis; |
| 2 | using Microsoft.CodeAnalysis.CSharp.Syntax; |
| 3 | using Microsoft.CodeAnalysis.Text; |
| 4 | |
| 5 | namespace CascadeIDE.Services; |
| 6 | |
| 7 | public sealed partial class CSharpLanguageService |
| 8 | { |
| 9 | /// <summary>Подсказка по параметрам (сигнатура метода) в позиции. Выполнять в фоне.</summary> |
| 10 | public string? GetSignatureHelp(string filePath, string sourceText, int line, int column, CancellationToken ct = default) |
| 11 | { |
| 12 | if (string.IsNullOrEmpty(filePath) || line < 1 || column < 1) return null; |
| 13 | var text = SourceText.From(sourceText); |
| 14 | var textHash = GetStableHash(text); |
| 15 | var cacheKey = (filePath, textHash, line, column); |
| 16 | if (_signatureCache.TryGetValue(cacheKey, out var cached)) |
| 17 | return cached; |
| 18 | |
| 19 | try |
| 20 | { |
| 21 | var model = GetOrCreateModel(filePath, text, ct); |
| 22 | var lines = text.Lines; |
| 23 | if (line > lines.Count) return null; |
| 24 | var lineInfo = lines[line - 1]; |
| 25 | var colIndex = column - 1; |
| 26 | var position = lineInfo.Start + Math.Min(Math.Max(0, colIndex), lineInfo.Span.Length); |
| 27 | |
| 28 | var root = model.SyntaxTree.GetRoot(ct); |
| 29 | var node = root.FindNode(new TextSpan(position, 0), findInsideTrivia: true); |
| 30 | InvocationExpressionSyntax? invocation = null; |
| 31 | for (var n = node; n is not null; n = n.Parent) |
| 32 | { |
| 33 | if (n is InvocationExpressionSyntax inv) |
| 34 | { |
| 35 | invocation = inv; |
| 36 | break; |
| 37 | } |
| 38 | } |
| 39 | if (invocation is null) return null; |
| 40 | |
| 41 | var symbolInfo = model.GetSymbolInfo(invocation, ct); |
| 42 | if (symbolInfo.Symbol is IMethodSymbol method) |
| 43 | { |
| 44 | var sig = method.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); |
| 45 | TrimCaches(_signatureCache); |
| 46 | _signatureCache[cacheKey] = sig; |
| 47 | return sig; |
| 48 | } |
| 49 | return null; |
| 50 | } |
| 51 | catch |
| 52 | { |
| 53 | return null; |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |