diff --git a/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.Statements.cs b/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.Statements.cs index c60ef809a4..cfba20e469 100644 --- a/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.Statements.cs +++ b/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.Statements.cs @@ -464,7 +464,10 @@ namespace Microsoft.AspNetCore.Razor.Parser var type = CurrentSymbol.Type; var loc = CurrentLocation; - var isSingleLineMarkup = type == CSharpSymbolType.Transition && NextIs(CSharpSymbolType.Colon); + // Both cases @: and @:: are triggered as markup, second colon in second case will be triggered as a plain text + var isSingleLineMarkup = type == CSharpSymbolType.Transition && + (NextIs(CSharpSymbolType.Colon, CSharpSymbolType.DoubleColon)); + var isMarkup = isSingleLineMarkup || type == CSharpSymbolType.LessThan || (type == CSharpSymbolType.Transition && NextIs(CSharpSymbolType.LessThan)); diff --git a/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.cs b/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.cs index 58f08045e8..e2b360b709 100644 --- a/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.cs +++ b/src/Microsoft.AspNetCore.Razor/Parser/CSharpCodeParser.cs @@ -637,7 +637,7 @@ namespace Microsoft.AspNetCore.Razor.Parser // No embedded transitions in C#, so ignore that param return allowTemplatesAndComments && ((Language.IsTransition(CurrentSymbol) - && NextIs(CSharpSymbolType.LessThan, CSharpSymbolType.Colon)) + && NextIs(CSharpSymbolType.LessThan, CSharpSymbolType.Colon, CSharpSymbolType.DoubleColon)) || Language.IsCommentStart(CurrentSymbol)); } diff --git a/test/Microsoft.AspNetCore.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs b/test/Microsoft.AspNetCore.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs index 3504a7c482..de1cf3cb40 100644 --- a/test/Microsoft.AspNetCore.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Test/Parser/CSharp/CSharpToMarkupSwitchTest.cs @@ -552,6 +552,43 @@ namespace Microsoft.AspNetCore.Razor.Test.Parser.CSharp Factory.Code("}").AsStatement())); } + [Fact] + public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByDoubleColon() + { + // Arrange + ParseBlockTest("if(foo) { @::Sometext" + Environment.NewLine + + "}", + new StatementBlock( + Factory.Code("if(foo) {").AsStatement(), + new MarkupBlock( + Factory.Markup(" "), + Factory.MarkupTransition(), + Factory.MetaMarkup(":", HtmlSymbolType.Colon), + Factory.Markup(":Sometext" + Environment.NewLine) + .With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None)) + ), + Factory.Code("}").AsStatement())); + } + + + [Fact] + public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByTripleColon() + { + // Arrange + ParseBlockTest("if(foo) { @:::Sometext" + Environment.NewLine + + "}", + new StatementBlock( + Factory.Code("if(foo) {").AsStatement(), + new MarkupBlock( + Factory.Markup(" "), + Factory.MarkupTransition(), + Factory.MetaMarkup(":", HtmlSymbolType.Colon), + Factory.Markup("::Sometext" + Environment.NewLine) + .With(new SingleLineMarkupEditHandler(CSharpLanguageCharacteristics.Instance.TokenizeString, AcceptedCharacters.None)) + ), + Factory.Code("}").AsStatement())); + } + [Fact] public void ParseBlockParsesMarkupStatementOnSwitchCharacterFollowedByColonInCodeBlock() { diff --git a/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs index d60fd76cfd..64f83f0179 100644 --- a/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs +++ b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/Templates.cs @@ -1,4 +1,4 @@ -#pragma checksum "Templates.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "32d88538b3b0ca3648493b240101d304878756fe" +#pragma checksum "Templates.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "ecd19ba0b3ae7ac597e19534c93fd2023208ae59" namespace TestOutput { using System; @@ -125,38 +125,92 @@ WriteTo(__razor_template_writer, item); #line default #line hidden Instrumentation.EndContext(); - Instrumentation.BeginContext(485, 20, true); - WriteLiteral("\r\n
\r\n\r\n\r\n"); Instrumentation.EndContext(); - Instrumentation.BeginContext(506, 11, false); + Instrumentation.BeginContext(501, 16, false); #line 27 "Templates.cshtml" -Write(Repeat(10, item => new Template(async(__razor_template_writer) => { - Instrumentation.BeginContext(518, 20, true); - WriteLiteralTo(__razor_template_writer, "
\r\n");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(574, 16, false);
+#line 33 "Templates.cshtml"
+Write(Repeat(10,
+ item => new Template(async(__razor_template_writer) => {
+ Instrumentation.BeginContext(592, 16, true);
+ WriteLiteralTo(__razor_template_writer, ":: This is line#");
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(609, 4, false);
+#line 34 "Templates.cshtml"
+WriteTo(__razor_template_writer, item);
+
+#line default
+#line hidden
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(613, 18, true);
+ WriteLiteralTo(__razor_template_writer, " of markup
\r\n");
+ Instrumentation.EndContext();
+}
+)
+));
+
+#line default
+#line hidden
+ Instrumentation.EndContext();
+ Instrumentation.BeginContext(632, 22, true);
+ WriteLiteral("\r\n
+@Repeat(10,
+ @:: This is line#@item of markup
+)
+
+@Repeat(10,
+ @::: This is line#@item of markup
+)
+