public async Task ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot()
        {
            // Arrange
            var factory   = new SpanFactory();
            var dotTyped  = new TestEdit(8, 0, new StringTextSnapshot("foo @foo bar"), 1, new StringTextSnapshot("foo @foo. bar"), ".");
            var charTyped = new TestEdit(9, 0, new StringTextSnapshot("foo @foo. bar"), 1, new StringTextSnapshot("foo @foo.b bar"), "b");

            using (var manager = CreateParserManager(dotTyped.OldSnapshot))
            {
                await manager.InitializeWithDocumentAsync(dotTyped.OldSnapshot);

                // Apply the dot change
                manager.ApplyEdit(dotTyped);

                // Act (apply the identifier start char change)
                manager.ApplyEdit(charTyped);

                // Assert
                Assert.Equal(1, manager.ParseCount);
                ParserTestBase.EvaluateParseTree(manager.PartialParsingSyntaxTreeRoot,
                                                 new MarkupBlock(
                                                     factory.Markup("foo "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code("foo.b")
                                                         .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
                                                         .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                     factory.Markup(" bar")));
            }
        }
        public void ImplicitExpressionProvisionallyAcceptsDotlessCommitInsertions()
        {
            SpanFactory       factory    = SpanFactory.CreateCsHtml();
            var               changed    = new StringTextBuffer("foo @DateT. baz");
            var               old        = new StringTextBuffer("foo @DateT baz");
            var               textChange = new TextChange(10, 0, old, 1, changed);
            TestParserManager manager    = CreateParserManager();
            Action <TextChange, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
            {
                PartialParseResult result = manager.CheckForStructureChangesAndWait(textChange);

                // Assert
                Assert.Equal(expectedResult, result);
                Assert.Equal(1, manager.ParseCount);

                ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree, new MarkupBlock(
                                                     factory.Markup("foo "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharacters.NonWhiteSpace)),
                                                     factory.Markup(" baz")));
            };

            manager.InitializeWithDocument(textChange.OldBuffer);

            // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
            applyAndVerifyPartialChange(textChange, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateT.");

            old        = changed;
            changed    = new StringTextBuffer("foo @DateTime. baz");
            textChange = new TextChange(10, 0, old, 3, changed);

            applyAndVerifyPartialChange(textChange, PartialParseResult.Accepted | PartialParseResult.Provisional, "DateTime.");
        }
        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")));
        }
