Skip to content

Commit 9811ca2

Browse files
remove usage of WaitAndGetResult
1 parent e075094 commit 9811ca2

File tree

1 file changed

+91
-106
lines changed

1 file changed

+91
-106
lines changed

src/VisualStudio/Core/Def/TableDataSource/Suppression/VisualStudioSuppressionFixService.cs

Lines changed: 91 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
using Microsoft.CodeAnalysis.Host.Mef;
2121
using Microsoft.CodeAnalysis.Options;
2222
using Microsoft.CodeAnalysis.Progress;
23-
using Microsoft.CodeAnalysis.Shared.Extensions;
2423
using Microsoft.CodeAnalysis.Shared.TestHooks;
2524
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
2625
using Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource;
@@ -40,54 +39,33 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Suppression;
4039
/// </summary>
4140
[Export(typeof(IVisualStudioSuppressionFixService))]
4241
[Export(typeof(VisualStudioSuppressionFixService))]
43-
internal sealed class VisualStudioSuppressionFixService : IVisualStudioSuppressionFixService
42+
[method: ImportingConstructor]
43+
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
44+
internal sealed class VisualStudioSuppressionFixService(
45+
IThreadingContext threadingContext,
46+
VisualStudioWorkspaceImpl workspace,
47+
IDiagnosticAnalyzerService diagnosticService,
48+
ICodeFixService codeFixService,
49+
ICodeActionEditHandlerService editHandlerService,
50+
VisualStudioDiagnosticListSuppressionStateService suppressionStateService,
51+
IUIThreadOperationExecutor uiThreadOperationExecutor,
52+
IVsHierarchyItemManager vsHierarchyItemManager,
53+
IAsynchronousOperationListenerProvider listenerProvider) : IVisualStudioSuppressionFixService
4454
{
45-
private readonly IThreadingContext _threadingContext;
46-
private readonly VisualStudioWorkspaceImpl _workspace;
47-
private readonly IAsynchronousOperationListener _listener;
48-
private readonly IDiagnosticAnalyzerService _diagnosticService;
49-
private readonly ExternalErrorDiagnosticUpdateSource _buildErrorDiagnosticService;
50-
private readonly ICodeFixService _codeFixService;
51-
private readonly IFixMultipleOccurrencesService _fixMultipleOccurencesService;
52-
private readonly ICodeActionEditHandlerService _editHandlerService;
53-
private readonly VisualStudioDiagnosticListSuppressionStateService _suppressionStateService;
54-
private readonly IUIThreadOperationExecutor _uiThreadOperationExecutor;
55-
private readonly IVsHierarchyItemManager _vsHierarchyItemManager;
56-
private readonly IHierarchyItemToProjectIdMap _projectMap;
57-
private readonly IGlobalOptionService _globalOptions;
55+
private readonly IThreadingContext _threadingContext = threadingContext;
56+
private readonly VisualStudioWorkspaceImpl _workspace = workspace;
57+
private readonly IAsynchronousOperationListener _listener = listenerProvider.GetListener(FeatureAttribute.ErrorList);
58+
private readonly IDiagnosticAnalyzerService _diagnosticService = diagnosticService;
59+
private readonly ICodeFixService _codeFixService = codeFixService;
60+
private readonly IFixMultipleOccurrencesService _fixMultipleOccurencesService = workspace.Services.GetRequiredService<IFixMultipleOccurrencesService>();
61+
private readonly ICodeActionEditHandlerService _editHandlerService = editHandlerService;
62+
private readonly VisualStudioDiagnosticListSuppressionStateService _suppressionStateService = suppressionStateService;
63+
private readonly IUIThreadOperationExecutor _uiThreadOperationExecutor = uiThreadOperationExecutor;
64+
private readonly IVsHierarchyItemManager _vsHierarchyItemManager = vsHierarchyItemManager;
65+
private readonly IHierarchyItemToProjectIdMap _projectMap = workspace.Services.GetRequiredService<IHierarchyItemToProjectIdMap>();
5866

5967
private IWpfTableControl? _tableControl;
6068

61-
[ImportingConstructor]
62-
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
63-
public VisualStudioSuppressionFixService(
64-
IThreadingContext threadingContext,
65-
SVsServiceProvider serviceProvider,
66-
VisualStudioWorkspaceImpl workspace,
67-
IDiagnosticAnalyzerService diagnosticService,
68-
ICodeFixService codeFixService,
69-
ICodeActionEditHandlerService editHandlerService,
70-
VisualStudioDiagnosticListSuppressionStateService suppressionStateService,
71-
IUIThreadOperationExecutor uiThreadOperationExecutor,
72-
IVsHierarchyItemManager vsHierarchyItemManager,
73-
IAsynchronousOperationListenerProvider listenerProvider,
74-
IGlobalOptionService globalOptions)
75-
{
76-
_threadingContext = threadingContext;
77-
_workspace = workspace;
78-
_diagnosticService = diagnosticService;
79-
_buildErrorDiagnosticService = workspace.ExternalErrorDiagnosticUpdateSource;
80-
_codeFixService = codeFixService;
81-
_suppressionStateService = suppressionStateService;
82-
_editHandlerService = editHandlerService;
83-
_uiThreadOperationExecutor = uiThreadOperationExecutor;
84-
_vsHierarchyItemManager = vsHierarchyItemManager;
85-
_fixMultipleOccurencesService = workspace.Services.GetRequiredService<IFixMultipleOccurrencesService>();
86-
_projectMap = workspace.Services.GetRequiredService<IHierarchyItemToProjectIdMap>();
87-
_listener = listenerProvider.GetListener(FeatureAttribute.ErrorList);
88-
_globalOptions = globalOptions;
89-
}
90-
9169
public async Task InitializeAsync(IAsyncServiceProvider serviceProvider)
9270
{
9371
var errorList = await serviceProvider.GetServiceAsync<SVsErrorList, IErrorList>(_threadingContext.JoinableTaskFactory, throwOnFailure: false).ConfigureAwait(false);
@@ -96,44 +74,57 @@ public async Task InitializeAsync(IAsyncServiceProvider serviceProvider)
9674

9775
public bool AddSuppressions(IVsHierarchy? projectHierarchy)
9876
{
99-
if (_tableControl == null)
77+
return _threadingContext.JoinableTaskFactory.Run(async () =>
10078
{
101-
return false;
102-
}
79+
if (_tableControl == null)
80+
return false;
10381

104-
var shouldFixInProject = GetShouldFixInProjectDelegate(_vsHierarchyItemManager, _projectMap, projectHierarchy);
82+
var shouldFixInProject = GetShouldFixInProjectDelegate(_vsHierarchyItemManager, _projectMap, projectHierarchy);
10583

106-
// Apply suppressions fix in global suppressions file for non-compiler diagnostics and
107-
// in source only for compiler diagnostics.
108-
var diagnosticsToFix = GetDiagnosticsToFix(selectedEntriesOnly: false, isAddSuppression: true);
109-
if (!ApplySuppressionFix(diagnosticsToFix, shouldFixInProject, filterStaleDiagnostics: false, isAddSuppression: true, isSuppressionInSource: false, onlyCompilerDiagnostics: false, showPreviewChangesDialog: false))
110-
{
111-
return false;
112-
}
84+
// Apply suppressions fix in global suppressions file for non-compiler diagnostics and
85+
// in source only for compiler diagnostics.
86+
var diagnosticsToFix = await GetDiagnosticsToFixAsync(selectedEntriesOnly: false, isAddSuppression: true).ConfigureAwait(true);
87+
if (!ApplySuppressionFix(diagnosticsToFix, shouldFixInProject, filterStaleDiagnostics: false, isAddSuppression: true, isSuppressionInSource: false, onlyCompilerDiagnostics: false, showPreviewChangesDialog: false))
88+
return false;
11389

114-
return ApplySuppressionFix(diagnosticsToFix, shouldFixInProject, filterStaleDiagnostics: false, isAddSuppression: true, isSuppressionInSource: true, onlyCompilerDiagnostics: true, showPreviewChangesDialog: false);
90+
return ApplySuppressionFix(diagnosticsToFix, shouldFixInProject, filterStaleDiagnostics: false, isAddSuppression: true, isSuppressionInSource: true, onlyCompilerDiagnostics: true, showPreviewChangesDialog: false);
91+
});
11592
}
11693

11794
public bool AddSuppressions(bool selectedErrorListEntriesOnly, bool suppressInSource, IVsHierarchy? projectHierarchy)
11895
{
119-
if (_tableControl == null)
96+
return _threadingContext.JoinableTaskFactory.Run(async () =>
12097
{
121-
return false;
122-
}
123-
124-
var shouldFixInProject = GetShouldFixInProjectDelegate(_vsHierarchyItemManager, _projectMap, projectHierarchy);
125-
return ApplySuppressionFix(shouldFixInProject, selectedErrorListEntriesOnly, isAddSuppression: true, isSuppressionInSource: suppressInSource, onlyCompilerDiagnostics: false, showPreviewChangesDialog: true);
98+
if (_tableControl == null)
99+
return false;
100+
101+
var shouldFixInProject = GetShouldFixInProjectDelegate(_vsHierarchyItemManager, _projectMap, projectHierarchy);
102+
return await ApplySuppressionFixAsync(
103+
shouldFixInProject,
104+
selectedErrorListEntriesOnly,
105+
isAddSuppression: true,
106+
isSuppressionInSource: suppressInSource,
107+
onlyCompilerDiagnostics: false,
108+
showPreviewChangesDialog: true).ConfigureAwait(true);
109+
});
126110
}
127111

