diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs index 437b4f3fca0..a3b3fdf5b49 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs @@ -10528,10 +10528,7 @@ public void AtAtHandled() CompileToAssembly(generated, // x:\dir\subdir\Test\TestComponent.cshtml(1,28): error CS0103: The name 'Html' does not exist in the current context // var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); - Diagnostic(ErrorCode.ERR_NameNotInContext, "@Html").WithArguments("Html").WithLocation(1, 28), - // x:\dir\subdir\Test\TestComponent.cshtml(1,70): error CS9008: Sequence of '@' characters is not allowed. A verbatim string or identifier can only have one '@' character and a raw string cannot have any. - // var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); - Diagnostic(ErrorCode.ERR_IllegalAtSequence, "@@").WithLocation(1, 70)); + Diagnostic(ErrorCode.ERR_NameNotInContext, "@Html").WithArguments("Html").WithLocation(1, 28)); } #endregion diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs index 0065e63e33f..4ff0f219262 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs @@ -26,7 +26,14 @@ protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components. { #nullable restore #line 1 "x:\dir\subdir\Test\TestComponent.cshtml" - var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); + var validationMessage = @Html.ValidationMessage("test", "", new { + +#line default +#line hidden +#nullable disable +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + @class = "invalid-feedback" }, "div"); #line default #line hidden diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt index 17aa3362a30..201966d5adb 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt @@ -14,5 +14,7 @@ CSharpCode - IntermediateToken - - CSharp - #pragma warning restore 0414 MethodDeclaration - - protected override - void - BuildRenderTree - CSharpCode - (2:0,2 [107] x:\dir\subdir\Test\TestComponent.cshtml) - LazyIntermediateToken - (2:0,2 [107] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); + CSharpCode - (2:0,2 [67] x:\dir\subdir\Test\TestComponent.cshtml) + LazyIntermediateToken - (2:0,2 [67] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - var validationMessage = @Html.ValidationMessage("test", "", new { + CSharpCode - (70:0,70 [39] x:\dir\subdir\Test\TestComponent.cshtml) + LazyIntermediateToken - (70:0,70 [39] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - @class = "invalid-feedback" }, "div"); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt index 63b81ba65a0..de670e4cb86 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt @@ -1,5 +1,10 @@ -Source Location: (2:0,2 [107] x:\dir\subdir\Test\TestComponent.cshtml) -| var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); | -Generated Location: (987:28,2 [107] ) -| var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); | +Source Location: (2:0,2 [67] x:\dir\subdir\Test\TestComponent.cshtml) +| var validationMessage = @Html.ValidationMessage("test", "", new { | +Generated Location: (987:28,2 [67] ) +| var validationMessage = @Html.ValidationMessage("test", "", new { | + +Source Location: (70:0,70 [39] x:\dir\subdir\Test\TestComponent.cshtml) +|@class = "invalid-feedback" }, "div"); | +Generated Location: (1246:35,70 [39] ) +|@class = "invalid-feedback" }, "div"); | diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs index 444867d7db6..a8821bf5df7 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.codegen.cs @@ -18,8 +18,16 @@ public partial class TestComponent : global::Microsoft.AspNetCore.Components.Com protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) { #nullable restore -#line (1,3)-(1,110) "x:\dir\subdir\Test\TestComponent.cshtml" - var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); +#line (1,3)-(1,70) "x:\dir\subdir\Test\TestComponent.cshtml" + var validationMessage = @Html.ValidationMessage("test", "", new { + +#line default +#line hidden +#nullable disable + +#nullable restore +#line (1,71)-(1,110) "x:\dir\subdir\Test\TestComponent.cshtml" +@class = "invalid-feedback" }, "div"); #line default #line hidden diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt index b83bab5a2a9..d62cb6bcb2f 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.ir.txt @@ -7,5 +7,7 @@ UsingDirective - (136:5,1 [47] ) - global::Microsoft.AspNetCore.Components ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase - MethodDeclaration - - protected override - void - BuildRenderTree - CSharpCode - (2:0,2 [107] x:\dir\subdir\Test\TestComponent.cshtml) - LazyIntermediateToken - (2:0,2 [107] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); + CSharpCode - (2:0,2 [67] x:\dir\subdir\Test\TestComponent.cshtml) + LazyIntermediateToken - (2:0,2 [67] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - var validationMessage = @Html.ValidationMessage("test", "", new { + CSharpCode - (70:0,70 [39] x:\dir\subdir\Test\TestComponent.cshtml) + LazyIntermediateToken - (70:0,70 [39] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - @class = "invalid-feedback" }, "div"); diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt index c5ebb96eb39..0cad3f4b3f4 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/AtAtHandled/TestComponent.mappings.txt @@ -1,5 +1,10 @@ -Source Location: (2:0,2 [107] x:\dir\subdir\Test\TestComponent.cshtml) -| var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); | -Generated Location: (736:21,0 [107] ) -| var validationMessage = @Html.ValidationMessage("test", "", new { @@class = "invalid-feedback" }, "div"); | +Source Location: (2:0,2 [67] x:\dir\subdir\Test\TestComponent.cshtml) +| var validationMessage = @Html.ValidationMessage("test", "", new { | +Generated Location: (735:21,0 [67] ) +| var validationMessage = @Html.ValidationMessage("test", "", new { | + +Source Location: (70:0,70 [39] x:\dir\subdir\Test\TestComponent.cshtml) +|@class = "invalid-feedback" }, "div"); | +Generated Location: (939:29,0 [39] ) +|@class = "invalid-feedback" }, "div"); | diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_01.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_01.stree.txt index f00da6ee152..1d6cb7d5a50 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_01.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_01.stree.txt @@ -37,8 +37,7 @@ LeftParenthesis;[(]; CSharpCodeBlock - [38..45)::7 CSharpExpressionLiteral - [38..45)::7 - [@string] - Gen - Transition;[@]; - Keyword;[string]; + Identifier;[@string]; RazorMetaCode - [45..46)::1 - Gen RightParenthesis;[)]; MarkupTextLiteral - [46..46)::0 - [] - Gen diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.diag.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.diag.txt deleted file mode 100644 index 73ab857191a..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.diag.txt +++ /dev/null @@ -1,10 +0,0 @@ -(2,9): Error RZ1009: The "@" character must be followed by a ":", "(", or a C# identifier. If you intended to switch to markup, use an HTML start tag, for example: - -@if(isLoggedIn) { -

Hello, @user!

-} -(3,13): Error RZ1009: The "@" character must be followed by a ":", "(", or a C# identifier. If you intended to switch to markup, use an HTML start tag, for example: - -@if(isLoggedIn) { -

