diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs b/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs index 71a7bb34c8fca..b8c77992aaaf6 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/AsyncSuggestedActionsSource.cs @@ -104,6 +104,7 @@ private async Task GetSuggestedActionsWorkerAsync( { VisualStudio.Utilities.DefaultOrderings.Highest => CodeActionRequestPriority.High, VisualStudio.Utilities.DefaultOrderings.Default => CodeActionRequestPriority.Normal, + VisualStudio.Utilities.DefaultOrderings.Lowest => CodeActionRequestPriority.Low, _ => (CodeActionRequestPriority?)null, }; @@ -116,7 +117,7 @@ private async Task GetSuggestedActionsWorkerAsync( state, requestedActionCategories, document, range, selection, addOperationScope: _ => null, - includeSuppressionFixes: priority.Value == CodeActionRequestPriority.Normal, + includeSuppressionFixes: priority.Value == CodeActionRequestPriority.Low, priority.Value, currentActionCount, cancellationToken).WithCancellation(cancellationToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs index 8bd8d132fbc6f..bd231cc8ee467 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs @@ -329,6 +329,13 @@ protected static Task> GetRefactorings return SpecializedTasks.EmptyImmutableArray(); } + // 'CodeActionRequestPriority.Low' is reserved for suppression/configuration code fixes. + // No code refactoring should have this request priority. + if (priority == CodeActionRequestPriority.Low) + { + return SpecializedTasks.EmptyImmutableArray(); + } + // If we are computing refactorings outside the 'Refactoring' context, i.e. for example, from the lightbulb under a squiggle or selection, // then we want to filter out refactorings outside the selection span. var filterOutsideSelection = !requestedActionCategories.Contains(PredefinedSuggestedActionCategoryNames.Refactoring); diff --git a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSourceProvider.cs b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSourceProvider.cs index e8a5212b44ca4..7add8d08ca957 100644 --- a/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSourceProvider.cs +++ b/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSourceProvider.cs @@ -33,6 +33,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions [Order] [SuggestedActionPriority(DefaultOrderings.Highest)] [SuggestedActionPriority(DefaultOrderings.Default)] + [SuggestedActionPriority(DefaultOrderings.Lowest)] internal partial class SuggestedActionsSourceProvider : ISuggestedActionsSourceProvider { private static readonly Guid s_CSharpSourceGuid = new Guid("b967fea8-e2c3-4984-87d4-71a38f49e16a"); diff --git a/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs b/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs index 07bcb195d2f42..a1248b8d0024d 100644 --- a/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs +++ b/src/EditorFeatures/Test/CodeFixes/CodeFixServiceTests.cs @@ -124,6 +124,40 @@ public async Task TestGetFixesAsyncHasNoDuplicateConfigurationActions() } } + [Fact, WorkItem(56843, "https://github.com/dotnet/roslyn/issues/56843")] + public async Task TestGetFixesAsyncForFixableAndNonFixableAnalyzersAsync() + { + var codeFix = new MockFixer(); + var analyzerWithFix = new MockAnalyzerReference.MockDiagnosticAnalyzer(); + Assert.Equal(codeFix.FixableDiagnosticIds.Single(), analyzerWithFix.SupportedDiagnostics.Single().Id); + + var analyzerWithoutFix = new MockAnalyzerReference.MockDiagnosticAnalyzer("AnalyzerWithoutFixId", "Category"); + var analyzers = ImmutableArray.Create(analyzerWithFix, analyzerWithoutFix); + var analyzerReference = new MockAnalyzerReference(codeFix, analyzers); + + // Verify no callbacks received at initialization. + Assert.False(analyzerWithFix.ReceivedCallback); + Assert.False(analyzerWithoutFix.ReceivedCallback); + + var tuple = ServiceSetup(codeFix, includeConfigurationFixProviders: true); + using var workspace = tuple.workspace; + GetDocumentAndExtensionManager(tuple.analyzerService, workspace, out var document, out var extensionManager, analyzerReference); + + // Verify only analyzerWithFix is executed when GetFixesAsync is invoked with 'CodeActionRequestPriority.Normal'. + _ = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0), + includeConfigurationFixes: false, priority: CodeActionRequestPriority.Normal, isBlocking: false, + addOperationScope: _ => null, cancellationToken: CancellationToken.None); + Assert.True(analyzerWithFix.ReceivedCallback); + Assert.False(analyzerWithoutFix.ReceivedCallback); + + // Verify both analyzerWithFix and analyzerWithoutFix are executed when GetFixesAsync is invoked with 'CodeActionRequestPriority.Low'. + _ = await tuple.codeFixService.GetFixesAsync(document, TextSpan.FromBounds(0, 0), + includeConfigurationFixes: true, priority: CodeActionRequestPriority.Low, isBlocking: false, + addOperationScope: _ => null, cancellationToken: CancellationToken.None); + Assert.True(analyzerWithFix.ReceivedCallback); + Assert.True(analyzerWithoutFix.ReceivedCallback); + } + [Fact] public async Task TestGetCodeFixWithExceptionInRegisterMethod_Diagnostic() { @@ -387,6 +421,8 @@ public MockDiagnosticAnalyzer() { } + public bool ReceivedCallback { get; private set; } + private static ImmutableArray CreateSupportedDiagnostics(ImmutableArray<(string id, string category)> reportedDiagnosticIdsWithCategories) { var builder = ArrayBuilder.GetInstance(); @@ -405,6 +441,8 @@ public override void Initialize(AnalysisContext context) { context.RegisterSyntaxTreeAction(c => { + this.ReceivedCallback = true; + foreach (var descriptor in SupportedDiagnostics) { c.ReportDiagnostic(Diagnostic.Create(descriptor, c.Tree.GetLocation(TextSpan.FromBounds(0, 0)))); diff --git a/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs b/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs index 42bdddb4a6613..b6ea7ea7b431f 100644 --- a/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs +++ b/src/EditorFeatures/Test/EditAndContinue/Helpers/MockDiagnosticAnalyzerService.cs @@ -44,6 +44,9 @@ public Task> GetDiagnosticsForIdsAsync(Solution s public Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, string? diagnosticId = null, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default) + => throw new NotImplementedException(); + public Task> GetProjectDiagnosticsForIdsAsync(Solution solution, ProjectId? projectId = null, ImmutableHashSet? diagnosticIds = null, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) => throw new NotImplementedException(); diff --git a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs index 78cc3ef162598..827fb7d8d5b6b 100644 --- a/src/Features/Core/Portable/CodeFixes/CodeFixService.cs +++ b/src/Features/Core/Portable/CodeFixes/CodeFixService.cs @@ -172,8 +172,12 @@ public async Task> GetFixesAsync( // invariant: later code gathers & runs CodeFixProviders for diagnostics with one identical diagnostics span (that gets set later as CodeFixCollection's TextSpan) // order diagnostics by span. SortedDictionary>? aggregatedDiagnostics = null; + + // Only execute analyzers with fixable diagnostics for 'CodeActionPriorityRequest.Normal' + var shouldIncludeDiagnostic = priority == CodeActionRequestPriority.Normal ? GetFixableDiagnosticFilter(document) : null; + var diagnostics = await _diagnosticService.GetDiagnosticsForSpanAsync( - document, range, diagnosticId: null, includeConfigurationFixes, priority, addOperationScope, cancellationToken).ConfigureAwait(false); + document, range, shouldIncludeDiagnostic, includeConfigurationFixes, priority, addOperationScope, cancellationToken).ConfigureAwait(false); foreach (var diagnostic in diagnostics) { if (diagnostic.IsSuppressed) @@ -196,11 +200,16 @@ public async Task> GetFixesAsync( // append fixes for all diagnostics with the same diagnostics span using var resultDisposer = ArrayBuilder.GetInstance(out var result); - foreach (var spanAndDiagnostic in aggregatedDiagnostics) + + // 'CodeActionRequestPriority.Low' is used when the client only wants suppression/configuration fixes. + if (priority != CodeActionRequestPriority.Low) { - await AppendFixesAsync( - document, spanAndDiagnostic.Key, spanAndDiagnostic.Value, fixAllForInSpan: false, - priority, isBlocking, result, addOperationScope, cancellationToken).ConfigureAwait(false); + foreach (var spanAndDiagnostic in aggregatedDiagnostics) + { + await AppendFixesAsync( + document, spanAndDiagnostic.Key, spanAndDiagnostic.Value, fixAllForInSpan: false, + priority, isBlocking, result, addOperationScope, cancellationToken).ConfigureAwait(false); + } } if (result.Count > 0 && TryGetWorkspaceFixersPriorityMap(document, out var fixersForLanguage)) @@ -231,6 +240,14 @@ await AppendConfigurationsAsync( return result.ToImmutable(); } + private Func GetFixableDiagnosticFilter(Document document) + { + var hasWorkspaceFixers = TryGetWorkspaceFixersMap(document, out var fixerMap); + var projectFixersMap = GetProjectFixers(document.Project); + + return id => hasWorkspaceFixers && fixerMap!.Value.ContainsKey(id) || projectFixersMap.ContainsKey(id); + } + public async Task GetDocumentFixAllForIdInSpanAsync(Document document, TextSpan range, string diagnosticId, CancellationToken cancellationToken) { var diagnostics = (await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, diagnosticId, includeSuppressedDiagnostics: false, cancellationToken: cancellationToken).ConfigureAwait(false)).ToList(); diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs index d62a7d90968b8..4f58c1dd5f638 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs @@ -71,7 +71,7 @@ public Task TryAppendDiagnosticsForSpanAsync(Document document, TextSpan r { // always make sure that analyzer is called on background thread. return Task.Run(() => analyzer.TryAppendDiagnosticsForSpanAsync( - document, range, diagnostics, diagnosticId: null, includeSuppressedDiagnostics, CodeActionRequestPriority.None, blockForData: false, addOperationScope: null, cancellationToken), cancellationToken); + document, range, diagnostics, shouldIncludeDiagnostic: null, includeSuppressedDiagnostics, CodeActionRequestPriority.None, blockForData: false, addOperationScope: null, cancellationToken), cancellationToken); } return SpecializedTasks.False; @@ -85,12 +85,26 @@ public Task> GetDiagnosticsForSpanAsync( CodeActionRequestPriority priority, Func? addOperationScope, CancellationToken cancellationToken) + { + Func? shouldIncludeDiagnostic = diagnosticId != null ? id => id == diagnosticId : null; + return GetDiagnosticsForSpanAsync(document, range, shouldIncludeDiagnostic, + includeSuppressedDiagnostics, priority, addOperationScope, cancellationToken); + } + + public Task> GetDiagnosticsForSpanAsync( + Document document, + TextSpan? range, + Func? shouldIncludeDiagnostic, + bool includeSuppressedDiagnostics, + CodeActionRequestPriority priority, + Func? addOperationScope, + CancellationToken cancellationToken) { if (_map.TryGetValue(document.Project.Solution.Workspace, out var analyzer)) { // always make sure that analyzer is called on background thread. return Task.Run(() => analyzer.GetDiagnosticsForSpanAsync( - document, range, diagnosticId, includeSuppressedDiagnostics, priority, + document, range, shouldIncludeDiagnostic, includeSuppressedDiagnostics, priority, blockForData: true, addOperationScope, cancellationToken), cancellationToken); } diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs index e08463c9f9d7c..be8c36532275e 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs @@ -21,20 +21,20 @@ namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2 internal partial class DiagnosticIncrementalAnalyzer { public async Task TryAppendDiagnosticsForSpanAsync( - Document document, TextSpan? range, ArrayBuilder result, string? diagnosticId, + Document document, TextSpan? range, ArrayBuilder result, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics, CodeActionRequestPriority priority, bool blockForData, Func? addOperationScope, CancellationToken cancellationToken) { var getter = await LatestDiagnosticsForSpanGetter.CreateAsync( this, document, range, blockForData, addOperationScope, includeSuppressedDiagnostics, - priority, diagnosticId, cancellationToken).ConfigureAwait(false); + priority, shouldIncludeDiagnostic, cancellationToken).ConfigureAwait(false); return await getter.TryGetAsync(result, cancellationToken).ConfigureAwait(false); } public async Task> GetDiagnosticsForSpanAsync( Document document, TextSpan? range, - string? diagnosticId, + Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics, CodeActionRequestPriority priority, bool blockForData, @@ -43,7 +43,7 @@ public async Task> GetDiagnosticsForSpanAsync( { using var _ = ArrayBuilder.GetInstance(out var list); var result = await TryAppendDiagnosticsForSpanAsync( - document, range, list, diagnosticId, includeSuppressedDiagnostics, + document, range, list, shouldIncludeDiagnostic, includeSuppressedDiagnostics, priority, blockForData, addOperationScope, cancellationToken).ConfigureAwait(false); Debug.Assert(result); return list.ToImmutable(); @@ -64,7 +64,7 @@ private sealed class LatestDiagnosticsForSpanGetter private readonly bool _blockForData; private readonly bool _includeSuppressedDiagnostics; private readonly CodeActionRequestPriority _priority; - private readonly string? _diagnosticId; + private readonly Func? _shouldIncludeDiagnostic; private readonly Func? _addOperationScope; private delegate Task> DiagnosticsGetterAsync(DiagnosticAnalyzer analyzer, DocumentAnalysisExecutor executor, CancellationToken cancellationToken); @@ -77,22 +77,22 @@ public static async Task CreateAsync( Func? addOperationScope, bool includeSuppressedDiagnostics, CodeActionRequestPriority priority, - string? diagnosticId, + Func? shouldIncludeDiagnostic, CancellationToken cancellationToken) { var stateSets = owner._stateManager .GetOrCreateStateSets(document.Project).Where(s => !owner.DiagnosticAnalyzerInfoCache.IsAnalyzerSuppressed(s.Analyzer, document.Project)); // filter to specific diagnostic it is looking for - if (diagnosticId != null) + if (shouldIncludeDiagnostic != null) { - stateSets = stateSets.Where(s => owner.DiagnosticAnalyzerInfoCache.GetDiagnosticDescriptors(s.Analyzer).Any(d => d.Id == diagnosticId)).ToList(); + stateSets = stateSets.Where(s => owner.DiagnosticAnalyzerInfoCache.GetDiagnosticDescriptors(s.Analyzer).Any(d => shouldIncludeDiagnostic(d.Id))).ToList(); } var compilationWithAnalyzers = await CreateCompilationWithAnalyzersAsync(document.Project, stateSets, includeSuppressedDiagnostics, cancellationToken).ConfigureAwait(false); return new LatestDiagnosticsForSpanGetter( - owner, compilationWithAnalyzers, document, stateSets, diagnosticId, range, + owner, compilationWithAnalyzers, document, stateSets, shouldIncludeDiagnostic, range, blockForData, addOperationScope, includeSuppressedDiagnostics, priority); } @@ -101,7 +101,7 @@ private LatestDiagnosticsForSpanGetter( CompilationWithAnalyzers? compilationWithAnalyzers, Document document, IEnumerable stateSets, - string? diagnosticId, + Func? shouldIncludeDiagnostic, TextSpan? range, bool blockForData, Func? addOperationScope, @@ -112,7 +112,7 @@ private LatestDiagnosticsForSpanGetter( _compilationWithAnalyzers = compilationWithAnalyzers; _document = document; _stateSets = stateSets; - _diagnosticId = diagnosticId; + _shouldIncludeDiagnostic = shouldIncludeDiagnostic; _range = range; _blockForData = blockForData; _addOperationScope = addOperationScope; @@ -243,6 +243,11 @@ private bool MatchesPriority(DiagnosticAnalyzer analyzer) if (_priority == CodeActionRequestPriority.None) return true; + // 'CodeActionRequestPriority.Low' is used for suppression/configuration fixes, + // which requires all analyzer diagnostics. + if (_priority == CodeActionRequestPriority.Low) + return true; + // The compiler analyzer always counts for any priority. It's diagnostics may be fixed // by high pri or normal pri fixers. if (analyzer.IsCompilerAnalyzer()) @@ -259,7 +264,7 @@ private bool ShouldInclude(DiagnosticData diagnostic) return diagnostic.DocumentId == _document.Id && (_range == null || _range.Value.IntersectsWith(diagnostic.GetTextSpan())) && (_includeSuppressedDiagnostics || !diagnostic.IsSuppressed) - && (_diagnosticId == null || _diagnosticId == diagnostic.Id); + && (_shouldIncludeDiagnostic == null || _shouldIncludeDiagnostic(diagnostic.Id)); } } } diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index a468253d1771c..e0dd1b6268f0b 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -86,6 +86,16 @@ internal interface IDiagnosticAnalyzerService /// /// Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, string? diagnosticId = null, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default); + + /// + /// Return up to date diagnostics for the given span for the document + /// + /// This can be expensive since it is force analyzing diagnostics if it doesn't have up-to-date one yet. + /// Predicate filters out analyzers from execution if + /// none of its reported diagnostics should be included in the result. + /// + /// + Task> GetDiagnosticsForSpanAsync(Document document, TextSpan? range, Func? shouldIncludeDiagnostic, bool includeSuppressedDiagnostics = false, CodeActionRequestPriority priority = CodeActionRequestPriority.None, Func? addOperationScope = null, CancellationToken cancellationToken = default); } internal static class IDiagnosticAnalyzerServiceExtensions diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index faaef5d0b3d92..1f5c2a0bcc06a 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -525,6 +525,10 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Return SpecializedTasks.EmptyImmutableArray(Of DiagnosticData) End Function + Public Function GetDiagnosticsForSpanAsync(document As Document, range As TextSpan?, shouldIncludeDiagnostic As Func(Of String, Boolean), Optional includeSuppressedDiagnostics As Boolean = False, Optional priority As CodeActionRequestPriority = CodeActionRequestPriority.None, Optional addOperationScope As Func(Of String, IDisposable) = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticAnalyzerService.GetDiagnosticsForSpanAsync + Return SpecializedTasks.EmptyImmutableArray(Of DiagnosticData) + End Function + Public Function TryAppendDiagnosticsForSpanAsync(document As Document, range As TextSpan, diagnostics As ArrayBuilder(Of DiagnosticData), Optional includeSuppressedDiagnostics As Boolean = False, Optional cancellationToken As CancellationToken = Nothing) As Task(Of Boolean) Implements IDiagnosticAnalyzerService.TryAppendDiagnosticsForSpanAsync Return Task.FromResult(False) End Function diff --git a/src/Workspaces/Core/Portable/CodeFixes/CodeFixProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/CodeFixProvider.cs index 3c3e70d190c13..03f217c474d36 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/CodeFixProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/CodeFixProvider.cs @@ -45,6 +45,7 @@ internal CodeActionRequestPriority RequestPriority get { var priority = ComputeRequestPriority(); + // Note: CodeActionRequestPriority.Low is reserved for IConfigurationFixProvider. Contract.ThrowIfFalse(priority is CodeActionRequestPriority.Normal or CodeActionRequestPriority.High); return priority; } diff --git a/src/Workspaces/Core/Portable/CodeRefactorings/CodeRefactoringProvider.cs b/src/Workspaces/Core/Portable/CodeRefactorings/CodeRefactoringProvider.cs index d2eec59ff6f11..007d7be8ad0f7 100644 --- a/src/Workspaces/Core/Portable/CodeRefactorings/CodeRefactoringProvider.cs +++ b/src/Workspaces/Core/Portable/CodeRefactorings/CodeRefactoringProvider.cs @@ -27,6 +27,7 @@ internal CodeActionRequestPriority RequestPriority get { var priority = ComputeRequestPriority(); + // Note: CodeActionRequestPriority.Low is reserved for IConfigurationFixProvider. Contract.ThrowIfFalse(priority is CodeActionRequestPriority.Normal or CodeActionRequestPriority.High); return priority; } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeActions/CodeActionRequestPriority.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeActions/CodeActionRequestPriority.cs index 49ce82b69d797..44d251788d001 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeActions/CodeActionRequestPriority.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeActions/CodeActionRequestPriority.cs @@ -11,17 +11,24 @@ internal enum CodeActionRequestPriority { /// /// No priority specified, all refactoring, code fixes, and analyzers should be run. This is equivalent - /// to and combined. + /// to , and combined. /// None = 0, + /// + /// Only low priority suppression and configuration fix providers should be run. Specifically, + /// providers will be run. + /// + Low = 1, + /// /// Only normal priority refactoring, code fix providers should be run. Specifically, /// providers will be run when or /// is . s - /// will be run except for . + /// which can report at least one fixable diagnostic will be run. /// - Normal = 1, + Normal = 2, + /// /// Only high priority refactoring, code fix providers should be run. Specifically, /// providers will be run when or @@ -29,6 +36,6 @@ internal enum CodeActionRequestPriority /// The /// will be run. /// - High = 2, + High = 3, } }