From 9bdbf910b4de2354d009f230e506b6dd26c12531 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:48:08 +0000 Subject: [PATCH 1/3] Initial plan From e4d528657eb53fc694f60a63e4f79cb164aec70c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Feb 2026 20:05:57 +0000 Subject: [PATCH 2/3] Mark empty outer tags as errors when context switching from C# to markup (RZ1022) Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../test/Legacy/HtmlErrorTest.cs | 12 +++++ ...erTagProducesErrorInMarkupBlock.cspans.txt | 9 ++++ ...uterTagProducesErrorInMarkupBlock.diag.txt | 1 + ...terTagProducesErrorInMarkupBlock.stree.txt | 32 ++++++++++++ ...oducesErrorInTemplateExpression.cspans.txt | 11 +++++ ...ProducesErrorInTemplateExpression.diag.txt | 1 + ...roducesErrorInTemplateExpression.stree.txt | 49 +++++++++++++++++++ .../HtmlTagsTest/EmptyTag.diag.txt | 1 + .../src/Language/Legacy/HtmlMarkupParser.cs | 11 +++++ 9 files changed, 127 insertions(+) create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.cspans.txt create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.diag.txt create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.stree.txt create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.cspans.txt create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.diag.txt create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.stree.txt create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Legacy/HtmlErrorTest.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Legacy/HtmlErrorTest.cs index b9ef9780545..3945a3c5e81 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Legacy/HtmlErrorTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Legacy/HtmlErrorTest.cs @@ -50,4 +50,16 @@ public void WithUnfinishedTagAtEOFErrorsWithIncompleteTag() { ParseDocumentTest("@{foo}"); + } + + [Fact] + public void EmptyOuterTagProducesErrorInTemplateExpression() + { + ParseDocumentTest("@Html.Repeat(10, @<>Foo #@item)"); + } } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.cspans.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.cspans.txt new file mode 100644 index 00000000000..055e71d94ee --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.cspans.txt @@ -0,0 +1,9 @@ +Markup span at (0:0,0 [0] ) - Parent: Markup block at (0:0,0 [11] ) +Transition span at (0:0,0 [1] ) - Parent: Statement block at (0:0,0 [11] ) +MetaCode span at (1:0,1 [1] ) - Parent: Statement block at (0:0,0 [11] ) +Markup span at (2:0,2 [2] ) - Parent: Tag block at (2:0,2 [2] ) +Markup span at (4:0,4 [3] ) - Parent: Markup block at (2:0,2 [8] ) +Markup span at (7:0,7 [3] ) - Parent: Tag block at (7:0,7 [3] ) +Code span at (10:0,10 [0] ) - Parent: Statement block at (0:0,0 [11] ) +MetaCode span at (10:0,10 [1] ) - Parent: Statement block at (0:0,0 [11] ) +Markup span at (11:0,11 [0] ) - Parent: Markup block at (0:0,0 [11] ) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.diag.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.diag.txt new file mode 100644 index 00000000000..b0ba1807ee2 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.diag.txt @@ -0,0 +1 @@ +(1,3): Error RZ1022: Outer tag is missing a name. The first character of a markup block must be an HTML tag with a valid name. diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.stree.txt new file mode 100644 index 00000000000..66f2ff8ac14 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInMarkupBlock.stree.txt @@ -0,0 +1,32 @@ +RazorDocument - [0..11)::11 - [@{<>foo}] + MarkupBlock - [0..11)::11 + MarkupTextLiteral - [0..0)::0 - [] - Gen + Marker;[]; + CSharpCodeBlock - [0..11)::11 + CSharpStatement - [0..11)::11 + CSharpTransition - [0..1)::1 - Gen + Transition;[@]; + CSharpStatementBody - [1..11)::10 + RazorMetaCode - [1..2)::1 - Gen + LeftBrace;[{]; + CSharpCodeBlock - [2..10)::8 + MarkupBlock - [2..10)::8 + MarkupElement - [2..10)::8 + MarkupStartTag - [2..4)::2 - [<>] - Gen + OpenAngle;[<]; + Text;[]; + CloseAngle;[>]; + MarkupTextLiteral - [4..7)::3 - [foo] - Gen + Text;[foo]; + MarkupEndTag - [7..10)::3 - [] - Gen + OpenAngle;[<]; + ForwardSlash;[/]; + Text;[]; + CloseAngle;[>]; + CSharpStatementLiteral - [10..10)::0 - [] - Gen + Marker;[]; + RazorMetaCode - [10..11)::1 - Gen + RightBrace;[}]; + MarkupTextLiteral - [11..11)::0 - [] - Gen + Marker;[]; + EndOfFile;[]; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.cspans.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.cspans.txt new file mode 100644 index 00000000000..f92d14e65fb --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.cspans.txt @@ -0,0 +1,11 @@ +Markup span at (0:0,0 [0] ) - Parent: Markup block at (0:0,0 [34] ) +Transition span at (0:0,0 [1] ) - Parent: Expression block at (0:0,0 [34] ) +Code span at (1:0,1 [16] ) - Parent: Expression block at (0:0,0 [34] ) +Transition span at (17:0,17 [1] ) - Parent: Markup block at (17:0,17 [16] ) +Markup span at (18:0,18 [2] ) - Parent: Tag block at (18:0,18 [2] ) +Markup span at (20:0,20 [5] ) - Parent: Markup block at (17:0,17 [16] ) +Transition span at (25:0,25 [1] ) - Parent: Expression block at (25:0,25 [5] ) +Code span at (26:0,26 [4] ) - Parent: Expression block at (25:0,25 [5] ) +Markup span at (30:0,30 [3] ) - Parent: Tag block at (30:0,30 [3] ) +Code span at (33:0,33 [1] ) - Parent: Expression block at (0:0,0 [34] ) +Markup span at (34:0,34 [0] ) - Parent: Markup block at (0:0,0 [34] ) diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.diag.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.diag.txt new file mode 100644 index 00000000000..6e3c91bbe4a --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.diag.txt @@ -0,0 +1 @@ +(1,19): Error RZ1022: Outer tag is missing a name. The first character of a markup block must be an HTML tag with a valid name. diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.stree.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.stree.txt new file mode 100644 index 00000000000..0c7d8aa842e --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlErrorTest/EmptyOuterTagProducesErrorInTemplateExpression.stree.txt @@ -0,0 +1,49 @@ +RazorDocument - [0..34)::34 - [@Html.Repeat(10, @<>Foo #@item)] + MarkupBlock - [0..34)::34 + MarkupTextLiteral - [0..0)::0 - [] - Gen + Marker;[]; + CSharpCodeBlock - [0..34)::34 + CSharpImplicitExpression - [0..34)::34 + CSharpTransition - [0..1)::1 - Gen + Transition;[@]; + CSharpImplicitExpressionBody - [1..34)::33 + CSharpCodeBlock - [1..34)::33 + CSharpExpressionLiteral - [1..17)::16 - [Html.Repeat(10, ] - Gen + Identifier;[Html]; + Dot;[.]; + Identifier;[Repeat]; + LeftParenthesis;[(]; + NumericLiteral;[10]; + Comma;[,]; + Whitespace;[ ]; + CSharpTemplateBlock - [17..33)::16 + MarkupBlock - [17..33)::16 + MarkupTransition - [17..18)::1 - Gen + Transition;[@]; + MarkupElement - [18..33)::15 + MarkupStartTag - [18..20)::2 - [<>] - Gen + OpenAngle;[<]; + Text;[]; + CloseAngle;[>]; + MarkupTextLiteral - [20..25)::5 - [Foo #] - Gen + Text;[Foo]; + Whitespace;[ ]; + Text;[#]; + CSharpCodeBlock - [25..30)::5 + CSharpImplicitExpression - [25..30)::5 + CSharpTransition - [25..26)::1 - Gen + Transition;[@]; + CSharpImplicitExpressionBody - [26..30)::4 + CSharpCodeBlock - [26..30)::4 + CSharpExpressionLiteral - [26..30)::4 - [item] - Gen + Identifier;[item]; + MarkupEndTag - [30..33)::3 - [] - Gen + OpenAngle;[<]; + ForwardSlash;[/]; + Text;[]; + CloseAngle;[>]; + CSharpExpressionLiteral - [33..34)::1 - [)] - Gen + RightParenthesis;[)]; + MarkupTextLiteral - [34..34)::0 - [] - Gen + Marker;[]; + EndOfFile;[]; diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt new file mode 100644 index 00000000000..b0ba1807ee2 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt @@ -0,0 +1 @@ +(1,3): Error RZ1022: Outer tag is missing a name. The first character of a markup block must be an HTML tag with a valid name. diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/HtmlMarkupParser.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/HtmlMarkupParser.cs index 40d69e2c29a..9279ae9bcc2 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/HtmlMarkupParser.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Legacy/HtmlMarkupParser.cs @@ -664,6 +664,17 @@ private MarkupStartTagSyntax ParseStartTag( return ParseStartTextTag(openAngleToken, out tagMode, out isWellFormed); } + if (mode == ParseMode.MarkupInCodeBlock && + _tagTracker.Count == 0 && + tagName.Length == 0 && + At(SyntaxKind.CloseAngle)) + { + // The outer tag of a markup block is missing a name. + Context.ErrorSink.OnError( + RazorDiagnosticFactory.CreateParsing_OuterTagMissingName( + new SourceSpan(tagStartLocation, contentLength: 1))); + } + var tagNameToken = At(SyntaxKind.Text) ? EatCurrentToken() : SyntaxFactory.MissingToken(SyntaxKind.Text); var attributes = EmptySyntaxList; From da25b1e54bb4e3983da4e9fac70133016b17aa2c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 22 Feb 2026 20:54:47 +0000 Subject: [PATCH 3/3] Add missing legacy test baseline for HtmlTagsTest.EmptyTag Co-authored-by: davidwengier <754264+davidwengier@users.noreply.github.com> --- .../TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/Compiler/Microsoft.AspNetCore.Razor.Language/legacyTest/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/legacyTest/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/legacyTest/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt new file mode 100644 index 00000000000..b0ba1807ee2 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/legacyTest/TestFiles/ParserTests/HtmlTagsTest/EmptyTag.diag.txt @@ -0,0 +1 @@ +(1,3): Error RZ1022: Outer tag is missing a name. The first character of a markup block must be an HTML tag with a valid name.