提交 5363c28a 编写于 作者: R Ravi Chande

Merge pull request #8890 from rchande/sighelpperf2

Cancel the signature help if the user navigates before it has been presented
...@@ -13,5 +13,7 @@ internal interface ISignatureHelpPresenterSession : IIntelliSensePresenterSessio ...@@ -13,5 +13,7 @@ internal interface ISignatureHelpPresenterSession : IIntelliSensePresenterSessio
void SelectNextItem(); void SelectNextItem();
event EventHandler<SignatureHelpItemEventArgs> ItemSelected; event EventHandler<SignatureHelpItemEventArgs> ItemSelected;
bool EditorSessionIsActive { get; }
} }
} }
...@@ -28,6 +28,15 @@ private bool ChangeSelection(Action computationAction) ...@@ -28,6 +28,15 @@ private bool ChangeSelection(Action computationAction)
return false; return false;
} }
// If we haven't started our editor session yet, just abort.
// The user hasn't seen a SigHelp presentation yet, so they're
// probably not trying to change the currently visible overload.
if (!sessionOpt.PresenterSession.EditorSessionIsActive)
{
DismissSessionIfActive();
return false;
}
// If we've finished computing the items then use the navigation commands to change the // If we've finished computing the items then use the navigation commands to change the
// selected item. Otherwise, the user was just typing and is now moving through the // selected item. Otherwise, the user was just typing and is now moving through the
// file. In this case stop everything we're doing. // file. In this case stop everything we're doing.
......
...@@ -31,6 +31,8 @@ private class SignatureHelpPresenterSession : ForegroundThreadAffinitizedObject, ...@@ -31,6 +31,8 @@ private class SignatureHelpPresenterSession : ForegroundThreadAffinitizedObject,
private ISignatureHelpSession _editorSessionOpt; private ISignatureHelpSession _editorSessionOpt;
private bool _ignoreSelectionStatusChangedEvent; private bool _ignoreSelectionStatusChangedEvent;
public bool EditorSessionIsActive => _editorSessionOpt?.IsDismissed == false;
public SignatureHelpPresenterSession( public SignatureHelpPresenterSession(
ISignatureHelpBroker sigHelpBroker, ISignatureHelpBroker sigHelpBroker,
ITextView textView, ITextView textView,
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.ComponentModel.Composition.Hosting
Imports System.Runtime.CompilerServices Imports System.Runtime.CompilerServices
Imports System.Threading Imports System.Threading
Imports System.Threading.Tasks Imports System.Threading.Tasks
Imports System.Windows.Threading
Imports Microsoft.CodeAnalysis.Editor.Commands Imports Microsoft.CodeAnalysis.Editor.Commands
Imports Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense Imports Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense
Imports Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp Imports Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.SignatureHelp
...@@ -13,7 +13,6 @@ Imports Microsoft.CodeAnalysis.Text ...@@ -13,7 +13,6 @@ Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.VisualStudio.Language.Intellisense Imports Microsoft.VisualStudio.Language.Intellisense
Imports Microsoft.VisualStudio.Text Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Editor Imports Microsoft.VisualStudio.Text.Editor
Imports Microsoft.VisualStudio.Text.Projection
Imports Moq Imports Moq
#Disable Warning RS0007 ' Avoid zero-length array allocations. This is non-shipping test code. #Disable Warning RS0007 ' Avoid zero-length array allocations. This is non-shipping test code.
...@@ -93,6 +92,79 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense ...@@ -93,6 +92,79 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
GetMocks(controller).PresenterSession.Verify(Sub(p) p.Dismiss(), Times.Once) GetMocks(controller).PresenterSession.Verify(Sub(p) p.Dismiss(), Times.Once)
End Sub End Sub
<WpfFact>
<WorkItem(179726, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workItems?id=179726&_a=edit")>
Public Sub DownKeyShouldNotBlockOnModelComputation()
Dim mre = New ManualResetEvent(False)
Dim controller = CreateController(items:=CreateItems(2), waitForPresentation:=False)
Dim slowProvider = New Mock(Of ISignatureHelpProvider)
slowProvider.Setup(Function(p) p.GetItemsAsync(It.IsAny(Of Document), It.IsAny(Of Integer), It.IsAny(Of SignatureHelpTriggerInfo), It.IsAny(Of CancellationToken))) _
.Returns(Function()
mre.WaitOne()
Return Task.FromResult(New SignatureHelpItems(CreateItems(2), TextSpan.FromBounds(0, 0), selectedItem:=0, argumentIndex:=0, argumentCount:=0, argumentName:=Nothing))
End Function)
Dim handled = controller.TryHandleDownKey()
Assert.False(handled)
End Sub
<WpfFact>
<WorkItem(179726, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workItems?id=179726&_a=edit")>
Public Sub UpKeyShouldNotBlockOnModelComputation()
Dim mre = New ManualResetEvent(False)
Dim controller = CreateController(items:=CreateItems(2), waitForPresentation:=False)
Dim slowProvider = New Mock(Of ISignatureHelpProvider)
slowProvider.Setup(Function(p) p.GetItemsAsync(It.IsAny(Of Document), It.IsAny(Of Integer), It.IsAny(Of SignatureHelpTriggerInfo), It.IsAny(Of CancellationToken))) _
.Returns(Function()
mre.WaitOne()
Return Task.FromResult(New SignatureHelpItems(CreateItems(2), TextSpan.FromBounds(0, 0), selectedItem:=0, argumentIndex:=0, argumentCount:=0, argumentName:=Nothing))
End Function)
Dim handled = controller.TryHandleUpKey()
Assert.False(handled)
End Sub
<WpfFact>
<WorkItem(179726, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workItems?id=179726&_a=edit")>
Public Async Function UpKeyShouldBlockOnRecomputationAfterPresentation() As Task
Dim dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher
Dim worker = Async Function()
Dim slowProvider = New Mock(Of ISignatureHelpProvider)
slowProvider.Setup(Function(p) p.GetItemsAsync(It.IsAny(Of Document), It.IsAny(Of Integer), It.IsAny(Of SignatureHelpTriggerInfo), It.IsAny(Of CancellationToken))) _
.Returns(Task.FromResult(New SignatureHelpItems(CreateItems(2), TextSpan.FromBounds(0, 0), selectedItem:=0, argumentIndex:=0, argumentCount:=0, argumentName:=Nothing)))
Dim controller = dispatcher.Invoke(Function() CreateController(provider:=slowProvider.Object, waitForPresentation:=True))
' Update session so that providers are requeried.
' SlowProvider now blocks on the checkpoint's task.
Dim checkpoint = New Checkpoint()
slowProvider.Setup(Function(p) p.GetItemsAsync(It.IsAny(Of Document), It.IsAny(Of Integer), It.IsAny(Of SignatureHelpTriggerInfo), It.IsAny(Of CancellationToken))) _
.Returns(Function()
checkpoint.Task.Wait()
Return Task.FromResult(New SignatureHelpItems(CreateItems(2), TextSpan.FromBounds(0, 2), selectedItem:=0, argumentIndex:=0, argumentCount:=0, argumentName:=Nothing))
End Function)
dispatcher.Invoke(Sub() DirectCast(controller, ICommandHandler(Of TypeCharCommandArgs)).ExecuteCommand(
New TypeCharCommandArgs(CreateMock(Of ITextView), CreateMock(Of ITextBuffer), " "c),
Sub() GetMocks(controller).Buffer.Insert(0, " ")))
Dim handled = dispatcher.InvokeAsync(Function() controller.TryHandleUpKey()) ' Send the controller an up key, which should block on the computation
checkpoint.Release() ' Allow slowprovider to finish
Await handled.Task.ConfigureAwait(False)
' We expect 2 calls to the presenter (because we had an existing presentation session when we started the second computation).
Assert.True(handled.Result)
GetMocks(controller).PresenterSession.Verify(Sub(p) p.PresentItems(It.IsAny(Of ITrackingSpan), It.IsAny(Of IList(Of SignatureHelpItem)),
It.IsAny(Of SignatureHelpItem), It.IsAny(Of Integer?)), Times.Exactly(2))
End Function
Await worker().ConfigureAwait(False)
End Function
<WpfFact> <WpfFact>
Public Sub DownKeyShouldNavigateWhenThereAreMultipleItems() Public Sub DownKeyShouldNavigateWhenThereAreMultipleItems()
Dim controller = CreateController(items:=CreateItems(2), waitForPresentation:=True) Dim controller = CreateController(items:=CreateItems(2), waitForPresentation:=True)
...@@ -195,6 +267,9 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense ...@@ -195,6 +267,9 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Dim presenter = New Mock(Of IIntelliSensePresenter(Of ISignatureHelpPresenterSession, ISignatureHelpSession)) With {.DefaultValue = DefaultValue.Mock} Dim presenter = New Mock(Of IIntelliSensePresenter(Of ISignatureHelpPresenterSession, ISignatureHelpSession)) With {.DefaultValue = DefaultValue.Mock}
presenterSession = If(presenterSession, New Mock(Of ISignatureHelpPresenterSession) With {.DefaultValue = DefaultValue.Mock}) presenterSession = If(presenterSession, New Mock(Of ISignatureHelpPresenterSession) With {.DefaultValue = DefaultValue.Mock})
presenter.Setup(Function(p) p.CreateSession(It.IsAny(Of ITextView), It.IsAny(Of ITextBuffer), It.IsAny(Of ISignatureHelpSession))).Returns(presenterSession.Object) presenter.Setup(Function(p) p.CreateSession(It.IsAny(Of ITextView), It.IsAny(Of ITextBuffer), It.IsAny(Of ISignatureHelpSession))).Returns(presenterSession.Object)
presenterSession.Setup(Sub(p) p.PresentItems(It.IsAny(Of ITrackingSpan), It.IsAny(Of IList(Of SignatureHelpItem)), It.IsAny(Of SignatureHelpItem), It.IsAny(Of Integer?))) _
.Callback(Sub() presenterSession.SetupGet(Function(p) p.EditorSessionIsActive).Returns(True))
Dim controller = New Controller( Dim controller = New Controller(
view.Object, view.Object,
......
...@@ -13,6 +13,13 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense ...@@ -13,6 +13,13 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Public SignatureHelpItems As IList(Of SignatureHelpItem) Public SignatureHelpItems As IList(Of SignatureHelpItem)
Public SelectedItem As SignatureHelpItem Public SelectedItem As SignatureHelpItem
Public SelectedParameter As Integer? Public SelectedParameter As Integer?
Private presented As Boolean = False
Public ReadOnly Property EditorSessionIsActive As Boolean Implements ISignatureHelpPresenterSession.EditorSessionIsActive
Get
Return presented
End Get
End Property
Public Event Dismissed As EventHandler(Of EventArgs) Implements ISignatureHelpPresenterSession.Dismissed Public Event Dismissed As EventHandler(Of EventArgs) Implements ISignatureHelpPresenterSession.Dismissed
Public Event ItemSelected As EventHandler(Of SignatureHelpItemEventArgs) Implements ISignatureHelpPresenterSession.ItemSelected Public Event ItemSelected As EventHandler(Of SignatureHelpItemEventArgs) Implements ISignatureHelpPresenterSession.ItemSelected
...@@ -30,10 +37,12 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense ...@@ -30,10 +37,12 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense
Me.SignatureHelpItems = signatureHelpItems Me.SignatureHelpItems = signatureHelpItems
Me.SelectedItem = selectedItem Me.SelectedItem = selectedItem
Me.SelectedParameter = selectedParameter Me.SelectedParameter = selectedParameter
Me.presented = True
End Sub End Sub
Public Sub Dismiss() Implements ISignatureHelpPresenterSession.Dismiss Public Sub Dismiss() Implements ISignatureHelpPresenterSession.Dismiss
_testState.CurrentSignatureHelpPresenterSession = Nothing _testState.CurrentSignatureHelpPresenterSession = Nothing
Me.presented = False
End Sub End Sub
Public Sub SetSelectedItem(item As SignatureHelpItem) Public Sub SetSelectedItem(item As SignatureHelpItem)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册