Exemple #4
0
        public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
        {
            // 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.AreEqual(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));

            // Act (apply the identifier start char change)
            PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);

            // Assert
            Assert.AreEqual(PartialParseResult.Rejected, result, "The change was accepted despite the previous change being provisionally accepted!");
            Assert.IsFalse(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
            ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
                                             new MarkupBlock(
                                                 new MarkupSpan("foo "),
                                                 new ExpressionBlock(
                                                     new TransitionSpan(RazorParser.TransitionString, hidden: false, acceptedCharacters: AcceptedCharacters.None),
                                                     new ImplicitExpressionSpan("foo", VBCodeParser.DefaultKeywords, acceptTrailingDot: false, acceptedCharacters: AcceptedCharacters.NonWhiteSpace)
                                                     ),
                                                 new MarkupSpan(". "),
                                                 new ExpressionBlock(
                                                     new TransitionSpan(RazorParser.TransitionString, hidden: false, acceptedCharacters: AcceptedCharacters.None),
                                                     new ImplicitExpressionSpan("barb", VBCodeParser.DefaultKeywords, acceptTrailingDot: false, acceptedCharacters: AcceptedCharacters.NonWhiteSpace)
                                                     ),
                                                 new MarkupSpan(String.Empty)));
        }
        public async Task ImplicitExpression_AcceptsParenthesisAtEnd_TwoEdits()
        {
            // Arrange
            var factory = new SpanFactory();
            var edit1   = new TestEdit(8, 0, new StringTextSnapshot("foo @foo bar"), 1, new StringTextSnapshot("foo @foo( bar"), "(");
            var edit2   = new TestEdit(9, 0, new StringTextSnapshot("foo @foo( bar"), 1, new StringTextSnapshot("foo @foo() bar"), ")");

            using (var manager = CreateParserManager(edit1.OldSnapshot))
            {
                await manager.InitializeWithDocumentAsync(edit1.OldSnapshot);

                // Apply the ( edit
                manager.ApplyEdit(edit1);

                // Apply the ) edit
                manager.ApplyEdit(edit2);

                // Assert
                Assert.Equal(1, manager.ParseCount);
                ParserTestBase.EvaluateParseTree(
                    manager.PartialParsingSyntaxTreeRoot,
                    new MarkupBlock(
                        factory.Markup("foo "),
                        new ExpressionBlock(
                            factory.CodeTransition(),
                            factory.Code("foo()")
                            .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
                            .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                        factory.Markup(" bar")));
            }
        }
Exemple #6
0
        public void ParseMethodUsesProvidedParserListenerIfSpecified()
        {
            var factory = SpanFactory.CreateCsHtml();

            // Arrange
            RazorParser parser = new RazorParser(new CSharpCodeParser(), new HtmlMarkupParser());

            // Act
            ParserResults results = parser.Parse(new StringReader("foo @bar baz"));

            // Assert
            ParserTestBase.EvaluateResults(
                results,
                new MarkupBlock(
                    factory.Markup("foo "),
                    new ExpressionBlock(
                        factory.CodeTransition(),
                        factory
                        .Code("bar")
                        .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
                        .Accepts(AcceptedCharacters.NonWhiteSpace)
                        ),
                    factory.Markup(" baz")
                    )
                );
        }
        public void Rewrite_Moves_Whitespace_Preceeding_ExpressionBlock_To_Parent_Block()
        {
            // Arrange
            var factory = SpanFactory.CreateCsHtml();
            var start   = new MarkupBlock(
                factory.Markup("test"),
                new ExpressionBlock(
                    factory.Code("    ").AsExpression(),
                    factory.CodeTransition(SyntaxConstants.TransitionString),
                    factory.Code("foo").AsExpression()
                    ),
                factory.Markup("test")
                );
            var rewriter         = new WhiteSpaceRewriter(new HtmlMarkupParser().BuildSpan);
            var rewritingContext = new RewritingContext(start, new ErrorSink());

            // Act
            rewriter.Rewrite(rewritingContext);

            factory.Reset();

            // Assert
            ParserTestBase.EvaluateParseTree(rewritingContext.SyntaxTree, new MarkupBlock(
                                                 factory.Markup("test"),
                                                 factory.Markup("    "),
                                                 new ExpressionBlock(
                                                     factory.CodeTransition(SyntaxConstants.TransitionString),
                                                     factory.Code("foo").AsExpression()
                                                     ),
                                                 factory.Markup("test")
                                                 ));
        }
Exemple #8
0
        public void AddSpanAddsSpanToCurrentBlockBuilder()
        {
            // Arrange
            var factory = SpanFactory.CreateCsHtml();
            Mock <ParserVisitor> mockListener = new Mock <ParserVisitor>();
            var context = SetupTestContext("phoo");

            var builder = new SpanBuilder()
            {
                Kind = SpanKind.Code
            };

            builder.Accept(new CSharpSymbol(1, 0, 1, "foo", CSharpSymbolType.Identifier));
            var added = builder.Build();

            using (context.StartBlock(BlockType.Functions))
            {
                context.AddSpan(added);
            }

            var expected = new BlockBuilder()
            {
                Type = BlockType.Functions,
            };

            expected.Children.Add(added);

            // Assert
            ParserTestBase.EvaluateResults(context.CompleteParse(), expected.Build());
        }
        public async Task AwaitPeriodInsertionAcceptedProvisionally()
        {
            // Arrange
            var original = new StringTextSnapshot("foo @await Html baz");

            using (var manager = CreateParserManager(original))
            {
                var factory = new SpanFactory();
                var changed = new StringTextSnapshot("foo @await Html. baz");
                var edit    = new TestEdit(15, 0, original, 1, changed, ".");
                await manager.InitializeWithDocumentAsync(edit.OldSnapshot);

                // Act
                await manager.ApplyEditAndWaitForReparseAsync(edit);

                // Assert
                Assert.Equal(2, manager.ParseCount);
                ParserTestBase.EvaluateParseTree(manager.CurrentSyntaxTree.Root, new MarkupBlock(
                                                     factory.Markup("foo "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code("await Html").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.WhiteSpace | AcceptedCharactersInternal.NonWhiteSpace)),
                                                     factory.Markup(". baz")));
            }
        }
