static async Task FixAll(TextEditor editor, ValidCodeDiagnosticAction fix, FixAllProvider provider, DiagnosticAnalyzer diagnosticAnalyzer) { var diagnosticIds = diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id).ToImmutableHashSet(); var analyzers = new [] { diagnosticAnalyzer }.ToImmutableArray(); var fixAllDiagnosticProvider = new FixAllState.FixAllDiagnosticProvider( diagnosticIds, async(doc, diagnostics, token) => await GetDiagnosticsForDocument(analyzers, doc, diagnostics, token).ConfigureAwait(false), (Project arg1, bool arg2, ImmutableHashSet <string> arg3, CancellationToken arg4) => { return(Task.FromResult((IEnumerable <Diagnostic>) new Diagnostic [] { })); }); var ctx = new FixAllContext( editor.DocumentContext.AnalysisDocument, fix.Diagnostic.GetCodeFixProvider(), FixAllScope.Document, fix.CodeAction.EquivalenceKey, diagnosticIds, fixAllDiagnosticProvider, default(CancellationToken) ); var fixAll = await provider.GetFixAsync(ctx); using (var undo = editor.OpenUndoGroup()) { await CodeDiagnosticDescriptor.RunAction(editor.DocumentContext, fixAll, default(CancellationToken)); } }
private static FixAllState GetFixAllState( FixAllProvider fixAllProvider, IEnumerable <Diagnostic> diagnostics, CodeFixProvider fixer, TestDiagnosticAnalyzerDriver testDriver, Document document, FixAllScope scope, string equivalenceKey) { Assert.NotEmpty(diagnostics); if (scope == FixAllScope.Custom) { // Bulk fixing diagnostics in selected scope. var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePairUtil.Create(document, diagnostics.ToImmutableArray()))); return(FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, equivalenceKey)); } var diagnostic = diagnostics.First(); var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id); 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)); }
private static void WriteCodeFixProviders(IEnumerable <CodeFixProvider> fixers) { WriteLine(" CodeFixProviders:", Verbosity.Detailed); foreach (CodeFixProvider fixer in fixers.OrderBy(f => f.GetType(), TypeComparer.NamespaceThenName)) { Type type = fixer.GetType(); ExportCodeFixProviderAttribute attribute = type.GetCustomAttribute <ExportCodeFixProviderAttribute>(); WriteLine($" {type.FullName}", Verbosity.Detailed); if (ShouldWrite(Verbosity.Diagnostic)) { WriteLine($" Languages: {string.Join(", ", attribute.Languages.Select(f => GetShortLanguageName(f)).OrderBy(f => f))}", ConsoleColors.DarkGray, Verbosity.Diagnostic); WriteLine($" FixableDiagnosticIds: {string.Join(", ", fixer.FixableDiagnosticIds.Distinct().OrderBy(f => f))}", ConsoleColors.DarkGray, Verbosity.Diagnostic); Write(" FixAllProvider: ", ConsoleColors.DarkGray, Verbosity.Diagnostic); FixAllProvider fixAllProvider = fixer.GetFixAllProvider(); if (fixAllProvider != null) { WriteLine($"{fixAllProvider.GetType().FullName} ({string.Join(", ", fixAllProvider.GetSupportedFixAllScopes().Select(f => f.ToString()).OrderBy(f => f))})", ConsoleColors.DarkGray, Verbosity.Diagnostic); } else { WriteLine("-", ConsoleColors.DarkGray, Verbosity.Diagnostic); } } } }
private async Task <FixedResult> FixCodeAllDiagnostics(FixAllProvider fixAllProvider, CancellationToken cancellationToken) { var diagnosticsProvider = new DocumentSingleDiagnotsticProvider(diagnostics); var fixAllContext = new FixAllContext( document, codeFixProvider, FixAllScope.Document, await diagnosticsProvider.GetEquivalenceKeyAsync(codeFixProvider, document, cancellationToken).ConfigureAwait(false), DiagnosticIds, diagnosticsProvider, cancellationToken); var action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); if (action == null) { Console.WriteLine($"{DiagnosticId} : Code fix action did not exists : {document.FilePath}"); return(FixedResult.Empty); } var oldSolution = document.Project.Solution; var changedDocument = await ConvertCodeActionToChangedDocument(action, cancellationToken).ConfigureAwait(false); return(GetFixedChanges(oldSolution, changedDocument.Project.Solution)); }
private static async Task <(CodeAction, Document)> GetFixAsync( ImmutableArray <Diagnostic> diagnostics, DiagnosticDescriptor descriptor, CodeFixProvider fixer, Project project, CodeFixerOptions options, IFormatProvider formatProvider = null, CancellationToken cancellationToken = default) { if (diagnostics.Length == 1) { return(await GetFixAsync(diagnostics[0], fixer, project, options, formatProvider, cancellationToken).ConfigureAwait(false)); } FixAllProvider fixAllProvider = fixer.GetFixAllProvider(); if (fixAllProvider == null) { if (options.DiagnosticIdsFixableOneByOne.Contains(descriptor.Id)) { return(await GetFixAsync(diagnostics[0], fixer, project, options, formatProvider, cancellationToken).ConfigureAwait(false)); } WriteLine($" '{fixer.GetType().FullName}' does not have FixAllProvider", ConsoleColor.Yellow, Verbosity.Diagnostic); return(default);
private static void RunFixAllProvider(DiagnosticAnalyzer diagnosticAnalyzer, CodeFixProvider codeFixProvider, string codeFixTitle, FixAllProvider fixAllProvider, Document document, ParseOptions parseOption, string pathToExpected) { var currentDocument = document; List <Diagnostic> diagnostics; string actualCode; CalculateDiagnosticsAndCode(diagnosticAnalyzer, currentDocument, parseOption, out diagnostics, out actualCode); diagnostics.Should().NotBeEmpty(); var fixAllDiagnosticProvider = new FixAllDiagnosticProvider( codeFixProvider.FixableDiagnosticIds.ToImmutableHashSet(), (doc, ids, ct) => Task.FromResult( GetDiagnostics(currentDocument.Project.GetCompilationAsync(ct).Result, diagnosticAnalyzer)), null); var fixAllContext = new FixAllContext(currentDocument, codeFixProvider, FixAllScope.Document, codeFixTitle, codeFixProvider.FixableDiagnosticIds, fixAllDiagnosticProvider, CancellationToken.None); var codeActionToExecute = fixAllProvider.GetFixAsync(fixAllContext).Result; codeActionToExecute.Should().NotBeNull(); currentDocument = ApplyCodeFix(currentDocument, codeActionToExecute); CalculateDiagnosticsAndCode(diagnosticAnalyzer, currentDocument, parseOption, out diagnostics, out actualCode); actualCode.Should().Be(File.ReadAllText(pathToExpected)); }
static async Task FixAll(TextEditor editor, ValidCodeDiagnosticAction fix, FixAllProvider provider, DiagnosticAnalyzer diagnosticAnalyzer) { var diagnosticIds = diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id).ToImmutableHashSet(); var analyzers = new [] { diagnosticAnalyzer }.ToImmutableArray(); var dict = ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty; var doc = editor.DocumentContext.AnalysisDocument; var diagnostics = await GetDiagnosticsForDocument(analyzers, doc, diagnosticIds, CancellationToken.None); dict = dict.Add(doc, diagnostics); var fixAllDiagnosticProvider = new FixAllState.FixMultipleDiagnosticProvider(dict); var ctx = new FixAllContext( editor.DocumentContext.AnalysisDocument, fix.Diagnostic.GetCodeFixProvider(), FixAllScope.Document, fix.CodeAction.EquivalenceKey, diagnosticIds, fixAllDiagnosticProvider, default(CancellationToken) ); var fixAll = await provider.GetFixAsync(ctx); using (var undo = editor.OpenUndoGroup()) { await CodeDiagnosticDescriptor.RunAction(editor.DocumentContext, fixAll, default(CancellationToken)); } }
private static void RunFixAllProvider(DiagnosticAnalyzer diagnosticAnalyzer, CodeFixProvider codeFixProvider, string codeFixTitle, FixAllProvider fixAllProvider, Document document, ParseOptions parseOption, string pathToExpected) { var currentDocument = document; CalculateDiagnosticsAndCode(diagnosticAnalyzer, currentDocument, parseOption, out var diagnostics, out var actualCode); diagnostics.Should().NotBeEmpty(); var fixAllDiagnosticProvider = new FixAllDiagnosticProvider( codeFixProvider.FixableDiagnosticIds.ToHashSet(), (doc, ids, ct) => Task.FromResult( DiagnosticVerifier.GetDiagnostics( currentDocument.Project.GetCompilationAsync(ct).Result, diagnosticAnalyzer, CompilationErrorBehavior.Ignore)), // ToDo: Is that the right decision? null); var fixAllContext = new FixAllContext(currentDocument, codeFixProvider, FixAllScope.Document, codeFixTitle, codeFixProvider.FixableDiagnosticIds, fixAllDiagnosticProvider, CancellationToken.None); var codeActionToExecute = fixAllProvider.GetFixAsync(fixAllContext).Result; codeActionToExecute.Should().NotBeNull(); currentDocument = ApplyCodeFix(currentDocument, codeActionToExecute); CalculateDiagnosticsAndCode(diagnosticAnalyzer, currentDocument, parseOption, out diagnostics, out actualCode); AreEqualIgnoringLineEnding(pathToExpected, actualCode); }
internal FixMultipleCodeAction(FixMultipleContext fixMultipleContext, FixAllProvider fixAllProvider, string title, string previewChangesDialogTitle, string computingFixWaitDialogMessage, bool showPreviewChangesDialog) : base (fixMultipleContext, fixAllProvider, showPreviewChangesDialog) { _title = title; _previewChangesDialogTitle = previewChangesDialogTitle; _computingFixWaitDialogMessage = computingFixWaitDialogMessage; }
private async Task <CodeAction> GetFixAllCodeActionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) { using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) { CodeAction action = null; try { action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); } catch (OperationCanceledException) { FixAllLogger.LogComputationResult(completed: false); } finally { if (action != null) { FixAllLogger.LogComputationResult(completed: true); } else { FixAllLogger.LogComputationResult(completed: false, timedOut: true); } } return(action); } }
public sealed override FixAllProvider GetFixAllProvider() => FixAllProvider.Create(async(context, document, diagnostics) => { var cancellationToken = context.CancellationToken; var options = await GetOptionsAsync(document, cancellationToken).ConfigureAwait(false); var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var updatedSyntaxRoot = Formatter.Format(syntaxRoot, this.SyntaxFormatting, options, cancellationToken); return(document.WithSyntaxRoot(updatedSyntaxRoot)); });
public Builder(string equivalenceKey, Project project, FixAllProvider fixAllProvider, CodeFixProvider codeFixProvider) { this.equivalenceKey = equivalenceKey; this.project = project; this.fixAllProvider = fixAllProvider; this.codeFixProvider = codeFixProvider; documentDiagnostics = new Dictionary <string, List <Diagnostic> >(); projectDiagnostics = new List <Diagnostic>(); }
public override FixAllProvider GetFixAllProvider() => FixAllProvider.Create(async(context, document, diagnostics) => { if (diagnostics.IsEmpty) { return(null); } return(await this.GetTransformedDocumentAsync(document, context.GetOptionsProvider(), context.CancellationToken).ConfigureAwait(false)); });
internal FixAllSuggestedAction( Workspace workspace, ITextBuffer subjectBuffer, ICodeActionEditHandlerService editHandler, FixAllCodeAction codeAction, FixAllProvider provider, Diagnostic originalFixedDiagnostic) : base(workspace, subjectBuffer, editHandler, codeAction, provider) { _fixedDiagnostic = originalFixedDiagnostic; }
public override FixAllProvider GetFixAllProvider() => FixAllProvider.Create( async(context, document, diagnostics) => await FixAllAsync( document, diagnostics, context.CodeActionEquivalenceKey == NegateExpression, context.CancellationToken ) .ConfigureAwait(false) );
static XElement CreateFixAllProviderElement(CodeFixProvider fixer) { FixAllProvider fixAllProvider = fixer.GetFixAllProvider(); if (fixAllProvider != null) { return(new XElement("FixAllProvider", new XAttribute("Name", fixAllProvider.GetType().FullName))); } return(null); }
internal FixMultipleSuggestedAction( Workspace workspace, ICodeActionEditHandlerService editHandler, FixMultipleCodeAction codeAction, FixAllProvider provider, ITextBuffer subjectBufferOpt = null) : base(workspace, subjectBufferOpt, editHandler, codeAction, provider, originalFixedDiagnostic: codeAction.GetTriggerDiagnostic()) { _triggerDocumentOpt = codeAction.FixAllContext.Document; _telemetryId = GetTelemetryId(codeAction.FixAllContext.DiagnosticIds); }
public async Task <Solution> GetFixAllChangedSolutionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext) { var codeAction = await GetFixAllCodeActionAsync(fixAllProvider, fixAllContext).ConfigureAwait(false); if (codeAction == null) { return(fixAllContext.Solution); } fixAllContext.CancellationToken.ThrowIfCancellationRequested(); return(await codeAction.GetChangedSolutionInternalAsync(cancellationToken : fixAllContext.CancellationToken).ConfigureAwait(false)); }
private CodeFixEquivalenceGroup( string equivalenceKey, Solution solution, FixAllProvider fixAllProvider, CodeFixProvider codeFixProvider, ImmutableArray <Diagnostic> diagnosticsToFix) { this.CodeFixEquivalenceKey = equivalenceKey; this.Solution = solution; this.FixAllProvider = fixAllProvider; this.CodeFixProvider = codeFixProvider; this.DiagnosticsToFix = diagnosticsToFix; }
private FixMultipleSuggestedAction GetSuggestedAction( FixMultipleContext fixMultipleContext, Workspace workspace, FixAllProvider fixAllProvider, string title, string waitDialogMessage, bool showPreviewChangesDialog, CancellationToken cancellationToken) { var fixMultipleCodeAction = new FixMultipleCodeAction(fixMultipleContext, fixAllProvider, title, waitDialogMessage, showPreviewChangesDialog); return(new FixMultipleSuggestedAction(workspace, _editHandler, _waitIndicator, fixMultipleCodeAction, fixAllProvider)); }
internal FixAllSuggestedAction( Workspace workspace, ITextBuffer subjectBuffer, ICodeActionEditHandlerService editHandler, IWaitIndicator waitIndicator, FixAllCodeAction codeAction, FixAllProvider provider, Diagnostic originalFixedDiagnostic, IAsynchronousOperationListener operationListener) : base(workspace, subjectBuffer, editHandler, waitIndicator, codeAction, provider, operationListener) { _fixedDiagnostic = originalFixedDiagnostic; }
internal FixMultipleCodeAction( FixAllContext fixAllContext, Diagnostic triggerDiagnostic, FixAllProvider fixAllProvider, string title, string computingFixWaitDialogMessage, bool showPreviewChangesDialog) : base(fixAllContext, fixAllProvider, showPreviewChangesDialog) { _triggerDiagnostic = triggerDiagnostic; _title = title; _computingFixWaitDialogMessage = computingFixWaitDialogMessage; }
public async Task <Solution> GetFixAllChangedSolutionAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext, string fixAllTitle, string waitDialogMessage) { // Compute fix all occurrences code fix for the given fix all context. // Bring up a cancellable wait dialog. var codeAction = GetFixAllCodeAction(fixAllProvider, fixAllContext, fixAllTitle, waitDialogMessage); if (codeAction == null) { return(null); } fixAllContext.CancellationToken.ThrowIfCancellationRequested(); return(await codeAction.GetChangedSolutionInternalAsync(fixAllContext.CancellationToken).ConfigureAwait(false)); }
internal FixMultipleSuggestedAction( IAsynchronousOperationListener operationListener, Workspace workspace, ICodeActionEditHandlerService editHandler, IWaitIndicator waitIndicator, FixMultipleCodeAction codeAction, FixAllProvider provider, ITextBuffer subjectBufferOpt = null) : base(workspace, subjectBufferOpt, editHandler, waitIndicator, codeAction, provider, originalFixedDiagnostic: codeAction.GetTriggerDiagnostic(), operationListener: operationListener) { _triggerDocumentOpt = codeAction.FixAllState.Document; _telemetryId = GetTelemetryId(codeAction.FixAllState.DiagnosticIds); }
private static FixAllState GetFixAllState( FixAllProvider fixAllProvider, IEnumerable <Diagnostic> diagnostics, DiagnosticAnalyzer provider, CodeFixProvider fixer, TestDiagnosticAnalyzerDriver testDriver, Document document, FixAllScope scope, string fixAllActionId) { Assert.NotEmpty(diagnostics); if (scope == FixAllScope.Custom) { // Bulk fixing diagnostics in selected scope. var diagnosticsToFix = ImmutableDictionary.CreateRange(SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, diagnostics.ToImmutableArray()))); return(FixAllState.Create(fixAllProvider, diagnosticsToFix, fixer, fixAllActionId)); } var diagnostic = diagnostics.First(); Func <Document, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getDocumentDiagnosticsAsync = async(d, diagIds, c) => { var root = await d.GetSyntaxRootAsync(); var diags = await testDriver.GetDocumentDiagnosticsAsync(provider, d, root.FullSpan); diags = diags.Where(diag => diagIds.Contains(diag.Id)); return(diags); }; Func <Project, bool, ImmutableHashSet <string>, CancellationToken, Task <IEnumerable <Diagnostic> > > getProjectDiagnosticsAsync = async(p, includeAllDocumentDiagnostics, diagIds, c) => { var diags = includeAllDocumentDiagnostics ? await testDriver.GetAllDiagnosticsAsync(provider, p) : await testDriver.GetProjectDiagnosticsAsync(provider, p); diags = diags.Where(diag => diagIds.Contains(diag.Id)); return(diags); }; var diagnosticIds = ImmutableHashSet.Create(diagnostic.Id); var fixAllDiagnosticProvider = new FixAllState.FixAllDiagnosticProvider(diagnosticIds, getDocumentDiagnosticsAsync, getProjectDiagnosticsAsync); return(diagnostic.Location.IsInSource ? new FixAllState(fixAllProvider, document, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider) : new FixAllState(fixAllProvider, document.Project, fixer, scope, fixAllActionId, diagnosticIds, fixAllDiagnosticProvider)); }
private CodeAction GetFixAllCodeAction(FixAllProvider fixAllProvider, FixAllContext fixAllContext, string fixAllTitle, string waitDialogMessage, out bool userCancelled) { userCancelled = false; // Compute fix all occurrences code fix for the given fix all context. // Bring up a cancellable wait dialog. CodeAction codeAction = null; using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation, fixAllContext.CancellationToken)) { var result = _waitIndicator.Wait( fixAllTitle, waitDialogMessage, allowCancel: true, action: waitContext => { fixAllContext.CancellationToken.ThrowIfCancellationRequested(); using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(waitContext.CancellationToken, fixAllContext.CancellationToken)) { try { var fixAllContextWithCancellation = fixAllContext.WithCancellationToken(linkedCts.Token); var fixTask = fixAllProvider.GetFixAsync(fixAllContextWithCancellation); if (fixTask != null) { codeAction = fixTask.WaitAndGetResult(linkedCts.Token); } } catch (OperationCanceledException) { fixAllContext.CancellationToken.ThrowIfCancellationRequested(); } } }); userCancelled = result == WaitIndicatorResult.Canceled; var cancelled = userCancelled || codeAction == null; if (cancelled) { FixAllLogger.LogComputationResult(completed: false, timedOut: result != WaitIndicatorResult.Canceled); return(null); } } FixAllLogger.LogComputationResult(completed: true); return(codeAction); }
public Solution GetFix( ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleContext = FixMultipleContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); var suggestedAction = GetSuggestedAction(fixMultipleContext, workspace, fixAllProvider, waitDialogTitle, waitDialogMessage, showPreviewChangesDialog: false, cancellationToken: cancellationToken); return(suggestedAction.GetChangedSolution(cancellationToken)); }
public void ComputeAndApplyFix( ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string title, string waitDialogMessage, bool showPreviewChangesDialog, CancellationToken cancellationToken) { var fixMultipleContext = FixMultipleContext.Create(diagnosticsToFix, fixProvider, equivalenceKey, cancellationToken); var suggestedAction = GetSuggestedAction(fixMultipleContext, workspace, fixAllProvider, title, waitDialogMessage, showPreviewChangesDialog, cancellationToken); suggestedAction.Invoke(cancellationToken); }
private static async Task <Solution> ApplyCodeFixAsync( FixAllProvider fixAllProvider, FixAllContext fixAllContext, CancellationToken cancellationToken) { var fixAllAction = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); RoslynDebug.AssertNotNull(fixAllAction); var operations = await fixAllAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false); var applyChangesOperation = operations.OfType <ApplyChangesOperation>().SingleOrDefault(); RoslynDebug.AssertNotNull(applyChangesOperation); return(applyChangesOperation.ChangedSolution); }
private CodeFixEquivalenceGroup( string equivalenceKey, Solution solution, FixAllProvider fixAllProvider, CodeFixProvider codeFixProvider, ImmutableDictionary <ProjectId, ImmutableDictionary <string, ImmutableArray <Diagnostic> > > documentDiagnosticsToFix, ImmutableDictionary <ProjectId, ImmutableArray <Diagnostic> > projectDiagnosticsToFix) { this.CodeFixEquivalenceKey = equivalenceKey; this.Solution = solution; this.FixAllProvider = fixAllProvider; this.CodeFixProvider = codeFixProvider; this.DocumentDiagnosticsToFix = documentDiagnosticsToFix; this.ProjectDiagnosticsToFix = projectDiagnosticsToFix; this.NumberOfDiagnostics = documentDiagnosticsToFix.SelectMany(x => x.Value.Select(y => y.Value).SelectMany(y => y)).Count() + projectDiagnosticsToFix.SelectMany(x => x.Value).Count(); }
public Solution GetFix( ImmutableDictionary <Project, ImmutableArray <Diagnostic> > diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create( fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); return(GetFixedSolution( fixMultipleState, workspace, waitDialogTitle, waitDialogMessage, cancellationToken)); }