Ejemplo n.º 1
0
        private static async Task <CodeAction> GetFixAllCodeActionAsync(FixAllContext fixAllContext)
        {
            using (Logger.LogBlock(
                       FunctionId.CodeFixes_FixAllOccurrencesComputation,
                       KeyValueLogMessage.Create(LogType.UserAction, m =>
            {
                m[FixAllLogger.CorrelationId] = fixAllContext.State.CorrelationId;
                m[FixAllLogger.FixAllScope] = fixAllContext.State.Scope.ToString();
            }),
                       fixAllContext.CancellationToken))
            {
                CodeAction action = null;
                try
                {
                    action = await fixAllContext.FixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    FixAllLogger.LogComputationResult(fixAllContext.State.CorrelationId, completed: false);
                }
                finally
                {
                    if (action != null)
                    {
                        FixAllLogger.LogComputationResult(fixAllContext.State.CorrelationId, completed: true);
                    }
                    else
                    {
                        FixAllLogger.LogComputationResult(fixAllContext.State.CorrelationId, completed: false, timedOut: true);
                    }
                }

                return(action);
            }
        }
            > GetDiagnosticsAndCodeActionsAsync(
            ImmutableDictionary <
                Document,
                ImmutableArray <Diagnostic>
                > documentsAndDiagnosticsToFixMap,
            FixAllContext fixAllContext
            )
        {
            var cancellationToken = fixAllContext.CancellationToken;
            var fixAllState       = fixAllContext.State;
            var fixesBag          = new ConcurrentBag <(Diagnostic diagnostic, CodeAction action)>();

            using (
                Logger.LogBlock(
                    FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Fixes,
                    FixAllLogger.CreateCorrelationLogMessage(fixAllState.CorrelationId),
                    cancellationToken
                    )
                )
            {
                cancellationToken.ThrowIfCancellationRequested();
                var progressTracker = fixAllContext.GetProgressTracker();

                using var _1 = ArrayBuilder <Task> .GetInstance(out var tasks);

                using var _2 = ArrayBuilder <Document> .GetInstance(out var documentsToFix);

                // Determine the set of documents to actually fix.  We can also use this to update the progress bar with
                // the amount of remaining work to perform.  We'll update the progress bar as we compute each fix in
                // AddDocumentFixesAsync.
                foreach (var(document, diagnosticsToFix) in documentsAndDiagnosticsToFixMap)
                {
                    if (!diagnosticsToFix.IsDefaultOrEmpty)
                    {
                        documentsToFix.Add(document);
                    }
                }

                progressTracker.AddItems(documentsToFix.Count);

                foreach (var document in documentsToFix)
                {
                    var diagnosticsToFix = documentsAndDiagnosticsToFixMap[document];
                    tasks.Add(
                        AddDocumentFixesAsync(
                            document,
                            diagnosticsToFix,
                            fixesBag,
                            fixAllState,
                            progressTracker,
                            cancellationToken
                            )
                        );
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);
            }

            return(fixesBag.ToImmutableArray());
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
        private async Task <CodeAction?> GetFixAsync(
            ImmutableDictionary <Document, ImmutableArray <Diagnostic> > documentsAndDiagnosticsToFixMap,
            FixAllContext fixAllContext)
        {
            var cancellationToken = fixAllContext.CancellationToken;

            if (documentsAndDiagnosticsToFixMap?.Any() == true)
            {
                var progressTracker = fixAllContext.GetProgressTracker();
                progressTracker.Description = FixAllContextHelper.GetDefaultFixAllTitle(fixAllContext);

                var fixAllState = fixAllContext.State;
                FixAllLogger.LogDiagnosticsStats(fixAllState.CorrelationId, documentsAndDiagnosticsToFixMap);

                var diagnosticsAndCodeActions = await GetDiagnosticsAndCodeActionsAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false);

                if (diagnosticsAndCodeActions.Length > 0)
                {
                    var functionId = FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Merge;
                    using (Logger.LogBlock(functionId, FixAllLogger.CreateCorrelationLogMessage(fixAllState.CorrelationId), cancellationToken))
                    {
                        FixAllLogger.LogFixesToMergeStats(functionId, fixAllState.CorrelationId, diagnosticsAndCodeActions.Length);
                        return(await TryGetMergedFixAsync(
                                   diagnosticsAndCodeActions, fixAllState, cancellationToken).ConfigureAwait(false));
                    }
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
        internal static Solution PreviewChanges(
            Solution currentSolution,
            Solution newSolution,
            string fixAllPreviewChangesTitle,
            string fixAllTopLevelHeader,
            string languageOpt,
            Workspace workspace,
            int?correlationId = null,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            using (Logger.LogBlock(
                       FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges,
                       KeyValueLogMessage.Create(LogType.UserAction, m =>
            {
                // only set when correlation id is given
                // we might not have this info for suppression
                if (correlationId.HasValue)
                {
                    m[FixAllLogger.CorrelationId] = correlationId;
                }
            }),
                       cancellationToken))
            {
                var previewService = workspace.Services.GetService <IPreviewDialogService>();
                var glyph          = languageOpt == null
                    ? Glyph.Assembly
                    : languageOpt == LanguageNames.CSharp
                        ? Glyph.CSharpProject
                        : Glyph.BasicProject;

                // Until IPreviewDialogService is implemented, just execute all changes without user ability to pick and choose
                if (previewService == null)
                {
                    return(newSolution);
                }

                var changedSolution = previewService.PreviewChanges(
                    string.Format(EditorFeaturesResources.Preview_Changes_0, fixAllPreviewChangesTitle),
                    "vs.codefix.fixall",
                    fixAllTopLevelHeader,
                    fixAllPreviewChangesTitle,
                    glyph,
                    newSolution,
                    currentSolution);

                if (changedSolution == null)
                {
                    // User clicked cancel.
                    FixAllLogger.LogPreviewChangesResult(correlationId, applied: false);
                    return(null);
                }

                FixAllLogger.LogPreviewChangesResult(correlationId, applied: true, allChangesApplied: changedSolution == newSolution);
                return(changedSolution);
            }
        }
Ejemplo n.º 6
0
        protected override void InnerInvoke(
            IProgressTracker progressTracker, CancellationToken cancellationToken)
        {
            this.AssertIsForeground();

            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesSession, FixAllLogger.CreateCorrelationLogMessage(_fixAllState.CorrelationId), cancellationToken))
            {
                base.InnerInvoke(progressTracker, cancellationToken);
            }
        }
Ejemplo n.º 7
0
        protected override async Task InnerInvokeAsync(
            IProgressTracker progressTracker, CancellationToken cancellationToken)
        {
            await this.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesSession, FixAllLogger.CreateCorrelationLogMessage(FixAllState.CorrelationId), cancellationToken))
            {
                await base.InnerInvokeAsync(progressTracker, cancellationToken).ConfigureAwait(false);
            }
        }
