Skip to content

Commit

Permalink
Merge pull request #33795 from sharwell/enable-async-completion
Browse files Browse the repository at this point in the history
Enable async completion
  • Loading branch information
sharwell committed Mar 3, 2019
2 parents 726c2bc + 90a0227 commit 2cab0d7
Show file tree
Hide file tree
Showing 21 changed files with 291 additions and 72 deletions.
18 changes: 13 additions & 5 deletions azure-pipelines-integration.yml
Expand Up @@ -22,16 +22,24 @@ jobs:
- job: Windows_VisualStudio_Integration_Tests
pool: dotnet-external-vs2019-preview
strategy:
maxParallel: 2
maxParallel: 4
matrix:
debug:
_configuration: Debug
_useLegacyCompletion: false
release:
_configuration: Release
_useLegacyCompletion: false
debug_legacy:
_configuration: Debug
_useLegacyCompletion: true
release_legacy:
_configuration: Release
_useLegacyCompletion: true
timeoutInMinutes: 135

steps:
- script: eng/cibuild.cmd -configuration $(_configuration) -prepareMachine -testVsi
- script: eng/cibuild.cmd -configuration $(_configuration) -prepareMachine -testVsi -testLegacyCompletion:$$(_useLegacyCompletion)
displayName: Build and Test

- task: PublishTestResults@1
Expand All @@ -40,14 +48,14 @@ jobs:
testRunner: XUnit
testResultsFiles: $(Build.SourcesDirectory)\artifacts\TestResults\$(_configuration)\*.xml
mergeTestResults: true
testRunTitle: 'Windows Visual Studio Integration $(_configuration)'
testRunTitle: 'Windows Visual Studio Integration $(_configuration)_$(_useLegacyCompletion)'
condition: always()

- task: PublishBuildArtifacts@1
displayName: Publish Logs
inputs:
PathtoPublish: '$(Build.SourcesDirectory)\artifacts\log\$(_configuration)'
ArtifactName: 'Windows Visual Studio Integration $(_configuration)'
ArtifactName: 'Windows Visual Studio Integration $(_configuration)_$(_useLegacyCompletion)'
publishLocation: Container
continueOnError: true
condition: not(succeeded())
Expand All @@ -56,7 +64,7 @@ jobs:
displayName: Publish Screenshots
inputs:
PathtoPublish: '$(Build.SourcesDirectory)\artifacts\bin\Microsoft.VisualStudio.LanguageServices.IntegrationTests\$(_configuration)\net472\xUnitResults'
ArtifactName: 'Screenshots $(_configuration)'
ArtifactName: 'Screenshots $(_configuration)_$(_useLegacyCompletion)'
publishLocation: Container
continueOnError: true
condition: not(succeeded())
9 changes: 9 additions & 0 deletions eng/build.ps1
Expand Up @@ -57,6 +57,7 @@ param (
[switch][Alias('test')]$testDesktop,
[switch]$testCoreClr,
[switch]$testIOperation,
[switch]$testLegacyCompletion,

[parameter(ValueFromRemainingArguments=$true)][string[]]$properties)

Expand Down Expand Up @@ -87,6 +88,7 @@ function Print-Usage() {
Write-Host " -testCoreClr Run CoreClr unit tests"
Write-Host " -testVsi Run all integration tests"
Write-Host " -testIOperation Run extra checks to validate IOperations"
Write-Host " -testLegacyCompletion Run integration tests with legacy completion"
Write-Host ""
Write-Host "Advanced settings:"
Write-Host " -ci Set when running on CI server"
Expand Down Expand Up @@ -325,6 +327,10 @@ function TestUsingOptimizedRunner() {
$env:ROSLYN_TEST_IOPERATION = "true"
}

if ($testLegacyCompletion) {
$env:ROSLYN_TEST_LEGACY_COMPLETION = "true"
}

$testResultsDir = Join-Path $ArtifactsDir "TestResults\$configuration"
$binDir = Join-Path $ArtifactsDir "bin"
$runTests = GetProjectOutputBinary "RunTests.exe"
Expand Down Expand Up @@ -397,6 +403,9 @@ function TestUsingOptimizedRunner() {
if ($testIOperation) {
Remove-Item env:\ROSLYN_TEST_IOPERATION
}
if ($testLegacyCompletion) {
Remove-Item env:\ROSLYN_TEST_LEGACY_COMPLETION
}
}
}

Expand Down
Expand Up @@ -162,5 +162,21 @@ private ImmutableHashSet<char> GetAllAutoBraceCompletionChars(IContentType buffe

return set;
}

internal TestAccessor GetTestAccessor()
=> new TestAccessor(this);

