static VSInternalCodeAction[] GenerateNestedVSCodeActions( CodeActionParams request, SourceText documentText, IUnifiedSuggestedAction suggestedAction, CodeActionKind codeActionKind, ref int currentHighestSetNumber, string currentTitle) { if (suggestedAction is not UnifiedSuggestedActionWithNestedActions suggestedActionWithNestedActions) { return(Array.Empty <VSInternalCodeAction>()); } using var _ = ArrayBuilder <VSInternalCodeAction> .GetInstance(out var nestedActions); foreach (var nestedActionSet in suggestedActionWithNestedActions.NestedActionSets) { // Nested code action sets should each have a unique set number that is not yet assigned to any set. var nestedSetNumber = ++currentHighestSetNumber; foreach (var nestedSuggestedAction in nestedActionSet.Actions) { nestedActions.Add(GenerateVSCodeAction( request, documentText, nestedSuggestedAction, codeActionKind, nestedActionSet.Priority, applicableRange: nestedActionSet.ApplicableToSpan.HasValue ? ProtocolConversions.TextSpanToRange(nestedActionSet.ApplicableToSpan.Value, documentText) : null, nestedSetNumber, ref currentHighestSetNumber, currentTitle)); } } return(nestedActions.ToArray()); }
private static VSCodeAction GenerateVSCodeAction( CodeActionParams request, SourceText documentText, IUnifiedSuggestedAction suggestedAction, LSP.CodeActionKind codeActionKind, UnifiedSuggestedActionSetPriority setPriority, LSP.Range?applicableRange, int currentSetNumber, ref int currentHighestSetNumber, string currentTitle = "") { if (!string.IsNullOrEmpty(currentTitle)) { // Adding a delimiter for nested code actions, e.g. 'Suppress or Configure issues|Suppress IDEXXXX|in Source' currentTitle += '|'; } var codeAction = suggestedAction.OriginalCodeAction; currentTitle += codeAction.Title; // Nested code actions' unique identifiers consist of: parent code action unique identifier + '|' + title of code action var nestedActions = GenerateNestedVSCodeActions(request, documentText, suggestedAction, codeActionKind, ref currentHighestSetNumber, currentTitle); return(new VSCodeAction { Title = codeAction.Title, Kind = codeActionKind, Diagnostics = request.Context.Diagnostics, Children = nestedActions, Priority = UnifiedSuggestedActionSetPriorityToPriorityLevel(setPriority), Group = $"Roslyn{currentSetNumber}", ApplicableRange = applicableRange, Data = new CodeActionResolveData(currentTitle, request.Range, request.TextDocument) });
private static void AddFix( CodeFix fix, IUnifiedSuggestedAction suggestedAction, IDictionary <CodeFixGroupKey, IList <IUnifiedSuggestedAction> > map, ArrayBuilder <CodeFixGroupKey> order) { var groupKey = GetGroupKey(fix); if (!map.ContainsKey(groupKey)) { order.Add(groupKey); map[groupKey] = ImmutableArray.CreateBuilder <IUnifiedSuggestedAction>(); } map[groupKey].Add(suggestedAction); return;
private static CodeAction GetNestedActionsFromActionSet(IUnifiedSuggestedAction suggestedAction) { var codeAction = suggestedAction.OriginalCodeAction; if (!(suggestedAction is UnifiedSuggestedActionWithNestedActions suggestedActionWithNestedActions)) { return(codeAction); } using var _ = ArrayBuilder <CodeAction> .GetInstance(out var nestedActions); foreach (var actionSet in suggestedActionWithNestedActions.NestedActionSets) { foreach (var action in actionSet.Actions) { nestedActions.Add(GetNestedActionsFromActionSet(action)); } } return(new CodeActionWithNestedActions( codeAction.Title, nestedActions.ToImmutable(), codeAction.IsInlinable, codeAction.Priority)); }
static LSP.Diagnostic[]? GetApplicableDiagnostics(LSP.CodeActionContext context, IUnifiedSuggestedAction action) { if (action is UnifiedCodeFixSuggestedAction codeFixAction) { // Associate the diagnostics from the request that match the diagnostic fixed by the code action by ID. // The request diagnostics are already restricted to the code fix location by the request. var diagnosticCodesFixedByAction = codeFixAction.CodeFix.Diagnostics.Select(d => d.Id); using var _ = ArrayBuilder <LSP.Diagnostic> .GetInstance(out var diagnosticsBuilder); foreach (var requestDiagnostic in context.Diagnostics) { var diagnosticCode = requestDiagnostic.Code?.Value?.ToString(); if (diagnosticCodesFixedByAction.Contains(diagnosticCode)) { diagnosticsBuilder.Add(requestDiagnostic); } } return(diagnosticsBuilder.ToArray()); } return(null); }