Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@ -0,0 +1,402 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using System.Web.WebPages.TestUtils;
using Xunit;
namespace System.Web.Razor.Test.Parser.PartialParsing
{
public class CSharpPartialParsingTest : PartialParsingTestBase<CSharpRazorCodeLanguage>
{
[Fact]
public void ImplicitExpressionProvisionallyAcceptsDeleteOfIdentifierPartsIfDotRemains()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("foo @User. baz");
StringTextBuffer old = new StringTextBuffer("foo @User.Name baz");
RunPartialParseTest(new TextChange(10, 4, old, 0, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")),
additionalFlags: PartialParseResult.Provisional);
}
[Fact]
public void ImplicitExpressionAcceptsDeleteOfIdentifierPartsIfSomeOfIdentifierRemains()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("foo @Us baz");
StringTextBuffer old = new StringTextBuffer("foo @User baz");
RunPartialParseTest(new TextChange(7, 2, old, 0, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("Us").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")));
}
[Fact]
public void ImplicitExpressionProvisionallyAcceptsMultipleInsertionIfItCausesIdentifierExpansionAndTrailingDot()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("foo @User. baz");
StringTextBuffer old = new StringTextBuffer("foo @U baz");
RunPartialParseTest(new TextChange(6, 0, old, 4, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("User.").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")),
additionalFlags: PartialParseResult.Provisional);
}
[Fact]
public void ImplicitExpressionAcceptsMultipleInsertionIfItOnlyCausesIdentifierExpansion()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("foo @barbiz baz");
StringTextBuffer old = new StringTextBuffer("foo @bar baz");
RunPartialParseTest(new TextChange(8, 0, old, 3, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("barbiz").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")));
}
[Fact]
public void ImplicitExpressionAcceptsIdentifierExpansionAtEndOfNonWhitespaceCharacters()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer(@"@{
@food
}");
StringTextBuffer old = new StringTextBuffer(@"@{
@foo
}");
RunPartialParseTest(new TextChange(12, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("{").Accepts(AcceptedCharacters.None),
factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("food")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Code("\r\n").AsStatement(),
factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionAcceptsIdentifierAfterDotAtEndOfNonWhitespaceCharacters()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer(@"@{
@foo.d
}");
StringTextBuffer old = new StringTextBuffer(@"@{
@foo.
}");
RunPartialParseTest(new TextChange(13, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("{").Accepts(AcceptedCharacters.None),
factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.d")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Code("\r\n").AsStatement(),
factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionAcceptsDotAtEndOfNonWhitespaceCharacters()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer(@"@{
@foo.
}");
StringTextBuffer old = new StringTextBuffer(@"@{
@foo
}");
RunPartialParseTest(new TextChange(12, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("{").Accepts(AcceptedCharacters.None),
factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code(@"foo.")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Code("\r\n").AsStatement(),
factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
{
var factory = SpanFactory.CreateCsHtml();
// Arrange
TextChange dotTyped = new TextChange(8, 0, new StringTextBuffer("foo @foo @bar"), 1, new StringTextBuffer("foo @foo. @bar"));
TextChange charTyped = new TextChange(14, 0, new StringTextBuffer("foo @foo. @bar"), 1, new StringTextBuffer("foo @foo. @barb"));
TestParserManager manager = CreateParserManager();
manager.InitializeWithDocument(dotTyped.OldBuffer);
// Apply the dot change
Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
// Act (apply the identifier start char change)
PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);
// Assert
Assert.Equal(PartialParseResult.Rejected, result);
Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(". "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("barb")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot()
{
var factory = SpanFactory.CreateCsHtml();
// Arrange
TextChange dotTyped = new TextChange(8, 0, new StringTextBuffer("foo @foo bar"), 1, new StringTextBuffer("foo @foo. bar"));
TextChange charTyped = new TextChange(9, 0, new StringTextBuffer("foo @foo. bar"), 1, new StringTextBuffer("foo @foo.b bar"));
TestParserManager manager = CreateParserManager();
manager.InitializeWithDocument(dotTyped.OldBuffer);
// Apply the dot change
Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
// Act (apply the identifier start char change)
PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);
// Assert
Assert.Equal(PartialParseResult.Accepted, result);
Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.b")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" bar")));
}
[Fact]
public void ImplicitExpressionProvisionallyAcceptsDotAfterIdentifierInMarkup()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("foo @foo. bar");
StringTextBuffer old = new StringTextBuffer("foo @foo bar");
RunPartialParseTest(new TextChange(8, 0, old, 1, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" bar")),
additionalFlags: PartialParseResult.Provisional);
}
[Fact]
public void ImplicitExpressionAcceptsAdditionalIdentifierCharactersIfEndOfSpanIsIdentifier()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("foo @foob bar");
StringTextBuffer old = new StringTextBuffer("foo @foo bar");
RunPartialParseTest(new TextChange(8, 0, old, 1, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foob")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" bar")));
}
[Fact]
public void ImplicitExpressionAcceptsAdditionalIdentifierStartCharactersIfEndOfSpanIsDot()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("@{@foo.b}");
StringTextBuffer old = new StringTextBuffer("@{@foo.}");
RunPartialParseTest(new TextChange(7, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("{").Accepts(AcceptedCharacters.None),
factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.b")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.EmptyCSharp().AsStatement(),
factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionAcceptsDotIfTrailingDotsAreAllowed()
{
var factory = SpanFactory.CreateCsHtml();
StringTextBuffer changed = new StringTextBuffer("@{@foo.}");
StringTextBuffer old = new StringTextBuffer("@{@foo}");
RunPartialParseTest(new TextChange(6, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("{").Accepts(AcceptedCharacters.None),
factory.EmptyCSharp().AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.")
.AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.EmptyCSharp().AsStatement(),
factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfIfKeywordTyped()
{
RunTypeKeywordTest("if");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfDoKeywordTyped()
{
RunTypeKeywordTest("do");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfTryKeywordTyped()
{
RunTypeKeywordTest("try");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfForKeywordTyped()
{
RunTypeKeywordTest("for");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfForEachKeywordTyped()
{
RunTypeKeywordTest("foreach");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfWhileKeywordTyped()
{
RunTypeKeywordTest("while");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfSwitchKeywordTyped()
{
RunTypeKeywordTest("switch");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfLockKeywordTyped()
{
RunTypeKeywordTest("lock");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfUsingKeywordTyped()
{
RunTypeKeywordTest("using");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfSectionKeywordTyped()
{
RunTypeKeywordTest("section");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfInheritsKeywordTyped()
{
RunTypeKeywordTest("inherits");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfHelperKeywordTyped()
{
RunTypeKeywordTest("helper");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfFunctionsKeywordTyped()
{
RunTypeKeywordTest("functions");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfNamespaceKeywordTyped()
{
RunTypeKeywordTest("namespace");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfClassKeywordTyped()
{
RunTypeKeywordTest("class");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfLayoutKeywordTyped()
{
RunTypeKeywordTest("layout");
}
}
}

View File

@ -0,0 +1,113 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Threading;
using System.Web.Razor.Generator;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Test.Utils;
using System.Web.Razor.Text;
using System.Web.WebPages.TestUtils;
using Xunit;
namespace System.Web.Razor.Test.Parser.PartialParsing
{
public abstract class PartialParsingTestBase<TLanguage>
where TLanguage : RazorCodeLanguage, new()
{
private const string TestLinePragmaFileName = "C:\\This\\Path\\Is\\Just\\For\\Line\\Pragmas.cshtml";
protected static void RunFullReparseTest(TextChange change, PartialParseResult additionalFlags = (PartialParseResult)0)
{
// Arrange
TestParserManager manager = CreateParserManager();
manager.InitializeWithDocument(change.OldBuffer);
// Act
PartialParseResult result = manager.CheckForStructureChangesAndWait(change);
// Assert
Assert.Equal(PartialParseResult.Rejected | additionalFlags, result);
Assert.Equal(2, manager.ParseCount);
}
protected static void RunPartialParseTest(TextChange change, Block newTreeRoot, PartialParseResult additionalFlags = (PartialParseResult)0)
{
// Arrange
TestParserManager manager = CreateParserManager();
manager.InitializeWithDocument(change.OldBuffer);
// Act
PartialParseResult result = manager.CheckForStructureChangesAndWait(change);
// Assert
Assert.Equal(PartialParseResult.Accepted | additionalFlags, result);
Assert.Equal(1, manager.ParseCount);
ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree, newTreeRoot);
}
protected static TestParserManager CreateParserManager()
{
RazorEngineHost host = CreateHost();
RazorEditorParser parser = new RazorEditorParser(host, TestLinePragmaFileName);
return new TestParserManager(parser);
}
protected static RazorEngineHost CreateHost()
{
return new RazorEngineHost(new TLanguage())
{
GeneratedClassContext = new GeneratedClassContext("Execute", "Write", "WriteLiteral", "WriteTo", "WriteLiteralTo", "Template", "DefineSection"),
DesignTimeMode = true
};
}
protected static void RunTypeKeywordTest(string keyword)
{
string before = "@" + keyword.Substring(0, keyword.Length - 1);
string after = "@" + keyword;
StringTextBuffer changed = new StringTextBuffer(after);
StringTextBuffer old = new StringTextBuffer(before);
RunFullReparseTest(new TextChange(keyword.Length, 0, old, 1, changed), additionalFlags: PartialParseResult.SpanContextChanged);
}
protected class TestParserManager
{
public RazorEditorParser Parser;
public ManualResetEventSlim ParserComplete;
public int ParseCount;
public TestParserManager(RazorEditorParser parser)
{
ParserComplete = new ManualResetEventSlim();
ParseCount = 0;
Parser = parser;
parser.DocumentParseComplete += (sender, args) =>
{
Interlocked.Increment(ref ParseCount);
ParserComplete.Set();
};
}
public void InitializeWithDocument(ITextBuffer startDocument)
{
CheckForStructureChangesAndWait(new TextChange(0, 0, new StringTextBuffer(String.Empty), startDocument.Length, startDocument));
}
public PartialParseResult CheckForStructureChangesAndWait(TextChange change)
{
PartialParseResult result = Parser.CheckForStructureChanges(change);
if (result.HasFlag(PartialParseResult.Rejected))
{
WaitForParse();
}
return result;
}
public void WaitForParse()
{
MiscUtils.DoWithTimeoutIfNotDebugging(ParserComplete.Wait); // Wait for the parse to finish
ParserComplete.Reset();
}
}
}
}

View File

@ -0,0 +1,374 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Parser;
using System.Web.Razor.Parser.SyntaxTree;
using System.Web.Razor.Test.Framework;
using System.Web.Razor.Text;
using System.Web.WebPages.TestUtils;
using Xunit;
namespace System.Web.Razor.Test.Parser.PartialParsing
{
public class VBPartialParsingTest : PartialParsingTestBase<VBRazorCodeLanguage>
{
[Fact]
public void ImplicitExpressionProvisionallyAcceptsDeleteOfIdentifierPartsIfDotRemains()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("foo @User. baz");
StringTextBuffer old = new StringTextBuffer("foo @User.Name baz");
RunPartialParseTest(new TextChange(10, 4, old, 0, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("User.")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")),
additionalFlags: PartialParseResult.Provisional);
}
[Fact]
public void ImplicitExpressionAcceptsDeleteOfIdentifierPartsIfSomeOfIdentifierRemains()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("foo @Us baz");
StringTextBuffer old = new StringTextBuffer("foo @User baz");
RunPartialParseTest(new TextChange(7, 2, old, 0, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("Us")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")));
}
[Fact]
public void ImplicitExpressionProvisionallyAcceptsMultipleInsertionIfItCausesIdentifierExpansionAndTrailingDot()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("foo @User. baz");
StringTextBuffer old = new StringTextBuffer("foo @U baz");
RunPartialParseTest(new TextChange(6, 0, old, 4, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("User.")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")),
additionalFlags: PartialParseResult.Provisional);
}
[Fact]
public void ImplicitExpressionAcceptsMultipleInsertionIfItOnlyCausesIdentifierExpansion()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("foo @barbiz baz");
StringTextBuffer old = new StringTextBuffer("foo @bar baz");
RunPartialParseTest(new TextChange(8, 0, old, 3, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("barbiz")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" baz")));
}
[Fact]
public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
{
var factory = SpanFactory.CreateVbHtml();
// Arrange
TextChange dotTyped = new TextChange(8, 0, new StringTextBuffer("foo @foo @bar"), 1, new StringTextBuffer("foo @foo. @bar"));
TextChange charTyped = new TextChange(14, 0, new StringTextBuffer("foo @foo. @barb"), 1, new StringTextBuffer("foo @foo. @barb"));
TestParserManager manager = CreateParserManager();
manager.InitializeWithDocument(dotTyped.OldBuffer);
// Apply the dot change
Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
// Act (apply the identifier start char change)
PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);
// Assert
Assert.Equal(PartialParseResult.Rejected, result);
Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(". "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("barb")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot()
{
var factory = SpanFactory.CreateVbHtml();
// Arrange
TextChange dotTyped = new TextChange(8, 0, new StringTextBuffer("foo @foo bar"), 1, new StringTextBuffer("foo @foo. bar"));
TextChange charTyped = new TextChange(9, 0, new StringTextBuffer("foo @foo. bar"), 1, new StringTextBuffer("foo @foo.b bar"));
TestParserManager manager = CreateParserManager();
manager.InitializeWithDocument(dotTyped.OldBuffer);
// Apply the dot change
Assert.Equal(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));
// Act (apply the identifier start char change)
PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);
// Assert
Assert.Equal(PartialParseResult.Accepted, result);
Assert.False(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.b")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" bar")));
}
[Fact]
public void ImplicitExpressionAcceptsIdentifierExpansionAtEndOfNonWhitespaceCharacters()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer(@"@Code
@food
End Code");
StringTextBuffer old = new StringTextBuffer(@"@Code
@foo
End Code");
RunPartialParseTest(new TextChange(15, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("Code")
.Accepts(AcceptedCharacters.None),
factory.Code("\r\n ").AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("food")
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Code("\r\n").AsStatement(),
factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionProvisionallyAcceptsDotAfterIdentifierInMarkup()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("foo @foo. bar");
StringTextBuffer old = new StringTextBuffer("foo @foo bar");
RunPartialParseTest(new TextChange(8, 0, old, 1, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" bar")),
additionalFlags: PartialParseResult.Provisional);
}
[Fact]
public void ImplicitExpressionAcceptsAdditionalIdentifierCharactersIfEndOfSpanIsIdentifier()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("foo @foob baz");
StringTextBuffer old = new StringTextBuffer("foo @foo bar");
RunPartialParseTest(new TextChange(8, 0, old, 1, changed),
new MarkupBlock(
factory.Markup("foo "),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foob")
.AsImplicitExpression(VBCodeParser.DefaultKeywords)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Markup(" bar")));
}
[Fact]
public void ImplicitExpressionAcceptsAdditionalIdentifierStartCharactersIfEndOfSpanIsDot()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("@Code @foo.b End Code");
StringTextBuffer old = new StringTextBuffer("@Code @foo. End Code");
RunPartialParseTest(new TextChange(11, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
factory.Code(" ").AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.b")
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Code(" ").AsStatement(),
factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionAcceptsDotIfTrailingDotsAreAllowed()
{
var factory = SpanFactory.CreateVbHtml();
StringTextBuffer changed = new StringTextBuffer("@Code @foo. End Code");
StringTextBuffer old = new StringTextBuffer("@Code @foo End Code");
RunPartialParseTest(new TextChange(10, 0, old, 1, changed),
new MarkupBlock(
factory.EmptyHtml(),
new StatementBlock(
factory.CodeTransition(),
factory.MetaCode("Code").Accepts(AcceptedCharacters.None),
factory.Code(" ").AsStatement(),
new ExpressionBlock(
factory.CodeTransition(),
factory.Code("foo.")
.AsImplicitExpression(VBCodeParser.DefaultKeywords, acceptTrailingDot: true)
.Accepts(AcceptedCharacters.NonWhiteSpace)),
factory.Code(" ").AsStatement(),
factory.MetaCode("End Code").Accepts(AcceptedCharacters.None)),
factory.EmptyHtml()));
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfFunctionsKeywordTyped()
{
RunTypeKeywordTest("functions");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfCodeKeywordTyped()
{
RunTypeKeywordTest("code");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfSectionKeywordTyped()
{
RunTypeKeywordTest("section");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfDoKeywordTyped()
{
RunTypeKeywordTest("do");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfWhileKeywordTyped()
{
RunTypeKeywordTest("while");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfIfKeywordTyped()
{
RunTypeKeywordTest("if");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfSelectKeywordTyped()
{
RunTypeKeywordTest("select");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfForKeywordTyped()
{
RunTypeKeywordTest("for");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfTryKeywordTyped()
{
RunTypeKeywordTest("try");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfWithKeywordTyped()
{
RunTypeKeywordTest("with");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfSyncLockKeywordTyped()
{
RunTypeKeywordTest("synclock");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfUsingKeywordTyped()
{
RunTypeKeywordTest("using");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfImportsKeywordTyped()
{
RunTypeKeywordTest("imports");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfInheritsKeywordTyped()
{
RunTypeKeywordTest("inherits");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfOptionKeywordTyped()
{
RunTypeKeywordTest("option");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfHelperKeywordTyped()
{
RunTypeKeywordTest("helper");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfNamespaceKeywordTyped()
{
RunTypeKeywordTest("namespace");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfClassKeywordTyped()
{
RunTypeKeywordTest("class");
}
[Fact]
public void ImplicitExpressionCorrectlyTriggersReparseIfLayoutKeywordTyped()
{
RunTypeKeywordTest("layout");
}
}
}