diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs index cebb426e8b4..9e17999b456 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs @@ -717,16 +717,25 @@ private void WritePropertyAccess(CodeRenderingContext context, ComponentAttribut context.CodeWriter.Write(", "); } - foreach (var token in typeArgumentNode.Children.OfType()) + writeTypeArgument(typeArgumentNode.Children); + + void writeTypeArgument(IntermediateNodeCollection typeArgumentComponents) { - // As per WriteComponentTypeArgument, we expect every token to be C#, but check just in case - if (token.IsCSharp) - { - context.CodeWriter.Write(token.Content); - } - else + foreach (var typeArgumentNodeComponent in typeArgumentComponents) { - Debug.Fail($"Unexpected non-C# content in a generic type parameter: '{token.Content}'"); + switch (typeArgumentNodeComponent) + { + case IntermediateToken { IsCSharp: true } token: + context.CodeWriter.Write(token.Content); + break; + case CSharpExpressionIntermediateNode cSharpExpression: + writeTypeArgument(cSharpExpression.Children); + break; + default: + // As per WriteComponentTypeArgument, we expect every token to be C#, but check just in case + Debug.Fail($"Unexpected non-C# content in a generic type parameter: '{typeArgumentNodeComponent}'"); + break; + } } } } diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs index c1c5291568b..5f258633a75 100644 --- a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs @@ -5886,6 +5886,27 @@ public class MyComponent : ComponentBase CompileToAssembly(generated); } + [Fact, WorkItem("https://github.com/dotnet/razor/issues/8467")] + public void ChildComponent_AtSpecifiedInRazorFileForTypeParameter() + { + AdditionalSyntaxTrees.Add(Parse(""" + using Microsoft.AspNetCore.Components; + namespace Test + { + public class C : ComponentBase + { + [Parameter] public int Item { get; set; } + } + } + """)); + + var generated = CompileToCSharp(""""""); + + AssertDocumentNodeMatchesBaseline(generated.CodeDocument); + AssertCSharpDocumentMatchesBaseline(generated.CodeDocument); + CompileToAssembly(generated); + } + [Fact] public void GenericComponent_NonPrimitiveType() { diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.codegen.cs new file mode 100644 index 00000000000..04792f49bf2 --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.codegen.cs @@ -0,0 +1,66 @@ +// +#pragma warning disable 1591 +namespace Test +{ + #line hidden + using global::System; + using global::System.Collections.Generic; + using global::System.Linq; + using global::System.Threading.Tasks; + using global::Microsoft.AspNetCore.Components; + public partial class TestComponent : global::Microsoft.AspNetCore.Components.ComponentBase + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + } + #pragma warning restore 219 + #pragma warning disable 0414 + private static object __o = null; + #pragma warning restore 0414 + #pragma warning disable 1998 + protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) + { + __o = typeof( +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + string + +#line default +#line hidden +#nullable disable + ); + __o = global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + 1 + +#line default +#line hidden +#nullable disable + ); + __builder.AddAttribute(-1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => { + } + )); + #pragma warning disable BL0005 + ((global::Test.C)default). +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + Item + +#line default +#line hidden +#nullable disable + = default; + #pragma warning restore BL0005 +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" +__o = typeof(global::Test.C<>); + +#line default +#line hidden +#nullable disable + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.ir.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.ir.txt new file mode 100644 index 00000000000..e314add09ef --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.ir.txt @@ -0,0 +1,22 @@ +Document - + NamespaceDeclaration - - Test + UsingDirective - (3:1,1 [20] ) - global::System + UsingDirective - (26:2,1 [40] ) - global::System.Collections.Generic + UsingDirective - (69:3,1 [25] ) - global::System.Linq + UsingDirective - (97:4,1 [36] ) - global::System.Threading.Tasks + UsingDirective - (136:5,1 [45] ) - global::Microsoft.AspNetCore.Components + ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase - + DesignTimeDirective - + CSharpCode - + IntermediateToken - - CSharp - #pragma warning disable 0414 + CSharpCode - + IntermediateToken - - CSharp - private static object __o = null; + CSharpCode - + IntermediateToken - - CSharp - #pragma warning restore 0414 + MethodDeclaration - - protected override - void - BuildRenderTree + Component - (0:0,0 [26] x:\dir\subdir\Test\TestComponent.cshtml) - C + ComponentTypeArgument - (6:0,6 [7] x:\dir\subdir\Test\TestComponent.cshtml) - T + CSharpExpression - (7:0,7 [6] x:\dir\subdir\Test\TestComponent.cshtml) + LazyIntermediateToken - (7:0,7 [6] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - string + ComponentAttribute - (21:0,21 [1] x:\dir\subdir\Test\TestComponent.cshtml) - Item - Item - AttributeStructure.DoubleQuotes + LazyIntermediateToken - (21:0,21 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 1 diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.mappings.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.mappings.txt new file mode 100644 index 00000000000..46fe3f1d09e --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.mappings.txt @@ -0,0 +1,15 @@ +Source Location: (7:0,7 [6] x:\dir\subdir\Test\TestComponent.cshtml) +|string| +Generated Location: (935:25,7 [6] ) +|string| + +Source Location: (21:0,21 [1] x:\dir\subdir\Test\TestComponent.cshtml) +|1| +Generated Location: (1224:34,21 [1] ) +|1| + +Source Location: (15:0,15 [4] x:\dir\subdir\Test\TestComponent.cshtml) +|Item| +Generated Location: (1633:47,15 [4] ) +|Item| + diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.codegen.cs b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.codegen.cs new file mode 100644 index 00000000000..c941a90c0ff --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.codegen.cs @@ -0,0 +1,31 @@ +// +#pragma warning disable 1591 +namespace Test +{ + #line hidden + using global::System; + using global::System.Collections.Generic; + using global::System.Linq; + using global::System.Threading.Tasks; + using global::Microsoft.AspNetCore.Components; + public partial class TestComponent : global::Microsoft.AspNetCore.Components.ComponentBase + { + #pragma warning disable 1998 + protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder) + { + __builder.OpenComponent>(0); + __builder.AddComponentParameter(1, "Item", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck( +#nullable restore +#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" + 1 + +#line default +#line hidden +#nullable disable + )); + __builder.CloseComponent(); + } + #pragma warning restore 1998 + } +} +#pragma warning restore 1591 diff --git a/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.ir.txt b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.ir.txt new file mode 100644 index 00000000000..1081715f38f --- /dev/null +++ b/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ChildComponent_AtSpecifiedInRazorFileForTypeParameter/TestComponent.ir.txt @@ -0,0 +1,15 @@ +Document - + NamespaceDeclaration - - Test + UsingDirective - (3:1,1 [22] ) - global::System + UsingDirective - (26:2,1 [42] ) - global::System.Collections.Generic + UsingDirective - (69:3,1 [27] ) - global::System.Linq + UsingDirective - (97:4,1 [38] ) - global::System.Threading.Tasks + UsingDirective - (136:5,1 [47] ) - global::Microsoft.AspNetCore.Components + ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase - + MethodDeclaration - - protected override - void - BuildRenderTree + Component - (0:0,0 [26] x:\dir\subdir\Test\TestComponent.cshtml) - C + ComponentTypeArgument - (6:0,6 [7] x:\dir\subdir\Test\TestComponent.cshtml) - T + CSharpExpression - (7:0,7 [6] x:\dir\subdir\Test\TestComponent.cshtml) + LazyIntermediateToken - (7:0,7 [6] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - string + ComponentAttribute - (21:0,21 [1] x:\dir\subdir\Test\TestComponent.cshtml) - Item - Item - AttributeStructure.DoubleQuotes + LazyIntermediateToken - (21:0,21 [1] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - 1