diff --git a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/BasicWriter.cs b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/BasicWriter.cs index d5502e55bb..b1dcfbcb88 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/BasicWriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/BasicWriter.cs @@ -24,5 +24,9 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration public abstract void WriteCSharpExpressionAttributeValue(CSharpRenderingContext context, CSharpExpressionAttributeValueIRNode node); public abstract void WriteCSharpCodeAttributeValue(CSharpRenderingContext context, CSharpCodeAttributeValueIRNode node); + + public abstract void BeginWriterScope(CSharpRenderingContext context, string writer); + + public abstract void EndWriterScope(CSharpRenderingContext context); } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DesignTimeBasicWriter.cs b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DesignTimeBasicWriter.cs index 00b5392458..e89dc43d1a 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DesignTimeBasicWriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/DesignTimeBasicWriter.cs @@ -269,5 +269,15 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration { // Do nothing } + + public override void BeginWriterScope(CSharpRenderingContext context, string writer) + { + // Do nothing + } + + public override void EndWriterScope(CSharpRenderingContext context) + { + // Do nothing + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/RuntimeBasicWriter.cs b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/RuntimeBasicWriter.cs index 7867e1f099..cd86141a52 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/RuntimeBasicWriter.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/CodeGeneration/RuntimeBasicWriter.cs @@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration using (context.Writer.BuildAsyncLambda(endLine: false, parameterNames: ValueWriterName)) { - context.Writer.WriteMethodInvocation(PushWriterMethod, ValueWriterName); + BeginWriterScope(context, ValueWriterName); for (var i = 0; i < node.Children.Count; i++) { @@ -310,7 +310,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration } } - context.Writer.WriteMethodInvocation(PopWriterMethod); + EndWriterScope(context); } context.Writer.WriteEndMethodInvocation(false); @@ -364,5 +364,15 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration charactersConsumed += textToRender.Length; } } + + public override void BeginWriterScope(CSharpRenderingContext context, string writer) + { + context.Writer.WriteMethodInvocation(PushWriterMethod, writer); + } + + public override void EndWriterScope(CSharpRenderingContext context) + { + context.Writer.WriteMethodInvocation(PopWriterMethod); + } } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/Extensions/TemplateTargetExtension.cs b/src/Microsoft.AspNetCore.Razor.Language/Extensions/TemplateTargetExtension.cs index 4035e74cc1..535d5fa2ce 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Extensions/TemplateTargetExtension.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Extensions/TemplateTargetExtension.cs @@ -8,15 +8,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions public class TemplateTargetExtension : ITemplateTargetExtension { public static readonly string DefaultTemplateTypeName = "Template"; - public static readonly string DefaultPushWriterMethod = "PushWriter"; - public static readonly string DefaultPopWriterMethod = "PopWriter"; public string TemplateTypeName { get; set; } = DefaultTemplateTypeName; - public string PushWriterMethod { get; set; } = DefaultPushWriterMethod; - - public string PopWriterMethod { get; set; } = DefaultPopWriterMethod; - public void WriteTemplate(CSharpRenderingContext context, TemplateIRNode node) { const string ItemParameterName = "item"; @@ -28,17 +22,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions using (context.Writer.BuildAsyncLambda(endLine: false, parameterNames: TemplateWriterName)) { - if (!context.Options.DesignTime) - { - context.Writer.WriteMethodInvocation(PushWriterMethod, TemplateWriterName); - } + context.BasicWriter.BeginWriterScope(context, TemplateWriterName); context.RenderChildren(node); - if (!context.Options.DesignTime) - { - context.Writer.WriteMethodInvocation(PopWriterMethod); - } + context.BasicWriter.EndWriterScope(context); } context.Writer.WriteEndMethodInvocation(endLine: false); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeBasicWriterTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeBasicWriterTest.cs index 6dc0210641..28b0cae251 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeBasicWriterTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/CodeGeneration/RuntimeBasicWriterTest.cs @@ -433,6 +433,7 @@ if (true) { } [Fact] public void WriteHtmlContent_RendersContentCorrectly() { + // Arrange var writer = new RuntimeBasicWriter(); var context = new CSharpRenderingContext() { @@ -462,6 +463,7 @@ if (true) { } [Fact] public void WriteHtmlContent_LargeStringLiteral_UsesMultipleWrites() { + // Arrange var writer = new RuntimeBasicWriter(); var context = new CSharpRenderingContext() { @@ -493,6 +495,7 @@ WriteLiteral(@""{1}""); [Fact] public void WriteHtmlAttribute_RendersCorrectly() { + // Arrange var writer = new RuntimeBasicWriter(); var context = GetCSharpRenderingContext(writer); @@ -519,6 +522,7 @@ EndWriteAttribute(); [Fact] public void WriteHtmlAttributeValue_RendersCorrectly() { + // Arrange var writer = new RuntimeBasicWriter(); var context = GetCSharpRenderingContext(writer); @@ -543,6 +547,7 @@ EndWriteAttribute(); [Fact] public void WriteCSharpExpressionAttributeValue_RendersCorrectly() { + // Arrange var writer = new RuntimeBasicWriter(); var context = GetCSharpRenderingContext(writer); @@ -571,6 +576,7 @@ WriteAttributeValue("" "", 27, false, 28, 6, false); [Fact] public void WriteCSharpCodeAttributeValue_BuffersResult() { + // Arrange var writer = new RuntimeBasicWriter(); var context = GetCSharpRenderingContext(writer); @@ -602,6 +608,50 @@ WriteAttributeValue("" "", 27, false, 28, 6, false); ignoreLineEndingDifferences: true); } + [Fact] + public void BeginWriterScope_UsesSpecifiedWriter_RendersCorrectly() + { + // Arrange + var writer = new RuntimeBasicWriter() + { + PushWriterMethod = "TestPushWriter" + }; + var context = GetCSharpRenderingContext(writer); + + // Act + writer.BeginWriterScope(context, "MyWriter"); + + // Assert + var csharp = context.Writer.Builder.ToString(); + Assert.Equal( +@"TestPushWriter(MyWriter); +", + csharp, + ignoreLineEndingDifferences: true); + } + + [Fact] + public void EndWriterScope_RendersCorrectly() + { + // Arrange + var writer = new RuntimeBasicWriter() + { + PopWriterMethod = "TestPopWriter" + }; + var context = GetCSharpRenderingContext(writer); + + // Act + writer.EndWriterScope(context); + + // Assert + var csharp = context.Writer.Builder.ToString(); + Assert.Equal( +@"TestPopWriter(); +", + csharp, + ignoreLineEndingDifferences: true); + } + private static CSharpRenderingContext GetCSharpRenderingContext(BasicWriter writer) { var options = RazorCodeGenerationOptions.CreateDefault(); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs index 9e016850a9..e74d2d1324 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/TemplateTargetExtensionTest.cs @@ -17,14 +17,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions var extension = new TemplateTargetExtension() { - TemplateTypeName = "global::TestTemplate", - PushWriterMethod = "TestPushWriter", - PopWriterMethod = "TestPopWriter" + TemplateTypeName = "global::TestTemplate" }; var context = new CSharpRenderingContext() { - BasicWriter = new RuntimeBasicWriter(), + BasicWriter = new RuntimeBasicWriter() + { + PushWriterMethod = "TestPushWriter", + PopWriterMethod = "TestPopWriter" + }, TagHelperWriter = new RuntimeTagHelperWriter(), Writer = new CSharpCodeWriter(), Options = RazorCodeGenerationOptions.CreateDefault(),