// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Extensions; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.TestHooks; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions { /// /// Service to compute and apply code fixes. /// [ExportWorkspaceServiceFactory(typeof(IFixMultipleOccurrencesService), ServiceLayer.Host), Shared] internal class FixMultipleOccurrencesService : IFixMultipleOccurrencesService, IWorkspaceServiceFactory { private readonly ICodeActionEditHandlerService _editHandler; private readonly IAsynchronousOperationListener _listener; private readonly IWaitIndicator _waitIndicator; [ImportingConstructor] public FixMultipleOccurrencesService( ICodeActionEditHandlerService editHandler, IWaitIndicator waitIndicator, [ImportMany] IEnumerable> asyncListeners) { _editHandler = editHandler; _waitIndicator = waitIndicator; _listener = new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.LightBulb); } public IWorkspaceService CreateService(HostWorkspaceServices workspaceServices) { return this; } public Solution GetFix( ImmutableDictionary> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var result = GetFixedSolution( fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, cancellationToken); return result; } public Solution GetFix( ImmutableDictionary> diagnosticsToFix, Workspace workspace, CodeFixProvider fixProvider, FixAllProvider fixAllProvider, string equivalenceKey, string waitDialogTitle, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleState = FixAllState.Create(fixAllProvider, diagnosticsToFix, fixProvider, equivalenceKey); var triggerDiagnostic = diagnosticsToFix.First().Value.First(); var result = GetFixedSolution( fixMultipleState, triggerDiagnostic, workspace, waitDialogTitle, waitDialogMessage, cancellationToken); return result; } private Solution GetFixedSolution( FixAllState fixAllState, Diagnostic triggerDiagnostic, Workspace workspace, string title, string waitDialogMessage, CancellationToken cancellationToken) { var fixMultipleCodeAction = new FixMultipleCodeAction( fixAllState, triggerDiagnostic, title, waitDialogMessage); Solution newSolution = null; var extensionManager = workspace.Services.GetService(); extensionManager.PerformAction(fixAllState.FixAllProvider, () => { // We don't need to post process changes here as the inner code action created for Fix multiple code fix already executes. newSolution = fixMultipleCodeAction.GetChangedSolutionInternalAsync( postProcessChanges: false, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken); }); return newSolution; } } }