From 6fa1003475f2523f58c100d00a211b99b3fb5af1 Mon Sep 17 00:00:00 2001 From: Tomas Matousek <tomat@microsoft.com> Date: Mon, 14 Feb 2022 15:01:22 -0800 Subject: [PATCH] CodeFixContext --- .../Services/Refactoring/FixUsingService.cs | 9 ++-- .../Refactoring/RunFixAllCodeActionService.cs | 12 +++++- .../CSharpDiagnosticWorkerWithAnalyzers.cs | 9 +--- .../Workers/Formatting/FormattingWorker.cs | 4 +- .../Workers/Refactoring/FixUsingsWorker.cs | 9 +++- .../Utilities/CodeFixContextFactory.cs | 41 +++++++++++++++++++ 6 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 src/OmniSharp.Roslyn/Utilities/CodeFixContextFactory.cs diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/FixUsingService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/FixUsingService.cs index 0c2fafb766..eee336d7fe 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/FixUsingService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/FixUsingService.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using OmniSharp.Mef; using OmniSharp.Models.FixUsings; +using OmniSharp.Options; using OmniSharp.Roslyn.Utilities; using OmniSharp.Services; @@ -14,17 +15,17 @@ namespace OmniSharp.Roslyn.CSharp.Services.Refactoring public class FixUsingService : IRequestHandler<FixUsingsRequest, FixUsingsResponse> { private readonly OmniSharpWorkspace _workspace; - private readonly ILoggerFactory _loggerFactory; + private readonly OmniSharpOptions _options; private readonly IEnumerable<ICodeActionProvider> _providers; [ImportingConstructor] public FixUsingService( OmniSharpWorkspace workspace, - ILoggerFactory loggerFactory, + OmniSharpOptions options, [ImportMany] IEnumerable<ICodeActionProvider> codeActionProviders) { _workspace = workspace; - _loggerFactory = loggerFactory; + _options = options; _providers = codeActionProviders; } @@ -35,7 +36,7 @@ public async Task<FixUsingsResponse> Handle(FixUsingsRequest request) var oldDocument = _workspace.GetDocument(request.FileName); if (oldDocument != null) { - var fixUsingsResponse = await new FixUsingsWorker(_providers) + var fixUsingsResponse = await new FixUsingsWorker(_providers, _options) .FixUsingsAsync(oldDocument); response.AmbiguousResults = fixUsingsResponse.AmbiguousResults; diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/RunFixAllCodeActionService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/RunFixAllCodeActionService.cs index 7b2c168cb6..0472eaad10 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/RunFixAllCodeActionService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Refactoring/RunFixAllCodeActionService.cs @@ -13,6 +13,8 @@ using Microsoft.Extensions.Logging; using OmniSharp.Abstractions.Models.V1.FixAll; using OmniSharp.Mef; +using OmniSharp.Options; +using OmniSharp.Roslyn.CodeActions; using OmniSharp.Roslyn.CSharp.Services.Refactoring.V2; using OmniSharp.Roslyn.CSharp.Workers.Diagnostics; using OmniSharp.Services; @@ -26,12 +28,14 @@ public class RunFixAllCodeActionService : BaseCodeActionService<RunFixAllRequest { private readonly ILogger<RunFixAllCodeActionService> _logger; private readonly FixAllDiagnosticProvider _fixAllDiagnosticProvider; + private readonly OmniSharpOptions _options; [ImportingConstructor] public RunFixAllCodeActionService(ICsDiagnosticWorker diagnosticWorker, [ImportMany] IEnumerable<ICodeActionProvider> providers, CachingCodeFixProviderForProjects codeFixProvider, OmniSharpWorkspace workspace, + OmniSharpOptions options, ILoggerFactory loggerFactory) : base( workspace, @@ -42,6 +46,7 @@ public RunFixAllCodeActionService(ICsDiagnosticWorker diagnosticWorker, { _logger = loggerFactory.CreateLogger<RunFixAllCodeActionService>(); _fixAllDiagnosticProvider = new FixAllDiagnosticProvider(diagnosticWorker); + _options = options; } public async override Task<RunFixAllResponse> Handle(RunFixAllRequest request) @@ -134,8 +139,12 @@ private async Task<Document> FixSpecificDiagnosticIdAsync(Document document, str } _logger.LogTrace("{0} is still present in the document. Getting fixes.", diagnosticId); + CodeAction action = null; - var context = new CodeFixContext(document, primaryDiagnostic, + var context = CodeFixContextFactory.Create( + document, + primaryDiagnostic.Location.SourceSpan, + ImmutableArray.Create(primaryDiagnostic), (a, _) => { if (action == null) @@ -143,6 +152,7 @@ private async Task<Document> FixSpecificDiagnosticIdAsync(Document document, str action = a; } }, + _options, cancellationToken); await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); diff --git a/src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs b/src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs index e065ca2bd8..b04cdac505 100644 --- a/src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs +++ b/src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs @@ -212,14 +212,7 @@ private void OnWorkspaceChanged(object sender, WorkspaceChangeEventArgs changeEv } private AnalyzerOptions CreateAnalyzerOptions(Project project) - { - var ideOptions = new OmniSharpIdeAnalyzerOptions( - ImplementTypeOptions: new OmniSharpImplementTypeOptions( - (OmniSharpImplementTypeInsertionBehavior)_options.ImplementTypeOptions.InsertionBehavior, - (OmniSharpImplementTypePropertyGenerationBehavior)_options.ImplementTypeOptions.PropertyGenerationBehavior)); - - return OmniSharpWorkspaceAnalyzerOptionsFactory.Create(project.Solution, project.AnalyzerOptions, ideOptions); - } + => OmniSharpWorkspaceAnalyzerOptionsFactory.Create(project.Solution, project.AnalyzerOptions); public async Task<IEnumerable<Diagnostic>> AnalyzeDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/OmniSharp.Roslyn.CSharp/Workers/Formatting/FormattingWorker.cs b/src/OmniSharp.Roslyn.CSharp/Workers/Formatting/FormattingWorker.cs index cb53dc1300..fc3eeb2d21 100644 --- a/src/OmniSharp.Roslyn.CSharp/Workers/Formatting/FormattingWorker.cs +++ b/src/OmniSharp.Roslyn.CSharp/Workers/Formatting/FormattingWorker.cs @@ -24,7 +24,7 @@ public static class FormattingWorker { public static async Task<IEnumerable<LinePositionSpanTextChange>> GetFormattingChangesAfterKeystroke(Document document, int position, char character, OmniSharpOptions omnisharpOptions) { - if (await GetDocumentationCommentChanges(document, position, character, omnisharpOptions) is LinePositionSpanTextChange change) + if (await GetDocumentationCommentChanges(document, position, character) is LinePositionSpanTextChange change) { return new[] { change }; } @@ -202,7 +202,7 @@ private static OmniSharpBinaryOperatorSpacingOptions BinaryOperatorSpacingOption _ => OmniSharpBinaryOperatorSpacingOptions.Single, }; - private static async Task<LinePositionSpanTextChange?> GetDocumentationCommentChanges(Document document, int position, char character, OmniSharpOptions omnisharpOptions) + private static async Task<LinePositionSpanTextChange?> GetDocumentationCommentChanges(Document document, int position, char character) { if (character != '\n' && character != '/') { diff --git a/src/OmniSharp.Roslyn.CSharp/Workers/Refactoring/FixUsingsWorker.cs b/src/OmniSharp.Roslyn.CSharp/Workers/Refactoring/FixUsingsWorker.cs index d64b17a659..485435f1dd 100644 --- a/src/OmniSharp.Roslyn.CSharp/Workers/Refactoring/FixUsingsWorker.cs +++ b/src/OmniSharp.Roslyn.CSharp/Workers/Refactoring/FixUsingsWorker.cs @@ -11,6 +11,8 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using OmniSharp.Models; +using OmniSharp.Options; +using OmniSharp.Roslyn.CodeActions; using OmniSharp.Roslyn.CSharp.Services.CodeActions; using OmniSharp.Services; @@ -27,8 +29,9 @@ public class FixUsingsWorker private readonly IEnumerable<ICodeActionProvider> _providers; private readonly CodeFixProvider _addImportProvider; private readonly CodeFixProvider _removeUnnecessaryUsingsProvider; + private readonly OmniSharpOptions _options; - public FixUsingsWorker(IEnumerable<ICodeActionProvider> providers) + public FixUsingsWorker(IEnumerable<ICodeActionProvider> providers, OmniSharpOptions options) { _providers = providers; @@ -36,6 +39,7 @@ public FixUsingsWorker(IEnumerable<ICodeActionProvider> providers) _addImportProvider = FindCodeFixProviderByTypeFullName(codeFixProviders, CodeActionHelper.AddImportProviderName); _removeUnnecessaryUsingsProvider = FindCodeFixProviderByTypeFullName(codeFixProviders, CodeActionHelper.RemoveUnnecessaryUsingsProviderName); + _options = options; } private static CodeFixProvider FindCodeFixProviderByTypeFullName(IEnumerable<CodeFixProvider> providers, string fullName) @@ -238,9 +242,10 @@ private async Task<ImmutableArray<CodeActionOperation>> GetCodeFixOperationsAsyn ImmutableArray<Diagnostic> diagnostics) { var codeFixes = new List<CodeAction>(); - var context = new CodeFixContext( + var context = CodeFixContextFactory.Create( document, span, diagnostics, registerCodeFix: (a, d) => codeFixes.Add(a), + _options, cancellationToken: CancellationToken.None); // Note: We're intentionally not checking CodeFixProvider.FixableDiagnosticIds here. diff --git a/src/OmniSharp.Roslyn/Utilities/CodeFixContextFactory.cs b/src/OmniSharp.Roslyn/Utilities/CodeFixContextFactory.cs new file mode 100644 index 0000000000..67fdbb5baa --- /dev/null +++ b/src/OmniSharp.Roslyn/Utilities/CodeFixContextFactory.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.ExternalAccess.OmniSharp.CodeActions; +using Microsoft.CodeAnalysis.ExternalAccess.OmniSharp.ImplementType; +using OmniSharp.Options; +using Microsoft.CodeAnalysis; +using System.Collections.Immutable; +using System.Threading; +using Microsoft.CodeAnalysis.Text; + +namespace OmniSharp.Roslyn.CodeActions +{ + internal static class CodeFixContextFactory + { + public static CodeFixContext Create( + Document document, + TextSpan span, + ImmutableArray<Diagnostic> diagnostics, + Action<CodeAction, ImmutableArray<Diagnostic>> registerCodeFix, + OmniSharpOptions options, + CancellationToken cancellationToken) + { + var implementTypeOptions = new OmniSharpImplementTypeOptions( + (OmniSharpImplementTypeInsertionBehavior)options.ImplementTypeOptions.InsertionBehavior, + (OmniSharpImplementTypePropertyGenerationBehavior)options.ImplementTypeOptions.PropertyGenerationBehavior); + + return OmniSharpCodeFixContextFactory.Create( + document, + span, + diagnostics, + registerCodeFix, + implementTypeOptions, + cancellationToken); + } + } +}