From 5c53d0e8fb80727adcdcb94e7aa178c95ea87467 Mon Sep 17 00:00:00 2001 From: Tomas Matousek Date: Tue, 15 Feb 2022 15:11:02 -0800 Subject: [PATCH 1/7] Tidy up argument validation in CodeFixContext public API --- .../Core/Portable/CodeFixes/CodeFixService.cs | 1 + .../FixAllOccurrences/FixAllContext.cs | 28 +++++-- .../Compiler/Core/Utilities/PublicContract.cs | 4 +- .../Core/CodeFixes/FixAll/FixAllState.cs | 82 ++++++------------- 4 files changed, 49 insertions(+), 66 deletions(-) diff --git a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs index 28d2a8ba5578a..762612a8ef803 100644 --- a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs +++ b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs @@ -703,6 +703,7 @@ await diagnosticsWithSameSpan.OrderByDescending(d => d.Severity) fixAllState = new FixAllState( fixAllProvider: fixAllProviderInfo.FixAllProvider, document: document, + project: document.Project, codeFixProvider: codeFixProvider, scope: FixAllScope.Document, codeActionEquivalenceKey: fixes[0].Action.EquivalenceKey, diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs index bdec6d9d3d771..aba77e80d776c 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs @@ -85,11 +85,19 @@ public FixAllContext( Document document, CodeFixProvider codeFixProvider, FixAllScope scope, - string codeActionEquivalenceKey, + string? codeActionEquivalenceKey, IEnumerable diagnosticIds, DiagnosticProvider fixAllDiagnosticProvider, CancellationToken cancellationToken) - : this(new FixAllState(null, document, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider), + : this(new FixAllState( + fixAllProvider: null, + document ?? throw new ArgumentNullException(nameof(document)), + document.Project, + codeFixProvider ?? throw new ArgumentNullException(nameof(codeFixProvider)), + scope, + codeActionEquivalenceKey, + PublicContract.RequireNonNullItems(diagnosticIds, nameof(diagnosticIds)), + fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider))), new ProgressTracker(), cancellationToken) { if (document == null) @@ -115,17 +123,21 @@ public FixAllContext( Project project, CodeFixProvider codeFixProvider, FixAllScope scope, - string codeActionEquivalenceKey, + string? codeActionEquivalenceKey, IEnumerable diagnosticIds, DiagnosticProvider fixAllDiagnosticProvider, CancellationToken cancellationToken) - : this(new FixAllState(null, project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider), + : this(new FixAllState( + fixAllProvider: null, + document: null, + project ?? throw new ArgumentNullException(nameof(project)), + codeFixProvider ?? throw new ArgumentNullException(nameof(codeFixProvider)), + scope, + codeActionEquivalenceKey, + PublicContract.RequireNonNullItems(diagnosticIds, nameof(diagnosticIds)), + fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider))), new ProgressTracker(), cancellationToken) { - if (project == null) - { - throw new ArgumentNullException(nameof(project)); - } } internal FixAllContext( diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/PublicContract.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/PublicContract.cs index c0867d061073c..d8acb0c5d347b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/PublicContract.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/PublicContract.cs @@ -24,7 +24,7 @@ internal static class PublicContract // while keeping the rarely executed code in a separate method. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void RequireNonNullItems([NotNull] IEnumerable? sequence, string argumentName) where T : class + internal static IEnumerable RequireNonNullItems([NotNull] IEnumerable? sequence, string argumentName) where T : class { if (sequence == null) { @@ -35,6 +35,8 @@ internal static void RequireNonNullItems([NotNull] IEnumerable? sequence, { ThrowArgumentItemNullException(sequence, argumentName); } + + return sequence; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs index 3d41be7ecef7c..8793a2eceb5ef 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis.Internal.Log; using Roslyn.Utilities; @@ -27,38 +28,6 @@ internal partial class FixAllState public Solution Solution => this.Project.Solution; internal FixAllState( - FixAllProvider? fixAllProvider, - Document document, - CodeFixProvider codeFixProvider, - FixAllScope scope, - string? codeActionEquivalenceKey, - IEnumerable diagnosticIds, - FixAllContext.DiagnosticProvider fixAllDiagnosticProvider) - : this(fixAllProvider, document, document.Project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider) - { - if (document == null) - { - throw new ArgumentNullException(nameof(document)); - } - } - - internal FixAllState( - FixAllProvider? fixAllProvider, - Project project, - CodeFixProvider codeFixProvider, - FixAllScope scope, - string? codeActionEquivalenceKey, - IEnumerable diagnosticIds, - FixAllContext.DiagnosticProvider fixAllDiagnosticProvider) - : this(fixAllProvider, null, project, codeFixProvider, scope, codeActionEquivalenceKey, diagnosticIds, fixAllDiagnosticProvider) - { - if (project == null) - { - throw new ArgumentNullException(nameof(project)); - } - } - - private FixAllState( FixAllProvider? fixAllProvider, Document? document, Project project, @@ -68,25 +37,16 @@ private FixAllState( IEnumerable diagnosticIds, FixAllContext.DiagnosticProvider fixAllDiagnosticProvider) { - Contract.ThrowIfNull(project); - if (diagnosticIds == null) - { - throw new ArgumentNullException(nameof(diagnosticIds)); - } - - if (diagnosticIds.Any(d => d == null)) - { - throw new ArgumentException(WorkspaceExtensionsResources.Supplied_diagnostic_cannot_be_null, nameof(diagnosticIds)); - } - - this.FixAllProvider = fixAllProvider; - this.Document = document; - this.Project = project; - this.CodeFixProvider = codeFixProvider ?? throw new ArgumentNullException(nameof(codeFixProvider)); - this.Scope = scope; - this.CodeActionEquivalenceKey = codeActionEquivalenceKey; - this.DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds); - this.DiagnosticProvider = fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider)); + Debug.Assert(document == null || document.Project == project); + + FixAllProvider = fixAllProvider; + Document = document; + Project = project; + CodeFixProvider = codeFixProvider; + Scope = scope; + CodeActionEquivalenceKey = codeActionEquivalenceKey; + DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds); + DiagnosticProvider = fixAllDiagnosticProvider; } internal bool IsFixMultiple => this.DiagnosticProvider is FixMultipleDiagnosticProvider; @@ -146,9 +106,13 @@ internal static FixAllState Create( var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix); return new FixAllState( fixAllProvider, - triggerDocument, codeFixProvider, - FixAllScope.Custom, codeActionEquivalenceKey, - diagnosticIds, diagnosticProvider); + triggerDocument, + triggerDocument.Project, + codeFixProvider, + FixAllScope.Custom, + codeActionEquivalenceKey, + diagnosticIds, + diagnosticProvider); } internal static FixAllState Create( @@ -162,9 +126,13 @@ internal static FixAllState Create( var diagnosticProvider = new FixMultipleDiagnosticProvider(diagnosticsToFix); return new FixAllState( fixAllProvider, - triggerProject, codeFixProvider, - FixAllScope.Custom, codeActionEquivalenceKey, - diagnosticIds, diagnosticProvider); + document: null, + triggerProject, + codeFixProvider, + FixAllScope.Custom, + codeActionEquivalenceKey, + diagnosticIds, + diagnosticProvider); } private static ImmutableHashSet GetDiagnosticsIds(IEnumerable> diagnosticsCollection) From 13a38722adc8bea8e7def7b0ff602408d6b59321 Mon Sep 17 00:00:00 2001 From: Tomas Matousek Date: Tue, 15 Feb 2022 17:25:38 -0800 Subject: [PATCH 2/7] Propagate CodeActionOptions through fix all --- eng/config/BannedSymbols.txt | 4 +- .../AsyncSuggestedActionsSource.cs | 2 +- .../FixAll/FixMultipleOccurrencesService.cs | 20 +++--- .../Suggestions/SuggestedActionsSource.cs | 9 +-- .../CodeActions/CodeActionOptionsStorage.cs | 15 ++++- .../CodeActions/CodeActionResolveHandler.cs | 2 +- .../CodeActions/CodeActionsHandler.cs | 2 +- .../CodeActions/RunCodeActionHandler.cs | 2 +- .../Diagnostics/AbstractUserDiagnosticTest.cs | 11 ++-- .../Test/CodeFixes/CodeFixServiceTests.cs | 4 +- .../Core/Portable/CodeFixes/CodeFixService.cs | 53 +++++++++------- .../IFixMultipleOccurrencesService.cs | 3 + .../Portable/CodeFixes/ICodeFixService.cs | 2 +- .../CodeCleanup/AbstractCodeCleanUpFixer.cs | 6 +- .../VisualStudioSuppressionFixService.cs | 11 +++- .../FixAllOccurrences/BatchFixAllProvider.cs | 4 +- .../FixAllOccurrences/FixAllContext.cs | 10 ++- .../Core/CodeFixes}/CodeActionOptions.cs | 11 ++++ .../Core/CodeFixes/FixAll/FixAllState.cs | 63 +++++++++++-------- .../Core/WorkspaceExtensions.projitems | 1 + 20 files changed, 151 insertions(+), 84 deletions(-) rename src/Workspaces/{Core/Portable/CodeActions => SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes}/CodeActionOptions.cs (79%) diff --git a/eng/config/BannedSymbols.txt b/eng/config/BannedSymbols.txt index 90dc1530bd4d1..ada110f216658 100644 --- a/eng/config/BannedSymbols.txt +++ b/eng/config/BannedSymbols.txt @@ -5,4 +5,6 @@ M:Microsoft.CodeAnalysis.Completion.CompletionProvider.GetDescriptionAsync(Micro M:Microsoft.CodeAnalysis.Completion.CompletionService.GetCompletionsAsync(Microsoft.CodeAnalysis.Document,System.Int32,Microsoft.CodeAnalysis.Completion.CompletionTrigger,System.Collections.Immutable.ImmutableHashSet{System.String},Microsoft.CodeAnalysis.Options.OptionSet,System.Threading.CancellationToken); Use internal overload instead M:Microsoft.CodeAnalysis.Completion.CompletionService.GetDescriptionAsync(Microsoft.CodeAnalysis.Document,Microsoft.CodeAnalysis.Completion.CompletionItem,System.Threading.CancellationToken); Use internal overload instead M:Microsoft.CodeAnalysis.Completion.CompletionService.GetRules; Use internal overload instead -M:Microsoft.CodeAnalysis.QuickInfo.QuickInfoService.GetQuickInfoAsync(Microsoft.CodeAnalysis.Document,System.Int32,System.Threading.CancellationToken); Use internal overload instead \ No newline at end of file +M:Microsoft.CodeAnalysis.QuickInfo.QuickInfoService.GetQuickInfoAsync(Microsoft.CodeAnalysis.Document,System.Int32,System.Threading.CancellationToken); Use internal overload instead +M:Microsoft.CodeAnalysis.CodeFixes.FixAllContext.#ctor(Microsoft.CodeAnalysis.Document,Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider,Microsoft.CodeAnalysis.CodeFixes.FixAllScope,System.String,System.Collections.Generic.IEnumerable{System.String},Microsoft.CodeAnalysis.CodeFixes.FixAllContext.DiagnosticProvider,System.Threading.CancellationToken); Use internal overload instead +M:Microsoft.CodeAnalysis.CodeFixes.FixAllContext.#ctor(Microsoft.CodeAnalysis.Project,Microsoft.CodeAnalysis.CodeFixes.CodeFixProvider,Microsoft.CodeAnalysis.CodeFixes.FixAllScope,System.String,System.Collections.Generic.IEnumerable{System.String},Microsoft.CodeAnalysis.CodeFixes.FixAllContext.DiagnosticProvider,System.Threading.CancellationToken); Use internal overload instead diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs b/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs index ed537090ce98e..cb22c62204420 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs @@ -168,7 +168,7 @@ private async IAsyncEnumerable GetCodeFixesAndRefactoringsAs var workspace = document.Project.Solution.Workspace; var supportsFeatureService = workspace.Services.GetRequiredService(); - var options = GlobalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = GlobalOptions.GetCodeActionOptions(document.Project.Language); var fixesTask = GetCodeFixesAsync( state, supportsFeatureService, requestedActionCategories, workspace, document, range, diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs b/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs index a8d4ac11673d2..390e2abfc7f1b 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs @@ -5,14 +5,16 @@ #nullable disable using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; +using System.Diagnostics; +using System.Linq; using System.Threading; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Extensions; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.TestHooks; using Roslyn.Utilities; @@ -22,25 +24,28 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions /// Service to compute and apply code fixes. /// [ExportWorkspaceService(typeof(IFixMultipleOccurrencesService), ServiceLayer.Host), Shared] - internal class FixMultipleOccurrencesService : IFixMultipleOccurrencesService + internal sealed class FixMultipleOccurrencesService : IFixMultipleOccurrencesService { [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public FixMultipleOccurrencesService(IAsynchronousOperationListenerProvider listenerProvider) - => listenerProvider.GetListener(FeatureAttribute.LightBulb); + public FixMultipleOccurrencesService(IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider) + { + listenerProvider.GetListener(FeatureAttribute.LightBulb); + } public Solution GetFix( ImmutableDictionary> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, + CodeActionOptionsProvider optionsProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create( - fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); + fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey, optionsProvider); return GetFixedSolution( fixMultipleState, workspace, waitDialogTitle, @@ -52,13 +57,14 @@ public Solution GetFix( Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, + CodeActionOptionsProvider optionsProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create( - fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); + fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey, optionsProvider); return GetFixedSolution( fixMultipleState, workspace, waitDialogTitle, diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs index 0d2a67374b859..332cf7daf6362 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs @@ -177,7 +177,7 @@ public bool TryGetTelemetryId(out Guid telemetryId) Func addOperationScope = description => operationContext?.AddScope(allowCancellation: true, string.Format(EditorFeaturesResources.Gathering_Suggestions_0, description)); - var options = GlobalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: true); + var options = GlobalOptions.GetBlockingCodeActionOptions(document.Project.Language); // We convert the code fixes and refactorings to UnifiedSuggestedActionSets instead of // SuggestedActionSets so that we can share logic between local Roslyn and LSP. @@ -414,13 +414,14 @@ await InvokeBelowInputPriorityAsync(() => ReferenceCountedDisposable state, Document document, SnapshotSpan range, + CodeActionOptions options, CancellationToken cancellationToken) { if (state.Target.Owner._codeFixService != null && state.Target.SubjectBuffer.SupportsCodeFixes()) { var result = await state.Target.Owner._codeFixService.GetMostSevereFixableDiagnosticAsync( - document, range.Span.ToTextSpan(), cancellationToken).ConfigureAwait(false); + document, range.Span.ToTextSpan(), options, cancellationToken).ConfigureAwait(false); if (result.HasFix) { @@ -614,12 +615,12 @@ private void OnSuggestedActionsChanged(Workspace currentWorkspace, DocumentId? c if (document == null) return null; - var options = GlobalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = GlobalOptions.GetCodeActionOptions(document.Project.Language); using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); var linkedToken = linkedTokenSource.Token; - var errorTask = Task.Run(() => GetFixLevelAsync(state, document, range, linkedToken), linkedToken); + var errorTask = Task.Run(() => GetFixLevelAsync(state, document, range, options, linkedToken), linkedToken); var selection = await GetSpanAsync(state, range, linkedToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionOptionsStorage.cs b/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionOptionsStorage.cs index bc5363d278095..c4a5784c02f94 100644 --- a/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionOptionsStorage.cs +++ b/src/EditorFeatures/Core/Implementation/CodeActions/CodeActionOptionsStorage.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Immutable; using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.SymbolSearch; @@ -10,10 +11,22 @@ namespace Microsoft.CodeAnalysis.CodeActions { internal static class CodeActionOptionsStorage { - internal static CodeActionOptions GetCodeActionOptions(this IGlobalOptionService globalOptions, string language, bool isBlocking) + internal static CodeActionOptions GetCodeActionOptions(this IGlobalOptionService globalOptions, string language) + => GetCodeActionOptions(globalOptions, language, isBlocking: false); + + internal static CodeActionOptions GetBlockingCodeActionOptions(this IGlobalOptionService globalOptions, string language) + => GetCodeActionOptions(globalOptions, language, isBlocking: true); + + private static CodeActionOptions GetCodeActionOptions(this IGlobalOptionService globalOptions, string language, bool isBlocking) => new( SearchOptions: globalOptions.GetSymbolSearchOptions(language), HideAdvancedMembers: globalOptions.GetOption(CompletionOptionsStorage.HideAdvancedMembers, language), IsBlocking: isBlocking); + + internal static CodeActionOptionsProvider GetCodeActionOptionsProvider(this IGlobalOptionService globalOptions) + { + var cache = ImmutableDictionary.Empty; + return language => ImmutableInterlocked.GetOrAdd(ref cache, language, (language, options) => GetCodeActionOptions(options, language), globalOptions); + } } } diff --git a/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionResolveHandler.cs b/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionResolveHandler.cs index 66a3f2f7d29e2..46b40d708f983 100644 --- a/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionResolveHandler.cs +++ b/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionResolveHandler.cs @@ -66,7 +66,7 @@ public CodeActionResolveHandler( var data = ((JToken)codeAction.Data!).ToObject(); Assumes.Present(data); - var options = _globalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = _globalOptions.GetCodeActionOptions(document.Project.Language); var codeActions = await CodeActionHelpers.GetCodeActionsAsync( _codeActionsCache, diff --git a/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionsHandler.cs b/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionsHandler.cs index 1553c5424a8ac..c059f005a7ee0 100644 --- a/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionsHandler.cs +++ b/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/CodeActionsHandler.cs @@ -57,7 +57,7 @@ public CodeActionsHandler( var document = context.Document; Contract.ThrowIfNull(document); - var options = _globalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = _globalOptions.GetCodeActionOptions(document.Project.Language); var codeActions = await CodeActionHelpers.GetVSCodeActionsAsync( request, _codeActionsCache, document, options, _codeFixService, _codeRefactoringService, cancellationToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/RunCodeActionHandler.cs b/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/RunCodeActionHandler.cs index 4a0224579340c..1e82bc010dc39 100644 --- a/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/RunCodeActionHandler.cs +++ b/src/EditorFeatures/Core/Implementation/LanguageServer/Handlers/CodeActions/RunCodeActionHandler.cs @@ -74,7 +74,7 @@ public override async Task HandleRequestAsync(LSP.ExecuteCommandParams r var runRequest = ((JToken)request.Arguments.Single()).ToObject(); Assumes.Present(runRequest); - var options = _globalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = _globalOptions.GetCodeActionOptions(document.Project.Language); var codeActions = await CodeActionHelpers.GetCodeActionsAsync( _codeActionsCache, document, runRequest.Range, options, _codeFixService, _codeRefactoringService, cancellationToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs b/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs index 4a5445c0d774d..1fa120d85c82e 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs @@ -219,7 +219,7 @@ protected static Document GetDocumentAndAnnotatedSpan(TestWorkspace workspace, o var fixAllState = GetFixAllState( fixAllProvider, diagnostics, fixer, testDriver, document, - scope.Value, equivalenceKey); + scope.Value, equivalenceKey, _ => options); var fixAllContext = new FixAllContext(fixAllState, new ProgressTracker(), CancellationToken.None); var fixAllFix = await fixAllProvider.GetFixAsync(fixAllContext); @@ -235,7 +235,8 @@ private static FixAllState GetFixAllState( TestDiagnosticAnalyzerDriver testDriver, Document document, FixAllScope scope, - string equivalenceKey) + string equivalenceKey, + CodeActionOptionsProvider optionsProvider) { Assert.NotEmpty(diagnostics); @@ -243,7 +244,7 @@ private static FixAllState GetFixAllState( { // Bulk fixing diagnostics in selected scope. var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePairUtil.Create(document, diagnostics.ToImmutableArray()))); - return FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, equivalenceKey); + return FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, equivalenceKey, optionsProvider); } var diagnostic = diagnostics.First(); @@ -251,8 +252,8 @@ private static FixAllState GetFixAllState( var fixAllDiagnosticProvider = new FixAllDiagnosticProvider(testDriver, diagnosticIds); return diagnostic.Location.IsInSource - ? new FixAllState(fixAllProvider, document, fixer, scope, equivalenceKey, diagnosticIds, fixAllDiagnosticProvider) - : new FixAllState(fixAllProvider, document.Project, fixer, scope, equivalenceKey, diagnosticIds, fixAllDiagnosticProvider); + ? new FixAllState(fixAllProvider, document, document.Project, fixer, scope, equivalenceKey, diagnosticIds, fixAllDiagnosticProvider, optionsProvider) + : new FixAllState(fixAllProvider, document: null, document.Project, fixer, scope, equivalenceKey, diagnosticIds, fixAllDiagnosticProvider, optionsProvider); } private protected Task TestActionCountInAllFixesAsync( diff --git a/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs b/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs index 0f0f4f1a4e01b..d29746f7892a1 100644 --- a/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs +++ b/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs @@ -60,7 +60,7 @@ public async Task TestGetFirstDiagnosticWithFixAsync() var reference = new MockAnalyzerReference(); var project = workspace.CurrentSolution.Projects.Single().AddAnalyzerReference(reference); var document = project.Documents.Single(); - var unused = await fixService.GetMostSevereFixableDiagnosticAsync(document, TextSpan.FromBounds(0, 0), cancellationToken: CancellationToken.None); + var unused = await fixService.GetMostSevereFixableDiagnosticAsync(document, TextSpan.FromBounds(0, 0), CodeActionOptions.Default, CancellationToken.None); var fixer1 = (MockFixer)fixers.Single().Value; var fixer2 = (MockFixer)reference.Fixer!; @@ -297,7 +297,7 @@ private static async Task GetFirstDiagnosticWithFixWithExceptionValidationAsync( errorReportingService.OnError = message => errorReported = true; GetDocumentAndExtensionManager(tuple.analyzerService, workspace, out var document, out var extensionManager); - var unused = await tuple.codeFixService.GetMostSevereFixableDiagnosticAsync(document, TextSpan.FromBounds(0, 0), cancellationToken: CancellationToken.None); + var unused = await tuple.codeFixService.GetMostSevereFixableDiagnosticAsync(document, TextSpan.FromBounds(0, 0), CodeActionOptions.Default, CancellationToken.None); Assert.True(extensionManager.IsDisabled(codefix)); Assert.False(extensionManager.IsIgnored(codefix)); Assert.True(errorReported); diff --git a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs index 762612a8ef803..401517ac5ebe0 100644 --- a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs +++ b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs @@ -74,11 +74,11 @@ public CodeFixService( } public async Task GetMostSevereFixableDiagnosticAsync( - Document document, TextSpan range, CancellationToken cancellationToken) + Document document, TextSpan range, CodeActionOptions options, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); - if (document == null || !document.IsOpen()) + if (!document.IsOpen()) { return default; } @@ -98,12 +98,12 @@ public async Task GetMostSevereFixableDiagnosticAsync( // Kick off a task that will determine there's an Error Diagnostic with a fixer var errorDiagnosticsTask = Task.Run( - () => GetFirstDiagnosticWithFixAsync(document, errorDiagnostics, range, linkedToken), + () => GetFirstDiagnosticWithFixAsync(document, errorDiagnostics, range, options, linkedToken), linkedToken); // Kick off a task that will determine if any non-Error Diagnostic has a fixer var otherDiagnosticsTask = Task.Run( - () => GetFirstDiagnosticWithFixAsync(document, otherDiagnostics, range, linkedToken), + () => GetFirstDiagnosticWithFixAsync(document, otherDiagnostics, range, options, linkedToken), linkedToken); // If the error diagnostics task happens to complete with a non-null result before @@ -121,6 +121,7 @@ public async Task GetMostSevereFixableDiagnosticAsync( Document document, IEnumerable severityGroup, TextSpan range, + CodeActionOptions options, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -132,7 +133,7 @@ public async Task GetMostSevereFixableDiagnosticAsync( continue; } - if (await ContainsAnyFixAsync(document, diagnostic, cancellationToken).ConfigureAwait(false)) + if (await ContainsAnyFixAsync(document, diagnostic, options, cancellationToken).ConfigureAwait(false)) { return diagnostic; } @@ -214,7 +215,7 @@ public async IAsyncEnumerable StreamFixesAsync( foreach (var (span, diagnosticList) in aggregatedDiagnostics) { await foreach (var codeFixCollection in StreamConfigurationFixesAsync( - document, span, diagnosticList, registeredConfigurationFixTitles, cancellationToken).ConfigureAwait(false)) + document, span, diagnosticList, registeredConfigurationFixTitles, options, cancellationToken).ConfigureAwait(false)) { yield return codeFixCollection; } @@ -458,6 +459,7 @@ private async IAsyncEnumerable StreamFixesAsync( } } }, + options, cancellationToken).ConfigureAwait(false); if (codeFixCollection != null) @@ -604,6 +606,7 @@ private async IAsyncEnumerable StreamConfigurationFixesAsync( TextSpan diagnosticsSpan, IEnumerable diagnostics, PooledHashSet registeredConfigurationFixTitles, + CodeActionOptions options, [EnumeratorCancellation] CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -627,6 +630,7 @@ private async IAsyncEnumerable StreamConfigurationFixesAsync( var fixes = await provider.GetFixesAsync(document, diagnosticsSpan, dxs, cancellationToken).ConfigureAwait(false); return fixes.WhereAsArray(f => registeredConfigurationFixTitles.Add(f.Action.Title)); }, + options, cancellationToken).ConfigureAwait(false); if (codeFixCollection != null) yield return codeFixCollection; @@ -642,6 +646,7 @@ private async IAsyncEnumerable StreamConfigurationFixesAsync( TCodeFixProvider fixer, Func hasFix, Func, Task>> getFixes, + CodeActionOptions options, CancellationToken cancellationToken) where TCodeFixProvider : notnull { @@ -701,14 +706,19 @@ await diagnosticsWithSameSpan.OrderByDescending(d => d.Severity) : (FixAllContext.DiagnosticProvider)new FixAllDiagnosticProvider(this, diagnosticIdsForDiagnosticProvider, includeSuppressedDiagnostics); fixAllState = new FixAllState( - fixAllProvider: fixAllProviderInfo.FixAllProvider, - document: document, - project: document.Project, - codeFixProvider: codeFixProvider, - scope: FixAllScope.Document, - codeActionEquivalenceKey: fixes[0].Action.EquivalenceKey, - diagnosticIds: diagnosticIds, - fixAllDiagnosticProvider: diagnosticProvider); + fixAllProviderInfo.FixAllProvider, + document, + document.Project, + codeFixProvider, + FixAllScope.Document, + fixes[0].Action.EquivalenceKey, + diagnosticIds, + diagnosticProvider, + codeActionOptionsProvider: language => + { + Contract.ThrowIfFalse(language == document.Project.Language); + return options; + }); supportedScopes = fixAllProviderInfo.SupportedScopes; } @@ -770,13 +780,13 @@ private async Task> GetProjectDiagnosticsAsync(Project p } private async Task ContainsAnyFixAsync( - Document document, DiagnosticData diagnostic, CancellationToken cancellationToken) + Document document, DiagnosticData diagnosticData, CodeActionOptions options, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var workspaceFixers = ImmutableArray.Empty; - var hasAnySharedFixer = TryGetWorkspaceFixersMap(document, out var fixerMap) && fixerMap.Value.TryGetValue(diagnostic.Id, out workspaceFixers); - var hasAnyProjectFixer = GetProjectFixers(document.Project).TryGetValue(diagnostic.Id, out var projectFixers); + var hasAnySharedFixer = TryGetWorkspaceFixersMap(document, out var fixerMap) && fixerMap.Value.TryGetValue(diagnosticData.Id, out workspaceFixers); + var hasAnyProjectFixer = GetProjectFixers(document.Project).TryGetValue(diagnosticData.Id, out var projectFixers); // TODO (https://github.com/dotnet/roslyn/issues/4932): Don't restrict CodeFixes in Interactive if (hasAnySharedFixer && document.Project.Solution.Workspace.Kind == WorkspaceKind.Interactive) @@ -805,13 +815,13 @@ private async Task ContainsAnyFixAsync( allFixers = allFixers.AddRange(projectFixers!); } - var dx = await diagnostic.ToDiagnosticAsync(document.Project, cancellationToken).ConfigureAwait(false); + var diagnostic = await diagnosticData.ToDiagnosticAsync(document.Project, cancellationToken).ConfigureAwait(false); if (hasConfigurationFixer) { foreach (var lazyConfigurationProvider in lazyConfigurationProviders!.Value) { - if (lazyConfigurationProvider.IsFixableDiagnostic(dx)) + if (lazyConfigurationProvider.IsFixableDiagnostic(diagnostic)) { return true; } @@ -819,7 +829,7 @@ private async Task ContainsAnyFixAsync( } var fixes = new List(); - var context = new CodeFixContext(document, dx, + var context = new CodeFixContext(document, diagnostic.Location.SourceSpan, ImmutableArray.Create(diagnostic), // TODO: Can we share code between similar lambdas that we pass to this API in BatchFixAllProvider.cs, CodeFixService.cs and CodeRefactoringService.cs? (action, applicableDiagnostics) => @@ -830,7 +840,8 @@ private async Task ContainsAnyFixAsync( fixes.Add(new CodeFix(document.Project, action, applicableDiagnostics)); } }, - cancellationToken: cancellationToken); + options, + cancellationToken); var extensionManager = document.Project.Solution.Workspace.Services.GetRequiredService(); diff --git a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixMultipleOccurrencesService.cs b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixMultipleOccurrencesService.cs index 4e0da11fa4ddd..73409995108b4 100644 --- a/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixMultipleOccurrencesService.cs +++ b/src/Features/Core/Portable/CodeFixes/FixAllOccurrences/IFixMultipleOccurrencesService.cs @@ -6,6 +6,7 @@ using System.Collections.Immutable; using System.Threading; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.CodeFixes @@ -21,6 +22,7 @@ Solution GetFix( Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, + CodeActionOptionsProvider optionsProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, @@ -35,6 +37,7 @@ Solution GetFix( Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, + CodeActionOptionsProvider optionsProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, diff --git a/src/Features/Core/Portable/CodeFixes/ICodeFixService.cs b/src/Features/Core/Portable/CodeFixes/ICodeFixService.cs index fc04f0104fd90..1f2109bc9fe6c 100644 --- a/src/Features/Core/Portable/CodeFixes/ICodeFixService.cs +++ b/src/Features/Core/Portable/CodeFixes/ICodeFixService.cs @@ -20,7 +20,7 @@ internal interface ICodeFixService Task GetDocumentFixAllForIdInSpanAsync(Document document, TextSpan textSpan, string diagnosticId, CodeActionOptions options, CancellationToken cancellationToken); Task ApplyCodeFixesForSpecificDiagnosticIdAsync(Document document, string diagnosticId, IProgressTracker progressTracker, CodeActionOptions options, CancellationToken cancellationToken); CodeFixProvider? GetSuppressionFixer(string language, IEnumerable diagnosticIds); - Task GetMostSevereFixableDiagnosticAsync(Document document, TextSpan range, CancellationToken cancellationToken); + Task GetMostSevereFixableDiagnosticAsync(Document document, TextSpan range, CodeActionOptions options, CancellationToken cancellationToken); } internal static class ICodeFixServiceExtensions diff --git a/src/VisualStudio/Core/Def/Implementation/CodeCleanup/AbstractCodeCleanUpFixer.cs b/src/VisualStudio/Core/Def/Implementation/CodeCleanup/AbstractCodeCleanUpFixer.cs index 347f758405c71..341662e19165b 100644 --- a/src/VisualStudio/Core/Def/Implementation/CodeCleanup/AbstractCodeCleanUpFixer.cs +++ b/src/VisualStudio/Core/Def/Implementation/CodeCleanup/AbstractCodeCleanUpFixer.cs @@ -133,7 +133,7 @@ private async Task FixHierarchyContentAsync(IVsHierarchyCodeCleanupScope h } var document = solution.GetRequiredDocument(documentId); - var options = _globalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = _globalOptions.GetCodeActionOptions(document.Project.Language); return await FixDocumentAsync(document, options, context).ConfigureAwait(true); } } @@ -202,7 +202,7 @@ async Task ApplyFixAsync(ProgressTracker progressTracker, Cancellation var document = buffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); Contract.ThrowIfNull(document); - var options = _globalOptions.GetCodeActionOptions(document.Project.Language, isBlocking: false); + var options = _globalOptions.GetCodeActionOptions(document.Project.Language); var newDoc = await FixDocumentAsync(document, context.EnabledFixIds, progressTracker, options, cancellationToken).ConfigureAwait(true); return newDoc.Project.Solution; } @@ -289,7 +289,7 @@ private async Task FixProjectAsync( progressTracker.AddItems(project.DocumentIds.Count); } - var options = _globalOptions.GetCodeActionOptions(project.Language, isBlocking: false); + var options = _globalOptions.GetCodeActionOptions(project.Language); foreach (var documentId in project.DocumentIds) { diff --git a/src/VisualStudio/Core/Def/Implementation/TableDataSource/Suppression/VisualStudioSuppressionFixService.cs b/src/VisualStudio/Core/Def/Implementation/TableDataSource/Suppression/VisualStudioSuppressionFixService.cs index 04908186f14ae..7b1536d7f6a5e 100644 --- a/src/VisualStudio/Core/Def/Implementation/TableDataSource/Suppression/VisualStudioSuppressionFixService.cs +++ b/src/VisualStudio/Core/Def/Implementation/TableDataSource/Suppression/VisualStudioSuppressionFixService.cs @@ -19,6 +19,7 @@ using Microsoft.CodeAnalysis.Editor.Implementation.Suggestions; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; @@ -52,6 +53,7 @@ internal sealed class VisualStudioSuppressionFixService : IVisualStudioSuppressi private readonly IUIThreadOperationExecutor _uiThreadOperationExecutor; private readonly IVsHierarchyItemManager _vsHierarchyItemManager; private readonly IHierarchyItemToProjectIdMap _projectMap; + private readonly IGlobalOptionService _globalOptions; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] @@ -64,7 +66,8 @@ public VisualStudioSuppressionFixService( IVisualStudioDiagnosticListSuppressionStateService suppressionStateService, IUIThreadOperationExecutor uiThreadOperationExecutor, IVsHierarchyItemManager vsHierarchyItemManager, - IAsynchronousOperationListenerProvider listenerProvider) + IAsynchronousOperationListenerProvider listenerProvider, + IGlobalOptionService globalOptions) { _workspace = workspace; _diagnosticService = diagnosticService; @@ -80,6 +83,7 @@ public VisualStudioSuppressionFixService( var errorList = serviceProvider.GetService(typeof(SVsErrorList)) as IErrorList; _tableControl = errorList?.TableControl; _listener = listenerProvider.GetListener(FeatureAttribute.ErrorList); + _globalOptions = globalOptions; } public bool AddSuppressions(IVsHierarchy? projectHierarchy) @@ -295,6 +299,9 @@ private async Task ApplySuppressionFixAsync(IEnumerable? diagnos cancellationToken.ThrowIfCancellationRequested(); + var options = _globalOptions.GetCodeActionOptions(language); + var optionsProvider = new CodeActionOptionsProvider(_ => options); + var documentDiagnosticsPerLanguage = GetDocumentDiagnosticsMappedToNewSolution(documentDiagnosticsToFixMap, newSolution, language); if (!documentDiagnosticsPerLanguage.IsEmpty) { @@ -307,6 +314,7 @@ private async Task ApplySuppressionFixAsync(IEnumerable? diagnos _workspace, suppressionFixer, suppressionFixAllProvider, + optionsProvider, equivalenceKey, title, waitDialogMessage, @@ -331,6 +339,7 @@ private async Task ApplySuppressionFixAsync(IEnumerable? diagnos _workspace, suppressionFixer, suppressionFixAllProvider, + optionsProvider, equivalenceKey, title, waitDialogMessage, diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs index b92e886034764..d439d0a007fff 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs @@ -141,13 +141,15 @@ private static async Task> GetAllChangedDocumentsInDiag foreach (var diagnostic in orderedDiagnostics) { var document = solution.GetRequiredDocument(diagnostic.Location.SourceTree!); + var options = fixAllContext.State.CodeActionOptionsProvider(document.Project.Language) with { IsBlocking = false }; cancellationToken.ThrowIfCancellationRequested(); tasks.Add(Task.Run(async () => { // Create a context that will add the reported code actions into this using var _2 = ArrayBuilder.GetInstance(out var codeActions); - var context = new CodeFixContext(document, diagnostic, GetRegisterCodeFixAction(fixAllContext.CodeActionEquivalenceKey, codeActions), cancellationToken); + var action = GetRegisterCodeFixAction(fixAllContext.CodeActionEquivalenceKey, codeActions); + var context = new CodeFixContext(document, diagnostic.Location.SourceSpan, ImmutableArray.Create(diagnostic), action, options, cancellationToken); // Wait for the all the code actions to be reported for this diagnostic. var registerTask = fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context) ?? Task.CompletedTask; diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs index aba77e80d776c..15540d44ff297 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs @@ -97,13 +97,10 @@ public FixAllContext( scope, codeActionEquivalenceKey, PublicContract.RequireNonNullItems(diagnosticIds, nameof(diagnosticIds)), - fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider))), + fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider)), + _ => CodeActionOptions.Default), new ProgressTracker(), cancellationToken) { - if (document == null) - { - throw new ArgumentNullException(nameof(document)); - } } /// @@ -135,7 +132,8 @@ public FixAllContext( scope, codeActionEquivalenceKey, PublicContract.RequireNonNullItems(diagnosticIds, nameof(diagnosticIds)), - fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider))), + fixAllDiagnosticProvider ?? throw new ArgumentNullException(nameof(fixAllDiagnosticProvider)), + _ => CodeActionOptions.Default), new ProgressTracker(), cancellationToken) { } diff --git a/src/Workspaces/Core/Portable/CodeActions/CodeActionOptions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs similarity index 79% rename from src/Workspaces/Core/Portable/CodeActions/CodeActionOptions.cs rename to src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs index 449e09b2c74c7..7a27888f664b8 100644 --- a/src/Workspaces/Core/Portable/CodeActions/CodeActionOptions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/CodeActionOptions.cs @@ -7,6 +7,14 @@ namespace Microsoft.CodeAnalysis.CodeActions { +#if CODE_STYLE + /// + /// Empty type to avoid excessive ifdefs. + /// + internal readonly struct CodeActionOptions + { + } +#else /// /// Options available to code fixes that are supplied by the IDE (i.e. not stored in editorconfig). /// @@ -23,4 +31,7 @@ public CodeActionOptions() public static readonly CodeActionOptions Default = new(); } +#endif + + internal delegate CodeActionOptions CodeActionOptionsProvider(string language); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs index 8793a2eceb5ef..1f724a8486552 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs @@ -7,16 +7,17 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Linq; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Internal.Log; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeFixes { - internal partial class FixAllState + internal sealed partial class FixAllState { - internal readonly int CorrelationId = LogAggregator.GetNextId(); + public readonly int CorrelationId = LogAggregator.GetNextId(); - internal FixAllContext.DiagnosticProvider DiagnosticProvider { get; } + public FixAllContext.DiagnosticProvider DiagnosticProvider { get; } public FixAllProvider? FixAllProvider { get; } public string? CodeActionEquivalenceKey { get; } @@ -25,7 +26,7 @@ internal partial class FixAllState public Document? Document { get; } public Project Project { get; } public FixAllScope Scope { get; } - public Solution Solution => this.Project.Solution; + public CodeActionOptionsProvider CodeActionOptionsProvider { get; } internal FixAllState( FixAllProvider? fixAllProvider, @@ -35,7 +36,8 @@ internal FixAllState( FixAllScope scope, string? codeActionEquivalenceKey, IEnumerable diagnosticIds, - FixAllContext.DiagnosticProvider fixAllDiagnosticProvider) + FixAllContext.DiagnosticProvider fixAllDiagnosticProvider, + CodeActionOptionsProvider codeActionOptionsProvider) { Debug.Assert(document == null || document.Project == project); @@ -47,21 +49,23 @@ internal FixAllState( CodeActionEquivalenceKey = codeActionEquivalenceKey; DiagnosticIds = ImmutableHashSet.CreateRange(diagnosticIds); DiagnosticProvider = fixAllDiagnosticProvider; + CodeActionOptionsProvider = codeActionOptionsProvider; } - internal bool IsFixMultiple => this.DiagnosticProvider is FixMultipleDiagnosticProvider; + public Solution Solution => Project.Solution; + internal bool IsFixMultiple => DiagnosticProvider is FixMultipleDiagnosticProvider; public FixAllState WithScope(FixAllScope scope) - => this.With(scope: scope); + => With(scope: scope); public FixAllState WithCodeActionEquivalenceKey(string codeActionEquivalenceKey) - => this.With(codeActionEquivalenceKey: codeActionEquivalenceKey); + => With(codeActionEquivalenceKey: codeActionEquivalenceKey); public FixAllState WithProject(Project project) - => this.With(project: project); + => With(project: project); public FixAllState WithDocument(Document? document) - => this.With(document: document); + => With(document: document); public FixAllState With( Optional document = default, @@ -69,28 +73,29 @@ public FixAllState With( Optional scope = default, Optional codeActionEquivalenceKey = default) { - var newDocument = document.HasValue ? document.Value : this.Document; - var newProject = project.HasValue ? project.Value : this.Project; - var newScope = scope.HasValue ? scope.Value : this.Scope; - var newCodeActionEquivalenceKey = codeActionEquivalenceKey.HasValue ? codeActionEquivalenceKey.Value : this.CodeActionEquivalenceKey; - - if (newDocument == this.Document && - newProject == this.Project && - newScope == this.Scope && - newCodeActionEquivalenceKey == this.CodeActionEquivalenceKey) + var newDocument = document.HasValue ? document.Value : Document; + var newProject = project.HasValue ? project.Value : Project; + var newScope = scope.HasValue ? scope.Value : Scope; + var newCodeActionEquivalenceKey = codeActionEquivalenceKey.HasValue ? codeActionEquivalenceKey.Value : CodeActionEquivalenceKey; + + if (newDocument == Document && + newProject == Project && + newScope == Scope && + newCodeActionEquivalenceKey == CodeActionEquivalenceKey) { return this; } return new FixAllState( - this.FixAllProvider, + FixAllProvider, newDocument, newProject, - this.CodeFixProvider, + CodeFixProvider, newScope, newCodeActionEquivalenceKey, - this.DiagnosticIds, - this.DiagnosticProvider); + DiagnosticIds, + DiagnosticProvider, + CodeActionOptionsProvider); } #region FixMultiple @@ -99,7 +104,8 @@ internal static FixAllState Create( FixAllProvider fixAllProvider, ImmutableDictionary> diagnosticsToFix, CodeFixProvider codeFixProvider, - string codeActionEquivalenceKey) + string? codeActionEquivalenceKey, + CodeActionOptionsProvider codeActionOptionsProvider) { var triggerDocument = diagnosticsToFix.First().Key; var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values); @@ -112,14 +118,16 @@ internal static FixAllState Create( FixAllScope.Custom, codeActionEquivalenceKey, diagnosticIds, - diagnosticProvider); + diagnosticProvider, + codeActionOptionsProvider); } internal static FixAllState Create( FixAllProvider fixAllProvider, ImmutableDictionary> diagnosticsToFix, CodeFixProvider codeFixProvider, - string codeActionEquivalenceKey) + string? codeActionEquivalenceKey, + CodeActionOptionsProvider codeActionOptionsProvider) { var triggerProject = diagnosticsToFix.First().Key; var diagnosticIds = GetDiagnosticsIds(diagnosticsToFix.Values); @@ -132,7 +140,8 @@ internal static FixAllState Create( FixAllScope.Custom, codeActionEquivalenceKey, diagnosticIds, - diagnosticProvider); + diagnosticProvider, + codeActionOptionsProvider); } private static ImmutableHashSet GetDiagnosticsIds(IEnumerable> diagnosticsCollection) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems index fd07f372126b2..dbc41c00a72b1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems @@ -9,6 +9,7 @@ Microsoft.CodeAnalysis.Shared + From 9523a5d2f7604868a0e5cff0dad931df31d6851e Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 16 Feb 2022 09:50:43 -0800 Subject: [PATCH 3/7] Fix FixAllState.With to preserve invariant --- .../DefaultFixAllProviderHelpers.cs | 4 ++-- .../CodeFixes/FixAllOccurrences/FixAllContext.cs | 7 ++----- .../Core/CodeFixes/FixAll/FixAllState.cs | 15 +++++---------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/DefaultFixAllProviderHelpers.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/DefaultFixAllProviderHelpers.cs index ed5dac078c342..04d8e28ab02bd 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/DefaultFixAllProviderHelpers.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/DefaultFixAllProviderHelpers.cs @@ -48,7 +48,7 @@ internal static class DefaultFixAllProviderHelpers => fixAllContextsAsync(fixAllContext, ImmutableArray.Create(fixAllContext)); private static Task GetProjectFixesAsync(FixAllContext fixAllContext, FixAllContexts fixAllContextsAsync) - => fixAllContextsAsync(fixAllContext, ImmutableArray.Create(fixAllContext.WithDocument(null))); + => fixAllContextsAsync(fixAllContext, ImmutableArray.Create(fixAllContext.WithDocumentAndProject(document: null, fixAllContext.Project))); private static Task GetSolutionFixesAsync(FixAllContext fixAllContext, FixAllContexts fixAllContextsAsync) { @@ -72,7 +72,7 @@ internal static class DefaultFixAllProviderHelpers .Where(p => p.Language == fixAllContext.Project.Language); return fixAllContextsAsync( fixAllContext, - sortedProjects.SelectAsArray(p => fixAllContext.WithScope(FixAllScope.Project).WithProject(p).WithDocument(null))); + sortedProjects.SelectAsArray(p => fixAllContext.WithScope(FixAllScope.Project).WithDocumentAndProject(document: null, p))); } } } diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs index 15540d44ff297..c2c9b18c8a944 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs @@ -245,11 +245,8 @@ public FixAllContext WithCancellationToken(CancellationToken cancellationToken) internal FixAllContext WithScope(FixAllScope scope) => this.WithState(State.WithScope(scope)); - internal FixAllContext WithProject(Project project) - => this.WithState(State.WithProject(project)); - - internal FixAllContext WithDocument(Document? document) - => this.WithState(State.WithDocument(document)); + internal FixAllContext WithDocumentAndProject(Document? document, Project project) + => this.WithState(State.WithDocumentAndProject(document, project)); private FixAllContext WithState(FixAllState state) => this.State == state ? this : new FixAllContext(state, ProgressTracker, CancellationToken); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs index 1f724a8486552..1b0fdac271bba 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/CodeFixes/FixAll/FixAllState.cs @@ -58,23 +58,18 @@ internal FixAllState( public FixAllState WithScope(FixAllScope scope) => With(scope: scope); - public FixAllState WithCodeActionEquivalenceKey(string codeActionEquivalenceKey) + public FixAllState WithCodeActionEquivalenceKey(string? codeActionEquivalenceKey) => With(codeActionEquivalenceKey: codeActionEquivalenceKey); - public FixAllState WithProject(Project project) - => With(project: project); - - public FixAllState WithDocument(Document? document) - => With(document: document); + public FixAllState WithDocumentAndProject(Document? document, Project project) + => With(documentAndProject: (document, project)); public FixAllState With( - Optional document = default, - Optional project = default, + Optional<(Document? document, Project project)> documentAndProject = default, Optional scope = default, Optional codeActionEquivalenceKey = default) { - var newDocument = document.HasValue ? document.Value : Document; - var newProject = project.HasValue ? project.Value : Project; + var (newDocument, newProject) = documentAndProject.HasValue ? documentAndProject.Value : (Document, Project); var newScope = scope.HasValue ? scope.Value : Scope; var newCodeActionEquivalenceKey = codeActionEquivalenceKey.HasValue ? codeActionEquivalenceKey.Value : CodeActionEquivalenceKey; From f7e3ac750e02d5cf948c66c0170a74721869fc94 Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 16 Feb 2022 10:29:28 -0800 Subject: [PATCH 4/7] Feedback --- .../Suggestions/FixAll/FixMultipleOccurrencesService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs b/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs index 390e2abfc7f1b..97cb4ed4b1ea9 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/FixAll/FixMultipleOccurrencesService.cs @@ -28,7 +28,7 @@ internal sealed class FixMultipleOccurrencesService : IFixMultipleOccurrencesSer { [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public FixMultipleOccurrencesService(IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider) + public FixMultipleOccurrencesService(IAsynchronousOperationListenerProvider listenerProvider) { listenerProvider.GetListener(FeatureAttribute.LightBulb); } From f5c220b9729d2c18e061137c7e6ebb44c837fe4a Mon Sep 17 00:00:00 2001 From: tmat Date: Wed, 16 Feb 2022 11:34:04 -0800 Subject: [PATCH 5/7] Fix --- .../Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs index c2c9b18c8a944..eec325ceba25f 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/FixAllContext.cs @@ -34,8 +34,7 @@ public partial class FixAllContext public Project Project => State.Project; /// - /// Document within which fix all occurrences was triggered. - /// Can be null if the context was created using . + /// Document within which fix all occurrences was triggered, null if the is scoped to a project. /// public Document? Document => State.Document; From 6c2b58f14b9c3f00511e6230530f628d23461e03 Mon Sep 17 00:00:00 2001 From: Tomas Matousek Date: Wed, 16 Feb 2022 18:03:17 -0800 Subject: [PATCH 6/7] Fix SyncNamespaces --- .../AbstractSyncNamespacesSevice.cs | 32 +++++++++++++------ .../SyncNamespaces/ISyncNamespacesService.cs | 3 +- .../SyncNamespacesCommandHandler.cs | 10 ++++-- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/Features/Core/Portable/SyncNamespaces/AbstractSyncNamespacesSevice.cs b/src/Features/Core/Portable/SyncNamespaces/AbstractSyncNamespacesSevice.cs index c03fd846ed1ed..922d3db1a794d 100644 --- a/src/Features/Core/Portable/SyncNamespaces/AbstractSyncNamespacesSevice.cs +++ b/src/Features/Core/Portable/SyncNamespaces/AbstractSyncNamespacesSevice.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -13,6 +14,7 @@ using Microsoft.CodeAnalysis.CodeFixes.MatchFolderAndNamespace; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.Utilities; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.SyncNamespaces @@ -28,8 +30,12 @@ internal abstract class AbstractSyncNamespacesSevice public async Task SyncNamespacesAsync( ImmutableArray projects, + CodeActionOptions options, CancellationToken cancellationToken) { + // all projects must be of the same language + Debug.Assert(projects.All(project => project.Language == projects[0].Language)); + var solution = projects[0].Solution; var diagnosticAnalyzers = ImmutableArray.Create(DiagnosticAnalyzer); var diagnosticsByProject = await GetDiagnosticsByProjectAsync(projects, diagnosticAnalyzers, cancellationToken).ConfigureAwait(false); @@ -40,7 +46,7 @@ public async Task SyncNamespacesAsync( return solution; } - var fixAllContext = await GetFixAllContextAsync(solution, CodeFixProvider, diagnosticsByProject, cancellationToken).ConfigureAwait(false); + var fixAllContext = await GetFixAllContextAsync(solution, CodeFixProvider, diagnosticsByProject, options, cancellationToken).ConfigureAwait(false); var fixAllProvider = CodeFixProvider.GetFixAllProvider(); RoslynDebug.AssertNotNull(fixAllProvider); @@ -86,6 +92,7 @@ private static async Task GetFixAllContextAsync( Solution solution, CodeFixProvider codeFixProvider, ImmutableDictionary> diagnosticsByProject, + CodeActionOptions options, CancellationToken cancellationToken) { var diagnosticProvider = new DiagnosticProvider(diagnosticsByProject); @@ -101,19 +108,26 @@ private static async Task GetFixAllContextAsync( CodeAction? action = null; var context = new CodeFixContext( document, - firstDiagnostic, + firstDiagnostic.Location.SourceSpan, + ImmutableArray.Create(firstDiagnostic), (a, _) => action ??= a, + options, cancellationToken); await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false); return new FixAllContext( - document: document, - codeFixProvider: codeFixProvider, - scope: FixAllScope.Solution, - codeActionEquivalenceKey: action?.EquivalenceKey!, // FixAllState supports null equivalence key. This should still be supported. - diagnosticIds: codeFixProvider.FixableDiagnosticIds, - fixAllDiagnosticProvider: diagnosticProvider, - cancellationToken: cancellationToken); + new FixAllState( + fixAllProvider: null, + document, + document.Project, + codeFixProvider, + FixAllScope.Solution, + codeActionEquivalenceKey: action?.EquivalenceKey!, // FixAllState supports null equivalence key. This should still be supported. + diagnosticIds: codeFixProvider.FixableDiagnosticIds, + fixAllDiagnosticProvider: diagnosticProvider, + _ => options), + new ProgressTracker(), + cancellationToken); } private static async Task ApplyCodeFixAsync( diff --git a/src/Features/Core/Portable/SyncNamespaces/ISyncNamespacesService.cs b/src/Features/Core/Portable/SyncNamespaces/ISyncNamespacesService.cs index c309e8391ecdb..a408b4f60b5c7 100644 --- a/src/Features/Core/Portable/SyncNamespaces/ISyncNamespacesService.cs +++ b/src/Features/Core/Portable/SyncNamespaces/ISyncNamespacesService.cs @@ -5,6 +5,7 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.SyncNamespaces @@ -15,6 +16,6 @@ internal interface ISyncNamespacesService : ILanguageService /// This will update documents in the specified projects so that their namespace matches the RootNamespace /// and their relative folder path. /// - Task SyncNamespacesAsync(ImmutableArray projects, CancellationToken cancellationToken); + Task SyncNamespacesAsync(ImmutableArray projects, CodeActionOptions options, CancellationToken cancellationToken); } } diff --git a/src/VisualStudio/Core/Def/Implementation/SyncNamespaces/SyncNamespacesCommandHandler.cs b/src/VisualStudio/Core/Def/Implementation/SyncNamespaces/SyncNamespacesCommandHandler.cs index 768fb57a1bf65..431282f6f70d9 100644 --- a/src/VisualStudio/Core/Def/Implementation/SyncNamespaces/SyncNamespacesCommandHandler.cs +++ b/src/VisualStudio/Core/Def/Implementation/SyncNamespaces/SyncNamespacesCommandHandler.cs @@ -8,7 +8,9 @@ using System.Composition; using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.SyncNamespaces; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; @@ -25,16 +27,19 @@ internal sealed class SyncNamespacesCommandHandler { private readonly VisualStudioWorkspace _workspace; private readonly IUIThreadOperationExecutor _threadOperationExecutor; + private readonly IGlobalOptionService _globalOptions; private IServiceProvider? _serviceProvider; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public SyncNamespacesCommandHandler( IUIThreadOperationExecutor threadOperationExecutor, - VisualStudioWorkspace workspace) + VisualStudioWorkspace workspace, + IGlobalOptionService globalOptions) { _threadOperationExecutor = threadOperationExecutor; _workspace = workspace; + _globalOptions = globalOptions; } public void Initialize(IServiceProvider serviceProvider) @@ -120,11 +125,12 @@ private void SyncNamespaces(ImmutableArray projects) } var syncService = projects[0].GetRequiredLanguageService(); + var options = _globalOptions.GetCodeActionOptions(projects[0].Language); Solution? solution = null; var status = _threadOperationExecutor.Execute(ServicesVSResources.Sync_Namespaces, ServicesVSResources.Updating_namspaces, allowCancellation: true, showProgress: true, (operationContext) => { - solution = ThreadHelper.JoinableTaskFactory.Run(() => syncService.SyncNamespacesAsync(projects, operationContext.UserCancellationToken)); + solution = ThreadHelper.JoinableTaskFactory.Run(() => syncService.SyncNamespacesAsync(projects, options, operationContext.UserCancellationToken)); }); if (status != UIThreadOperationStatus.Canceled && solution is not null) From d17769e45cc15297b75450600eab482ef7c2e5e3 Mon Sep 17 00:00:00 2001 From: tmat Date: Thu, 17 Feb 2022 09:32:23 -0800 Subject: [PATCH 7/7] Fix --- .../SyncNamespaces/SyncNamespacesServiceTests.vb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/EditorFeatures/Test2/SyncNamespaces/SyncNamespacesServiceTests.vb b/src/EditorFeatures/Test2/SyncNamespaces/SyncNamespacesServiceTests.vb index 4f9e3cb964cc5..19e4ca34cac16 100644 --- a/src/EditorFeatures/Test2/SyncNamespaces/SyncNamespacesServiceTests.vb +++ b/src/EditorFeatures/Test2/SyncNamespaces/SyncNamespacesServiceTests.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports System.Threading +Imports Microsoft.CodeAnalysis.CodeActions Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Host Imports Microsoft.CodeAnalysis.SyncNamespaces @@ -39,7 +40,7 @@ namespace Test.Namespace.App Dim document = project.Documents.Single() Dim syncService = project.GetLanguageService(Of ISyncNamespacesService)() - Dim newSolution = Await syncService.SyncNamespacesAsync(ImmutableArray.Create(project), CancellationToken.None) + Dim newSolution = Await syncService.SyncNamespacesAsync(ImmutableArray.Create(project), CodeActionOptions.Default, CancellationToken.None) Dim solutionChanges = workspace.CurrentSolution.GetChanges(newSolution) @@ -75,7 +76,7 @@ namespace Test Dim document = project.Documents.Single() Dim syncService = project.GetLanguageService(Of ISyncNamespacesService)() - Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CancellationToken.None) + Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CodeActionOptions.Default, CancellationToken.None) Dim solutionChanges = workspace.CurrentSolution.GetChanges(newSolution) Dim projectChanges = solutionChanges.GetProjectChanges().Single() @@ -132,7 +133,7 @@ namespace Test2.Namespace.App Dim project = projects(0) Dim syncService = project.GetLanguageService(Of ISyncNamespacesService)() - Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CancellationToken.None) + Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CodeActionOptions.Default, CancellationToken.None) Dim solutionChanges = workspace.CurrentSolution.GetChanges(newSolution) @@ -186,7 +187,7 @@ namespace Test2.Namespace.App Dim document = project.Documents.Single() Dim syncService = project.GetLanguageService(Of ISyncNamespacesService)() - Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CancellationToken.None) + Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CodeActionOptions.Default, CancellationToken.None) Dim solutionChanges = workspace.CurrentSolution.GetChanges(newSolution) Dim projectChanges = solutionChanges.GetProjectChanges().Single() @@ -251,7 +252,7 @@ namespace Test2.Namespace Dim document2 = project2.Documents.Single() Dim syncService = project.GetLanguageService(Of ISyncNamespacesService)() - Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CancellationToken.None) + Dim newSolution = Await syncService.SyncNamespacesAsync(projects, CodeActionOptions.Default, CancellationToken.None) Dim solutionChanges = workspace.CurrentSolution.GetChanges(newSolution) Dim projectChanges = solutionChanges.GetProjectChanges().ToImmutableArray()