Prefer child content over a matching component (dotnet/aspnetcore-tooling#1180)

* Prefer child content over a matching component

* feedback
\n\nCommit migrated from 9c83a09944
This commit is contained in:
Ajay Bhargav Baaskaran 2019-09-27 14:27:10 -07:00 committed by GitHub
parent 39d8e322d1
commit 3dcc779659
8 changed files with 186 additions and 6 deletions

View File

@ -34,7 +34,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
var reference = references[i];
var node = (TagHelperIntermediateNode)reference.Node;
if (node.TagHelpers.Any(t => t.IsChildContentTagHelper()))
{
// This is a child content tag helper. This will be rewritten when we visit its parent.
continue;
}
// The element didn't match any child content descriptors. Look for any matching component descriptors.
var count = 0;
for (var j = 0; j < node.TagHelpers.Count; j++)
{
@ -42,7 +48,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
// Only allow a single component tag helper per element. If there are multiple, we'll just consider
// the first one and ignore the others.
if (count++ > 1)
if (++count > 1)
{
node.Diagnostics.Add(ComponentDiagnosticFactory.Create_MultipleComponents(node.Source, node.TagName, node.TagHelpers));
break;
@ -54,10 +60,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
{
reference.Replace(RewriteAsComponent(node, node.TagHelpers.First(t => t.IsComponentTagHelper())));
}
else if (node.TagHelpers.Any(t => t.IsChildContentTagHelper()))
{
// Ignore, this will be handled when we rewrite the parent.
}
else
{
reference.Replace(RewriteAsElement(node));

View File

@ -1698,6 +1698,44 @@ namespace Test
CompileToAssembly(generated);
}
[Fact]
public void MultipleChildContentMatchingComponentName()
{
// Arrange
AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Components;
namespace Test
{
public class MyComponent : ComponentBase
{
[Parameter]
public RenderFragment Header { get; set; }
[Parameter]
public RenderFragment Footer { get; set; }
}
public class Header : ComponentBase
{
}
}
"));
// Act
var generated = CompileToCSharp(@"
<MyComponent>
<Header>Hi!</Header>
<Footer>Bye!</Footer>
</MyComponent>
<Header>Hello!</Header>");
// Assert
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
CompileToAssembly(generated);
}
#endregion
#region Directives
@ -1804,7 +1842,7 @@ namespace Test3
// Assert
AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
var result = CompileToAssembly(generated, throwOnFailure: !DesignTime);
var result = CompileToAssembly(generated, throwOnFailure: false);
if (DesignTime)
{

View File

@ -0,0 +1 @@
x:\dir\subdir\Test\TestComponent.cshtml(4,1): Error RZ9985: Multiple components use the tag 'SomeComponent'. Components: Test2.SomeComponent, Test3.SomeComponent

View File

@ -0,0 +1,50 @@
// <auto-generated/>
#pragma warning disable 1591
namespace Test
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
public class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
{
#pragma warning disable 219
private void __RazorDirectiveTokenHelpers__() {
}
#pragma warning restore 219
#pragma warning disable 0414
private static System.Object __o = null;
#pragma warning restore 0414
#pragma warning disable 1998
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
__builder.AddAttribute(-1, "Header", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
}
));
__builder.AddAttribute(-1, "Footer", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
}
));
#nullable restore
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
__o = typeof(MyComponent);
#line default
#line hidden
#nullable disable
__builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
}
));
#nullable restore
#line 5 "x:\dir\subdir\Test\TestComponent.cshtml"
__o = typeof(Header);
#line default
#line hidden
#nullable disable
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,29 @@
Document -
NamespaceDeclaration - - Test
UsingDirective - (3:1,1 [12] ) - System
UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
UsingDirective - (53:3,1 [17] ) - System.Linq
UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
UsingDirective - (104:5,1 [37] ) - Microsoft.AspNetCore.Components
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
DesignTimeDirective -
CSharpCode -
IntermediateToken - - CSharp - #pragma warning disable 0414
CSharpCode -
IntermediateToken - - CSharp - private static System.Object __o = null;
CSharpCode -
IntermediateToken - - CSharp - #pragma warning restore 0414
MethodDeclaration - - protected override - void - BuildRenderTree
Component - (0:0,0 [78] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent
ComponentChildContent - (17:1,2 [20] x:\dir\subdir\Test\TestComponent.cshtml) - Header - context
HtmlContent - (25:1,10 [3] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (25:1,10 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Hi!
ComponentChildContent - (41:2,2 [21] x:\dir\subdir\Test\TestComponent.cshtml) - Footer - context
HtmlContent - (49:2,10 [4] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (49:2,10 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Bye!
HtmlContent - (78:3,14 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (78:3,14 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
Component - (80:4,0 [23] x:\dir\subdir\Test\TestComponent.cshtml) - Header
ComponentChildContent - - ChildContent - context
HtmlContent - (88:4,8 [6] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (88:4,8 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Hello!

View File

@ -0,0 +1 @@
x:\dir\subdir\Test\TestComponent.cshtml(4,1): Error RZ9985: Multiple components use the tag 'SomeComponent'. Components: Test2.SomeComponent, Test3.SomeComponent

View File

@ -0,0 +1,37 @@
// <auto-generated/>
#pragma warning disable 1591
namespace Test
{
#line hidden
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
public class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
{
#pragma warning disable 1998
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
__builder.OpenComponent<Test.MyComponent>(0);
__builder.AddAttribute(1, "Header", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
__builder2.AddContent(2, "Hi!");
}
));
__builder.AddAttribute(3, "Footer", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
__builder2.AddContent(4, "Bye!");
}
));
__builder.CloseComponent();
__builder.AddMarkupContent(5, "\r\n");
__builder.OpenComponent<Test.Header>(6);
__builder.AddAttribute(7, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
__builder2.AddContent(8, "Hello!");
}
));
__builder.CloseComponent();
}
#pragma warning restore 1998
}
}
#pragma warning restore 1591

View File

@ -0,0 +1,22 @@
Document -
NamespaceDeclaration - - Test
UsingDirective - (3:1,1 [14] ) - System
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
UsingDirective - (53:3,1 [19] ) - System.Linq
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
UsingDirective - (104:5,1 [39] ) - Microsoft.AspNetCore.Components
ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Components.ComponentBase -
MethodDeclaration - - protected override - void - BuildRenderTree
Component - (0:0,0 [78] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent
ComponentChildContent - (17:1,2 [20] x:\dir\subdir\Test\TestComponent.cshtml) - Header - context
HtmlContent - (25:1,10 [3] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (25:1,10 [3] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Hi!
ComponentChildContent - (41:2,2 [21] x:\dir\subdir\Test\TestComponent.cshtml) - Footer - context
HtmlContent - (49:2,10 [4] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (49:2,10 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Bye!
HtmlContent - (78:3,14 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (78:3,14 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
Component - (80:4,0 [23] x:\dir\subdir\Test\TestComponent.cshtml) - Header
ComponentChildContent - - ChildContent - context
HtmlContent - (88:4,8 [6] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (88:4,8 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Hello!