128112
public bool RemoveSuppressions(bool selectedErrorListEntriesOnly, IVsHierarchy? projectHierarchy)
129113
{
130-
if (_tableControl == null)
114+
return _threadingContext.JoinableTaskFactory.Run(async () =>
131115
{
132-
return false;
133-
}
134-
135-
var shouldFixInProject = GetShouldFixInProjectDelegate(_vsHierarchyItemManager, _projectMap, projectHierarchy);
136-
return ApplySuppressionFix(shouldFixInProject, selectedErrorListEntriesOnly, isAddSuppression: false, isSuppressionInSource: false, onlyCompilerDiagnostics: false, showPreviewChangesDialog: true);
116+
if (_tableControl == null)
117+
return false;
118+
119+
var shouldFixInProject = GetShouldFixInProjectDelegate(_vsHierarchyItemManager, _projectMap, projectHierarchy);
120+
return await ApplySuppressionFixAsync(
121+
shouldFixInProject,
122+
selectedErrorListEntriesOnly,
123+
isAddSuppression: false,
124+
isSuppressionInSource: false,
125+
onlyCompilerDiagnostics: false,
126+
showPreviewChangesDialog: true).ConfigureAwait(true);
127+
});
137128
}
138129

139130
private static Func<Project, bool> GetShouldFixInProjectDelegate(IVsHierarchyItemManager vsHierarchyItemManager, IHierarchyItemToProjectIdMap projectMap, IVsHierarchy? projectHierarchy)
@@ -157,38 +148,38 @@ private static string GetFixTitle(bool isAddSuppression)
157148
private static string GetWaitDialogMessage(bool isAddSuppression)
158149
=> isAddSuppression ? ServicesVSResources.Computing_suppressions_fix : ServicesVSResources.Computing_remove_suppressions_fix;
159150

