Moved DeclareTagHelperFields from renderer to writer

This commit is contained in:
Ajay Bhargav Baaskaran 2017-04-03 13:30:46 -07:00
parent ac176f8671
commit 7d8bd29724
10 changed files with 292 additions and 97 deletions

View File

@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
_context.RenderNode = visitor.Visit;
_context.BasicWriter = _context.Options.DesignTimeMode ? (BasicWriter)new DesignTimeBasicWriter() : new RuntimeBasicWriter();
_context.TagHelperWriter = new DefaultTagHelperWriter();
_context.TagHelperWriter = _context.Options.DesignTimeMode ? (TagHelperWriter)new DesignTimeTagHelperWriter() : new RuntimeTagHelperWriter();
visitor.VisitDocument(node);
_context.RenderChildren = null;
@ -188,6 +188,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
Context.BasicWriter.WriteCSharpStatement(Context, node);
}
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
{
Context.TagHelperWriter.WriteDeclareTagHelperFields(Context, node);
}
public override void VisitDefault(RazorIRNode node)
{
// This is a temporary bridge to the renderer, which allows us to move functionality piecemeal

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration

View File

@ -316,20 +316,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
}
}
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
{
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
{
var tagHelperVariableName = GetTagHelperVariableName(tagHelperTypeName);
Context.Writer
.Write("private global::")
.WriteVariableDeclaration(
tagHelperTypeName,
tagHelperVariableName,
value: null);
}
}
private void RenderTagHelperAttributeInline(
RazorIRNode node,
SourceSpan documentLocation)

View File

