private void SyncNamespaces(ImmutableArray <Project> projects)
        {
            if (projects.IsEmpty)
            {
                return;
            }

            var syncService = projects[0].GetRequiredLanguageService <ISyncNamespacesService>();
            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, options, operationContext.UserCancellationToken));
            });

            if (status != UIThreadOperationStatus.Canceled && solution is not null)
            {
                if (_workspace.CurrentSolution.GetChanges(solution).GetProjectChanges().Any())
                {
                    _workspace.TryApplyChanges(solution);
                    MessageDialog.Show(ServicesVSResources.Sync_Namespaces, ServicesVSResources.Namespaces_have_been_updated, MessageDialogCommandSet.Ok);
                }
                else
                {
                    MessageDialog.Show(ServicesVSResources.Sync_Namespaces, ServicesVSResources.No_namespaces_needed_updating, MessageDialogCommandSet.Ok);
                }
            }
        }
Пример #2
0
        public override async Task <object> HandleRequestAsync(LSP.ExecuteCommandParams request, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            Contract.ThrowIfNull(document);

            var runRequest = ((JToken)request.Arguments.Single()).ToObject <CodeActionResolveData>();

            Assumes.Present(runRequest);

            var options = _globalOptions.GetCodeActionOptions(document.Project.Language);

            var codeActions = await CodeActionHelpers.GetCodeActionsAsync(
                _codeActionsCache, document, runRequest.Range, options, _codeFixService, _codeRefactoringService, cancellationToken).ConfigureAwait(false);

            var actionToRun = CodeActionHelpers.GetCodeActionToResolve(runRequest.UniqueIdentifier, codeActions);

            Contract.ThrowIfNull(actionToRun);

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

            // TODO - This UI thread dependency should be removed.
            // https://github.com/dotnet/roslyn/projects/45#card-20619668
            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            foreach (var operation in operations)
            {
                operation.Apply(document.Project.Solution.Workspace, cancellationToken);
            }

            return(true);
        }
Пример #3
0
        public async Task <LSP.CodeAction[]> HandleRequestAsync(LSP.CodeActionParams request, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            Contract.ThrowIfNull(document);

            var options = _globalOptions.GetCodeActionOptions(document.Project.Language);

            var codeActions = await CodeActionHelpers.GetVSCodeActionsAsync(
                request, _codeActionsCache, document, options, _codeFixService, _codeRefactoringService, cancellationToken).ConfigureAwait(false);

            return(codeActions);
        }
