提交 7a964c3a 编写于 作者: R Ravi Chande

Add an AsyncWaiter for Encapsulate Field

上级 4544a108
// 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.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Implementation.EncapsulateField;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Utilities;
......@@ -15,8 +18,9 @@ internal class EncapsulateFieldCommandHandler : AbstractEncapsulateFieldCommandH
[ImportingConstructor]
public EncapsulateFieldCommandHandler(
IWaitIndicator waitIndicator,
ITextBufferUndoManagerProvider undoManager)
: base(waitIndicator, undoManager)
ITextBufferUndoManagerProvider undoManager,
[ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners)
: base(waitIndicator, undoManager, asyncListeners)
{
}
}
......
......@@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis.Editor.Implementation.Interactive;
using Microsoft.CodeAnalysis.Editor.UnitTests;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Text.Operations;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -210,7 +211,8 @@ class C
var textView = workspace.Documents.Single().GetTextView();
var handler = new EncapsulateFieldCommandHandler(workspace.GetService<Host.IWaitIndicator>(), workspace.GetService<ITextBufferUndoManagerProvider>());
var handler = new EncapsulateFieldCommandHandler(workspace.GetService<Host.IWaitIndicator>(), workspace.GetService<ITextBufferUndoManagerProvider>(),
workspace.ExportProvider.GetExportedValues<Lazy< IAsynchronousOperationListener, FeatureMetadata>>());
var delegatedToNext = false;
Func<CommandState> nextHandler = () =>
{
......
......@@ -14,6 +14,7 @@
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Composition;
using Microsoft.VisualStudio.Text.Operations;
using Xunit;
......@@ -56,7 +57,8 @@ public static EncapsulateFieldTestState Create(string markup)
public void Encapsulate()
{
var args = new EncapsulateFieldCommandArgs(_testDocument.GetTextView(), _testDocument.GetTextBuffer());
var commandHandler = new EncapsulateFieldCommandHandler(TestWaitIndicator.Default, Workspace.GetService<ITextBufferUndoManagerProvider>());
var commandHandler = new EncapsulateFieldCommandHandler(TestWaitIndicator.Default, Workspace.GetService<ITextBufferUndoManagerProvider>(),
Workspace.ExportProvider.GetExportedValues<Lazy<IAsynchronousOperationListener, FeatureMetadata>>());
commandHandler.ExecuteCommand(args, () => { });
}
......
// 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.Linq;
using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Host;
......@@ -9,6 +10,7 @@
using Microsoft.CodeAnalysis.EncapsulateField;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text.Operations;
using Roslyn.Utilities;
......@@ -19,13 +21,16 @@ internal abstract class AbstractEncapsulateFieldCommandHandler : ICommandHandler
{
private readonly IWaitIndicator _waitIndicator;
private readonly ITextBufferUndoManagerProvider _undoManager;
private readonly AggregateAsynchronousOperationListener _listener;
public AbstractEncapsulateFieldCommandHandler(
IWaitIndicator waitIndicator,
ITextBufferUndoManagerProvider undoManager)
ITextBufferUndoManagerProvider undoManager,
IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners)
{
_waitIndicator = waitIndicator;
_undoManager = undoManager;
_listener = new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.EncapsulateField);
}
public void ExecuteCommand(EncapsulateFieldCommandArgs args, Action nextHandler)
......@@ -63,73 +68,78 @@ public void ExecuteCommand(EncapsulateFieldCommandArgs args, Action nextHandler)
private bool Execute(EncapsulateFieldCommandArgs args, IWaitContext waitContext)
{
var text = args.TextView.TextBuffer.CurrentSnapshot.AsText();
var cancellationToken = waitContext.CancellationToken;
if (!Workspace.TryGetWorkspace(text.Container, out var workspace))
using (var token = _listener.BeginAsyncOperation("EncapsulateField"))
{
return false;
}
var text = args.TextView.TextBuffer.CurrentSnapshot.AsText();
var cancellationToken = waitContext.CancellationToken;
if (!Workspace.TryGetWorkspace(text.Container, out var workspace))
{
return false;
}
var documentId = workspace.GetDocumentIdInCurrentContext(text.Container);
if (documentId == null)
{
return false;
}
var documentId = workspace.GetDocumentIdInCurrentContext(text.Container);
if (documentId == null)
{
return false;
}
var document = workspace.CurrentSolution.GetDocument(documentId);
if (document == null)
{
return false;
}
var document = workspace.CurrentSolution.GetDocument(documentId);
if (document == null)
{
return false;
}
var spans = args.TextView.Selection.GetSnapshotSpansOnBuffer(args.SubjectBuffer);
var spans = args.TextView.Selection.GetSnapshotSpansOnBuffer(args.SubjectBuffer);
var service = document.GetLanguageService<AbstractEncapsulateFieldService>();
var service = document.GetLanguageService<AbstractEncapsulateFieldService>();
var result = service.EncapsulateFieldAsync(document, spans.First().Span.ToTextSpan(), true, cancellationToken).WaitAndGetResult(cancellationToken);
var result = service.EncapsulateFieldAsync(document, spans.First().Span.ToTextSpan(), true, cancellationToken).WaitAndGetResult(cancellationToken);
if (result == null)
{
var notificationService = workspace.Services.GetService<INotificationService>();
notificationService.SendNotification(EditorFeaturesResources.Please_select_the_definition_of_the_field_to_encapsulate, severity: NotificationSeverity.Error);
return false;
}
if (result == null)
{
var notificationService = workspace.Services.GetService<INotificationService>();
notificationService.SendNotification(EditorFeaturesResources.Please_select_the_definition_of_the_field_to_encapsulate, severity: NotificationSeverity.Error);
return false;
}
waitContext.AllowCancel = false;
waitContext.AllowCancel = false;
var finalSolution = result.GetSolutionAsync(cancellationToken).WaitAndGetResult(cancellationToken);
var finalSolution = result.GetSolutionAsync(cancellationToken).WaitAndGetResult(cancellationToken);
var previewService = workspace.Services.GetService<IPreviewDialogService>();
if (previewService != null)
{
finalSolution = previewService.PreviewChanges(
string.Format(EditorFeaturesResources.Preview_Changes_0, EditorFeaturesResources.Encapsulate_Field),
"vs.csharp.refactoring.preview",
EditorFeaturesResources.Encapsulate_Field_colon,
result.GetNameAsync(cancellationToken).WaitAndGetResult(cancellationToken),
result.GetGlyphAsync(cancellationToken).WaitAndGetResult(cancellationToken),
finalSolution,
document.Project.Solution);
}
var previewService = workspace.Services.GetService<IPreviewDialogService>();
if (previewService != null)
{
finalSolution = previewService.PreviewChanges(
string.Format(EditorFeaturesResources.Preview_Changes_0, EditorFeaturesResources.Encapsulate_Field),
"vs.csharp.refactoring.preview",
EditorFeaturesResources.Encapsulate_Field_colon,
result.GetNameAsync(cancellationToken).WaitAndGetResult(cancellationToken),
result.GetGlyphAsync(cancellationToken).WaitAndGetResult(cancellationToken),
finalSolution,
document.Project.Solution);
}
if (finalSolution == null)
{
// User clicked cancel.
return true;
}
if (finalSolution == null)
{
// User clicked cancel.
return true;
}
using (var undoTransaction = _undoManager.GetTextBufferUndoManager(args.SubjectBuffer).TextBufferUndoHistory.CreateTransaction(EditorFeaturesResources.Encapsulate_Field))
{
if (!workspace.TryApplyChanges(finalSolution))
using (var undoTransaction = _undoManager.GetTextBufferUndoManager(args.SubjectBuffer).TextBufferUndoHistory.CreateTransaction(EditorFeaturesResources.Encapsulate_Field))
{
undoTransaction.Cancel();
return false;
if (!workspace.TryApplyChanges(finalSolution))
{
undoTransaction.Cancel();
return false;
}
undoTransaction.Complete();
}
undoTransaction.Complete();
}
System.Threading.Thread.Sleep(10000);
return true;
return true;
}
}
public CommandState GetCommandState(EncapsulateFieldCommandArgs args, Func<CommandState> nextHandler)
......
......@@ -3,6 +3,7 @@
Imports System.ComponentModel.Composition
Imports Microsoft.CodeAnalysis.Editor.Host
Imports Microsoft.CodeAnalysis.Editor.Implementation.EncapsulateField
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.VisualStudio.Text.Operations
Imports Microsoft.VisualStudio.Utilities
......@@ -13,8 +14,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.EncapsulateField
Inherits AbstractEncapsulateFieldCommandHandler
<ImportingConstructor>
Public Sub New(waitIndicator As IWaitIndicator, undoManager As ITextBufferUndoManagerProvider)
MyBase.New(waitIndicator, undoManager)
Public Sub New(waitIndicator As IWaitIndicator,
undoManager As ITextBufferUndoManagerProvider,
<ImportMany> asyncListeners As IEnumerable(Of Lazy(Of IAsynchronousOperationListener, FeatureMetadata)))
MyBase.New(waitIndicator, undoManager, asyncListeners)
End Sub
End Class
End Namespace
......@@ -5,6 +5,7 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.EncapsulateField
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.VisualStudio.Text.Operations
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EncapsulateField
......@@ -149,7 +150,8 @@ End Class
Dim textView = workspace.Documents.Single().GetTextView()
Dim handler = New EncapsulateFieldCommandHandler(workspace.GetService(Of Host.IWaitIndicator), workspace.GetService(Of ITextBufferUndoManagerProvider))
Dim handler = New EncapsulateFieldCommandHandler(workspace.GetService(Of Host.IWaitIndicator), workspace.GetService(Of ITextBufferUndoManagerProvider),
workspace.ExportProvider.GetExportedValues(Of Lazy(Of IAsynchronousOperationListener, FeatureMetadata)))
Dim delegatedToNext = False
Dim nextHandler =
Function()
......
......@@ -6,6 +6,7 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.EncapsulateField
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.CodeAnalysis.VisualBasic.EncapsulateField
Imports Microsoft.VisualStudio.Composition
Imports Microsoft.VisualStudio.Text.Operations
......@@ -36,7 +37,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EncapsulateField
Public Sub Encapsulate()
Dim args = New EncapsulateFieldCommandArgs(_testDocument.GetTextView(), _testDocument.GetTextBuffer())
Dim commandHandler = New EncapsulateFieldCommandHandler(TestWaitIndicator.Default, Workspace.GetService(Of ITextBufferUndoManagerProvider)())
Dim commandHandler = New EncapsulateFieldCommandHandler(TestWaitIndicator.Default, Workspace.GetService(Of ITextBufferUndoManagerProvider)(),
Workspace.ExportProvider.GetExportedValues(Of Lazy(Of IAsynchronousOperationListener, FeatureMetadata)))
commandHandler.ExecuteCommand(args, Nothing)
End Sub
......
......@@ -13,6 +13,7 @@ internal partial class FeatureAttribute
public const string CompletionSet = nameof(CompletionSet);
public const string DesignerAttribute = nameof(DesignerAttribute);
public const string DiagnosticService = nameof(DiagnosticService);
public const string EncapsulateField = nameof(EncapsulateField);
public const string ErrorList = nameof(ErrorList);
public const string ErrorSquiggles = nameof(ErrorSquiggles);
public const string EventHookup = nameof(EventHookup);
......
......@@ -36,6 +36,7 @@
<Compile Update="PerfMargin\StatusIndicator.xaml.cs">
<DependentUpon>StatusIndicator.xaml</DependentUpon>
</Compile>
<Compile Include="Waiters\EncapsulateFieldWaiter.cs" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Roslyn.VisualStudio.DiagnosticsWindow" />
......
// 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.Composition;
using Microsoft.CodeAnalysis.Shared.TestHooks;
namespace Roslyn.Hosting.Diagnostics.Waiters
{
[Shared]
[Export(typeof(IAsynchronousOperationListener))]
[Export(typeof(IAsynchronousOperationWaiter))]
[Feature(FeatureAttribute.EncapsulateField)]
internal class EncapsulateFieldWaiter : EditorAdornmentWaiter { }
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -34,7 +35,6 @@ static void Main(string[] args)
public void EncapsulateThroughCommand()
{
SetUpEditor(TestSource);
var encapsulateField = VisualStudio.EncapsulateField;
var dialog = VisualStudio.PreviewChangesDialog;
encapsulateField.Invoke();
......@@ -43,8 +43,7 @@ public void EncapsulateThroughCommand()
dialog.VerifyClosed(encapsulateField.DialogName);
encapsulateField.Invoke();
dialog.VerifyOpen(encapsulateField.DialogName);
dialog.ClickApply(encapsulateField.DialogName);
VisualStudio.Workspace.WaitForAllAsyncOperations();
dialog.ClickApplyAndWaitForFeature(encapsulateField.DialogName, FeatureAttribute.EncapsulateField);
VisualStudio.Editor.Verify.TextContains("public static int? Param { get => param; set => param = value; }");
}
......
// 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 Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -38,7 +39,7 @@ public void EncapsulateThroughCommand()
dialog.VerifyClosed(encapsulateField.DialogName);
encapsulateField.Invoke();
dialog.VerifyOpen(encapsulateField.DialogName);
dialog.ClickApply(encapsulateField.DialogName);
dialog.ClickApplyAndWaitForFeature(encapsulateField.DialogName, FeatureAttribute.EncapsulateField);
VisualStudio.Editor.Verify.TextContains(@" Private _name As Integer? = 0
Public Property Name As Integer?
......
......@@ -29,8 +29,11 @@ public void VerifyOpen(string expectedTitle)
public void VerifyClosed(string expectedTitle)
=> DialogHelpers.FindDialogByName(GetMainWindowHWnd(), expectedTitle, isOpen: false);
public void ClickApply(string expectedTitle)
=> DialogHelpers.PressButtonWithNameFromDialogWithName(GetMainWindowHWnd(), expectedTitle, "Apply");
public void ClickApplyAndWaitForFeature(string expectedTitle, string featureName)
{
DialogHelpers.PressButtonWithNameFromDialogWithName(GetMainWindowHWnd(), expectedTitle, "Apply");
VisualStudioInstance.Workspace.WaitForAsyncOperations(featureName);
}
public void ClickCancel(string expectedTitle)
=> DialogHelpers.PressButtonWithNameFromDialogWithName(GetMainWindowHWnd(), expectedTitle, "Cancel");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册