diff --git a/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs b/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs new file mode 100644 index 0000000000..5c3f4403e0 --- /dev/null +++ b/src/Microsoft.AspNetCore.Razor.Language/DirectiveTokenEditHandler.cs @@ -0,0 +1,49 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Razor.Language.Legacy; + +namespace Microsoft.AspNetCore.Razor.Language +{ + internal class DirectiveTokenEditHandler : SpanEditHandler + { + public DirectiveTokenEditHandler(Func> tokenizer) : base(tokenizer) + { + } + + protected override PartialParseResult CanAcceptChange(Span target, SourceChange change) + { + if (AcceptedCharacters == AcceptedCharactersInternal.NonWhiteSpace) + { + var originalText = change.GetOriginalText(target); + var editedContent = change.GetEditedContent(target); + + if (!ContainsWhitespace(originalText) && !ContainsWhitespace(editedContent)) + { + // Did not modify whitespace, directive format should be the same. + // Return provisional so extensible IR/code gen pieces can see the full directive text + // once the user stops editing the document. + return PartialParseResult.Accepted | PartialParseResult.Provisional; + } + } + + return PartialParseResult.Rejected; + + } + + private static bool ContainsWhitespace(string content) + { + for (var i = 0; i < content.Length; i++) + { + if (char.IsWhiteSpace(content[i])) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs index 6d45b45404..a26b06d68a 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Legacy/CSharpCodeParser.cs @@ -913,21 +913,53 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy // qualified-identifier: // identifier // qualified-identifier . identifier - protected bool QualifiedIdentifier() + protected bool QualifiedIdentifier(out int identifierLength) { - if (At(CSharpSymbolType.Identifier)) + var currentIdentifierLength = 0; + var expectingDot = false; + var tokens = ReadWhile(token => { - AcceptAndMoveNext(); - - if (Optional(CSharpSymbolType.Dot)) + var type = token.Type; + if ((expectingDot && type == CSharpSymbolType.Dot) || + (!expectingDot && type == CSharpSymbolType.Identifier)) { - return QualifiedIdentifier(); + expectingDot = !expectingDot; + return true; + } + + if (type != CSharpSymbolType.WhiteSpace && + type != CSharpSymbolType.NewLine) + { + expectingDot = false; + currentIdentifierLength += token.Content.Length; + } + + return false; + }); + + identifierLength = currentIdentifierLength; + var validQualifiedIdentifier = expectingDot; + if (validQualifiedIdentifier) + { + foreach (var token in tokens) + { + identifierLength += token.Content.Length; + Accept(token); } return true; } else { + PutCurrentBack(); + + foreach (var token in tokens) + { + identifierLength += token.Content.Length; + PutBack(token); + } + + EnsureCurrent(); return false; } } @@ -1602,12 +1634,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy break; case DirectiveTokenKind.Namespace: - if (!QualifiedIdentifier()) + if (!QualifiedIdentifier(out var identifierLength)) { Context.ErrorSink.OnError( CurrentStart, LegacyResources.FormatDirectiveExpectsNamespace(descriptor.Name), - CurrentSymbol.Content.Length); + identifierLength); return; } @@ -1645,6 +1677,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy } Span.ChunkGenerator = new DirectiveTokenChunkGenerator(tokenDescriptor); + Span.EditHandler = new DirectiveTokenEditHandler(Language.TokenizeString); Output(SpanKindInternal.Code, AcceptedCharactersInternal.NonWhiteSpace); } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs index 50cd7e2180..85bea39884 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -27,6 +27,16 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.IntegrationTests private static readonly RazorSourceDocument DefaultImports = MvcRazorTemplateEngine.GetDefaultImports(); #region Runtime + [Fact] + public void InvalidNamespaceAtEOF_Runtime() + { + var references = CreateCompilationReferences(CurrentMvcShim); + RunRuntimeTest(references, expectedErrors: new[] + { + "Identifier expected" + }); + } + [Fact] public void IncompleteDirectives_Runtime() { @@ -256,6 +266,13 @@ public class AllTagHelper : {typeof(TagHelper).FullName} #endregion #region DesignTime + [Fact] + public void InvalidNamespaceAtEOF_DesignTime() + { + var references = CreateCompilationReferences(CurrentMvcShim); + RunDesignTimeTest(references, expectedErrors: new[] { "Identifier expected" }); + } + [Fact] public void IncompleteDirectives_DesignTime() { diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml new file mode 100644 index 0000000000..6dfb72bc31 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml @@ -0,0 +1 @@ +@namespace Test. \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs new file mode 100644 index 0000000000..0dd729a78d --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.codegen.cs @@ -0,0 +1,35 @@ +namespace +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + } + #pragma warning restore 219 + private static System.Object __o = null; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt new file mode 100644 index 0000000000..6cf3ca93c9 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.ir.txt @@ -0,0 +1,36 @@ +Document - + Checksum - + NamespaceDeclaration - - + UsingStatement - - TModel = global::System.Object + UsingStatement - (1:0,1 [12] ) - System + UsingStatement - (16:1,1 [32] ) - System.Collections.Generic + UsingStatement - (51:2,1 [17] ) - System.Linq + UsingStatement - (71:3,1 [28] ) - System.Threading.Tasks + UsingStatement - (102:4,1 [30] ) - Microsoft.AspNetCore.Mvc + UsingStatement - (135:5,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingStatement - (178:6,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + DesignTimeDirective - + DirectiveToken - (231:7,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper + DirectiveToken - (294:7,71 [4] ) - Html + DirectiveToken - (308:8,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper + DirectiveToken - (363:8,63 [4] ) - Json + DirectiveToken - (377:9,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper + DirectiveToken - (431:9,62 [9] ) - Component + DirectiveToken - (450:10,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper + DirectiveToken - (494:10,52 [3] ) - Url + DirectiveToken - (507:11,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider + DirectiveToken - (578:11,79 [23] ) - ModelExpressionProvider + DirectiveToken - (617:12,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (729:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor + DirectiveToken - (832:14,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor + CSharpStatement - + RazorIRToken - - CSharp - private static System.Object __o = null; + MethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync + HtmlContent - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) + RazorIRToken - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) - Html - Test. + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_DesignTime.mappings.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs new file mode 100644 index 0000000000..0e8e0f2afd --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.codegen.cs @@ -0,0 +1,33 @@ +#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "de132bd3e2a46a0d2ec953a168427c01e5829cde" +namespace +{ + #line hidden + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage + { + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + BeginContext(11, 5, true); + WriteLiteral("Test."); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper Html { get; private set; } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt new file mode 100644 index 0000000000..637caafd8d --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/InvalidNamespaceAtEOF_Runtime.ir.txt @@ -0,0 +1,23 @@ +Document - + Checksum - + NamespaceDeclaration - - + UsingStatement - (1:0,1 [14] ) - System + UsingStatement - (16:1,1 [34] ) - System.Collections.Generic + UsingStatement - (51:2,1 [19] ) - System.Linq + UsingStatement - (71:3,1 [30] ) - System.Threading.Tasks + UsingStatement - (102:4,1 [32] ) - Microsoft.AspNetCore.Mvc + UsingStatement - (135:5,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering + UsingStatement - (178:6,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures + ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_InvalidNamespaceAtEOF_cshtml - global::Microsoft.AspNetCore.Mvc.Razor.RazorPage - + MethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync + CSharpStatement - + RazorIRToken - - CSharp - BeginContext(11, 5, true); + HtmlContent - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) + RazorIRToken - (11:0,11 [5] InvalidNamespaceAtEOF.cshtml) - Html - Test. + CSharpStatement - + RazorIRToken - - CSharp - EndContext(); + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs new file mode 100644 index 0000000000..1a5aae94b7 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/DirectiveTokenEditHandlerTest.cs @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.AspNetCore.Razor.Language.Legacy; +using Xunit; + +namespace Microsoft.AspNetCore.Razor.Language.Test +{ + public class DirectiveTokenEditHandlerTest + { + [Theory] + [InlineData(0, 4, "")] // "Namespace" + [InlineData(4, 0, "Other")] // "SomeOtherNamespace" + [InlineData(0, 4, "Other")] // "OtherNamespace" + public void CanAcceptChange_ProvisionallyAcceptsNonWhitespaceChanges(int index, int length, string newText) + { + // Arrange + var factory = new SpanFactory(); + var directiveTokenHandler = new TestDirectiveTokenEditHandler(); + var target = factory.Span(SpanKindInternal.Code, "SomeNamespace", markup: false) + .With(directiveTokenHandler) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace); + var sourceChange = new SourceChange(index, length, newText); + + // Act + var result = directiveTokenHandler.CanAcceptChange(target, sourceChange); + + // Assert + Assert.Equal(PartialParseResult.Accepted | PartialParseResult.Provisional, result); + } + + [Theory] + [InlineData(4, 1, "")] // "SomeNamespace" + [InlineData(9, 0, " ")] // "Some Name space" + [InlineData(9, 5, " Space")] // "Some Name Space" + public void CanAcceptChange_RejectsWhitespaceChanges(int index, int length, string newText) + { + // Arrange + var factory = new SpanFactory(); + var directiveTokenHandler = new TestDirectiveTokenEditHandler(); + var target = factory.Span(SpanKindInternal.Code, "Some Namespace", markup: false) + .With(directiveTokenHandler) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace); + var sourceChange = new SourceChange(index, length, newText); + + // Act + var result = directiveTokenHandler.CanAcceptChange(target, sourceChange); + + // Assert + Assert.Equal(PartialParseResult.Rejected, result); + } + + private class TestDirectiveTokenEditHandler : DirectiveTokenEditHandler + { + public TestDirectiveTokenEditHandler() : base(content => SpanConstructor.TestTokenizer(content)) + { + } + + public new PartialParseResult CanAcceptChange(Span target, SourceChange change) + => base.CanAcceptChange(target, change); + } + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs index 8fe0121b5e..58ee104f94 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpAutoCompleteTest.cs @@ -33,8 +33,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + .AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First()), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -87,9 +86,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First()), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs index f51d8e33b1..eb8fcb58fb 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpDirectivesTest.cs @@ -10,6 +10,97 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy { public class CSharpDirectivesTest : CsHtmlCodeParserTestBase { + [Fact] + public void DirectiveDescriptor_CanHandleEOFIncompleteNamespaceTokens() + { + // Arrange + var descriptor = DirectiveDescriptor.CreateDirective( + "custom", + DirectiveKind.SingleLine, + b => b.AddNamespaceToken()); + + // Act & Assert + ParseCodeBlockTest( + "@custom System.", + new[] { descriptor }, + new DirectiveBlock( + new DirectiveChunkGenerator(descriptor), + Factory.CodeTransition(), + Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), + Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)), + new RazorError( + LegacyResources.FormatDirectiveExpectsNamespace("custom"), + 8, 0, 8, 7)); + } + + [Fact] + public void DirectiveDescriptor_CanHandleEOFInvalidNamespaceTokens() + { + // Arrange + var descriptor = DirectiveDescriptor.CreateDirective( + "custom", + DirectiveKind.SingleLine, + b => b.AddNamespaceToken()); + + // Act & Assert + ParseCodeBlockTest( + "@custom System<", + new[] { descriptor }, + new DirectiveBlock( + new DirectiveChunkGenerator(descriptor), + Factory.CodeTransition(), + Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), + Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)), + new RazorError( + LegacyResources.FormatDirectiveExpectsNamespace("custom"), + 8, 0, 8, 7)); + } + [Fact] + public void DirectiveDescriptor_CanHandleIncompleteNamespaceTokens() + { + // Arrange + var descriptor = DirectiveDescriptor.CreateDirective( + "custom", + DirectiveKind.SingleLine, + b => b.AddNamespaceToken()); + + // Act & Assert + ParseCodeBlockTest( + "@custom System." + Environment.NewLine, + new[] { descriptor }, + new DirectiveBlock( + new DirectiveChunkGenerator(descriptor), + Factory.CodeTransition(), + Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), + Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)), + new RazorError( + LegacyResources.FormatDirectiveExpectsNamespace("custom"), + 8, 0, 8, 7)); + } + + [Fact] + public void DirectiveDescriptor_CanHandleInvalidNamespaceTokens() + { + // Arrange + var descriptor = DirectiveDescriptor.CreateDirective( + "custom", + DirectiveKind.SingleLine, + b => b.AddNamespaceToken()); + + // Act & Assert + ParseCodeBlockTest( + "@custom System<" + Environment.NewLine, + new[] { descriptor }, + new DirectiveBlock( + new DirectiveChunkGenerator(descriptor), + Factory.CodeTransition(), + Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), + Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)), + new RazorError( + LegacyResources.FormatDirectiveExpectsNamespace("custom"), + 8, 0, 8, 7)); + } + [Fact] public void ExtensibleDirectiveDoesNotErorrIfNotAtStartOfLineBecauseOfWhitespace() { @@ -28,9 +119,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -96,9 +185,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)), Factory.EmptyCSharp().AsStatement(), Factory.MetaCode("}").Accepts(AcceptedCharactersInternal.None)), @@ -126,9 +213,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -149,9 +234,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -172,9 +255,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "BaseNamespace", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "BaseNamespace", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -195,9 +276,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "BaseNamespace.Foo.Bar", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "BaseNamespace.Foo.Bar", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -218,9 +297,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"AString\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "\"AString\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -343,19 +420,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[1])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false).AsDirectiveToken(descriptor.Tokens[1]), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"AString\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[2])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace))); + Factory.Span(SpanKindInternal.Code, "\"AString\"", markup: false).AsDirectiveToken(descriptor.Tokens[2]))); } [Fact] @@ -376,9 +447,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"Header\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "\"Header\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{") .AutoCompleteWith(null, atEndOfSpan: true) @@ -412,9 +481,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"Name\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "\"Name\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{") .AutoCompleteWith(null, atEndOfSpan: true) @@ -442,14 +509,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "System.Text.Encoding.ASCIIEncoding", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[1])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "Some_Member", markup: false).AsDirectiveToken(descriptor.Tokens[1]), Factory.Span(SpanKindInternal.Markup, " ", markup: false) .Accepts(AcceptedCharactersInternal.WhiteSpace))); @@ -499,9 +562,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"hello\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "\"hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ; ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace))); } @@ -528,9 +589,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"hello\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "\"hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace)), expectedErorr); @@ -559,9 +618,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace)), expectedErorr); @@ -590,9 +647,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace)), + Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0])), expectedErorr); } @@ -619,9 +674,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace), + Factory.Span(SpanKindInternal.Code, "\"Hello\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{") .AutoCompleteWith("}", atEndOfSpan: true) @@ -942,9 +995,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.Web.WebPages.WebPage", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First())))); + Factory.Span(SpanKindInternal.Code, "System.Web.WebPages.WebPage", markup: false).AsDirectiveToken(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))); } [Fact] @@ -955,9 +1006,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "string[[]][]", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First())))); + Factory.Span(SpanKindInternal.Code, "string[[]][]", markup: false).AsDirectiveToken(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))); } [Fact] @@ -969,8 +1018,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), Factory.Span(SpanKindInternal.Code, "System.Web.Mvc.WebViewPage>", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First())))); + .AsDirectiveToken(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))); } [Fact] @@ -982,8 +1030,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), Factory.Span(SpanKindInternal.Code, "string", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First())))); + .AsDirectiveToken(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First()))); } [Fact] @@ -1021,8 +1068,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), Factory.Span(SpanKindInternal.Code, "Header", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + .AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First()), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -1066,8 +1112,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy DirectiveKind.SingleLine, b => b.AddOptionalStringToken()); - var chunkGenerator = new DirectiveTokenChunkGenerator(descriptor.Tokens.First()); - // Act & Assert ParseCodeBlockTest( "@custom \"simple-value\"", @@ -1078,8 +1122,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), Factory.Span(SpanKindInternal.Code, "\"simple-value\"", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(chunkGenerator))); + .AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -1091,8 +1134,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy DirectiveKind.SingleLine, b => b.AddOptionalStringToken()); - var chunkGenerator = new DirectiveTokenChunkGenerator(descriptor.Tokens.First()); - // Act & Assert ParseCodeBlockTest( "@custom \"{formaction}?/{id}?\"", @@ -1103,8 +1144,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), Factory.Span(SpanKindInternal.Code, "\"{formaction}?/{id}?\"", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(chunkGenerator))); + .AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] @@ -1125,13 +1165,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Markup, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "\"{formaction}?/{id}?\"", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "\"{formaction}?/{id}?\"", markup: false).AsDirectiveToken(descriptor.Tokens[0]), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "System.String", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens.Last())))); + Factory.Span(SpanKindInternal.Code, "System.String", markup: false).AsDirectiveToken(descriptor.Tokens.Last()))); } [Fact] @@ -1172,9 +1208,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("TestDirective").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", markup: false).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "PropertyName", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(descriptor.Tokens.First())))); + Factory.Span(SpanKindInternal.Code, "PropertyName", markup: false).AsDirectiveToken(descriptor.Tokens[0]))); } [Fact] diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs index 3f4511525a..e0657c1999 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSectionTest.cs @@ -35,9 +35,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " " + Environment.NewLine + " ", markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace)), Factory.EmptyHtml()), new RazorError( @@ -110,9 +108,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First()))), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0])), Factory.Markup("-bar { "), new MarkupTagBlock( Factory.Markup("

")), @@ -136,9 +132,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -147,9 +141,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "bar", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "bar", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -184,9 +176,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -211,9 +201,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -234,9 +222,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -269,9 +255,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Test", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Test", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, Environment.NewLine, CSharpSymbolType.NewLine).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith("}", atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -303,9 +287,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " " + Environment.NewLine, markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace)), Factory.EmptyHtml()), new RazorError( @@ -332,9 +314,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " " + string.Format("{0}{0}{0}{0}{0}{0}", Environment.NewLine), markup: false).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -359,9 +339,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -386,9 +364,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( Factory.Markup(" "), @@ -412,9 +388,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -439,9 +413,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -469,9 +441,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -496,9 +466,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -521,9 +489,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -542,9 +508,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -565,9 +529,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -587,9 +549,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -612,9 +572,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -639,9 +597,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy factory.CodeTransition(), factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -666,9 +622,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy factory.CodeTransition(), factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + factory.Span(SpanKindInternal.Code, "s", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs index 7e95b373f6..e51227991f 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/CSharpSpecialBlockTest.cs @@ -27,9 +27,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy new DirectiveBlock(new DirectiveChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor), Factory.MetaCode("inherits").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo.Bar, string, int>.Baz", markup: false) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens.First())))); + Factory.Span(SpanKindInternal.Code, "Foo.Bar, string, int>.Baz", markup: false).AsDirectiveToken(CSharpCodeParser.InheritsDirectiveDescriptor.Tokens[0]))); } [Fact] diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs index d5d0df8678..890e83714d 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlDocumentTest.cs @@ -113,9 +113,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -478,9 +476,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs index 925f2e2c51..a854d838b4 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/HtmlToCodeSwitchTest.cs @@ -295,9 +295,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -398,9 +396,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( @@ -426,9 +422,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy Factory.CodeTransition(), Factory.MetaCode("section").Accepts(AcceptedCharactersInternal.None), Factory.Span(SpanKindInternal.Code, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.WhiteSpace), - Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier) - .Accepts(AcceptedCharactersInternal.NonWhiteSpace) - .With(new DirectiveTokenChunkGenerator(CSharpCodeParser.SectionDirectiveDescriptor.Tokens.First())), + Factory.Span(SpanKindInternal.Code, "Foo", CSharpSymbolType.Identifier).AsDirectiveToken(CSharpCodeParser.SectionDirectiveDescriptor.Tokens[0]), Factory.Span(SpanKindInternal.Markup, " ", CSharpSymbolType.WhiteSpace).Accepts(AcceptedCharactersInternal.AllWhiteSpace), Factory.MetaCode("{").AutoCompleteWith(null, atEndOfSpan: true).Accepts(AcceptedCharactersInternal.None), new MarkupBlock( diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TestSpanBuilder.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TestSpanBuilder.cs index 4ac533e007..213883c0ff 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TestSpanBuilder.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Legacy/TestSpanBuilder.cs @@ -153,6 +153,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy .Accepts(AcceptedCharactersInternal.AnyExceptNewline); } + public static SpanConstructor AsDirectiveToken(this SpanConstructor self, DirectiveTokenDescriptor descriptor) + { + return self + .With(new DirectiveTokenChunkGenerator(descriptor)) + .With(new DirectiveTokenEditHandler((content) => SpanConstructor.TestTokenizer(content))) + .Accepts(AcceptedCharactersInternal.NonWhiteSpace); + } + public static SourceLocation GetLocationAndAdvance(this SourceLocationTracker self, string content) { var ret = self.CurrentLocation;