@ -6,8 +6,22 @@ using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
{
public class DefaultTagHelperWriter : TagHelperWriter
public class DesignTimeTagHelperWriter : TagHelperWriter
{
public override void WriteDeclareTagHelperFields(CSharpRenderingContext context, DeclareTagHelperFieldsIRNode node)
{
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
{
var tagHelperVariableName = GetTagHelperVariableName(tagHelperTypeName);
context.Writer
.Write("private global::")
.WriteVariableDeclaration(
tagHelperTypeName,
tagHelperVariableName,
value: null);
}
}
public override void WriteAddTagHelperHtmlAttribute(CSharpRenderingContext context, AddTagHelperHtmlAttributeIRNode node)
{
throw new NotImplementedException();
@ -32,5 +46,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
{
throw new NotImplementedException();
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
}
}

View File

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration

View File

@ -601,85 +601,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
.WriteEndMethodInvocation();
}
public override void VisitDeclareTagHelperFields(DeclareTagHelperFieldsIRNode node)
{
Context.Writer.WriteLineHiddenDirective();
// Need to disable the warning "X is assigned to but never used." for the value buffer since
// whether it's used depends on how a TagHelper is used.
Context.Writer
.WritePragma("warning disable 0414")
.Write("private ")
.WriteVariableDeclaration("string", "__tagHelperStringValueBuffer" /* ORIGINAL: StringValueBufferVariableName */, value: null)
.WritePragma("warning restore 0414");
Context.Writer
.Write("private global::")
.WriteVariableDeclaration(
"Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext" /* ORIGINAL: ExecutionContextTypeName */,
"__tagHelperExecutionContext" /* ORIGINAL: ExecutionContextVariableName */,
value: null);
Context.Writer
.Write("private global::")
.Write("Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner" /* ORIGINAL: RunnerTypeName */)
.Write(" ")
.Write("__tagHelperRunner" /* ORIGINAL: RunnerVariableName */)
.Write(" = new global::")
.Write("Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner" /* ORIGINAL: RunnerTypeName */)
.WriteLine("();");
const string backedScopeManageVariableName = "__backed" + "__tagHelperScopeManager" /* ORIGINAL: ScopeManagerVariableName */;
Context.Writer
.Write("private global::")
.WriteVariableDeclaration(
"Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager",
backedScopeManageVariableName,
value: null);
Context.Writer
.Write("private global::")
.Write("Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager" /* ORIGINAL: ScopeManagerTypeName */)
.Write(" ")
.WriteLine("__tagHelperScopeManager" /* ORIGINAL: ScopeManagerVariableName */);
using (Context.Writer.BuildScope())
{
Context.Writer.WriteLine("get");
using (Context.Writer.BuildScope())
{
Context.Writer
.Write("if (")
.Write(backedScopeManageVariableName)
.WriteLine(" == null)");
using (Context.Writer.BuildScope())
{
Context.Writer
.WriteStartAssignment(backedScopeManageVariableName)
.WriteStartNewObject("Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager" /* ORIGINAL: ScopeManagerTypeName */)
.Write("StartTagHelperWritingScope" /* ORIGINAL: StartTagHelperWritingScopeMethodName */)
.WriteParameterSeparator()
.Write("EndTagHelperWritingScope" /* ORIGINAL: EndTagHelperWritingScopeMethodName */)
.WriteEndMethodInvocation();
}
Context.Writer.WriteReturn(backedScopeManageVariableName);
}
}
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
{
var tagHelperVariableName = GetTagHelperVariableName(tagHelperTypeName);
Context.Writer
.Write("private global::")
.WriteVariableDeclaration(
tagHelperTypeName,
tagHelperVariableName,
value: null);
}
}
private void RenderTagHelperAttributeInline(
RazorIRNode node,
SourceSpan documentLocation)

View File

@ -0,0 +1,135 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
{
public class RuntimeTagHelperWriter : TagHelperWriter
{
public string StringValueBufferVariableName { get; set; } = "__tagHelperStringValueBuffer";
public string ExecutionContextTypeName { get; set; } = "Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext";
public string ExecutionContextVariableName { get; set; } = "__tagHelperExecutionContext";
public string RunnerTypeName { get; set; } = "Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner";
public string RunnerVariableName { get; set; } = "__tagHelperRunner";
public string ScopeManagerTypeName { get; set; } = "Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager";
public string ScopeManagerVariableName { get; set; } = "__tagHelperScopeManager";
public string StartTagHelperWritingScopeMethodName { get; set; } = "StartTagHelperWritingScope";
public string EndTagHelperWritingScopeMethodName { get; set; } = "EndTagHelperWritingScope";
public override void WriteDeclareTagHelperFields(CSharpRenderingContext context, DeclareTagHelperFieldsIRNode node)
{
context.Writer.WriteLineHiddenDirective();
// Need to disable the warning "X is assigned to but never used." for the value buffer since
// whether it's used depends on how a TagHelper is used.
context.Writer
.WritePragma("warning disable 0414")
.Write("private ")
.WriteVariableDeclaration("string", StringValueBufferVariableName, value: null)
.WritePragma("warning restore 0414");
context.Writer
.Write("private global::")
.WriteVariableDeclaration(
ExecutionContextTypeName,
ExecutionContextVariableName,
value: null);
context.Writer
.Write("private global::")
.Write(RunnerTypeName)
.Write(" ")
.Write(RunnerVariableName)
.Write(" = new global::")
.Write(RunnerTypeName)
.WriteLine("();");
var backedScopeManageVariableName = "__backed" + ScopeManagerVariableName;
context.Writer
.Write("private global::")
.WriteVariableDeclaration(
ScopeManagerTypeName,
backedScopeManageVariableName,
value: null);
context.Writer
.Write("private global::")
.Write(ScopeManagerTypeName)
.Write(" ")
.WriteLine(ScopeManagerVariableName);
using (context.Writer.BuildScope())
{
context.Writer.WriteLine("get");
using (context.Writer.BuildScope())
{
context.Writer
.Write("if (")
.Write(backedScopeManageVariableName)
.WriteLine(" == null)");
using (context.Writer.BuildScope())
{
context.Writer
.WriteStartAssignment(backedScopeManageVariableName)
.WriteStartNewObject(ScopeManagerTypeName)
.Write(StartTagHelperWritingScopeMethodName)
.WriteParameterSeparator()
.Write(EndTagHelperWritingScopeMethodName)
.WriteEndMethodInvocation();
}
context.Writer.WriteReturn(backedScopeManageVariableName);
}
}
foreach (var tagHelperTypeName in node.UsedTagHelperTypeNames)
{
var tagHelperVariableName = GetTagHelperVariableName(tagHelperTypeName);
context.Writer
.Write("private global::")
.WriteVariableDeclaration(
tagHelperTypeName,
tagHelperVariableName,
value: null);
}
}
public override void WriteAddTagHelperHtmlAttribute(CSharpRenderingContext context, AddTagHelperHtmlAttributeIRNode node)
{
throw new NotImplementedException();
}
public override void WriteCreateTagHelper(CSharpRenderingContext context, CreateTagHelperIRNode node)
{
throw new NotImplementedException();
}
public override void WriteExecuteTagHelpers(CSharpRenderingContext context, ExecuteTagHelpersIRNode node)
{
throw new NotImplementedException();
}
public override void WriteInitializeTagHelperStructure(CSharpRenderingContext context, InitializeTagHelperStructureIRNode node)
{
throw new NotImplementedException();
}
public override void WriteSetTagHelperProperty(CSharpRenderingContext context, SetTagHelperPropertyIRNode node)
{
throw new NotImplementedException();
}
private static string GetTagHelperVariableName(string tagHelperTypeName) => "__" + tagHelperTypeName.Replace('.', '_');
}
}

View File

@ -7,6 +7,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
{
public abstract class TagHelperWriter
{
public abstract void WriteDeclareTagHelperFields(CSharpRenderingContext context, DeclareTagHelperFieldsIRNode node);
public abstract void WriteInitializeTagHelperStructure(CSharpRenderingContext context, InitializeTagHelperStructureIRNode node);
public abstract void WriteSetTagHelperProperty(CSharpRenderingContext context, SetTagHelperPropertyIRNode node);

View File

@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
{
public class DesignTimeTagHelperWriterTest
{
[Fact]
public void WriteDeclareTagHelperFields_DeclaresUsedTagHelperTypes()
{
// Arrange
var writer = new DesignTimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new DeclareTagHelperFieldsIRNode();
node.UsedTagHelperTypeNames.Add("PTagHelper");
node.UsedTagHelperTypeNames.Add("MyTagHelper");
// Act
writer.WriteDeclareTagHelperFields(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"private global::PTagHelper __PTagHelper = null;
private global::MyTagHelper __MyTagHelper = null;
",
csharp,
ignoreLineEndingDifferences: true);
}
}
}

View File

@ -0,0 +1,95 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Razor.Evolution.Intermediate;
using Xunit;
namespace Microsoft.AspNetCore.Razor.Evolution.CodeGeneration
{
public class RuntimeTagHelperWriterTest
{
[Fact]
public void WriteDeclareTagHelperFields_DeclaresRequiredFields()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new DeclareTagHelperFieldsIRNode();
// Act
writer.WriteDeclareTagHelperFields(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
",
csharp,
ignoreLineEndingDifferences: true);
}
[Fact]
public void WriteDeclareTagHelperFields_DeclaresUsedTagHelperTypes()
{
// Arrange
var writer = new RuntimeTagHelperWriter();
var context = new CSharpRenderingContext()
{
Writer = new Legacy.CSharpCodeWriter(),
};
var node = new DeclareTagHelperFieldsIRNode();
node.UsedTagHelperTypeNames.Add("PTagHelper");
node.UsedTagHelperTypeNames.Add("MyTagHelper");
// Act
writer.WriteDeclareTagHelperFields(context, node);
// Assert
var csharp = context.Writer.Builder.ToString();
Assert.Equal(
@"#line hidden
#pragma warning disable 0414
private string __tagHelperStringValueBuffer = null;
#pragma warning restore 0414
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
private global::PTagHelper __PTagHelper = null;
private global::MyTagHelper __MyTagHelper = null;
",
csharp,
ignoreLineEndingDifferences: true);
}
}
}