Nodes that have children should use .Children
This removes special casing for nodes that contain children that were hiding them in a .Content or .Value property.
This commit is contained in:
parent
18bb31cee4
commit
026f9ffb69
|
|
@ -50,45 +50,44 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
|
||||
public RazorMethodDeclarationIRNode Method { get; }
|
||||
|
||||
// Example
|
||||
// <input` checked="foo-bar @false"`/>
|
||||
// Name=checked
|
||||
// Prefix= checked="
|
||||
// Suffix="
|
||||
public override void VisitStartAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
var value = new ContainerRazorIRNode();
|
||||
Builder.Add(new HtmlAttributeIRNode()
|
||||
Builder.Push(new HtmlAttributeIRNode()
|
||||
{
|
||||
Name = chunkGenerator.Name,
|
||||
Prefix = chunkGenerator.Prefix,
|
||||
Value = value,
|
||||
Suffix = chunkGenerator.Suffix,
|
||||
|
||||
SourceLocation = block.Start,
|
||||
});
|
||||
|
||||
var valueBuilder = RazorIRBuilder.Create(value);
|
||||
_builders.Push(valueBuilder);
|
||||
}
|
||||
|
||||
public override void VisitEndAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
_builders.Pop();
|
||||
Builder.Pop();
|
||||
}
|
||||
|
||||
// Example
|
||||
// <input checked="foo-bar `@false`"/>
|
||||
// Prefix= (space)
|
||||
// Children will contain a token for @false.
|
||||
public override void VisitStartDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
var content = new ContainerRazorIRNode();
|
||||
Builder.Add(new CSharpAttributeValueIRNode()
|
||||
Builder.Push(new CSharpAttributeValueIRNode()
|
||||
{
|
||||
Prefix = chunkGenerator.Prefix,
|
||||
Content = content,
|
||||
SourceLocation = block.Start,
|
||||
});
|
||||
|
||||
var valueBuilder = RazorIRBuilder.Create(content);
|
||||
_builders.Push(valueBuilder);
|
||||
}
|
||||
|
||||
public override void VisitEndDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
_builders.Pop();
|
||||
Builder.Pop();
|
||||
}
|
||||
|
||||
public override void VisitLiteralAttributeSpan(LiteralAttributeChunkGenerator chunkGenerator, Span span)
|
||||
|
|
@ -119,20 +118,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
// We need to capture this in the IR so that we can give each piece the correct source mappings
|
||||
public override void VisitStartExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
var value = new ContainerRazorIRNode();
|
||||
Builder.Add(new CSharpExpressionIRNode()
|
||||
Builder.Push(new CSharpExpressionIRNode()
|
||||
{
|
||||
Content = value,
|
||||
SourceLocation = block.Start,
|
||||
});
|
||||
|
||||
var valueBuilder = RazorIRBuilder.Create(value);
|
||||
_builders.Push(valueBuilder);
|
||||
}
|
||||
|
||||
public override void VisitEndExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
|
||||
{
|
||||
_builders.Pop();
|
||||
Builder.Pop();
|
||||
}
|
||||
|
||||
public override void VisitExpressionSpan(ExpressionChunkGenerator chunkGenerator, Span span)
|
||||
|
|
@ -228,47 +222,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
|||
{
|
||||
Builder.Pop();
|
||||
}
|
||||
|
||||
private class ContainerRazorIRNode : RazorIRNode
|
||||
{
|
||||
private SourceLocation? _location;
|
||||
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
public override RazorIRNode Parent { get; set; }
|
||||
|
||||
internal override SourceLocation SourceLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_location == null)
|
||||
{
|
||||
if (Children.Count > 0)
|
||||
{
|
||||
return Children[0].SourceLocation;
|
||||
}
|
||||
|
||||
return SourceLocation.Undefined;
|
||||
}
|
||||
|
||||
return _location.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_location = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Accept(RazorIRNodeVisitor visitor)
|
||||
{
|
||||
visitor.VisitDefault(this);
|
||||
}
|
||||
|
||||
public override TResult Accept<TResult>(RazorIRNodeVisitor<TResult> visitor)
|
||||
{
|
||||
return visitor.VisitDefault(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
{
|
||||
public class CSharpAttributeValueIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
public override RazorIRNode Parent { get; set; }
|
||||
|
||||
|
|
@ -17,8 +17,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
|
||||
public string Prefix { get; set; }
|
||||
|
||||
public RazorIRNode Content { get; set; }
|
||||
|
||||
public override void Accept(RazorIRNodeVisitor visitor)
|
||||
{
|
||||
if (visitor == null)
|
||||
|
|
|
|||
|
|
@ -9,14 +9,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
{
|
||||
public class CSharpExpressionIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
public override RazorIRNode Parent { get; set; }
|
||||
|
||||
internal override SourceLocation SourceLocation { get; set; }
|
||||
|
||||
public RazorIRNode Content { get; set; }
|
||||
|
||||
public override void Accept(RazorIRNodeVisitor visitor)
|
||||
{
|
||||
if (visitor == null)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
{
|
||||
public class HtmlAttributeIRNode : RazorIRNode
|
||||
{
|
||||
public override IList<RazorIRNode> Children { get; } = EmptyArray;
|
||||
public override IList<RazorIRNode> Children { get; } = new List<RazorIRNode>();
|
||||
|
||||
public override RazorIRNode Parent { get; set; }
|
||||
|
||||
|
|
@ -19,8 +19,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
|
||||
public string Prefix { get; set; }
|
||||
|
||||
public RazorIRNode Value { get; set; }
|
||||
|
||||
public string Suffix { get; set; }
|
||||
|
||||
public override void Accept(RazorIRNodeVisitor visitor)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
// 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 Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
||||
{
|
||||
public class HtmlAttributeIntegrationTest : IntegrationTestBase
|
||||
{
|
||||
[Fact]
|
||||
public void HtmlWithDataDashAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var engine = RazorEngine.Create();
|
||||
|
||||
var document = CreateCodeDocument();
|
||||
|
||||
// Act
|
||||
engine.Process(document);
|
||||
|
||||
// Assert
|
||||
AssertIRMatchesBaseline(document.GetIRDocument());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void HtmlWithConditionalAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var engine = RazorEngine.Create();
|
||||
|
||||
var document = CreateCodeDocument();
|
||||
|
||||
// Act
|
||||
engine.Process(document);
|
||||
|
||||
// Assert
|
||||
AssertIRMatchesBaseline(document.GetIRDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,12 +31,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
|||
|
||||
public override void VisitCSharpAttributeValue(CSharpAttributeValueIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.Prefix, node.Content.ToString()); // This is broken.
|
||||
}
|
||||
|
||||
public override void VisitCSharpExpression(CSharpExpressionIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.Content.ToString()); // This is broken
|
||||
WriteContentNode(node, node.Prefix);
|
||||
}
|
||||
|
||||
public override void VisitCSharpStatement(CSharpStatementIRNode node)
|
||||
|
|
@ -66,7 +61,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.IntegrationTests
|
|||
|
||||
public override void VisitHtmlAttribute(HtmlAttributeIRNode node)
|
||||
{
|
||||
WriteContentNode(node, node.Prefix, node.Value.ToString(), node.Suffix);
|
||||
WriteContentNode(node, node.Prefix, node.Suffix);
|
||||
}
|
||||
|
||||
public override void VisitHtmlAttributeValue(HtmlAttributeValueIRNode node)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void Lower_WithUsing()
|
||||
public void Lower_WithFunctions()
|
||||
{
|
||||
// Arrange
|
||||
var codeDocument = TestRazorCodeDocument.Create(@"@functions { public int Foo { get; set; }}");
|
||||
|
|
@ -133,7 +133,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void Lower_WithFunctions()
|
||||
public void Lower_WithUsing()
|
||||
{
|
||||
// Arrange
|
||||
var codeDocument = TestRazorCodeDocument.Create(@"@using System");
|
||||
|
|
|
|||
|
|
@ -101,11 +101,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
Assert.Equal(name, attribute.Name);
|
||||
Assert.Equal(suffix, attribute.Suffix);
|
||||
|
||||
Children(attribute.Value, valueValidators);
|
||||
Children(attribute, valueValidators);
|
||||
}
|
||||
catch (XunitException e)
|
||||
{
|
||||
throw new IRAssertException(attribute, attribute.Value.Children, e.Message, e);
|
||||
throw new IRAssertException(attribute, attribute.Children, e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,11 +117,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
{
|
||||
Assert.Equal(prefix, attributeValue.Prefix);
|
||||
|
||||
Children(attributeValue.Content, n => CSharpExpression(expected, n));
|
||||
Children(attributeValue, n => CSharpExpression(expected, n));
|
||||
}
|
||||
catch (XunitException e)
|
||||
{
|
||||
throw new IRAssertException(attributeValue, attributeValue.Content.Children, e.Message, e);
|
||||
throw new IRAssertException(attributeValue, attributeValue.Children, e.Message, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,9 +147,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Intermediate
|
|||
var cSharp = Assert.IsType<CSharpExpressionIRNode>(node);
|
||||
|
||||
var content = new StringBuilder();
|
||||
for (var i = 0; i < cSharp.Content.Children.Count; i++)
|
||||
for (var i = 0; i < cSharp.Children.Count; i++)
|
||||
{
|
||||
content.Append(((CSharpTokenIRNode)cSharp.Content.Children[i]).Content);
|
||||
content.Append(((CSharpTokenIRNode)cSharp.Children[i]).Content);
|
||||
}
|
||||
|
||||
Assert.Equal(expected, content.ToString());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<body>
|
||||
<span val="@Hello" />
|
||||
</body>
|
||||
</html>"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
Document - (0:0,0)
|
||||
NamespaceDeclaration - (0:0,0) -
|
||||
ClassDeclaration - (0:0,0) - - - -
|
||||
RazorMethodDeclaration - (0:0,0) - - - -
|
||||
HtmlContent - (0:0,0) - <html>\r\n<body>\r\n <span
|
||||
HtmlAttribute - (25:2,9) - val=" - "
|
||||
CSharpAttributeValue - (31:2,15) -
|
||||
CSharpExpression - (31:2,15)
|
||||
CSharpToken - (32:2,16) - Hello
|
||||
HtmlContent - (38:2,22) - />\r\n</body>\r\n</html>"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<body>
|
||||
<span data-val="@Hello" />
|
||||
</body>
|
||||
</html>"
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
Document - (0:0,0)
|
||||
NamespaceDeclaration - (0:0,0) -
|
||||
ClassDeclaration - (0:0,0) - - - -
|
||||
RazorMethodDeclaration - (0:0,0) - - - -
|
||||
HtmlContent - (0:0,0) - <html>\r\n<body>\r\n <span data\-val="
|
||||
CSharpExpression - (36:2,20)
|
||||
CSharpToken - (37:2,21) - Hello
|
||||
HtmlContent - (42:2,26) - " />\r\n</body>\r\n</html>"
|
||||
Loading…
Reference in New Issue