Ejemplo n.º 8
0
        private async Task <IEnumerable <CodeActionOperation> > GetFixAllOperationsAsync(CodeAction codeAction, FixAllContext fixAllContext)
        {
            // We have computed the fix all occurrences code fix.
            // Now fetch the new solution with applied fix and bring up the Preview changes dialog.

            var cancellationToken = fixAllContext.CancellationToken;
            var workspace         = fixAllContext.Project.Solution.Workspace;

            cancellationToken.ThrowIfCancellationRequested();
            var operations = await codeAction.GetOperationsAsync(cancellationToken).ConfigureAwait(false);

            if (operations == null)
            {
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();
            var newSolution = await codeAction.GetChangedSolutionInternalAsync(cancellationToken).ConfigureAwait(false);

            cancellationToken.ThrowIfCancellationRequested();
            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges, cancellationToken))
            {
                var previewService = workspace.Services.GetService <IPreviewDialogService>();
                var glyph          = fixAllContext.Project.Language == LanguageNames.CSharp ?
                                     Glyph.CSharpProject :
                                     Glyph.BasicProject;

                var changedSolution = previewService.PreviewChanges(
                    string.Format(EditorFeaturesResources.PreviewChangesOf, EditorFeaturesResources.FixAllOccurrences),
                    "vs.codefix.fixall",
                    codeAction.Title,
                    EditorFeaturesResources.FixAllOccurrences,
                    glyph,
                    newSolution,
                    fixAllContext.Project.Solution);

                if (changedSolution == null)
                {
                    // User clicked cancel.
                    FixAllLogger.LogPreviewChangesResult(applied: false);
                    return(null);
                }

                FixAllLogger.LogPreviewChangesResult(applied: true, allChangesApplied: changedSolution == newSolution);
                newSolution = changedSolution;
            }

            // Get a code action, with apply changes operation replaced with the newSolution.
            return(GetNewFixAllOperations(operations, newSolution, cancellationToken));
        }
        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);
        }
