Fix lowering of taghelpers inside a section

The IR lowering phase was attaching the 'tag helper fields' node to the
builder instead of to the top-level node (document). This meant that
things wouldn't be where we expect when the first tag helper occurrence is
inside a directive block (section).

Found this porting MVC to use the new Razor codebase.
This commit is contained in:
Ryan Nowak 2017-01-26 13:03:18 -08:00
parent 7725c20c47
commit 6a95002f0e
2 changed files with 65 additions and 12 deletions

View File

@ -17,6 +17,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
ThrowForMissingDependency(syntaxTree);
var builder = RazorIRBuilder.Document();
var document = (DocumentIRNode)builder.Current;
var namespaces = new HashSet<string>();
var i = 0;
@ -40,7 +41,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
var imports = codeDocument.GetImportSyntaxTrees();
if (imports != null)
{
var importsVisitor = new ImportsVisitor(builder, namespaces);
var importsVisitor = new ImportsVisitor(document, builder, namespaces);
for (var j = 0; j < imports.Count; j++)
{
@ -51,24 +52,25 @@ namespace Microsoft.AspNetCore.Razor.Evolution
}
}
var visitor = new MainSourceVisitor(builder, namespaces)
var visitor = new MainSourceVisitor(document, builder, namespaces)
{
Filename = syntaxTree.Source.Filename,
};
visitor.VisitBlock(syntaxTree.Root);
var irDocument = (DocumentIRNode)builder.Build();
codeDocument.SetIRDocument(irDocument);
codeDocument.SetIRDocument(document);
}
private class LoweringVisitor : ParserVisitor
{
protected readonly RazorIRBuilder _builder;
protected readonly DocumentIRNode _document;
protected readonly HashSet<string> _namespaces;
public LoweringVisitor(RazorIRBuilder builder, HashSet<string> namespaces)
public LoweringVisitor(DocumentIRNode document, RazorIRBuilder builder, HashSet<string> namespaces)
{
_document = document;
_builder = builder;
_namespaces = namespaces;
}
@ -146,8 +148,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
// this simple.
private bool _insideLineDirective;
public ImportsVisitor(RazorIRBuilder builder, HashSet<string> namespaces)
: base(builder, namespaces)
public ImportsVisitor(DocumentIRNode document, RazorIRBuilder builder, HashSet<string> namespaces)
: base(document, builder, namespaces)
{
}
@ -182,8 +184,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
{
private DeclareTagHelperFieldsIRNode _tagHelperFields;
public MainSourceVisitor(RazorIRBuilder builder, HashSet<string> namespaces)
: base(builder, namespaces)
public MainSourceVisitor(DocumentIRNode document, RazorIRBuilder builder, HashSet<string> namespaces)
: base(document, builder, namespaces)
{
}
@ -416,8 +418,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
{
if (_tagHelperFields == null)
{
_tagHelperFields = new DeclareTagHelperFieldsIRNode();
_builder.Add(_tagHelperFields);
_tagHelperFields = new DeclareTagHelperFieldsIRNode() { Parent = _document, };
_document.Children.Add(_tagHelperFields);
}
foreach (var descriptor in block.Descriptors)

View File

@ -194,6 +194,57 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
});
}
[Fact]
public void Lower_TagHelper_InSection()
{
// Arrange
var codeDocument = TestRazorCodeDocument.Create(@"@addTagHelper *, TestAssembly
@section test {
<span val=""@Hello World""></span>
}");
var tagHelpers = new[]
{
new TagHelperDescriptor
{
TagName = "span",
TypeName = "SpanTagHelper",
AssemblyName = "TestAssembly",
}
};
// Act
var irDocument = Lower(codeDocument, tagHelpers: tagHelpers);
// Assert
Children(
irDocument,
n => Checksum(n),
n => Using("System", n),
n => Using(typeof(Task).Namespace, n),
n => Directive(
"section",
n,
c1 => DirectiveToken(DirectiveTokenKind.Member, "test", c1),
c1 => Html(Environment.NewLine, c1),
c1 =>
{
var tagHelperNode = Assert.IsType<TagHelperIRNode>(c1);
Children(
tagHelperNode,
c2 => TagHelperStructure("span", TagMode.StartTagAndEndTag, c2),
c2 => Assert.IsType<CreateTagHelperIRNode>(c2),
c2 => TagHelperHtmlAttribute(
"val",
HtmlAttributeValueStyle.DoubleQuotes,
c2,
v => CSharpAttributeValue(string.Empty, "Hello", v),
v => LiteralAttributeValue(" ", "World", v)),
c2 => Assert.IsType<ExecuteTagHelpersIRNode>(c2));
},
c1 => Html(Environment.NewLine, c1)),
n => TagHelperFieldDeclaration(n, "SpanTagHelper"));
}
[Fact]
public void Lower_TagHelpersWithBoundAttribute()
{