/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/EditorFeatures/Core/ExtractInterface/AbstractExtractInterfaceCommandHandler.cs
99 строк
4 KB
Tomáš Matoušek
Remove fallbacks (2) (#74319)
10 июл 2024, 05:38
Не верифицирован
10 июл 2024, 05:38
6d1db01
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System.Threading; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Notification; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; namespace Microsoft.CodeAnalysis.ExtractInterface; internal abstract class AbstractExtractInterfaceCommandHandler : ICommandHandler<ExtractInterfaceCommandArgs> { private readonly IThreadingContext _threadingContext; protected AbstractExtractInterfaceCommandHandler(IThreadingContext threadingContext) { _threadingContext = threadingContext; } public string DisplayName => EditorFeaturesResources.Extract_Interface; public CommandState GetCommandState(ExtractInterfaceCommandArgs args) => IsAvailable(args.SubjectBuffer, out _) ? CommandState.Available : CommandState.Unspecified; public bool ExecuteCommand(ExtractInterfaceCommandArgs args, CommandExecutionContext context) { using (context.OperationContext.AddScope(allowCancellation: true, EditorFeaturesResources.Extract_Interface)) { var subjectBuffer = args.SubjectBuffer; if (!IsAvailable(subjectBuffer, out var workspace)) { return false; } var caretPoint = args.TextView.GetCaretPoint(subjectBuffer); if (!caretPoint.HasValue) { return false; } var document = subjectBuffer.CurrentSnapshot.GetFullyLoadedOpenDocumentInCurrentContextWithChanges( context.OperationContext, _threadingContext); if (document == null) { return false; } // 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. context.OperationContext.TakeOwnership(); var extractInterfaceService = document.GetLanguageService<AbstractExtractInterfaceService>(); _threadingContext.JoinableTaskFactory.Run(async () => { // ConfigureAwait(true) here so we are back on the UI thread // before calling TryApplyChanges below. Make sure if other // async code is added between the two calls to handle thread // affinity accordingly var result = await extractInterfaceService.ExtractInterfaceAsync( document, caretPoint.Value.Position, (errorMessage, severity) => workspace.Services.GetService<INotificationService>().SendNotification(errorMessage, severity: severity), CancellationToken.None).ConfigureAwait(true); if (result == null || !result.Succeeded) { return; } if (!document.Project.Solution.Workspace.TryApplyChanges(result.UpdatedSolution)) { // TODO: handle failure return; } var navigationService = workspace.Services.GetService<IDocumentNavigationService>(); await navigationService.TryNavigateToPositionAsync( _threadingContext, workspace, result.NavigationDocumentId, position: 0, CancellationToken.None).ConfigureAwait(false); }); return true; } } private static bool IsAvailable(ITextBuffer subjectBuffer, out Workspace workspace) => subjectBuffer.TryGetWorkspace(out workspace) && workspace.CanApplyChange(ApplyChangesKind.AddDocument) && workspace.CanApplyChange(ApplyChangesKind.ChangeDocument) && subjectBuffer.SupportsRefactorings(); }