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 b3ad3dba5069..84d06cd5a226 100644
--- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs
@@ -231,6 +231,65 @@ @typeparam TItem2
CompileToAssembly(generated);
}
+ [Fact]
+ public void ComponentWithTypeParameterArray()
+ {
+ // Arrange
+ var classes = @"
+public class Tag
+{
+ public string description { get; set; }
+}
+";
+
+ AdditionalSyntaxTrees.Add(Parse(classes));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@using Microsoft.AspNetCore.Components;
+@typeparam TItem
+
+
Item
+
+@ChildContent(Items1)
+
+@foreach (var item in Items2)
+{
+ @ChildContent(item)
+}
+
+@ChildContent(Items3())
+
+@code {
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+
+ AdditionalSyntaxTrees.Add(Parse(generated.CodeDocument.GetCSharpDocument().GeneratedCode));
+ var useGenerated = CompileToCSharp("UseTestComponent.cshtml", @"
+@using Test
+
+ @context[0].description
+
+
+@code {
+ static Tag tag = new Tag() { description = ""A description.""};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+}");
+ AssertDocumentNodeMatchesBaseline(useGenerated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(useGenerated.CodeDocument);
+ CompileToAssembly(useGenerated);
+ }
+
[Fact]
public void ComponentWithConstrainedTypeParameters()
{
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.codegen.cs
new file mode 100644
index 000000000000..91832e303de8
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.codegen.cs
@@ -0,0 +1,92 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+#nullable restore
+#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Components;
+
+#line default
+#line hidden
+#nullable disable
+ public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+#nullable restore
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+global::System.Object TItem = null!;
+
+#line default
+#line hidden
+#nullable disable
+ }
+ ))();
+ }
+ #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)
+ {
+#nullable restore
+#line 6 "x:\dir\subdir\Test\TestComponent.cshtml"
+__o = ChildContent(Items1);
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 8 "x:\dir\subdir\Test\TestComponent.cshtml"
+ foreach (var item in Items2)
+{
+
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 10 "x:\dir\subdir\Test\TestComponent.cshtml"
+ __o = ChildContent(item);
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 10 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+}
+
+#line default
+#line hidden
+#nullable disable
+#nullable restore
+#line 13 "x:\dir\subdir\Test\TestComponent.cshtml"
+__o = ChildContent(Items3());
+
+#line default
+#line hidden
+#nullable disable
+ }
+ #pragma warning restore 1998
+#nullable restore
+#line 15 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+
+#line default
+#line hidden
+#nullable disable
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.ir.txt
new file mode 100644
index 000000000000..0b8c4732b4d3
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.ir.txt
@@ -0,0 +1,47 @@
+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 - (1:0,1 [38] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components
+ ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - - TItem
+ DesignTimeDirective -
+ DirectiveToken - (52:1,11 [5] x:\dir\subdir\Test\TestComponent.cshtml) - TItem
+ 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
+ HtmlContent - (39:0,39 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (39:0,39 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ HtmlContent - (59:2,0 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (59:2,0 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ MarkupElement - (61:3,0 [13] x:\dir\subdir\Test\TestComponent.cshtml) - h1
+ HtmlContent - (65:3,4 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (65:3,4 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Item
+ HtmlContent - (74:3,13 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (74:3,13 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ MarkupElement - (78:5,0 [28] x:\dir\subdir\Test\TestComponent.cshtml) - p
+ CSharpExpression - (82:5,4 [20] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (82:5,4 [20] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - ChildContent(Items1)
+ HtmlContent - (106:5,28 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (106:5,28 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (111:7,1 [37] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (111:7,1 [37] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - foreach (var item in Items2)\n{\n
+ MarkupElement - (148:9,4 [26] x:\dir\subdir\Test\TestComponent.cshtml) - p
+ CSharpExpression - (152:9,8 [18] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (152:9,8 [18] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - ChildContent(item)
+ CSharpCode - (174:9,30 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (174:9,30 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n}
+ HtmlContent - (177:10,1 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (177:10,1 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ MarkupElement - (181:12,0 [30] x:\dir\subdir\Test\TestComponent.cshtml) - p
+ CSharpExpression - (185:12,4 [22] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (185:12,4 [22] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - ChildContent(Items3())
+ HtmlContent - (211:12,30 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (211:12,30 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (222:14,7 [248] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (222:14,7 [248] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n [Parameter] public TItem[] Items1 { get; set; }\n [Parameter] public List Items2 { get; set; }\n [Parameter] public Func Items3 { get; set; }\n [Parameter] public RenderFragment ChildContent { get; set; }\n
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.mappings.txt
new file mode 100644
index 000000000000..8b6a8334545c
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.mappings.txt
@@ -0,0 +1,56 @@
+Source Location: (1:0,1 [38] x:\dir\subdir\Test\TestComponent.cshtml)
+|using Microsoft.AspNetCore.Components;|
+Generated Location: (276:11,0 [38] )
+|using Microsoft.AspNetCore.Components;|
+
+Source Location: (52:1,11 [5] x:\dir\subdir\Test\TestComponent.cshtml)
+|TItem|
+Generated Location: (688:23,22 [5] )
+|TItem|
+
+Source Location: (82:5,4 [20] x:\dir\subdir\Test\TestComponent.cshtml)
+|ChildContent(Items1)|
+Generated Location: (1199:40,6 [20] )
+|ChildContent(Items1)|
+
+Source Location: (111:7,1 [37] x:\dir\subdir\Test\TestComponent.cshtml)
+|foreach (var item in Items2)
+{
+ |
+Generated Location: (1343:47,1 [37] )
+|foreach (var item in Items2)
+{
+ |
+
+Source Location: (152:9,8 [18] x:\dir\subdir\Test\TestComponent.cshtml)
+|ChildContent(item)|
+Generated Location: (1511:56,8 [18] )
+|ChildContent(item)|
+
+Source Location: (174:9,30 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+}|
+Generated Location: (1683:63,30 [3] )
+|
+}|
+
+Source Location: (185:12,4 [22] x:\dir\subdir\Test\TestComponent.cshtml)
+|ChildContent(Items3())|
+Generated Location: (1815:71,6 [22] )
+|ChildContent(Items3())|
+
+Source Location: (222:14,7 [248] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+|
+Generated Location: (2017:80,7 [248] )
+|
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+|
+
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.codegen.cs
new file mode 100644
index 000000000000..1ae9da23aa09
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.codegen.cs
@@ -0,0 +1,102 @@
+//
+#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;
+#nullable restore
+#line 1 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+using Test;
+
+#line default
+#line hidden
+#nullable disable
+ public partial class UseTestComponent : 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)
+ {
+ __Blazor.Test.UseTestComponent.TypeInference.CreateTestComponent_0(__builder, -1, -1,
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ items1
+
+#line default
+#line hidden
+#nullable disable
+ , -1,
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ items2
+
+#line default
+#line hidden
+#nullable disable
+ , -1,
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ items3
+
+#line default
+#line hidden
+#nullable disable
+ , -1, (context) => (__builder2) => {
+#nullable restore
+#line 3 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ __o = context[0].description;
+
+#line default
+#line hidden
+#nullable disable
+ }
+ );
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+__o = typeof(TestComponent<>);
+
+#line default
+#line hidden
+#nullable disable
+ }
+ #pragma warning restore 1998
+#nullable restore
+#line 6 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+
+ static Tag tag = new Tag() { description = "A description."};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+
+#line default
+#line hidden
+#nullable disable
+ }
+}
+namespace __Blazor.Test.UseTestComponent
+{
+ #line hidden
+ internal static class TypeInference
+ {
+ public static void CreateTestComponent_0(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, TItem[] __arg0, int __seq1, global::System.Collections.Generic.List __arg1, int __seq2, global::System.Func __arg2, int __seq3, global::Microsoft.AspNetCore.Components.RenderFragment __arg3)
+ {
+ __builder.OpenComponent>(seq);
+ __builder.AddAttribute(__seq0, "Items1", __arg0);
+ __builder.AddAttribute(__seq1, "Items2", __arg1);
+ __builder.AddAttribute(__seq2, "Items3", __arg2);
+ __builder.AddAttribute(__seq3, "ChildContent", __arg3);
+ __builder.CloseComponent();
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.ir.txt
new file mode 100644
index 000000000000..9ec057a01c1a
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.ir.txt
@@ -0,0 +1,41 @@
+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
+ UsingDirective - (1:0,1 [10] x:\dir\subdir\Test\UseTestComponent.cshtml) - Test
+ ClassDeclaration - - public partial - UseTestComponent - 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
+ HtmlContent - (11:0,11 [2] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (11:0,11 [2] x:\dir\subdir\Test\UseTestComponent.cshtml) - Html - \n
+ Component - (13:1,0 [111] x:\dir\subdir\Test\UseTestComponent.cshtml) - TestComponent
+ ComponentChildContent - - ChildContent - context
+ HtmlContent - (70:1,57 [6] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (70:1,57 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Html - \n
+ MarkupElement - (76:2,4 [30] x:\dir\subdir\Test\UseTestComponent.cshtml) - p
+ CSharpExpression - (80:2,8 [22] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (80:2,8 [22] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - context[0].description
+ HtmlContent - (106:2,34 [2] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (106:2,34 [2] x:\dir\subdir\Test\UseTestComponent.cshtml) - Html - \n
+ ComponentAttribute - (35:1,22 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Items1 - Items1 - AttributeStructure.DoubleQuotes
+ LazyIntermediateToken - (35:1,22 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - items1
+ ComponentAttribute - (49:1,36 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Items2 - Items2 - AttributeStructure.DoubleQuotes
+ LazyIntermediateToken - (49:1,36 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - items2
+ ComponentAttribute - (63:1,50 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Items3 - Items3 - AttributeStructure.DoubleQuotes
+ LazyIntermediateToken - (63:1,50 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - items3
+ HtmlContent - (124:3,16 [4] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (124:3,16 [4] x:\dir\subdir\Test\UseTestComponent.cshtml) - Html - \n\n
+ CSharpCode - (135:5,7 [208] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (135:5,7 [208] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - \n static Tag tag = new Tag() { description = "A description."};\n Tag[] items1 = new [] { tag };\n List items2 = new List() { new [] { tag } };\n Tag[] items3() => new [] { tag };\n
+ NamespaceDeclaration - - __Blazor.Test.UseTestComponent
+ ClassDeclaration - - internal static - TypeInference - -
+ ComponentTypeInferenceMethod - - __Blazor.Test.UseTestComponent.TypeInference - CreateTestComponent_0
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.mappings.txt
new file mode 100644
index 000000000000..3c8991a194fe
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentDesignTimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.mappings.txt
@@ -0,0 +1,40 @@
+Source Location: (1:0,1 [10] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|using Test|
+Generated Location: (323:12,0 [10] )
+|using Test|
+
+Source Location: (35:1,22 [6] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|items1|
+Generated Location: (1116:32,22 [6] )
+|items1|
+
+Source Location: (49:1,36 [6] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|items2|
+Generated Location: (1303:40,36 [6] )
+|items2|
+
+Source Location: (63:1,50 [6] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|items3|
+Generated Location: (1504:48,50 [6] )
+|items3|
+
+Source Location: (80:2,8 [22] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|context[0].description|
+Generated Location: (1693:56,8 [22] )
+|context[0].description|
+
+Source Location: (135:5,7 [208] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|
+ static Tag tag = new Tag() { description = "A description."};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+|
+Generated Location: (2083:74,7 [208] )
+|
+ static Tag tag = new Tag() { description = "A description."};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+|
+
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.codegen.cs
new file mode 100644
index 000000000000..34045c4265c0
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.codegen.cs
@@ -0,0 +1,80 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+#nullable restore
+#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
+using Microsoft.AspNetCore.Components;
+
+#line default
+#line hidden
+#nullable disable
+ public partial class TestComponent : Microsoft.AspNetCore.Components.ComponentBase
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
+ {
+ __builder.AddMarkupContent(0, "Item
\r\n\r\n");
+ __builder.OpenElement(1, "p");
+#nullable restore
+#line (6,5)-(6,25) 24 "x:\dir\subdir\Test\TestComponent.cshtml"
+__builder.AddContent(2, ChildContent(Items1));
+
+#line default
+#line hidden
+#nullable disable
+ __builder.CloseElement();
+#nullable restore
+#line 8 "x:\dir\subdir\Test\TestComponent.cshtml"
+ foreach (var item in Items2)
+{
+
+#line default
+#line hidden
+#nullable disable
+ __builder.OpenElement(3, "p");
+#nullable restore
+#line (10,9)-(10,27) 24 "x:\dir\subdir\Test\TestComponent.cshtml"
+__builder.AddContent(4, ChildContent(item));
+
+#line default
+#line hidden
+#nullable disable
+ __builder.CloseElement();
+#nullable restore
+#line 11 "x:\dir\subdir\Test\TestComponent.cshtml"
+}
+
+#line default
+#line hidden
+#nullable disable
+ __builder.OpenElement(5, "p");
+#nullable restore
+#line (13,5)-(13,27) 24 "x:\dir\subdir\Test\TestComponent.cshtml"
+__builder.AddContent(6, ChildContent(Items3()));
+
+#line default
+#line hidden
+#nullable disable
+ __builder.CloseElement();
+ }
+ #pragma warning restore 1998
+#nullable restore
+#line 15 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+
+#line default
+#line hidden
+#nullable disable
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.ir.txt
new file mode 100644
index 000000000000..f715dfa9db3e
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.ir.txt
@@ -0,0 +1,25 @@
+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 - (1:0,1 [40] x:\dir\subdir\Test\TestComponent.cshtml) - Microsoft.AspNetCore.Components
+ ClassDeclaration - - public partial - TestComponent - Microsoft.AspNetCore.Components.ComponentBase - - TItem
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ MarkupBlock - - Item
\n\n
+ MarkupElement - (78:5,0 [28] x:\dir\subdir\Test\TestComponent.cshtml) - p
+ CSharpExpression - (82:5,4 [20] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (82:5,4 [20] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - ChildContent(Items1)
+ CSharpCode - (111:7,1 [33] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (111:7,1 [33] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - foreach (var item in Items2)\n{\n
+ MarkupElement - (148:9,4 [26] x:\dir\subdir\Test\TestComponent.cshtml) - p
+ CSharpExpression - (152:9,8 [18] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (152:9,8 [18] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - ChildContent(item)
+ CSharpCode - (176:10,0 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (176:10,0 [3] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - }\n
+ MarkupElement - (181:12,0 [30] x:\dir\subdir\Test\TestComponent.cshtml) - p
+ CSharpExpression - (185:12,4 [22] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (185:12,4 [22] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - ChildContent(Items3())
+ CSharpCode - (222:14,7 [248] x:\dir\subdir\Test\TestComponent.cshtml)
+ LazyIntermediateToken - (222:14,7 [248] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n [Parameter] public TItem[] Items1 { get; set; }\n [Parameter] public List Items2 { get; set; }\n [Parameter] public Func Items3 { get; set; }\n [Parameter] public RenderFragment ChildContent { get; set; }\n
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.mappings.txt
new file mode 100644
index 000000000000..1c3e4c2065bf
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/TestComponent.mappings.txt
@@ -0,0 +1,31 @@
+Source Location: (111:7,1 [33] x:\dir\subdir\Test\TestComponent.cshtml)
+|foreach (var item in Items2)
+{
+|
+Generated Location: (1042:37,1 [33] )
+|foreach (var item in Items2)
+{
+|
+
+Source Location: (176:10,0 [3] x:\dir\subdir\Test\TestComponent.cshtml)
+|}
+|
+Generated Location: (1461:54,0 [3] )
+|}
+|
+
+Source Location: (222:14,7 [248] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+|
+Generated Location: (1910:72,7 [248] )
+|
+ [Parameter] public TItem[] Items1 { get; set; }
+ [Parameter] public List Items2 { get; set; }
+ [Parameter] public Func Items3 { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+|
+
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.codegen.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.codegen.cs
new file mode 100644
index 000000000000..0b92fd41f9b8
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.codegen.cs
@@ -0,0 +1,90 @@
+//
+#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;
+#nullable restore
+#line 1 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+using Test;
+
+#line default
+#line hidden
+#nullable disable
+ public partial class UseTestComponent : Microsoft.AspNetCore.Components.ComponentBase
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
+ {
+ __Blazor.Test.UseTestComponent.TypeInference.CreateTestComponent_0(__builder, 0, 1,
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ items1
+
+#line default
+#line hidden
+#nullable disable
+ , 2,
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ items2
+
+#line default
+#line hidden
+#nullable disable
+ , 3,
+#nullable restore
+#line 2 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+ items3
+
+#line default
+#line hidden
+#nullable disable
+ , 4, (context) => (__builder2) => {
+ __builder2.OpenElement(5, "p");
+#nullable restore
+#line (3,9)-(3,31) 25 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+__builder2.AddContent(6, context[0].description);
+
+#line default
+#line hidden
+#nullable disable
+ __builder2.CloseElement();
+ }
+ );
+ }
+ #pragma warning restore 1998
+#nullable restore
+#line 6 "x:\dir\subdir\Test\UseTestComponent.cshtml"
+
+ static Tag tag = new Tag() { description = "A description."};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+
+#line default
+#line hidden
+#nullable disable
+ }
+}
+namespace __Blazor.Test.UseTestComponent
+{
+ #line hidden
+ internal static class TypeInference
+ {
+ public static void CreateTestComponent_0(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, TItem[] __arg0, int __seq1, global::System.Collections.Generic.List __arg1, int __seq2, global::System.Func __arg2, int __seq3, global::Microsoft.AspNetCore.Components.RenderFragment __arg3)
+ {
+ __builder.OpenComponent>(seq);
+ __builder.AddAttribute(__seq0, "Items1", __arg0);
+ __builder.AddAttribute(__seq1, "Items2", __arg1);
+ __builder.AddAttribute(__seq2, "Items3", __arg2);
+ __builder.AddAttribute(__seq3, "ChildContent", __arg3);
+ __builder.CloseComponent();
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.ir.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.ir.txt
new file mode 100644
index 000000000000..55cf5e472edc
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.ir.txt
@@ -0,0 +1,26 @@
+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
+ UsingDirective - (1:0,1 [12] x:\dir\subdir\Test\UseTestComponent.cshtml) - Test
+ ClassDeclaration - - public partial - UseTestComponent - Microsoft.AspNetCore.Components.ComponentBase -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ Component - (13:1,0 [111] x:\dir\subdir\Test\UseTestComponent.cshtml) - TestComponent
+ ComponentChildContent - - ChildContent - context
+ MarkupElement - (76:2,4 [30] x:\dir\subdir\Test\UseTestComponent.cshtml) - p
+ CSharpExpression - (80:2,8 [22] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (80:2,8 [22] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - context[0].description
+ ComponentAttribute - (35:1,22 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Items1 - Items1 - AttributeStructure.DoubleQuotes
+ LazyIntermediateToken - (35:1,22 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - items1
+ ComponentAttribute - (49:1,36 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Items2 - Items2 - AttributeStructure.DoubleQuotes
+ LazyIntermediateToken - (49:1,36 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - items2
+ ComponentAttribute - (63:1,50 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - Items3 - Items3 - AttributeStructure.DoubleQuotes
+ LazyIntermediateToken - (63:1,50 [6] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - items3
+ CSharpCode - (135:5,7 [208] x:\dir\subdir\Test\UseTestComponent.cshtml)
+ LazyIntermediateToken - (135:5,7 [208] x:\dir\subdir\Test\UseTestComponent.cshtml) - CSharp - \n static Tag tag = new Tag() { description = "A description."};\n Tag[] items1 = new [] { tag };\n List items2 = new List() { new [] { tag } };\n Tag[] items3() => new [] { tag };\n
+ NamespaceDeclaration - - __Blazor.Test.UseTestComponent
+ ClassDeclaration - - internal static - TypeInference - -
+ ComponentTypeInferenceMethod - - __Blazor.Test.UseTestComponent.TypeInference - CreateTestComponent_0
diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.mappings.txt
new file mode 100644
index 000000000000..6f36ee1bbe2f
--- /dev/null
+++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithTypeParameterArray/UseTestComponent.mappings.txt
@@ -0,0 +1,15 @@
+Source Location: (135:5,7 [208] x:\dir\subdir\Test\UseTestComponent.cshtml)
+|
+ static Tag tag = new Tag() { description = "A description."};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+|
+Generated Location: (1780:62,7 [208] )
+|
+ static Tag tag = new Tag() { description = "A description."};
+ Tag[] items1 = new [] { tag };
+ List items2 = new List() { new [] { tag } };
+ Tag[] items3() => new [] { tag };
+|
+
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs
index 0b5f8457a89d..80acb5501b50 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/ComponentTagHelperDescriptorProvider.cs
@@ -243,6 +243,12 @@ bool HasTypeParameter(ITypeSymbol type)
return true;
}
}
+ // Also check for cases like:
+ // [Parameter] public T[] MyProperty { get; set; }
+ else if (type is IArrayTypeSymbol array && HasTypeParameter(array.ElementType))
+ {
+ return true;
+ }
return false;
}
diff --git a/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTypeNameFeature.cs b/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTypeNameFeature.cs
index 27c4830fbc00..d08c15b7f47a 100644
--- a/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTypeNameFeature.cs
+++ b/src/Razor/Microsoft.CodeAnalysis.Razor/src/DefaultTypeNameFeature.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
@@ -24,6 +24,10 @@ public override IReadOnlyList ParseTypeParameters(string typeName)
{
return Array.Empty();
}
+ else if (parsed is ArrayTypeSyntax array)
+ {
+ return new[] { array.ElementType.ToString() };
+ }
else
{
return parsed.DescendantNodesAndSelf()