Пример #4
0
        private async Task ApplySuppressionFixAsync(IEnumerable <DiagnosticData>?diagnosticsToFix, Func <Project, bool> shouldFixInProject, bool filterStaleDiagnostics, bool isAddSuppression, bool isSuppressionInSource, bool onlyCompilerDiagnostics, bool showPreviewChangesDialog)
        {
            try
            {
                using var token = _listener.BeginAsyncOperation(nameof(ApplySuppressionFix));
                var title             = GetFixTitle(isAddSuppression);
                var waitDialogMessage = GetWaitDialogMessage(isAddSuppression);

                using var context = _uiThreadOperationExecutor.BeginExecute(
                          title,
                          waitDialogMessage,
                          allowCancellation: true,
                          showProgress: true);

                if (diagnosticsToFix == null)
                {
                    return;
                }

                diagnosticsToFix = FilterDiagnostics(diagnosticsToFix, isAddSuppression, isSuppressionInSource, onlyCompilerDiagnostics);
                if (diagnosticsToFix.IsEmpty())
                {
                    return;
                }

                var newSolution = _workspace.CurrentSolution;

                var cancellationToken = context.UserCancellationToken;
                cancellationToken.ThrowIfCancellationRequested();
                var documentDiagnosticsToFixMap = await GetDocumentDiagnosticsToFixAsync(
                    diagnosticsToFix, shouldFixInProject, filterStaleDiagnostics, cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
                var projectDiagnosticsToFixMap = isSuppressionInSource
                    ? ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty
                    : await GetProjectDiagnosticsToFixAsync(diagnosticsToFix, shouldFixInProject, filterStaleDiagnostics, cancellationToken).ConfigureAwait(false);

                if (documentDiagnosticsToFixMap == null ||
                    projectDiagnosticsToFixMap == null ||
                    (documentDiagnosticsToFixMap.IsEmpty && projectDiagnosticsToFixMap.IsEmpty))
                {
                    // Nothing to fix.
                    return;
                }

                cancellationToken.ThrowIfCancellationRequested();

                // Equivalence key determines what fix will be applied.
                // Make sure we don't include any specific diagnostic ID, as we want all of the given diagnostics (which can have varied ID) to be fixed.
                var equivalenceKey = isAddSuppression
                    ? (isSuppressionInSource ? FeaturesResources.in_Source : FeaturesResources.in_Suppression_File)
                    : FeaturesResources.Remove_Suppression;

                // We have different suppression fixers for every language.
                // So we need to group diagnostics by the containing project language and apply fixes separately.
                var languages = new HashSet <string>(projectDiagnosticsToFixMap.Select(p => p.Key.Language).Concat(documentDiagnosticsToFixMap.Select(kvp => kvp.Key.Project.Language)));

                foreach (var language in languages)
                {
                    // Use the Fix multiple occurrences service to compute a bulk suppression fix for the specified document and project diagnostics,
                    // show a preview changes dialog and then apply the fix to the workspace.

                    cancellationToken.ThrowIfCancellationRequested();

                    var options         = _globalOptions.GetCodeActionOptions(language);
                    var optionsProvider = new CodeActionOptionsProvider(_ => options);

                    var documentDiagnosticsPerLanguage = GetDocumentDiagnosticsMappedToNewSolution(documentDiagnosticsToFixMap, newSolution, language);
                    if (!documentDiagnosticsPerLanguage.IsEmpty)
                    {
                        var suppressionFixer = GetSuppressionFixer(documentDiagnosticsPerLanguage.SelectMany(kvp => kvp.Value), language, _codeFixService);
                        if (suppressionFixer != null)
                        {
                            var suppressionFixAllProvider = suppressionFixer.GetFixAllProvider();
                            newSolution = _fixMultipleOccurencesService.GetFix(
                                documentDiagnosticsPerLanguage,
                                _workspace,
                                suppressionFixer,
                                suppressionFixAllProvider,
                                optionsProvider,
                                equivalenceKey,
                                title,
                                waitDialogMessage,
                                cancellationToken);
                            if (newSolution == null)
                            {
                                // User cancelled or fixer threw an exception, so we just bail out.
                                return;
                            }
                        }
                    }

                    var projectDiagnosticsPerLanguage = GetProjectDiagnosticsMappedToNewSolution(projectDiagnosticsToFixMap, newSolution, language);
                    if (!projectDiagnosticsPerLanguage.IsEmpty)
                    {
                        var suppressionFixer = GetSuppressionFixer(projectDiagnosticsPerLanguage.SelectMany(kvp => kvp.Value), language, _codeFixService);
                        if (suppressionFixer != null)
                        {
                            var suppressionFixAllProvider = suppressionFixer.GetFixAllProvider();
                            newSolution = _fixMultipleOccurencesService.GetFix(
                                projectDiagnosticsPerLanguage,
                                _workspace,
                                suppressionFixer,
                                suppressionFixAllProvider,
                                optionsProvider,
                                equivalenceKey,
                                title,
                                waitDialogMessage,
                                cancellationToken);
                            if (newSolution == null)
                            {
                                return;
                            }
                        }
                    }

                    if (newSolution == _workspace.CurrentSolution)
                    {
                        // No changes.
                        return;
                    }

                    if (showPreviewChangesDialog)
                    {
                        newSolution = FixAllGetFixesService.PreviewChanges(
                            _workspace.CurrentSolution,
                            newSolution,
                            fixAllPreviewChangesTitle: title,
                            fixAllTopLevelHeader: title,
                            languageOpt: languages?.Count == 1 ? languages.Single() : null,
                            workspace: _workspace);
                        if (newSolution == null)
                        {
                            return;
                        }
                    }

                    waitDialogMessage = isAddSuppression ? ServicesVSResources.Applying_suppressions_fix : ServicesVSResources.Applying_remove_suppressions_fix;
                    var operations = ImmutableArray.Create <CodeActionOperation>(new ApplyChangesOperation(newSolution));
                    using var scope = context.AddScope(allowCancellation: true, description: waitDialogMessage);
                    await _editHandlerService.ApplyAsync(
                        _workspace,
                        fromDocument : null,
                        operations : operations,
                        title : title,
                        progressTracker : new UIThreadOperationContextProgressTracker(scope),
                        cancellationToken : cancellationToken).ConfigureAwait(false);

                    // Kick off diagnostic re-analysis for affected projects so that diagnostics gets refreshed.
                    _ = Task.Run(() =>
                    {
                        var reanalyzeDocuments = diagnosticsToFix.Select(d => d.DocumentId).WhereNotNull().Distinct();
                        _diagnosticService.Reanalyze(_workspace, documentIds: reanalyzeDocuments, highPriority: true);
                    });
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex) when(FatalError.ReportAndCatch(ex))
            {
            }
        }