diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/Legacy/CSharpCodeParser.cs b/src/Microsoft.AspNetCore.Razor.Evolution/Legacy/CSharpCodeParser.cs
index f4ef8f5b8b..2eb411e9c4 100644
--- a/src/Microsoft.AspNetCore.Razor.Evolution/Legacy/CSharpCodeParser.cs
+++ b/src/Microsoft.AspNetCore.Razor.Evolution/Legacy/CSharpCodeParser.cs
@@ -1553,7 +1553,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
outputKind = SpanKind.Code;
break;
case DirectiveTokenKind.String:
- AcceptUntil(CSharpSymbolType.WhiteSpace, CSharpSymbolType.NewLine);
+ if (At(CSharpSymbolType.StringLiteral))
+ {
+ AcceptAndMoveNext();
+ }
+ else
+ {
+ var startLocation = CurrentStart;
+ AcceptUntil(CSharpSymbolType.WhiteSpace, CSharpSymbolType.NewLine);
+ Context.ErrorSink.OnError(
+ startLocation,
+ LegacyResources.FormatDirectiveExpectsQuotedStringLiteral(descriptor.Name),
+ Span.End.AbsoluteIndex - Span.Start.AbsoluteIndex);
+ }
break;
}
diff --git a/src/Microsoft.AspNetCore.Razor.Evolution/LegacyResources.resx b/src/Microsoft.AspNetCore.Razor.Evolution/LegacyResources.resx
index cfbead3383..5661657e3f 100644
--- a/src/Microsoft.AspNetCore.Razor.Evolution/LegacyResources.resx
+++ b/src/Microsoft.AspNetCore.Razor.Evolution/LegacyResources.resx
@@ -182,6 +182,9 @@
F{o}o
}", + "@custom \"Header\" {F{o}o
}", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "Header", markup: false) + Factory.Span(SpanKind.Markup, "\"Header\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace), @@ -146,14 +248,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy // Act & Assert ParseCodeBlockTest( - "@custom Name { foo(); bar(); }", + "@custom \"Name\" { foo(); bar(); }", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "Name", markup: false) + Factory.Span(SpanKind.Markup, "\"Name\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace), @@ -226,14 +328,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy // Act & Assert ParseCodeBlockTest( - "@custom hello ; ", + "@custom \"hello\" ; ", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "hello", markup: false) + Factory.Span(SpanKind.Markup, "\"hello\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace), Factory.Span(SpanKind.Markup, " ; ", markup: false).Accepts(AcceptedCharacters.WhiteSpace))); @@ -246,19 +348,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy var descriptor = DirectiveDescriptorBuilder.Create("custom").AddString().Build(); var expectedErorr = new RazorError( LegacyResources.FormatUnexpectedDirectiveLiteral("custom", Environment.NewLine), - new SourceLocation(14, 0, 14), - length: 5); + new SourceLocation(16, 0, 16), + length: 7); // Act & Assert ParseCodeBlockTest( - "@custom hello world", + "@custom \"hello\" \"world\"", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "hello", markup: false) + Factory.Span(SpanKind.Markup, "\"hello\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace), @@ -273,19 +375,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build(); var expectedErorr = new RazorError( LegacyResources.FormatUnexpectedDirectiveLiteral("custom", "{"), - new SourceLocation(14, 0, 14), + new SourceLocation(16, 0, 16), length: 5); // Act & Assert ParseCodeBlockTest( - "@custom Hello World { foo(); bar(); }", + "@custom \"Hello\" World { foo(); bar(); }", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "Hello", markup: false) + Factory.Span(SpanKind.Markup, "\"Hello\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace), @@ -300,19 +402,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build(); var expectedErorr = new RazorError( LegacyResources.FormatUnexpectedEOFAfterDirective("custom", "{"), - new SourceLocation(13, 0, 13), + new SourceLocation(15, 0, 15), length: 1); // Act & Assert ParseCodeBlockTest( - "@custom Hello", + "@custom \"Hello\"", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "Hello", markup: false) + Factory.Span(SpanKind.Markup, "\"Hello\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace)), expectedErorr); @@ -325,19 +427,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy var descriptor = DirectiveDescriptorBuilder.CreateCodeBlock("custom").AddString().Build(); var expectedErorr = new RazorError( LegacyResources.FormatParseError_Expected_EndOfBlock_Before_EOF("custom", "}", "{"), - new SourceLocation(14, 0, 14), + new SourceLocation(16, 0, 16), length: 1); // Act & Assert ParseCodeBlockTest( - "@custom Hello {", + "@custom \"Hello\" {", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "Hello", markup: false) + Factory.Span(SpanKind.Markup, "\"Hello\"", markup: false) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens[0])) .Accepts(AcceptedCharacters.NonWhiteSpace), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.AllWhiteSpace), @@ -781,14 +883,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy // Act & Assert ParseCodeBlockTest( - "@custom simple-value", + "@custom \"simple-value\"", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "simple-value", markup: false) + Factory.Span(SpanKind.Markup, "\"simple-value\"", markup: false) .Accepts(AcceptedCharacters.NonWhiteSpace) .With(chunkGenerator))); } @@ -802,14 +904,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy // Act & Assert ParseCodeBlockTest( - "@custom {formaction}?/{id}?", + "@custom \"{formaction}?/{id}?\"", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "{formaction}?/{id}?", markup: false) + Factory.Span(SpanKind.Markup, "\"{formaction}?/{id}?\"", markup: false) .Accepts(AcceptedCharacters.NonWhiteSpace) .With(chunkGenerator))); } @@ -822,14 +924,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy // Act & Assert ParseCodeBlockTest( - "@custom {formaction}?/{id}? System.String", + "@custom \"{formaction}?/{id}?\" System.String", new[] { descriptor }, new DirectiveBlock( new DirectiveChunkGenerator(descriptor), Factory.CodeTransition(), Factory.MetaCode("custom").Accepts(AcceptedCharacters.None), Factory.Span(SpanKind.Markup, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace), - Factory.Span(SpanKind.Markup, "{formaction}?/{id}?", markup: false) + Factory.Span(SpanKind.Markup, "\"{formaction}?/{id}?\"", markup: false) .Accepts(AcceptedCharacters.NonWhiteSpace) .With(new DirectiveTokenChunkGenerator(descriptor.Tokens.First())), Factory.Span(SpanKind.Code, " ", markup: false).Accepts(AcceptedCharacters.WhiteSpace),