diff --git a/src/Microsoft.AspNetCore.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs b/src/Microsoft.AspNetCore.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs index e6357d5769..48af0cfb09 100644 --- a/src/Microsoft.AspNetCore.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs +++ b/src/Microsoft.AspNetCore.Razor/CodeGenerators/Visitors/CSharpCodeVisitor.cs @@ -399,36 +399,47 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators.Visitors public void RenderDesignTimeExpressionBlockChunk(ExpressionBlockChunk chunk) { - var firstChild = (ExpressionChunk)chunk.Children.FirstOrDefault(); - - if (firstChild != null) + var firstChild = chunk.Children.FirstOrDefault(); + if (firstChild == null) { - var currentIndent = Writer.CurrentIndent; - var designTimeAssignment = "__o = "; - Writer.ResetIndent(); + return; + } - var documentLocation = firstChild.Association.Start; - // This is only here to enable accurate formatting by the C# editor. - Writer.WriteLineNumberDirective(documentLocation, Context.SourceFile); + var currentIndent = Writer.CurrentIndent; + Writer.ResetIndent(); + var documentLocation = firstChild.Association.Start; + + // This is only here to enable accurate formatting by the C# editor. + Writer.WriteLineNumberDirective(documentLocation, Context.SourceFile); + + var designTimeAssignment = "__o = "; + var firstChildExpressionChunk = firstChild as ExpressionChunk; + if (firstChildExpressionChunk != null) + { // We build the padding with an offset of the design time assignment statement. - Writer.Write(_paddingBuilder.BuildExpressionPadding((Span)firstChild.Association, designTimeAssignment.Length)) - .Write(designTimeAssignment); + Writer.Write(_paddingBuilder.BuildExpressionPadding((Span)firstChildExpressionChunk.Association, designTimeAssignment.Length)) + .Write(designTimeAssignment); // We map the first line of code but do not write the line pragmas associated with it. - CreateRawCodeMapping(firstChild.Code, documentLocation); + CreateRawCodeMapping(firstChildExpressionChunk.Code, documentLocation); // Render all but the first child. // The reason why we render the other children differently is because when formatting the C# code // the formatter expects the start line to have the assignment statement on it. Accept(chunk.Children.Skip(1).ToList()); - - Writer.WriteLine(";") - .WriteLine() - .WriteLineDefaultDirective() - .WriteLineHiddenDirective() - .SetIndent(currentIndent); } + else + { + // First child is not an expression chunk + Accept(chunk.Children); + } + + Writer.WriteLine(";") + .WriteLine() + .WriteLineDefaultDirective() + .WriteLineHiddenDirective() + .SetIndent(currentIndent); } public void RenderRuntimeExpressionBlockChunk(ExpressionBlockChunk chunk) diff --git a/test/Microsoft.AspNetCore.Razor.Test/CodeGenerators/CSharpRazorCodeGeneratorTest.cs b/test/Microsoft.AspNetCore.Razor.Test/CodeGenerators/CSharpRazorCodeGeneratorTest.cs index 50aae30f47..b437517783 100644 --- a/test/Microsoft.AspNetCore.Razor.Test/CodeGenerators/CSharpRazorCodeGeneratorTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Test/CodeGenerators/CSharpRazorCodeGeneratorTest.cs @@ -72,6 +72,7 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators [InlineData("ConditionalAttributes")] [InlineData("Await")] [InlineData("CodeBlockWithTextElement")] + [InlineData("ExplicitExpressionWithMarkup")] public void CSharpChunkGeneratorCorrectlyGeneratesRunTimeCode(string testType) { RunTest(testType); @@ -404,6 +405,15 @@ namespace Microsoft.AspNetCore.Razor.CodeGenerators }); } + [Fact] + public void CSharpChunkGeneratorCorrectlyGeneratesDesignTimePragmasForExplicitExpressionContainingMarkup() + { + RunTest( + "ExplicitExpressionWithMarkup", + "ExplicitExpressionWithMarkup.DesignTime", + designTimeMode: true, + expectedDesignTimePragmas: new List()); + } [Fact] public void CSharpChunkGeneratorCorrectlyGeneratesDesignTimePragmasForImplicitExpressionStartedAtEOF() diff --git a/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/ExplicitExpressionWithMarkup.DesignTime.cs b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/ExplicitExpressionWithMarkup.DesignTime.cs new file mode 100644 index 0000000000..eccd240bec --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/ExplicitExpressionWithMarkup.DesignTime.cs @@ -0,0 +1,33 @@ +namespace TestOutput +{ + using System; + using System.Threading.Tasks; + + public class ExplicitExpressionWithMarkup + { + private static object @__o; + private void @__RazorDesignTimeHelpers__() + { + #pragma warning disable 219 + #pragma warning restore 219 + } + #line hidden + public ExplicitExpressionWithMarkup() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { +#line 1 "ExplicitExpressionWithMarkup.cshtml" +item => new Template(async(__razor_template_writer) => { +} +) +; + +#line default +#line hidden + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/ExplicitExpressionWithMarkup.cs b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/ExplicitExpressionWithMarkup.cs new file mode 100644 index 0000000000..7d82532ea1 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Output/ExplicitExpressionWithMarkup.cs @@ -0,0 +1,36 @@ +#pragma checksum "ExplicitExpressionWithMarkup.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "1252c799cdeb86a71e4304f01ebaae540fa26894" +namespace TestOutput +{ + using System; + using System.Threading.Tasks; + + public class ExplicitExpressionWithMarkup + { + #line hidden + public ExplicitExpressionWithMarkup() + { + } + + #pragma warning disable 1998 + public override async Task ExecuteAsync() + { + Instrumentation.BeginContext(0, 5, true); + WriteLiteral("
"); + Instrumentation.EndContext(); + Instrumentation.BeginContext(14, 0, false); +#line 1 "ExplicitExpressionWithMarkup.cshtml" + Write(item => new Template(async(__razor_template_writer) => { + Instrumentation.BeginContext(8, 6, true); + WriteLiteralTo(__razor_template_writer, "
"); + Instrumentation.EndContext(); +} +) +); + +#line default +#line hidden + Instrumentation.EndContext(); + } + #pragma warning restore 1998 + } +} diff --git a/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Source/ExplicitExpressionWithMarkup.cshtml b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Source/ExplicitExpressionWithMarkup.cshtml new file mode 100644 index 0000000000..70d8cefd95 --- /dev/null +++ b/test/Microsoft.AspNetCore.Razor.Test/TestFiles/CodeGenerator/Source/ExplicitExpressionWithMarkup.cshtml @@ -0,0 +1 @@ +
@(@
\ No newline at end of file