Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Properly support TableEntryNavigateEventArgs.ShouldActivate #57889

Merged
merged 2 commits into from
Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public bool CanNavigateTo()
return false;
}

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public Task NavigateToAsync(bool isPreview, bool shouldActivate, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(CanNavigateTo());

Expand All @@ -309,7 +309,9 @@ public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
workspace,
_excerptResult.Document.Id,
_excerptResult.Span,
solution.Options.WithChangedOption(NavigationOptions.PreferProvisionalTab, isPreview),
solution.Options
.WithChangedOption(NavigationOptions.PreferProvisionalTab, isPreview)
.WithChangedOption(NavigationOptions.ActivateTab, shouldActivate),
cancellationToken);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public MetadataDefinitionItemEntry(
public bool CanNavigateTo()
=> true;

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public Task NavigateToAsync(bool isPreview, bool shouldActivate, CancellationToken cancellationToken)
=> DefinitionBucket.DefinitionItem.TryNavigateToAsync(
Presenter._workspace, showInPreviewTab: isPreview, activateTab: !isPreview, cancellationToken); // Only activate the tab if not opening in preview
Presenter._workspace, showInPreviewTab: isPreview, activateTab: shouldActivate, cancellationToken); // Only activate the tab if requested

protected override IList<Inline> CreateLineTextInlines()
=> DefinitionBucket.DefinitionItem.DisplayParts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public static Task<Entry> CreateAsync(
public bool CanNavigateTo()
=> _navigationBucket != null && _navigationBucket.CanNavigateTo();

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public Task NavigateToAsync(bool isPreview, bool shouldActivate, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(CanNavigateTo());
Contract.ThrowIfNull(_navigationBucket);
return _navigationBucket.NavigateToAsync(isPreview, cancellationToken);
return _navigationBucket.NavigateToAsync(isPreview, shouldActivate, cancellationToken);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async static Task ProcessNavigateAsync(
allowCancellation: true,
showProgress: false);

await supportsNavigation.NavigateToAsync(e.IsPreview, context.UserCancellationToken).ConfigureAwait(false);
await supportsNavigation.NavigateToAsync(e.IsPreview, e.ShouldActivate, context.UserCancellationToken).ConfigureAwait(false);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ namespace Microsoft.VisualStudio.LanguageServices.FindUsages
internal interface ISupportsNavigation
{
bool CanNavigateTo();
Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken);
Task NavigateToAsync(bool isPreview, bool shouldActivate, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ public static RoslynDefinitionBucket Create(
public bool CanNavigateTo()
=> true;

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public Task NavigateToAsync(bool isPreview, bool shouldActivate, CancellationToken cancellationToken)
=> DefinitionItem.TryNavigateToAsync(
_presenter._workspace, showInPreviewTab: isPreview, activateTab: !isPreview, cancellationToken); // Only activate the tab if not opening in preview
_presenter._workspace, showInPreviewTab: isPreview, activateTab: shouldActivate, cancellationToken); // Only activate the tab if requested

public override bool TryGetValue(string key, out object? content)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ void M()
}
});

VisualStudio.FindReferencesWindow.NavigateTo(activeWindowCaption, results[0], isPreview: false);
VisualStudio.FindReferencesWindow.NavigateTo(activeWindowCaption, results[0], isPreview: false, shouldActivate: true);
// Assert we are in the right file now
VisualStudio.Editor.Activate();
Assert.Equal("Class1.cs", VisualStudio.Shell.GetActiveWindowCaption());
Assert.Equal("Program", VisualStudio.Editor.GetLineTextAfterCaret());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public static void Main()
var programReferencesCaption = $"'{HelloWorldGenerator.GeneratedEnglishClassName}' references";
var results = VisualStudio.FindReferencesWindow.GetContents(programReferencesCaption);
var referenceInGeneratedFile = results.Single(r => r.Code.Contains("<summary>"));
VisualStudio.FindReferencesWindow.NavigateTo(programReferencesCaption, referenceInGeneratedFile, isPreview: isPreview);
VisualStudio.FindReferencesWindow.NavigateTo(programReferencesCaption, referenceInGeneratedFile, isPreview: isPreview, shouldActivate: true);