Exemple #10
0
        public void ImplicitExpressionAcceptsIdentifierTypedAfterDotIfLastChangeWasProvisionalAcceptanceOfDot()
        {
            // 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.AreEqual(PartialParseResult.Provisional | PartialParseResult.Accepted, manager.CheckForStructureChangesAndWait(dotTyped));

            // Act (apply the identifier start char change)
            PartialParseResult result = manager.CheckForStructureChangesAndWait(charTyped);

            // Assert
            Assert.AreEqual(PartialParseResult.Accepted, result, "The change was not fully accepted!");
            Assert.IsFalse(manager.Parser.LastResultProvisional, "LastResultProvisional flag should have been cleared but it was not");
            ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree,
                                             new MarkupBlock(
                                                 new MarkupSpan("foo "),
                                                 new ExpressionBlock(
                                                     new TransitionSpan(RazorParser.TransitionString, hidden: false, acceptedCharacters: AcceptedCharacters.None),
                                                     new ImplicitExpressionSpan("foo.b", CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false, acceptedCharacters: AcceptedCharacters.NonWhiteSpace)
                                                     ),
                                                 new MarkupSpan(" bar")));
        }
Exemple #11
0
        public void ImplicitExpressionAcceptsDotlessCommitInsertionsInStatementBlockAfterIdentifiers()
        {
            SpanFactory      factory = SpanFactory.CreateCsHtml();
            StringTextBuffer changed = new StringTextBuffer("@{" + Environment.NewLine
                                                            + "    @DateTime." + Environment.NewLine
                                                            + "}");
            StringTextBuffer old = new StringTextBuffer("@{" + Environment.NewLine
                                                        + "    @DateTime" + Environment.NewLine
                                                        + "}");

            var textChange = new TextChange(17, 0, old, 1, changed);

            using (TestParserManager manager = CreateParserManager())
            {
                Action <TextChange, PartialParseResult, string> applyAndVerifyPartialChange = (changeToApply, expectedResult, expectedCode) =>
                {
                    PartialParseResult result = manager.CheckForStructureChangesAndWait(textChange);

                    // Assert
                    Assert.Equal(expectedResult, result);
                    Assert.Equal(1, manager.ParseCount);
                    ParserTestBase.EvaluateParseTree(manager.Parser.CurrentParseTree, new MarkupBlock(
                                                         factory.EmptyHtml(),
                                                         new StatementBlock(
                                                             factory.CodeTransition(),
                                                             factory.MetaCode("{").Accepts(AcceptedCharacters.None),
                                                             factory.Code("\r\n    ").AsStatement(),
                                                             new ExpressionBlock(
                                                                 factory.CodeTransition(),
                                                                 factory.Code(expectedCode)
                                                                 .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
                                                                 .Accepts(AcceptedCharacters.NonWhiteSpace)),
                                                             factory.Code("\r\n").AsStatement(),
                                                             factory.MetaCode("}").Accepts(AcceptedCharacters.None)),
                                                         factory.EmptyHtml()));
                };

                manager.InitializeWithDocument(textChange.OldBuffer);

                // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
                applyAndVerifyPartialChange(textChange, PartialParseResult.Accepted, "DateTime.");

                old     = changed;
                changed = new StringTextBuffer("@{" + Environment.NewLine
                                               + "    @DateTime.." + Environment.NewLine
                                               + "}");
                textChange = new TextChange(18, 0, old, 1, changed);

                applyAndVerifyPartialChange(textChange, PartialParseResult.Accepted, "DateTime..");

                old     = changed;
                changed = new StringTextBuffer("@{" + Environment.NewLine
                                               + "    @DateTime.Now." + Environment.NewLine
                                               + "}");
                textChange = new TextChange(18, 0, old, 3, changed);

                applyAndVerifyPartialChange(textChange, PartialParseResult.Accepted, "DateTime.Now.");
            }
        }
        public async Task ImplicitExpressionAcceptsDotlessCommitInsertionsInStatementBlockAfterIdentifiers()
        {
            var factory = new SpanFactory();
            var changed = new StringTextSnapshot("@{" + Environment.NewLine
                                                 + "    @DateTime." + Environment.NewLine
                                                 + "}");
            var original = new StringTextSnapshot("@{" + Environment.NewLine
                                                  + "    @DateTime" + Environment.NewLine
                                                  + "}");

            var edit = new TestEdit(15 + Environment.NewLine.Length, 0, original, 1, changed, ".");

            using (var manager = CreateParserManager(original))
            {
                void ApplyAndVerifyPartialChange(TestEdit testEdit, string expectedCode)
                {
                    manager.ApplyEdit(testEdit);
                    Assert.Equal(1, manager.ParseCount);
                    ParserTestBase.EvaluateParseTree(manager.PartialParsingSyntaxTreeRoot, new MarkupBlock(
                                                         factory.EmptyHtml(),
                                                         new StatementBlock(
                                                             factory.CodeTransition(),
                                                             factory.MetaCode("{").Accepts(AcceptedCharactersInternal.None),
                                                             factory.Code(Environment.NewLine + "    ")
                                                             .AsStatement()
                                                             .AutoCompleteWith(autoCompleteString: null),
                                                             new ExpressionBlock(
                                                                 factory.CodeTransition(),
                                                                 factory.Code(expectedCode)
                                                                 .AsImplicitExpression(CSharpCodeParser.DefaultKeywords, acceptTrailingDot: true)
                                                                 .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                             factory.Code(Environment.NewLine).AsStatement(),
                                                             factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)),
                                                         factory.EmptyHtml()));
                };

                await manager.InitializeWithDocumentAsync(edit.OldSnapshot);

                // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
                ApplyAndVerifyPartialChange(edit, "DateTime.");

                original = changed;
                changed  = new StringTextSnapshot("@{" + Environment.NewLine
                                                  + "    @DateTime.." + Environment.NewLine
                                                  + "}");
                edit = new TestEdit(16 + Environment.NewLine.Length, 0, original, 1, changed, ".");

                ApplyAndVerifyPartialChange(edit, "DateTime..");

                original = changed;
                changed  = new StringTextSnapshot("@{" + Environment.NewLine
                                                  + "    @DateTime.Now." + Environment.NewLine
                                                  + "}");
                edit = new TestEdit(16 + Environment.NewLine.Length, 0, original, 3, changed, "Now");

                ApplyAndVerifyPartialChange(edit, "DateTime.Now.");
            }
        }
        public async Task ImplicitExpressionProvisionallyAcceptsDotlessCommitInsertionsAfterIdentifiers()
        {
            var factory  = new SpanFactory();
            var changed  = new StringTextSnapshot("foo @DateTime. baz");
            var original = new StringTextSnapshot("foo @DateTime baz");
            var edit     = new TestEdit(13, 0, original, 1, changed, ".");

            using (var manager = CreateParserManager(original))
            {
                void ApplyAndVerifyPartialChange(TestEdit testEdit, string expectedCode)
                {
                    manager.ApplyEdit(testEdit);
                    Assert.Equal(1, manager.ParseCount);

                    ParserTestBase.EvaluateParseTree(manager.PartialParsingSyntaxTreeRoot, new MarkupBlock(
                                                         factory.Markup("foo "),
                                                         new ExpressionBlock(
                                                             factory.CodeTransition(),
                                                             factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                         factory.Markup(" baz")));
                };

                await manager.InitializeWithDocumentAsync(edit.OldSnapshot);

                // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.
                ApplyAndVerifyPartialChange(edit, "DateTime.");

                original = changed;
                changed  = new StringTextSnapshot("foo @DateTime.. baz");
                edit     = new TestEdit(14, 0, original, 1, changed, ".");

                ApplyAndVerifyPartialChange(edit, "DateTime..");

                original = changed;
                changed  = new StringTextSnapshot("foo @DateTime.Now. baz");
                edit     = new TestEdit(14, 0, original, 3, changed, "Now");

                ApplyAndVerifyPartialChange(edit, "DateTime.Now.");

                // Verify the reparse eventually happens
                await manager.WaitForReparseAsync();

                Assert.Equal(2, manager.ParseCount);
                ParserTestBase.EvaluateParseTree(manager.CurrentSyntaxTree.Root, new MarkupBlock(
                                                     factory.Markup("foo "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code("DateTime.Now").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                     factory.Markup(". baz")));
            }
        }
Exemple #14
0
        private static void RunPartialParseTest(TestEdit edit, Block expectedTree, PartialParseResultInternal additionalFlags = 0)
        {
            var templateEngine = CreateProjectEngine();
            var document       = TestRazorCodeDocument.Create(edit.OldSnapshot.GetText());

            templateEngine.Engine.Process(document);
            var syntaxTree = document.GetSyntaxTree();
            var parser     = new RazorSyntaxTreePartialParser(syntaxTree);

            var result = parser.Parse(edit.Change);

            Assert.Equal(PartialParseResultInternal.Accepted | additionalFlags, result);
            ParserTestBase.EvaluateParseTree(parser.SyntaxTreeRoot, expectedTree);
        }
Exemple #15
0
        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);
        }