160-
private IEnumerable<DiagnosticData>? GetDiagnosticsToFix(bool selectedEntriesOnly, bool isAddSuppression)
151+
private async Task<ImmutableHashSet<DiagnosticData>?> GetDiagnosticsToFixAsync(
152+
bool selectedEntriesOnly,
153+
bool isAddSuppression)
161154
{
162155
var diagnosticsToFix = ImmutableHashSet<DiagnosticData>.Empty;
163-
void computeDiagnosticsToFix(IUIThreadOperationContext context)
164-
{
165-
var cancellationToken = context.UserCancellationToken;
166156

167-
// If we are fixing selected diagnostics in error list, then get the diagnostics from error list entry
157+
var result = await InvokeWithWaitDialogAsync(async cancellationToken =>
158+
{ // If we are fixing selected diagnostics in error list, then get the diagnostics from error list entry
168159
// snapshots. Otherwise, get all diagnostics from the diagnostic service.
169-
var diagnosticsToFixTask = selectedEntriesOnly
170-
? _suppressionStateService.GetSelectedItemsAsync(isAddSuppression, cancellationToken)
171-
: Task.FromResult<ImmutableArray<DiagnosticData>>([]);
160+
var diagnosticsToFixArray = selectedEntriesOnly
161+
? await _suppressionStateService.GetSelectedItemsAsync(isAddSuppression, cancellationToken).ConfigureAwait(true)
162+
: [];
172163

173-
diagnosticsToFix = diagnosticsToFixTask.WaitAndGetResult(cancellationToken).ToImmutableHashSet();
174-
}
164+
diagnosticsToFix = diagnosticsToFixArray.ToImmutableHashSet();
175165

176-
var title = GetFixTitle(isAddSuppression);
177-
var waitDialogMessage = GetWaitDialogMessage(isAddSuppression);
178-
var result = InvokeWithWaitDialog(computeDiagnosticsToFix, title, waitDialogMessage);
166+
}, GetFixTitle(isAddSuppression), GetWaitDialogMessage(isAddSuppression)).ConfigureAwait(true);
179167

180-
// Bail out if the user cancelled.
181168
if (result == UIThreadOperationStatus.Canceled)
182-
{
183169
return null;
184-
}
185170

186171
return diagnosticsToFix;
187172
}
188173

