diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentLoweringPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentLoweringPass.cs
index 2954c6361c..3a7e3c748e 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentLoweringPass.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentLoweringPass.cs
@@ -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));
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
index c10ecd7ccc..a6cc308951 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
@@ -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(@"
+
+
+
+
+");
+
+ // 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)
{
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithUsingDirectives_AmbiguousImport/TestComponent.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithUsingDirectives_AmbiguousImport/TestComponent.diagnostics.txt
new file mode 100644
index 0000000000..a60f089416
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/Component_WithUsingDirectives_AmbiguousImport/TestComponent.diagnostics.txt
@@ -0,0 +1 @@
+x:\dir\subdir\Test\TestComponent.cshtml(4,1): Error RZ9985: Multiple components use the tag 'SomeComponent'. Components: Test2.SomeComponent, Test3.SomeComponent
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.codegen.cs
new file mode 100644
index 0000000000..cbbb4df936
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.codegen.cs
@@ -0,0 +1,50 @@
+//
+#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
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.ir.txt
new file mode 100644
index 0000000000..aea9472c47
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.ir.txt
@@ -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!
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithUsingDirectives_AmbiguousImport/TestComponent.diagnostics.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithUsingDirectives_AmbiguousImport/TestComponent.diagnostics.txt
new file mode 100644
index 0000000000..a60f089416
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/Component_WithUsingDirectives_AmbiguousImport/TestComponent.diagnostics.txt
@@ -0,0 +1 @@
+x:\dir\subdir\Test\TestComponent.cshtml(4,1): Error RZ9985: Multiple components use the tag 'SomeComponent'. Components: Test2.SomeComponent, Test3.SomeComponent
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.codegen.cs
new file mode 100644
index 0000000000..fb27ee3716
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.codegen.cs
@@ -0,0 +1,37 @@
+//
+#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(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(6);
+ __builder.AddAttribute(7, "ChildContent", (Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
+ __builder2.AddContent(8, "Hello!");
+ }
+ ));
+ __builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.ir.txt
new file mode 100644
index 0000000000..bb0c9a9624
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/MultipleChildContentMatchingComponentName/TestComponent.ir.txt
@@ -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!