Ejemplo n.º 10
0
        public async Task <IEnumerable <CodeActionOperation> > GetFixAllOperationsAsync(FixAllProvider fixAllProvider, FixAllContext fixAllContext)
        {
            // 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(
                    EditorFeaturesResources.FixAllOccurrences,
                    EditorFeaturesResources.ComputingFixAllOccurrences,
                    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();
                        }
                    }
                });

                var cancelled = result == WaitIndicatorResult.Canceled || codeAction == null;

                if (cancelled)
                {
                    FixAllLogger.LogComputationResult(completed: false, timedOut: result != WaitIndicatorResult.Canceled);
                    return(null);
                }
            }

            FixAllLogger.LogComputationResult(completed: true);
            return(await GetFixAllOperationsAsync(codeAction, fixAllContext).ConfigureAwait(false));
        }
Ejemplo n.º 11
0
        protected override async Task InnerInvokeAsync(
            IProgressTracker progressTracker, CancellationToken cancellationToken)
        {
            await this.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            var fixAllKind = FixAllState.FixAllKind;
            var functionId = fixAllKind switch
            {
                FixAllKind.CodeFix => FunctionId.CodeFixes_FixAllOccurrencesSession,
                FixAllKind.Refactoring => FunctionId.Refactoring_FixAllOccurrencesSession,
                _ => throw ExceptionUtilities.UnexpectedValue(fixAllKind)
            };

            using (Logger.LogBlock(functionId, FixAllLogger.CreateCorrelationLogMessage(FixAllState.CorrelationId), cancellationToken))
            {
                await base.InnerInvokeAsync(progressTracker, cancellationToken).ConfigureAwait(false);
            }
        }
    }
Ejemplo n.º 12
0
        private static async Task <CodeAction> GetFixAllCodeActionAsync(IFixAllContext fixAllContext)
        {
            var fixAllKind = fixAllContext.State.FixAllKind;
            var functionId = fixAllKind switch
            {
                FixAllKind.CodeFix => FunctionId.CodeFixes_FixAllOccurrencesComputation,
                FixAllKind.Refactoring => FunctionId.Refactoring_FixAllOccurrencesComputation,
                _ => throw ExceptionUtilities.UnexpectedValue(fixAllKind)
            };

            using (Logger.LogBlock(
                       functionId,
                       KeyValueLogMessage.Create(LogType.UserAction, m =>
            {
                m[FixAllLogger.CorrelationId] = fixAllContext.State.CorrelationId;
                m[FixAllLogger.FixAllScope] = fixAllContext.State.Scope.ToString();
            }),
                       fixAllContext.CancellationToken))
            {
                CodeAction action = null;
                try
                {
                    action = await fixAllContext.FixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    FixAllLogger.LogComputationResult(fixAllKind, fixAllContext.State.CorrelationId, completed: false);
                }
                finally
                {
                    if (action != null)
                    {
                        FixAllLogger.LogComputationResult(fixAllKind, fixAllContext.State.CorrelationId, completed: true);
                    }
                    else
                    {
                        FixAllLogger.LogComputationResult(fixAllKind, fixAllContext.State.CorrelationId, completed: false, timedOut: true);
                    }
                }

                return(action);
            }
        }
Ejemplo n.º 13
0
        internal static Solution PreviewChanges(
            Solution currentSolution,
            Solution newSolution,
            string fixAllPreviewChangesTitle,
            string fixAllTopLevelHeader,
            string languageOpt,
            Workspace workspace,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();
            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesPreviewChanges, cancellationToken))
            {
                var previewService = workspace.Services.GetService <IPreviewDialogService>();
                var glyph          = languageOpt == null
                     ? Glyph.Assembly
                     : languageOpt == LanguageNames.CSharp
                         ? Glyph.CSharpProject
                         : Glyph.BasicProject;

                var changedSolution = previewService.PreviewChanges(
                    string.Format(EditorFeaturesResources.PreviewChangesOf, fixAllPreviewChangesTitle),
                    "vs.codefix.fixall",
                    fixAllTopLevelHeader,
                    fixAllPreviewChangesTitle,
                    glyph,
                    newSolution,
                    currentSolution);

                if (changedSolution == null)
                {
                    // User clicked cancel.
                    FixAllLogger.LogPreviewChangesResult(applied: false);
                    return(null);
                }

                FixAllLogger.LogPreviewChangesResult(applied: true, allChangesApplied: changedSolution == newSolution);
                return(changedSolution);
            }
        }