提交 b0369a86 编写于 作者: C CyrusNajmabadi

Move to WpfFact for indentation tests.

Here's why we need this:  This set of commits changes SplitString and Indentation to use a synchronous
path for getting a syntax tree.  This is so that those features willblock hte UI thread for as small an
amount of time as possible.

*However*, it's not always the case that they actually get the syntax tree synchronously.  in order for
them to get the tree, they need to call AsyncLazy.GetValue to actually get the value.  However, AsyncLazy.GetValue
will not actually perform synchronously if there is an existing async request already in flight.

In practice that can happen because the background parser ends up kicking off work to try to get the
syntax tree asynchronously.  Because of this, when we call into get the tree synchronously the asynclazy
actually has us wait on the async work that is in flight.

In tests this causes us to assert because we're blocking on async work on a non-UI thread.  We had two options
here:

1. Change AsyncLazy to not wait on the async work here and instead go execute the work synchronously.
2. Change teh tests to be WpfFact

Jason and I discussed hte first option but decided against it.  Changing async lazy has huge downstream ramifications
and we weren't comfortable just changing it's behavior in that manner.

Note: during tests we found 99% of the time, we did go through the sync path.  So, ideally, the impact
of us blocking the UI thread on async work is minimal in practice.
上级 00181a01
......@@ -30,23 +30,28 @@ public bool ExecuteCommandWorker(ReturnKeyCommandArgs args)
{
var textView = args.TextView;
var subjectBuffer = args.SubjectBuffer;
var caret = textView.GetCaretPoint(subjectBuffer);
var spans = textView.Selection.GetSnapshotSpansOnBuffer(subjectBuffer);
if (caret != null)
// Don't split strings if there is any actual selection.
if (spans.Count == 1 && spans[0].IsEmpty)
{
// Quick check. If the line doesn't contain a quote in it before the caret,
// then no point in doing any more expensive synchronous work.
var line = subjectBuffer.CurrentSnapshot.GetLineFromPosition(caret.Value);
if (LineContainsQuote(line, caret.Value))
var caret = textView.GetCaretPoint(subjectBuffer);
if (caret != null)
{
return SplitString(textView, subjectBuffer, caret);
// Quick check. If the line doesn't contain a quote in it before the caret,
// then no point in doing any more expensive synchronous work.
var line = subjectBuffer.CurrentSnapshot.GetLineFromPosition(caret.Value);
if (LineContainsQuote(line, caret.Value))
{
return SplitString(textView, subjectBuffer, caret.Value);
}
}
}
return false;
}
private bool SplitString(ITextView textView, ITextBuffer subjectBuffer, SnapshotPoint? caret)
private bool SplitString(ITextView textView, ITextBuffer subjectBuffer, SnapshotPoint caret)
{
var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
......@@ -58,7 +63,7 @@ private bool SplitString(ITextView textView, ITextBuffer subjectBuffer, Snapshot
if (enabled)
{
var cursorPosition = SplitStringLiteral(
subjectBuffer, document, caret.Value.Position, CancellationToken.None);
subjectBuffer, document, caret, CancellationToken.None);
if (cursorPosition != null)
{
......
......@@ -17,7 +17,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting.Indentation
public class SmartIndenterEnterOnTokenTests : FormatterTestsBase
{
[WorkItem(537808, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537808")]
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MethodBody1()
{
......@@ -34,7 +34,7 @@ void method()
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Preprocessor1()
{
......@@ -50,7 +50,7 @@ public async Task Preprocessor1()
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Preprocessor2()
{
......@@ -66,7 +66,7 @@ public async Task Preprocessor2()
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Preprocessor3()
{
......@@ -79,7 +79,7 @@ public async Task Preprocessor3()
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Comments()
{
......@@ -96,7 +96,7 @@ class Class
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task UsingDirective()
{
......@@ -110,7 +110,7 @@ public async Task UsingDirective()
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task AfterTopOfFileComment()
{
......@@ -124,7 +124,7 @@ public async Task AfterTopOfFileComment()
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task DottedName()
{
......@@ -137,7 +137,7 @@ public async Task DottedName()
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Namespace()
{
......@@ -153,7 +153,7 @@ namespace NS
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task NamespaceDottedName()
{
......@@ -168,7 +168,7 @@ namespace NS.
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task NamespaceBody()
{
......@@ -185,7 +185,7 @@ namespace NS
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task NamespaceCloseBrace()
{
......@@ -202,7 +202,7 @@ namespace NS
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Class()
{
......@@ -220,7 +220,7 @@ class Class
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task ClassBody()
{
......@@ -239,7 +239,7 @@ class Class
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task ClassCloseBrace()
{
......@@ -258,7 +258,7 @@ class Class
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Method()
{
......@@ -279,7 +279,7 @@ void Method()
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MethodBody()
{
......@@ -301,7 +301,7 @@ void Method()
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MethodCloseBrace()
{
......@@ -323,7 +323,7 @@ void Method()
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Statement()
{
......@@ -346,7 +346,7 @@ void Method()
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MethodCall()
{
......@@ -366,7 +366,7 @@ void Method()
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Switch()
{
......@@ -389,7 +389,7 @@ void Method()
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task SwitchBody()
{
......@@ -413,7 +413,7 @@ void Method()
expectedIndentation: 16);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task SwitchCase()
{
......@@ -438,7 +438,7 @@ void Method()
expectedIndentation: 20);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task SwitchCaseBlock()
{
......@@ -463,7 +463,7 @@ void Method()
expectedIndentation: 20);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Block()
{
......@@ -489,7 +489,7 @@ void Method()
expectedIndentation: 24);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MultilineStatement1()
{
......@@ -511,7 +511,7 @@ void Method()
expectedIndentation: 16);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MultilineStatement2()
{
......@@ -535,7 +535,7 @@ void Method()
}
// Bug number 902477
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Comments2()
{
......@@ -555,7 +555,7 @@ void Method()
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task AfterCompletedBlock()
{
......@@ -576,7 +576,7 @@ static void Main(string[] args)
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task AfterTopLevelAttribute()
{
......@@ -595,7 +595,7 @@ public async Task AfterTopLevelAttribute()
}
[WorkItem(537802, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537802")]
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task EmbededStatement()
{
......@@ -618,7 +618,7 @@ static void Main(string[] args)
}
[WorkItem(537808, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537808")]
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MethodBraces1()
{
......@@ -636,7 +636,7 @@ void method()
}
[WorkItem(537808, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537808")]
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task MethodBraces2()
{
......@@ -655,7 +655,7 @@ void method()
}
[WorkItem(537795, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537795")]
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Property1()
{
......@@ -676,7 +676,7 @@ string Name
}
[WorkItem(537563, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537563")]
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Class1()
{
......@@ -691,7 +691,7 @@ public async Task Class1()
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[WorkItem(1070773, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task ArrayInitializer1()
......@@ -708,7 +708,7 @@ public async Task ArrayInitializer1()
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task ArrayInitializer2()
{
......@@ -727,7 +727,7 @@ public async Task ArrayInitializer2()
expectedIndentation: 4);
}
[Fact]
[WpfFact]
[WorkItem(1070773, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")]
[Trait(Traits.Feature, Traits.Features.SmartTokenFormatting)]
public async Task ArrayInitializer3()
......@@ -748,7 +748,7 @@ void Method(int i)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task QueryExpression2()
{
......@@ -768,7 +768,7 @@ void Method()
expectedIndentation: 16);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task QueryExpression3()
{
......@@ -788,7 +788,7 @@ where select
expectedIndentation: 16);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task QueryExpression4()
{
......@@ -808,7 +808,7 @@ void Method()
expectedIndentation: 16);
}
[Fact]
[WpfFact]
[WorkItem(853748, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/853748")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task ArrayInitializer()
......@@ -829,7 +829,7 @@ void Method()
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(939305, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/939305")]
[WorkItem(1070773, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
......@@ -851,7 +851,7 @@ void M(object[] q)
expectedIndentation: 14);
}
[Fact]
[WpfFact]
[WorkItem(1070773, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task CollectionExpression()
......@@ -873,7 +873,7 @@ void M(List<int> e)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(1070773, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task ObjectInitializer()
......@@ -900,7 +900,7 @@ class What
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task Preprocessor()
{
......@@ -913,7 +913,7 @@ public async Task Preprocessor()
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[WorkItem(1070774, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070774")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInitializerWithTypeBody_Implicit()
......@@ -930,7 +930,7 @@ public async Task InsideInitializerWithTypeBody_Implicit()
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(1070774, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070774")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInitializerWithTypeBody_ImplicitNew()
......@@ -947,7 +947,7 @@ public async Task InsideInitializerWithTypeBody_ImplicitNew()
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(1070774, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070774")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInitializerWithTypeBody_Explicit()
......@@ -964,7 +964,7 @@ public async Task InsideInitializerWithTypeBody_Explicit()
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(1070774, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070774")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInitializerWithTypeBody_Collection()
......@@ -982,7 +982,7 @@ class X {
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(1070774, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070774")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInitializerWithTypeBody_ObjectInitializers()
......@@ -1007,7 +1007,7 @@ class What
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationString_1()
......@@ -1028,7 +1028,7 @@ static void Main(string[] args)
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationString_2()
......@@ -1049,7 +1049,7 @@ static void Main(string[] args)
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationString_3()
......@@ -1070,7 +1070,7 @@ static void Main(string[] args)
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationString_4()
......@@ -1091,7 +1091,7 @@ static void Main(string[] args)
expectedIndentation: 0);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task OutsideInterpolationString()
......@@ -1112,7 +1112,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_1()
......@@ -1133,7 +1133,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_2()
......@@ -1155,7 +1155,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_3()
......@@ -1176,7 +1176,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_4()
......@@ -1197,7 +1197,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_5()
......@@ -1218,7 +1218,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_6()
......@@ -1239,7 +1239,7 @@ static void Main(string[] args)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task InsideInterpolationSyntax_7()
......@@ -1260,7 +1260,7 @@ static void Main(string[] args)
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(872, "https://github.com/dotnet/roslyn/issues/872")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task IndentLambdaBodyOneIndentationToFirstTokenOfTheStatement()
......@@ -1281,7 +1281,7 @@ static void Main(string[] args)
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[WorkItem(1339, "https://github.com/dotnet/roslyn/issues/1339")]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task IndentAutoPropertyInitializerAsPartOfTheDeclaration()
......@@ -1300,7 +1300,7 @@ static void Main(string[] args)
expectedIndentation: 8);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task IndentPatternPropertyFirst()
{
......@@ -1321,7 +1321,7 @@ void Main(object o)
expectedIndentation: 12);
}
[Fact]
[WpfFact]
[Trait(Traits.Feature, Traits.Features.SmartIndent)]
public async Task IndentPatternPropertySecond()
{
......
......@@ -5,9 +5,11 @@
using Microsoft.CodeAnalysis.Editor.CSharp.SplitStringLiteral;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text;
using Roslyn.Test.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SplitStringLiteral
{
......@@ -20,9 +22,9 @@ public class SplitStringLiteralCommandHandlerTests
{
var document = workspace.Documents.Single();
var view = document.GetTextView();
var cursorPosition = document.CursorPosition.Value;
view.Caret.MoveTo(new SnapshotPoint(view.TextBuffer.CurrentSnapshot, cursorPosition));
var snapshot = view.TextBuffer.CurrentSnapshot;
view.SetSelection(document.SelectedSpans.Single().ToSnapshotSpan(snapshot));
var commandHandler = new SplitStringLiteralCommandHandler();
commandHandler.ExecuteCommand(new ReturnKeyCommandArgs(view, view.TextBuffer), callback);
......@@ -30,11 +32,11 @@ public class SplitStringLiteralCommandHandlerTests
if (expectedOutputMarkup != null)
{
string expectedOutput;
int expectedCursorPosition;
MarkupTestFile.GetPosition(expectedOutputMarkup, out expectedOutput, out expectedCursorPosition);
IList<TextSpan> expectedSpans;
MarkupTestFile.GetSpans(expectedOutputMarkup, out expectedOutput, out expectedSpans);
Assert.Equal(expectedOutput, view.TextBuffer.CurrentSnapshot.AsText().ToString());
Assert.Equal(expectedCursorPosition, view.Caret.Position.BufferPosition.Position);
Assert.Equal(expectedSpans.Single().Start, view.Caret.Position.BufferPosition.Position);
}
}
}
......@@ -68,7 +70,7 @@ public async Task TestMissingBeforeString()
await TestNotHandledAsync(
@"class C {
void M() {
var v = $$"""";
var v = [||]"""";
}
}");
}
......@@ -79,7 +81,7 @@ public async Task TestMissingBeforeInterpolatedString()
await TestNotHandledAsync(
@"class C {
void M() {
var v = $$$"""";
var v = [||]$"""";
}
}");
}
......@@ -90,7 +92,7 @@ public async Task TestMissingAfterString()
await TestNotHandledAsync(
@"class C {
void M() {
var v = """"$$;
var v = """"[||];
}
}");
}
......@@ -101,7 +103,7 @@ public async Task TestMissingAfterInterpolatedString()
await TestNotHandledAsync(
@"class C {
void M() {
var v = $""""$$;
var v = $""""[||];
}
}");
}
......@@ -112,7 +114,7 @@ public async Task TestMissingInVerbatimString()
await TestNotHandledAsync(
@"class C {
void M() {
var v = @""a$$b"";
var v = @""a[||]b"";
}
}");
}
......@@ -123,7 +125,7 @@ public async Task TestMissingInInterpolatedVerbatimString()
await TestNotHandledAsync(
@"class C {
void M() {
var v = $@""a$$b"";
var v = $@""a[||]b"";
}
}");
}
......@@ -134,13 +136,13 @@ public async Task TestInEmptyString()
await TestHandledAsync(
@"class C {
void M() {
var v = ""$$"";
var v = ""[||]"";
}
}",
@"class C {
void M() {
var v = """" +
""$$"";
""[||]"";
}
}");
}
......@@ -151,13 +153,13 @@ public async Task TestInEmptyInterpolatedString()
await TestHandledAsync(
@"class C {
void M() {
var v = $""$$"";
var v = $""[||]"";
}
}",
@"class C {
void M() {
var v = $"""" +
$""$$"";
$""[||]"";
}
}");
}
......@@ -168,13 +170,13 @@ public async Task TestSimpleString1()
await TestHandledAsync(
@"class C {
void M() {
var v = ""now is $$the time"";
var v = ""now is [||]the time"";
}
}",
@"class C {
void M() {
var v = ""now is "" +
""$$the time"";
""[||]the time"";
}
}");
}
......@@ -185,13 +187,13 @@ public async Task TestInterpolatedString1()
await TestHandledAsync(
@"class C {
void M() {
var v = $""now is $$the { 1 + 2 } time for { 3 + 4 } all good men"";
var v = $""now is [||]the { 1 + 2 } time for { 3 + 4 } all good men"";
}
}",
@"class C {
void M() {
var v = $""now is "" +
$""$$the { 1 + 2 } time for { 3 + 4 } all good men"";
$""[||]the { 1 + 2 } time for { 3 + 4 } all good men"";
}
}");
}
......@@ -202,13 +204,13 @@ public async Task TestInterpolatedString2()
await TestHandledAsync(
@"class C {
void M() {
var v = $""now is the $${ 1 + 2 } time for { 3 + 4 } all good men"";
var v = $""now is the [||]{ 1 + 2 } time for { 3 + 4 } all good men"";
}
}",
@"class C {
void M() {
var v = $""now is the "" +
$""$${ 1 + 2 } time for { 3 + 4 } all good men"";
$""[||]{ 1 + 2 } time for { 3 + 4 } all good men"";
}
}");
}
......@@ -219,13 +221,13 @@ public async Task TestInterpolatedString3()
await TestHandledAsync(
@"class C {
void M() {
var v = $""now is the { 1 + 2 }$$ time for { 3 + 4 } all good men"";
var v = $""now is the { 1 + 2 }[||] time for { 3 + 4 } all good men"";
}
}",
@"class C {
void M() {
var v = $""now is the { 1 + 2 }"" +
$""$$ time for { 3 + 4 } all good men"";
$""[||] time for { 3 + 4 } all good men"";
}
}");
}
......@@ -236,7 +238,7 @@ public async Task TestMissingInInterpolation1()
await TestNotHandledAsync(
@"class C {
void M() {
var v = $""now is the {$$ 1 + 2 } time for { 3 + 4 } all good men"";
var v = $""now is the {[||] 1 + 2 } time for { 3 + 4 } all good men"";
}
}");
}
......@@ -247,7 +249,18 @@ public async Task TestMissingInInterpolation2()
await TestNotHandledAsync(
@"class C {
void M() {
var v = $""now is the { 1 + 2 $$} time for { 3 + 4 } all good men"";
var v = $""now is the { 1 + 2 [||]} time for { 3 + 4 } all good men"";
}
}");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.SplitStringLiteral)]
public async Task TestSelection()
{
await TestNotHandledAsync(
@"class C {
void M() {
var v = ""now is [|the|] time"";
}
}");
}
......
......@@ -15,7 +15,7 @@ Imports Moq
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Formatting.Indentation
Public Class SmartIndentProviderTests
<Fact>
<WpfFact>
<Trait(Traits.Feature, Traits.Features.SmartIndent)>
Public Sub GetSmartIndent1()
Dim provider = New SmartIndentProvider()
......@@ -52,4 +52,4 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Formatting.Indenta
End Using
End Sub
End Class
End Namespace
End Namespace
\ No newline at end of file
......@@ -2001,7 +2001,7 @@ End Module</text>.Value
End Function
#End Region
<Fact>
<WpfFact>
<Trait(Traits.Feature, Traits.Features.SmartIndent)>
Public Sub TestSmartIndenterConstructorThrows1()
Assert.Throws(Of ArgumentNullException)(
......
......@@ -111,6 +111,7 @@ private static string GetSyntaxTreeFilePath(DocumentInfo info)
{
return new AsyncLazy<TreeAndVersion>(
c => FullyParseTreeAsync(newTextSource, cacheKey, filePath, options, languageServices, solutionServices, mode, c),
c => FullyParseTree(newTextSource, cacheKey, filePath, options, languageServices, solutionServices, mode, c),
cacheResult: true);
}
......@@ -127,23 +128,50 @@ private static string GetSyntaxTreeFilePath(DocumentInfo info)
using (Logger.LogBlock(FunctionId.Workspace_Document_State_FullyParseSyntaxTree, s_fullParseLog, filePath, mode, cancellationToken))
{
var textAndVersion = await newTextSource.GetValueAsync(cancellationToken).ConfigureAwait(false);
var text = textAndVersion.Text;
return CreateTreeAndVersion(newTextSource, cacheKey, filePath, options, languageServices, mode, textAndVersion, cancellationToken);
}
}
var treeFactory = languageServices.GetService<ISyntaxTreeFactoryService>();
private static TreeAndVersion FullyParseTree(
ValueSource<TextAndVersion> newTextSource,
ProjectId cacheKey,
string filePath,
ParseOptions options,
HostLanguageServices languageServices,
SolutionServices solutionServices,
PreservationMode mode,
CancellationToken cancellationToken)
{
using (Logger.LogBlock(FunctionId.Workspace_Document_State_FullyParseSyntaxTree, s_fullParseLog, filePath, mode, cancellationToken))
{
var textAndVersion = newTextSource.GetValue(cancellationToken);
return CreateTreeAndVersion(newTextSource, cacheKey, filePath, options, languageServices, mode, textAndVersion, cancellationToken);
}
}
var tree = treeFactory.ParseSyntaxTree(filePath, options, text, cancellationToken);
private static TreeAndVersion CreateTreeAndVersion(
ValueSource<TextAndVersion> newTextSource,
ProjectId cacheKey, string filePath,
ParseOptions options, HostLanguageServices languageServices,
PreservationMode mode, TextAndVersion textAndVersion,
CancellationToken cancellationToken)
{
var text = textAndVersion.Text;
var root = tree.GetRoot(cancellationToken);
if (mode == PreservationMode.PreserveValue && treeFactory.CanCreateRecoverableTree(root))
{
tree = treeFactory.CreateRecoverableTree(cacheKey, tree.FilePath, tree.Options, newTextSource, text.Encoding, root);
}
var treeFactory = languageServices.GetService<ISyntaxTreeFactoryService>();
Contract.ThrowIfNull(tree);
var tree = treeFactory.ParseSyntaxTree(filePath, options, text, cancellationToken);
// text version for this document should be unique. use it as a starting point.
return TreeAndVersion.Create(tree, textAndVersion.Version);
var root = tree.GetRoot(cancellationToken);
if (mode == PreservationMode.PreserveValue && treeFactory.CanCreateRecoverableTree(root))
{
tree = treeFactory.CreateRecoverableTree(cacheKey, tree.FilePath, tree.Options, newTextSource, text.Encoding, root);
}
Contract.ThrowIfNull(tree);
// text version for this document should be unique. use it as a starting point.
return TreeAndVersion.Create(tree, textAndVersion.Version);
}
private static ValueSource<TreeAndVersion> CreateLazyIncrementallyParsedTree(
......@@ -152,6 +180,7 @@ private static string GetSyntaxTreeFilePath(DocumentInfo info)
{
return new AsyncLazy<TreeAndVersion>(
c => IncrementallyParseTreeAsync(oldTreeSource, newTextSource, c),
c => IncrementallyParseTree(oldTreeSource, newTextSource, c),
cacheResult: true);
}
......@@ -165,16 +194,30 @@ private static string GetSyntaxTreeFilePath(DocumentInfo info)
using (Logger.LogBlock(FunctionId.Workspace_Document_State_IncrementallyParseSyntaxTree, cancellationToken))
{
var newTextAndVersion = await newTextSource.GetValueAsync(cancellationToken).ConfigureAwait(false);
var newText = newTextAndVersion.Text;
var oldTreeAndVersion = await oldTreeSource.GetValueAsync(cancellationToken).ConfigureAwait(false);
var oldTree = oldTreeAndVersion.Tree;
var oldText = await oldTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
var newTree = oldTree.WithChangedText(newText);
Contract.ThrowIfNull(newTree);
return IncrementallyParse(newTextAndVersion, oldTreeAndVersion, cancellationToken);
}
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
throw ExceptionUtilities.Unreachable;
}
}
private static TreeAndVersion IncrementallyParseTree(
ValueSource<TreeAndVersion> oldTreeSource,
ValueSource<TextAndVersion> newTextSource,
CancellationToken cancellationToken)
{
try
{
using (Logger.LogBlock(FunctionId.Workspace_Document_State_IncrementallyParseSyntaxTree, cancellationToken))
{
var newTextAndVersion = newTextSource.GetValue(cancellationToken);
var oldTreeAndVersion = oldTreeSource.GetValue(cancellationToken);
return MakeNewTreeAndVersion(oldTree, oldText, oldTreeAndVersion.Version, newTree, newText, newTextAndVersion.Version);
return IncrementallyParse(newTextAndVersion, oldTreeAndVersion, cancellationToken);
}
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
......@@ -183,6 +226,21 @@ private static string GetSyntaxTreeFilePath(DocumentInfo info)
}
}
private static TreeAndVersion IncrementallyParse(
TextAndVersion newTextAndVersion,
TreeAndVersion oldTreeAndVersion,
CancellationToken cancellationToken)
{
var newText = newTextAndVersion.Text;
var oldTree = oldTreeAndVersion.Tree;
var oldText = oldTree.GetText(cancellationToken);
var newTree = oldTree.WithChangedText(newText);
Contract.ThrowIfNull(newTree);
return MakeNewTreeAndVersion(oldTree, oldText, oldTreeAndVersion.Version, newTree, newText, newTextAndVersion.Version);
}
private static TreeAndVersion MakeNewTreeAndVersion(SyntaxTree oldTree, SourceText oldText, VersionStamp oldVersion, SyntaxTree newTree, SourceText newText, VersionStamp newVersion)
{
var topLevelChanged = TopLevelChanged(oldTree, oldText, newTree, newText);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册