Exemple #16
0
        public void ParseMethodCallsParseDocumentOnMarkupParserAndReturnsResults()
        {
            // Arrange
            RazorParser parser = new RazorParser(new CSharpCodeParser(), new HtmlMarkupParser());

            // Act/Assert
            ParserTestBase.EvaluateResults(TestContext,
                                           parser.Parse(new StringReader("foo @bar baz")),
                                           new MarkupBlock(
                                               new MarkupSpan("foo "),
                                               new ExpressionBlock(
                                                   new TransitionSpan(RazorParser.TransitionString, hidden: false, acceptedCharacters: AcceptedCharacters.None),
                                                   new ImplicitExpressionSpan("bar", CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false, acceptedCharacters: AcceptedCharacters.NonWhiteSpace)
                                                   ),
                                               new MarkupSpan(" baz")
                                               ));
        }
Exemple #17
0
        public void ParseMethodCallsParseDocumentOnMarkupParserAndReturnsResults()
        {
            var factory = SpanFactory.CreateCsHtml();

            // Arrange
            RazorParser parser = new RazorParser(new CSharpCodeParser(), new HtmlMarkupParser());

            // Act/Assert
            ParserTestBase.EvaluateResults(parser.Parse(new StringReader("foo @bar baz")),
                                           new MarkupBlock(
                                               factory.Markup("foo "),
                                               new ExpressionBlock(
                                                   factory.CodeTransition(),
                                                   factory.Code("bar")
                                                   .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
                                                   .Accepts(AcceptedCharacters.NonWhiteSpace)),
                                               factory.Markup(" baz")));
        }