internal readonly struct TestAccessor
{
private readonly AsyncCompletionService _asyncCompletionService;

public TestAccessor(AsyncCompletionService asyncCompletionService)
{
_asyncCompletionService = asyncCompletionService;
}

internal bool UseLegacyCompletion(ITextView textView, ITextBuffer subjectBuffer)
=> _asyncCompletionService.UseLegacyCompletion(textView, subjectBuffer);
}
}
}
Expand Up @@ -51,7 +51,7 @@ public override async Task InitializeAsync()
_projectTemplate != WellKnownProjectTemplates.WpfApplication &&
_projectTemplate != WellKnownProjectTemplates.CSharpNetCoreClassLibrary)
{
VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);
ClearEditor();
}
}
Expand Down
Expand Up @@ -63,6 +63,13 @@ public virtual async Task InitializeAsync()
/// </summary>
public virtual Task DisposeAsync()
{
if (VisualStudio?.Editor.IsCompletionActive() ?? false)
{
// Make sure completion isn't visible.
// 🐛 Only needed as a workaround for https://devdiv.visualstudio.com/DevDiv/_workitems/edit/801435
VisualStudio.SendKeys.Send(VirtualKey.Escape);
}

_visualStudioContext.Dispose();
return Task.CompletedTask;
}
Expand Down
@@ -1,5 +1,7 @@
// 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.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
Expand Down Expand Up @@ -87,7 +89,7 @@ public static class NavigateTo
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public void CtrlAltSpace()
{
VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);

VisualStudio.Editor.SendKeys("nam Goo", VirtualKey.Enter);
VisualStudio.Editor.SendKeys('{', VirtualKey.Enter, '}', VirtualKey.Up, VirtualKey.Enter);
Expand All @@ -99,7 +101,7 @@ public void CtrlAltSpace()
VisualStudio.Editor.Verify.CurrentLineText("System.Console.WriteLine();$$", assertCaretPosition: true);
VisualStudio.Editor.SendKeys(VirtualKey.Home, Shift(VirtualKey.End), VirtualKey.Delete);

VisualStudio.ExecuteCommand(WellKnownCommandNames.Edit_ToggleCompletionMode);
VisualStudio.Editor.SendKeys(new KeyPress(VirtualKey.Space, ShiftState.Ctrl | ShiftState.Alt));

VisualStudio.Editor.SendKeys("System.Console.writeline();");
VisualStudio.Editor.Verify.CurrentLineText("System.Console.writeline();$$", assertCaretPosition: true);
Expand All @@ -108,13 +110,13 @@ public void CtrlAltSpace()
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public void CtrlAltSpaceOption()
{
VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);

VisualStudio.Editor.SendKeys("nam Goo");
VisualStudio.Editor.Verify.CurrentLineText("namespace Goo$$", assertCaretPosition: true);

ClearEditor();
VisualStudio.Workspace.SetUseSuggestionMode(true);
VisualStudio.Editor.SetUseSuggestionMode(true);

VisualStudio.Editor.SendKeys("nam Goo");
VisualStudio.Editor.Verify.CurrentLineText("nam Goo$$", assertCaretPosition: true);
Expand Down Expand Up @@ -157,6 +159,20 @@ void Main(string[] args)
VisualStudio.Editor.SendKeys("<s");
VisualStudio.Editor.Verify.CompletionItemsExist("see", "seealso", "summary");

if (LegacyCompletionCondition.Instance.ShouldSkip)
{
// 🐛 Workaround for https://github.com/dotnet/roslyn/issues/33824
var completionItems = VisualStudio.Editor.GetCompletionItems();
var targetIndex = Array.IndexOf(completionItems, "see");
var currentIndex = Array.IndexOf(completionItems, VisualStudio.Editor.GetCurrentCompletionItem());
if (currentIndex != targetIndex)
{
var key = currentIndex < targetIndex ? VirtualKey.Down : VirtualKey.Up;
var keys = Enumerable.Repeat(key, Math.Abs(currentIndex - targetIndex)).Cast<object>().ToArray();
VisualStudio.Editor.SendKeys(keys);
}
}

VisualStudio.Editor.SendKeys(VirtualKey.Enter);
VisualStudio.Editor.Verify.CurrentLineText("///<see cref=\"$$\"/>", assertCaretPosition: true);
}
Expand Down Expand Up @@ -193,15 +209,17 @@ void Main(string[] args)
}
}");

VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);

VisualStudio.Editor.SendKeys("Mai(");

VisualStudio.Editor.Verify.CurrentSignature("void Class1.Main(string[] args)");
VisualStudio.Editor.Verify.CurrentParameter("args", "");
}