189-
private bool ApplySuppressionFix(Func<Project, bool> shouldFixInProject, bool selectedEntriesOnly, bool isAddSuppression, bool isSuppressionInSource, bool onlyCompilerDiagnostics, bool showPreviewChangesDialog)
174+
private async Task<bool> ApplySuppressionFixAsync(
175+
Func<Project, bool> shouldFixInProject,
176+
bool selectedEntriesOnly,
177+
bool isAddSuppression,
178+
bool isSuppressionInSource,
179+
bool onlyCompilerDiagnostics,
180+
bool showPreviewChangesDialog)
190181
{
191-
var diagnosticsToFix = GetDiagnosticsToFix(selectedEntriesOnly, isAddSuppression);
182+
var diagnosticsToFix = await GetDiagnosticsToFixAsync(selectedEntriesOnly, isAddSuppression).ConfigureAwait(true);
192183
return ApplySuppressionFix(diagnosticsToFix, shouldFixInProject, selectedEntriesOnly, isAddSuppression, isSuppressionInSource, onlyCompilerDiagnostics, showPreviewChangesDialog);
193184
}
194185

@@ -395,28 +386,22 @@ private static IEnumerable<DiagnosticData> FilterDiagnostics(IEnumerable<Diagnos
395386
}
396387
}
397388

398-
private UIThreadOperationStatus InvokeWithWaitDialog(
399-
Action<IUIThreadOperationContext> action, string waitDialogTitle, string waitDialogMessage)
389+
private async Task<UIThreadOperationStatus> InvokeWithWaitDialogAsync(
390+
Func<CancellationToken, Task> action, string waitDialogTitle, string waitDialogMessage)
400391
{
392+
using var waitContext = _uiThreadOperationExecutor.BeginExecute(waitDialogTitle, waitDialogMessage, allowCancellation: true, showProgress: true);
393+
401394
var cancelled = false;
402-
var result = _uiThreadOperationExecutor.Execute(
403-
waitDialogTitle,
404-
waitDialogMessage,
405-
allowCancellation: true,
406-
showProgress: true,
407-
action: waitContext =>
408-
{
409-
try
410-
{
411-
action(waitContext);
412-
}
413-
catch (OperationCanceledException)
414-
{
415-
cancelled = true;
416-
}
417-
});
395+
try
396+
{
397+
await action(waitContext.UserCancellationToken).ConfigureAwait(true);
398+
}
399+
catch (OperationCanceledException)
400+
{
401+
cancelled = true;
402+
}
418403

419-
return cancelled ? UIThreadOperationStatus.Canceled : result;
404+
return cancelled ? UIThreadOperationStatus.Canceled : UIThreadOperationStatus.Completed;
420405
}
421406

422407
private static ImmutableDictionary<Document, ImmutableArray<Diagnostic>> GetDocumentDiagnosticsMappedToNewSolution(ImmutableDictionary<Document, ImmutableArray<Diagnostic>> documentDiagnosticsToFixMap, Solution newSolution, string language)

0 commit comments

Comments
 (0)