private async Task <ImmutableArray <CodeActionOperation> > GetCodeFixOperationsAsync( CodeFixProvider provider, Document document, TextSpan span, ImmutableArray <Diagnostic> diagnostics) { var codeFixes = new List <CodeAction>(); var context = OmniSharpCodeFixContextFactory.CreateCodeFixContext( document, span, diagnostics, registerCodeFix: (a, d) => codeFixes.Add(a), CodeActionOptionsFactory.Create(_options), cancellationToken: CancellationToken.None); // Note: We're intentionally not checking CodeFixProvider.FixableDiagnosticIds here. // The problem is that some providers (like Remove Unnecessary Usings) only listen // for custom IDs produced by their associated diagnostic analyzer. Once we have a // proper diagnostic engine in OmniSharp, we may be able remove this. await provider.RegisterCodeFixesAsync(context); var getOperationsTasks = codeFixes .Select(a => a.GetOperationsAsync(CancellationToken.None)); // Wait until all tasks to produce CodeActionOperations finish running in parallel. await Task.WhenAll(getOperationsTasks); return(getOperationsTasks .Select(t => t.Result) .SelectMany(ops => ops) .ToImmutableArray()); }
private async Task AppendFixesAsync(Document document, TextSpan span, IEnumerable <Diagnostic> diagnostics, List <CodeAction> codeActions) { var codeActionOptions = CodeActionOptionsFactory.Create(Options); foreach (var codeFixProvider in GetSortedCodeFixProviders(document)) { var fixableDiagnostics = diagnostics.Where(d => HasFix(codeFixProvider, d.Id)).ToImmutableArray(); if (fixableDiagnostics.Length > 0) { var context = OmniSharpCodeFixContextFactory.CreateCodeFixContext( document, span, fixableDiagnostics, (a, _) => codeActions.Add(a), codeActionOptions, CancellationToken.None); try { await codeFixProvider.RegisterCodeFixesAsync(context); } catch (Exception ex) { this.Logger.LogError(ex, $"Error registering code fixes for {codeFixProvider.GetType().FullName}"); } } } }