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()