Exemple #18
0
        public void ParseMethodUsesProvidedParserListenerIfSpecified()
        {
            // Arrange
            RazorParser parser = new RazorParser(new CSharpCodeParser(), new HtmlMarkupParser());
            SyntaxTreeBuilderVisitor builder = new SyntaxTreeBuilderVisitor();

            // Act
            parser.Parse(new StringReader("foo @bar baz"), builder);

            // Assert
            ParserTestBase.EvaluateResults(TestContext,
                                           builder.Results,
                                           new MarkupBlock(
                                               new MarkupSpan("foo "),
                                               new ExpressionBlock(
                                                   new TransitionSpan(RazorParser.TransitionString, hidden: false, acceptedCharacters: AcceptedCharacters.None),
                                                   new ImplicitExpressionSpan("bar", CSharpCodeParser.DefaultKeywords, acceptTrailingDot: false, acceptedCharacters: AcceptedCharacters.NonWhiteSpace)
                                                   ),
                                               new MarkupSpan(" baz")
                                               ));
        }
        public void ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
        {
            var factory = SpanFactory.CreateCsHtml();

            // Arrange
            var dotTyped  = new TextChange(8, 0, new StringTextBuffer("foo @foo @bar"), 1, new StringTextBuffer("foo @foo. @bar"));
            var charTyped = new TextChange(14, 0, new StringTextBuffer("foo @foo. @bar"), 1, new StringTextBuffer("foo @foo. @barb"));

            using (var 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)
                var 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()));
            }
        }
        public async Task ImplicitExpressionRejectsChangeWhichWouldHaveBeenAcceptedIfLastChangeWasProvisionallyAcceptedOnDifferentSpan()
        {
            // Arrange
            var factory   = new SpanFactory();
            var dotTyped  = new TestEdit(8, 0, new StringTextSnapshot("foo @foo @bar"), 1, new StringTextSnapshot("foo @foo. @bar"), ".");
            var charTyped = new TestEdit(14, 0, new StringTextSnapshot("foo @foo. @bar"), 1, new StringTextSnapshot("foo @foo. @barb"), "b");

            using (var manager = CreateParserManager(dotTyped.OldSnapshot))
            {
                await manager.InitializeWithDocumentAsync(dotTyped.OldSnapshot);

                // Apply the dot change
                await manager.ApplyEditAndWaitForReparseAsync(dotTyped);

                // Act (apply the identifier start char change)
                await manager.ApplyEditAndWaitForParseAsync(charTyped);

                // Assert
                Assert.Equal(2, manager.ParseCount);
                ParserTestBase.EvaluateParseTree(manager.PartialParsingSyntaxTreeRoot,
                                                 new MarkupBlock(
                                                     factory.Markup("foo "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code("foo")
                                                         .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
                                                         .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                     factory.Markup(". "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code("barb")
                                                         .AsImplicitExpression(CSharpCodeParser.DefaultKeywords)
                                                         .Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                     factory.EmptyHtml()));
            }
        }
        // [Fact] Silent skip to avoid warnings. Skipping until we can control the parser more directly.
        private void ImplicitExpressionProvisionallyAcceptsCaseInsensitiveDotlessCommitInsertions_NewRoslynIntegration()
        {
            var factory  = new SpanFactory();
            var original = new StringTextSnapshot("foo @date baz");
            var changed  = new StringTextSnapshot("foo @date. baz");
            var edit     = new TestEdit(9, 0, original, 1, changed, ".");

            using (var manager = CreateParserManager(original))
            {
                void ApplyAndVerifyPartialChange(Action applyEdit, string expectedCode)
                {
                    applyEdit();
                    Assert.Equal(1, manager.ParseCount);

                    ParserTestBase.EvaluateParseTree(manager.CurrentSyntaxTree.Root, new MarkupBlock(
                                                         factory.Markup("foo "),
                                                         new ExpressionBlock(
                                                             factory.CodeTransition(),
                                                             factory.Code(expectedCode).AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                         factory.Markup(" baz")));
                };

                manager.InitializeWithDocument(edit.OldSnapshot);

                // This is the process of a dotless commit when doing "." insertions to commit intellisense changes.

                // @date => @date.
                ApplyAndVerifyPartialChange(() => manager.ApplyEdit(edit), "date.");

                original = changed;
                changed  = new StringTextSnapshot("foo @date baz");
                edit     = new TestEdit(9, 1, original, 0, changed, "");

                // @date. => @date
                ApplyAndVerifyPartialChange(() => manager.ApplyEdit(edit), "date");

                original = changed;
                changed  = new StringTextSnapshot("foo @DateTime baz");
                edit     = new TestEdit(5, 4, original, 8, changed, "DateTime");

                // @date => @DateTime
                ApplyAndVerifyPartialChange(() => manager.ApplyEdit(edit), "DateTime");

                original = changed;
                changed  = new StringTextSnapshot("foo @DateTime. baz");
                edit     = new TestEdit(13, 0, original, 1, changed, ".");

                // @DateTime => @DateTime.
                ApplyAndVerifyPartialChange(() => manager.ApplyEdit(edit), "DateTime.");

                // Verify the reparse eventually happens
                manager.WaitForReparse();

                Assert.Equal(2, manager.ParseCount);
                ParserTestBase.EvaluateParseTree(manager.CurrentSyntaxTree.Root, new MarkupBlock(
                                                     factory.Markup("foo "),
                                                     new ExpressionBlock(
                                                         factory.CodeTransition(),
                                                         factory.Code("DateTime").AsImplicitExpression(CSharpCodeParser.DefaultKeywords).Accepts(AcceptedCharactersInternal.NonWhiteSpace)),
                                                     factory.Markup(". baz")));
            }
        }