AbstractExtractInterfaceCommandHandler.cs 4.1 KB
Newer Older
1 2 3
// 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.Threading;
4
using Microsoft.CodeAnalysis.Editor.Shared;
5 6 7 8 9 10
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.ExtractInterface;
using Microsoft.CodeAnalysis.Navigation;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
11 12 13
using Microsoft.VisualStudio.Commanding;
using Microsoft.VisualStudio.Text.Editor.Commanding.Commands;
using VSCommanding = Microsoft.VisualStudio.Commanding;
14 15 16

namespace Microsoft.CodeAnalysis.Editor.Implementation.ExtractInterface
{
17
    internal abstract class AbstractExtractInterfaceCommandHandler : VSCommanding.ICommandHandler<ExtractInterfaceCommandArgs>
18
    {
19 20 21
        public string DisplayName => EditorFeaturesResources.Extract_Interface_Command_Handler;

        public VSCommanding.CommandState GetCommandState(ExtractInterfaceCommandArgs args)
22 23 24 25 26 27
        {
            var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document == null ||
                !document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.AddDocument) ||
                !document.Project.Solution.Workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
            {
28
                return VSCommanding.CommandState.Unspecified;
29 30
            }

31 32
            var supportsFeatureService = document.Project.Solution.Workspace.Services.GetService<IDocumentSupportsFeatureService>();
            if (!supportsFeatureService.SupportsRefactorings(document))
33
            {
34
                return VSCommanding.CommandState.Unspecified;
35 36
            }

37
            return VSCommanding.CommandState.Available;
38 39
        }

40
        public bool ExecuteCommand(ExtractInterfaceCommandArgs args, CommandExecutionContext context)
41 42 43 44
        {
            var document = args.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document == null)
            {
45
                return false;
46 47 48 49 50 51 52
            }

            var workspace = document.Project.Solution.Workspace;

            if (!workspace.CanApplyChange(ApplyChangesKind.AddDocument) ||
                !workspace.CanApplyChange(ApplyChangesKind.ChangeDocument))
            {
53
                return false;
54 55
            }

56 57
            var supportsFeatureService = document.Project.Solution.Workspace.Services.GetService<IDocumentSupportsFeatureService>();
            if (!supportsFeatureService.SupportsRefactorings(document))
58
            {
59
                return false;
60 61 62 63 64
            }

            var caretPoint = args.TextView.GetCaretPoint(args.SubjectBuffer);
            if (!caretPoint.HasValue)
            {
65
                return false;
66 67
            }

68 69 70
            // We are about to show a modal UI dialog so we should take over the command execution
            // wait context. That means the command system won't attempt to show its own wait dialog 
            // and also will take it into consideration when measuring command handling duration.
71
            context.OperationContext.TakeOwnership();
72 73 74 75 76 77 78 79 80
            var extractInterfaceService = document.GetLanguageService<AbstractExtractInterfaceService>();
            var result = extractInterfaceService.ExtractInterface(
                document,
                caretPoint.Value.Position,
                (errorMessage, severity) => workspace.Services.GetService<INotificationService>().SendNotification(errorMessage, severity: severity),
                CancellationToken.None);

            if (result == null || !result.Succeeded)
            {
81
                return true;
82 83 84 85 86
            }

            if (!document.Project.Solution.Workspace.TryApplyChanges(result.UpdatedSolution))
            {
                // TODO: handle failure
87
                return true;
88 89 90 91
            }

            var navigationService = workspace.Services.GetService<IDocumentNavigationService>();
            navigationService.TryNavigateToPosition(workspace, result.NavigationDocumentId, 0);
92 93

            return true;
94 95 96
        }
    }
}