[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
// 🐛 The async completion controller in 16.0 Preview 4 fails to account for brace completion sessions.
[ConditionalWpfFact(typeof(LegacyCompletionCondition)), Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem(33825, "https://github.com/dotnet/roslyn/issues/33825")]
public void CompletionUsesTrackingPointsInTheFaceOfAutomaticBraceCompletion()
{
SetUpEditor(@"
Expand All @@ -211,7 +229,7 @@ void Main(string[] args)
$$
}");

VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);

VisualStudio.Editor.SendKeys(
'{',
Expand All @@ -232,7 +250,9 @@ void Main(string[] args)
assertCaretPosition: true);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
// 🐛 This should work with async completion, but currently does not.
[ConditionalWpfFact(typeof(LegacyCompletionCondition)), Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem(33823, "https://github.com/dotnet/roslyn/issues/33823")]
public void CommitOnShiftEnter()
{
SetUpEditor(@"
Expand All @@ -244,7 +264,7 @@ void Main(string[] args)
}
}");

VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);

VisualStudio.Editor.SendKeys(
'M',
Expand All @@ -261,6 +281,36 @@ void Main(string[] args)
assertCaretPosition: true);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public void LineBreakOnShiftEnter()
{
SetUpEditor(@"
class Class1
{
void Main(string[] args)
{
$$
}
}");

VisualStudio.Editor.SetUseSuggestionMode(true);

VisualStudio.Editor.SendKeys(
'M',
Shift(VirtualKey.Enter));

VisualStudio.Editor.Verify.TextContains(@"
class Class1
{
void Main(string[] args)
{
M
$$
}
}",
assertCaretPosition: true);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public void CommitOnLeftCurly()
{
Expand All @@ -270,7 +320,7 @@ class Class1
$$
}");

VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);

VisualStudio.Editor.SendKeys("int P { g{");

Expand All @@ -282,26 +332,31 @@ class Class1
assertCaretPosition: true);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
[ConditionalWpfFact(typeof(LegacyCompletionCondition)), Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem(33822, "https://github.com/dotnet/roslyn/issues/33822")]
public void EnsureTheCaretIsVisibleAfterALongEdit()
{
SetUpEditor(@"
var visibleColumns = VisualStudio.Editor.GetVisibleColumnCount();
var variableName = new string('a', (int)(0.75 * visibleColumns));
SetUpEditor($@"
public class Program
{
{{
static void Main(string[] args)
{
var aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 0;
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = $$
}
}");
{{
var {variableName} = 0;
{variableName} = $$
}}
}}");

Assert.True(variableName.Length > 0);
VisualStudio.Editor.SendKeys(
VirtualKey.Delete,
"aaa",
VirtualKey.Tab);
var actualText = VisualStudio.Editor.GetText();
Assert.Contains("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", actualText);
Assert.Contains($"{variableName} = {variableName}", actualText);
Assert.True(VisualStudio.Editor.IsCaretOnScreen());
Assert.True(VisualStudio.Editor.GetCaretColumn() > visibleColumns, "This test is inconclusive if the view didn't need to move to keep the caret on screen.");
}

[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
Expand Down
Expand Up @@ -97,7 +97,6 @@ public async Task WpfInteractionAsync()
[WpfFact]
public void TypingHelpDirectiveWorks()
{
VisualStudio.Workspace.SetUseSuggestionMode(true);
VisualStudio.InteractiveWindow.ShowWindow(waitForPrompt: true);

// Directly type #help, rather than sending it through VisualStudio.InteractiveWindow.SubmitText. We want to actually test
Expand Down
Expand Up @@ -18,7 +18,6 @@ public CSharpInteractiveDirectives(VisualStudioInstanceFactory instanceFactory)
[WpfFact]
public void VerifyHostCommandsCompletionList()
{
VisualStudio.Workspace.SetUseSuggestionMode(true);
VisualStudio.InteractiveWindow.InsertCode("#");
VisualStudio.InteractiveWindow.InvokeCompletionList();

Expand Down
Expand Up @@ -16,15 +16,9 @@ public CSharpReplIdeFeatures(VisualStudioInstanceFactory instanceFactory)
{
}

public override async Task InitializeAsync()
{
await base.InitializeAsync().ConfigureAwait(true);
VisualStudio.Workspace.SetUseSuggestionMode(true);
}

public override Task DisposeAsync()
{
VisualStudio.Workspace.SetUseSuggestionMode(false);
VisualStudio.Editor.SetUseSuggestionMode(false);
VisualStudio.InteractiveWindow.ClearReplText();
VisualStudio.InteractiveWindow.Reset();
return base.DisposeAsync();
Expand Down

0 comments on commit 2cab0d7

Please sign in to comment.