Hello, @user!

-} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.stree.txt index 121bf6fed21..d981280da8c 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_03.stree.txt @@ -15,7 +15,7 @@ Whitespace;[ ]; Identifier;[var]; Whitespace;[ ]; - Identifier;[@]; + Transition;[@]; Identifier;[@class]; Whitespace;[ ]; Assign;[=]; @@ -30,7 +30,7 @@ Whitespace;[ ]; Assign;[=]; Whitespace;[ ]; - Identifier;[@]; + Transition;[@]; Identifier;[@class]; Semicolon;[;]; NewLine;[LF]; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_04.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_04.stree.txt index 264730983f5..925ba941821 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_04.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_04.stree.txt @@ -53,8 +53,7 @@ LeftParenthesis;[(]; CSharpCodeBlock - [74..81)::7 CSharpExpressionLiteral - [74..81)::7 - [@string] - Gen - Transition;[@]; - Keyword;[string]; + Identifier;[@string]; RazorMetaCode - [81..82)::1 - Gen RightParenthesis;[)]; MarkupTextLiteral - [82..82)::0 - [] - Gen diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_05.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_05.stree.txt index 084ec8ffed9..01f88cdc7c3 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_05.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_05.stree.txt @@ -49,8 +49,7 @@ LeftParenthesis;[(]; CSharpCodeBlock - [75..82)::7 CSharpExpressionLiteral - [75..82)::7 - [@string] - Gen - Transition;[@]; - Keyword;[string]; + Identifier;[@string]; RazorMetaCode - [82..83)::1 - Gen RightParenthesis;[)]; MarkupTextLiteral - [83..83)::0 - [] - Gen diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_06.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_06.stree.txt index df0971af655..455c1823c53 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_06.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_06.stree.txt @@ -75,8 +75,7 @@ LeftParenthesis;[(]; CSharpCodeBlock - [115..122)::7 CSharpExpressionLiteral - [115..122)::7 - [@string] - Gen - Transition;[@]; - Keyword;[string]; + Identifier;[@string]; RazorMetaCode - [122..123)::1 - Gen RightParenthesis;[)]; MarkupTextLiteral - [123..123)::0 - [] - Gen diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_07.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_07.stree.txt index 11a0d918c07..6a50645544d 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_07.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_07.stree.txt @@ -67,8 +67,7 @@ LeftParenthesis;[(]; CSharpCodeBlock - [117..124)::7 CSharpExpressionLiteral - [117..124)::7 - [@string] - Gen - Transition;[@]; - Keyword;[string]; + Identifier;[@string]; RazorMetaCode - [124..125)::1 - Gen RightParenthesis;[)]; MarkupTextLiteral - [125..125)::0 - [] - Gen diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.cspans.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.cspans.txt index a1a34a89347..73091dcf9f5 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.cspans.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.cspans.txt @@ -2,6 +2,8 @@ Code span at (0:0,0 [1] ) - Parent: Statement block at (0:0,0 [118] ) Transition span at (1:0,1 [1] ) - Parent: Statement block at (1:0,1 [117] ) MetaCode span at (2:0,2 [1] ) - Parent: Statement block at (1:0,1 [117] ) -Code span at (3:0,3 [114] ) - Parent: Statement block at (1:0,1 [117] ) +Code span at (3:0,3 [74] ) - Parent: Statement block at (1:0,1 [117] ) +Code span at (77:0,77 [1] ) - Parent: Statement block at (1:0,1 [117] ) +Code span at (78:0,78 [39] ) - Parent: Statement block at (1:0,1 [117] ) MetaCode span at (117:0,117 [1] ) - Parent: Statement block at (1:0,1 [117] ) Markup span at (118:0,118 [0] ) - Parent: Markup block at (0:0,0 [118] ) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.stree.txt index 02478530f70..c4820879c0d 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/EscapedIdentifiers_11.stree.txt @@ -12,7 +12,7 @@ RazorMetaCode - [2..3)::1 - Gen LeftBrace;[{]; CSharpCodeBlock - [3..117)::114 - CSharpStatementLiteral - [3..117)::114 - [ var validationMessage = @Html.ValidationMessage(Model.Binding, "", new { @@class = "invalid-feedback" }, "div"); ] - Gen + CSharpStatementLiteral - [3..77)::74 - [ var validationMessage = @Html.ValidationMessage(Model.Binding, "", new { ] - Gen Whitespace;[ ]; Identifier;[var]; Whitespace;[ ]; @@ -36,9 +36,10 @@ Whitespace;[ ]; LeftBrace;[{]; Whitespace;[ ]; + CSharpEphemeralTextLiteral - [77..78)::1 - [@] - Gen Transition;[@]; - Transition;[@]; - Keyword;[class]; + CSharpStatementLiteral - [78..117)::39 - [@class = "invalid-feedback" }, "div"); ] - Gen + Identifier;[@class]; Whitespace;[ ]; Assign;[=]; Whitespace;[ ]; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.diag.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.diag.txt deleted file mode 100644 index bd189123b2f..00000000000 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.diag.txt +++ /dev/null @@ -1,5 +0,0 @@ -(1,14): Error RZ1009: The "@" character must be followed by a ":", "(", or a C# identifier. If you intended to switch to markup, use an HTML start tag, for example: - -@if(isLoggedIn) { -

Hello, @user!

-} diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.stree.txt index 89ff4c9b8bc..e6fc333bcc1 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.stree.txt +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/CSharpBlockTest/TreatsAtSignsAfterFirstPairAsPartOfCSharpStatement.stree.txt @@ -17,7 +17,7 @@ Transition;[@]; CSharpStatementLiteral - [12..28)::16 - [@@@class.Foo() }] - Gen Transition;[@]; - Identifier;[@]; + Transition;[@]; Identifier;[@class]; Dot;[.]; Identifier;[Foo]; diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/CSharpCodeParser.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/CSharpCodeParser.cs index 2f19316adec..0d91e46a2f6 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/CSharpCodeParser.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/CSharpCodeParser.cs @@ -977,23 +977,28 @@ not SyntaxKind.LeftBracket and case SyntaxKind.Keyword: // We want to stitch together `@text`. Accept(in read); + Accept(NextAsEscapedIdentifier()); + continue; - var transition = CurrentToken; - NextToken(); - var identifier = CurrentToken; - NextToken(); - Debug.Assert(transition.Kind == SyntaxKind.Transition); - Debug.Assert(identifier.Kind is SyntaxKind.Identifier or SyntaxKind.Keyword); + // We special case @@identifier because the old compiler behavior was to simply accept it and treat it as if it was @identifier. While + // this isn't legal, the runtime compiler doesn't handle @identifier correctly. We'll continue to accept this for now, but will potentially + // break it in the future when we move to the roslyn lexer and the runtime/compiletime split is much greater. + case SyntaxKind.Transition: + if (Lookahead(2) is not { Kind: SyntaxKind.Identifier or SyntaxKind.Keyword }) + { + goto default; + } - var finalIdentifier = SyntaxFactory.Token(SyntaxKind.Identifier, $"{transition.Content}{identifier.Content}"); - Accept(finalIdentifier); + Accept(in read); + AcceptAndMoveNext(); + Accept(NextAsEscapedIdentifier()); continue; default: // Accept a broken identifier `@` and mark an error Accept(in read); - transition = CurrentToken; + var transition = CurrentToken; Debug.Assert(transition.Kind == SyntaxKind.Transition); @@ -1002,7 +1007,7 @@ not SyntaxKind.LeftBracket and new SourceSpan(CurrentStart, contentLength: 1 /* @ */))); NextToken(); - finalIdentifier = SyntaxFactory.Token(SyntaxKind.Identifier, transition.Content); + var finalIdentifier = SyntaxFactory.Token(SyntaxKind.Identifier, transition.Content); Accept(finalIdentifier); continue; } @@ -2639,7 +2644,7 @@ private void ParseReservedDirective(SyntaxListBuilder builder, } protected void CompleteBlock() - { + { AcceptMarkerTokenIfNecessary(); CaptureWhitespaceToEndOfLine(); } @@ -2822,8 +2827,7 @@ private bool Balance(SyntaxListBuilder builder, BalancingModes do { if (IsAtEmbeddedTransition( - (mode & BalancingModes.AllowCommentsAndTemplates) == BalancingModes.AllowCommentsAndTemplates, - (mode & BalancingModes.AllowEmbeddedTransitions) == BalancingModes.AllowEmbeddedTransitions)) + (mode & BalancingModes.AllowCommentsAndTemplates) == BalancingModes.AllowCommentsAndTemplates)) { Accept(in tokens); tokens.Clear(); @@ -2832,6 +2836,31 @@ private bool Balance(SyntaxListBuilder builder, BalancingModes // Reset backtracking since we've already outputted some spans. startPosition = CurrentStart.AbsoluteIndex; } + + if (At(SyntaxKind.Transition)) + { + // We special case @@identifier because the old compiler behavior was to simply accept it and treat it as if it was @identifier. While + // this isn't legal, the runtime compiler doesn't handle @identifier correctly. We'll continue to accept this for now, but will potentially + // break it in the future when we move to the roslyn lexer and the runtime/compiletime split is much greater. + if (NextIs(SyntaxKind.Transition) && Lookahead(2) is { Kind: SyntaxKind.Identifier or SyntaxKind.Keyword }) + { + Accept(in tokens); + tokens.Clear(); + builder.Add(OutputTokensAsStatementLiteral()); + AcceptAndMoveNext(); + builder.Add(OutputTokensAsEphemeralLiteral()); + + // Reset backtracking since we've already outputted some spans. + startPosition = CurrentStart.AbsoluteIndex; + continue; + } + else if (NextIs(SyntaxKind.Keyword, SyntaxKind.Identifier)) + { + tokens.Add(NextAsEscapedIdentifier()); + continue; + } + } + if (At(left)) { nesting++; @@ -2840,12 +2869,14 @@ private bool Balance(SyntaxListBuilder builder, BalancingModes { nesting--; } + if (nesting > 0) { tokens.Add(CurrentToken); + NextToken(); } } - while (nesting > 0 && NextToken() && !(stopAtEndOfLine && At(SyntaxKind.NewLine))); + while (nesting > 0 && EnsureCurrent() && !(stopAtEndOfLine && At(SyntaxKind.NewLine))); if (nesting > 0) { @@ -2876,9 +2907,8 @@ private bool Balance(SyntaxListBuilder builder, BalancingModes return nesting == 0; } - private bool IsAtEmbeddedTransition(bool allowTemplatesAndComments, bool allowTransitions) + private bool IsAtEmbeddedTransition(bool allowTemplatesAndComments) { - // No embedded transitions in C#, so ignore that param return allowTemplatesAndComments && ((Language.IsTransition(CurrentToken) && NextIs(SyntaxKind.LessThan, SyntaxKind.Colon, SyntaxKind.DoubleColon)) @@ -2910,6 +2940,19 @@ private void ParseEmbeddedTransition(in SyntaxListBuilder build } } + private SyntaxToken NextAsEscapedIdentifier() + { + Debug.Assert(CurrentToken.Kind == SyntaxKind.Transition); + var transition = CurrentToken; + NextToken(); + Debug.Assert(CurrentToken.Kind is SyntaxKind.Identifier or SyntaxKind.Keyword); + var identifier = CurrentToken; + NextToken(); + + var finalIdentifier = SyntaxFactory.Token(SyntaxKind.Identifier, $"{transition.Content}{identifier.Content}"); + return finalIdentifier; + } + [Conditional("DEBUG")] internal void Assert(CSharpKeyword expectedKeyword) {