// Assert we are in the right file now
Assert.Equal($"{HelloWorldGenerator.GeneratedEnglishClassName}.cs {ServicesVSResources.generated_suffix}", VisualStudio.Shell.GetActiveWindowCaption());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ End Class
}
});

VisualStudio.FindReferencesWindow.NavigateTo(activeWindowCaption, results[0], isPreview: false);
VisualStudio.FindReferencesWindow.NavigateTo(activeWindowCaption, results[0], isPreview: false, shouldActivate: true);
// Assert we are in the right file now
VisualStudio.Editor.Activate();
Assert.Equal("Class1.vb", VisualStudio.Shell.GetActiveWindowCaption());
Assert.Equal("Alpha As Int32", VisualStudio.Editor.GetLineTextAfterCaret());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,24 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.UnitTests;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Common;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Input;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Outlining;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;
using UIAutomationClient;
using Xunit;
using ThreadHelper = Microsoft.VisualStudio.Shell.ThreadHelper;

namespace Microsoft.VisualStudio.IntegrationTest.Utilities.InProcess
Expand Down Expand Up @@ -820,5 +823,27 @@ public void SendExplicitFocus()
var view = GetActiveVsTextView();
view.SendExplicitFocus();
});

public void WaitForEditorOperations(TimeSpan timeout)
{
var joinableTaskCollection = InvokeOnUIThread(cancellationToken =>
{
var shell = GetGlobalService<SVsShell, IVsShell>();
if (shell.IsPackageLoaded(DefGuidList.guidEditorPkg, out var editorPackage) == VSConstants.S_OK)
{
var asyncPackage = (AsyncPackage)editorPackage;
var collection = asyncPackage.GetPropertyValue<JoinableTaskCollection>("JoinableTaskCollection");
return collection;
}

return null;
});

if (joinableTaskCollection is not null)
{
using var cts = new CancellationTokenSource(timeout);
joinableTaskCollection.JoinTillEmptyAsync(cts.Token).Wait(cts.Token);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public Reference[] GetContents(string windowCaption)
});
}

public void NavigateTo(string windowCaption, Reference reference, bool isPreview)
public void NavigateTo(string windowCaption, Reference reference, bool isPreview, bool shouldActivate)
{
InvokeOnUIThread(cancellationToken =>
{
Expand All @@ -63,7 +63,7 @@ public void NavigateTo(string windowCaption, Reference reference, bool isPreview
{
if (reference.Equals(CreateReference(item)))
{
item.NavigateTo(isPreview);
item.NavigateTo(isPreview, shouldActivate);
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
Expand Down Expand Up @@ -377,5 +378,8 @@ public void GoToImplementation(string expectedWindowName)

public void SendExplicitFocus()
=> _editorInProc.SendExplicitFocus();

public void WaitForEditorOperations(TimeSpan timeout)
=> _editorInProc.WaitForEditorOperations(timeout);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,19 @@ public Reference[] GetContents(string windowCaption)
return _inProc.GetContents(windowCaption);
}

public void NavigateTo(string windowCaption, Reference reference, bool isPreview)
public void NavigateTo(string windowCaption, Reference reference, bool isPreview, bool shouldActivate)
{
_inProc.NavigateTo(windowCaption, reference, isPreview);
_inProc.NavigateTo(windowCaption, reference, isPreview, shouldActivate);
WaitForNavigate();
}

private void WaitForNavigate()
{
// Navigation operations handled by Roslyn are tracked by FeatureAttribute.FindReferences
VisualStudioInstance.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.FindReferences);

// Navigation operations handled by the editor are tracked within its own JoinableTaskFactory instance
VisualStudioInstance.Editor.WaitForEditorOperations(Helper.HangMitigatingTimeout);
}
}
}