Skip to content

Commit b8cab05

Browse files
authored
Add constraints to CaptureParameters method (#11530)
* Add a test * Add constraints to CaptureParameters method
1 parent e4b99f0 commit b8cab05

File tree

6 files changed

+213
-14
lines changed

6 files changed

+213
-14
lines changed

src/Compiler/Microsoft.AspNetCore.Razor.Language/test/IntegrationTests/ComponentCodeGenerationTestBase.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9293,6 +9293,31 @@ private class String
92939293
CompileToAssembly(generated);
92949294
}
92959295

9296+
[IntegrationTestFact, WorkItem("https://github.com/dotnet/razor/issues/11505")]
9297+
public void CaptureParametersConstraint()
9298+
{
9299+
AdditionalSyntaxTrees.Add(Parse("""
9300+
using Microsoft.AspNetCore.Components;
9301+
9302+
namespace Test;
9303+
9304+
public interface IMyInterface;
9305+
9306+
public class MyClass<T> where T : IMyInterface;
9307+
9308+
[CascadingTypeParameter(nameof(T))]
9309+
public class MyComponent<T> : ComponentBase where T : IMyInterface
9310+
{
9311+
[Parameter] public MyClass<T> Param { get; set; }
9312+
}
9313+
"""));
9314+
var generated = CompileToCSharp("""
9315+
<MyComponent Param="new MyClass<IMyInterface>()" />
9316+
""");
9317+
AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
9318+
CompileToAssembly(generated);
9319+
}
9320+
92969321
#endregion
92979322

92989323
#region Key
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// <auto-generated/>
2+
#pragma warning disable 1591
3+
namespace Test
4+
{
5+
#line default
6+
using global::System;
7+
using global::System.Collections.Generic;
8+
using global::System.Linq;
9+
using global::System.Threading.Tasks;
10+
using global::Microsoft.AspNetCore.Components;
11+
#line default
12+
#line hidden
13+
#nullable restore
14+
public partial class TestComponent : global::Microsoft.AspNetCore.Components.ComponentBase
15+
#nullable disable
16+
{
17+
#pragma warning disable 219
18+
private void __RazorDirectiveTokenHelpers__() {
19+
}
20+
#pragma warning restore 219
21+
#pragma warning disable 0414
22+
private static object __o = null;
23+
#pragma warning restore 0414
24+
#pragma warning disable 1998
25+
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
26+
{
27+
{
28+
global::__Blazor.Test.TestComponent.TypeInference.CreateMyComponent_0_CaptureParameters(
29+
#nullable restore
30+
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
31+
new MyClass<IMyInterface>()
32+
33+
#line default
34+
#line hidden
35+
#nullable disable
36+
, out var __typeInferenceArg_0___arg0);
37+
var __typeInference_CreateMyComponent_0 = global::__Blazor.Test.TestComponent.TypeInference.CreateMyComponent_0(__builder, -1, -1, __typeInferenceArg_0___arg0);
38+
#pragma warning disable BL0005
39+
__typeInference_CreateMyComponent_0.
40+
#nullable restore
41+
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
42+
Param
43+
44+
#line default
45+
#line hidden
46+
#nullable disable
47+
= default;
48+
#pragma warning restore BL0005
49+
}
50+
#nullable restore
51+
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
52+
__o = typeof(global::Test.MyComponent<>);
53+
54+
#line default
55+
#line hidden
56+
#nullable disable
57+
}
58+
#pragma warning restore 1998
59+
}
60+
}
61+
namespace __Blazor.Test.TestComponent
62+
{
63+
#line hidden
64+
internal static class TypeInference
65+
{
66+
public static global::Test.MyComponent<T> CreateMyComponent_0<T>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, global::Test.MyClass<T> __arg0)
67+
where T : global::Test.IMyInterface
68+
{
69+
__builder.OpenComponent<global::Test.MyComponent<T>>(seq);
70+
__builder.AddAttribute(__seq0, "Param", (object)__arg0);
71+
__builder.CloseComponent();
72+
return default;
73+
}
74+
75+
public static void CreateMyComponent_0_CaptureParameters<T>(global::Test.MyClass<T> __arg0, out global::Test.MyClass<T> __arg0_out)
76+
where T : global::Test.IMyInterface
77+
{
78+
__arg0_out = __arg0;
79+
}
80+
}
81+
}
82+
#pragma warning restore 1591
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Source Location: (20:0,20 [27] x:\dir\subdir\Test\TestComponent.cshtml)
2+
|new MyClass<IMyInterface>()|
3+
Generated Location: (1126:30,20 [27] )
4+
|new MyClass<IMyInterface>()|
5+
6+
Source Location: (13:0,13 [5] x:\dir\subdir\Test\TestComponent.cshtml)
7+
|Param|
8+
Generated Location: (1625:41,13 [5] )
9+
|Param|
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// <auto-generated/>
2+
#pragma warning disable 1591
3+
namespace Test
4+
{
5+
#line default
6+
using global::System;
7+
using global::System.Collections.Generic;
8+
using global::System.Linq;
9+
using global::System.Threading.Tasks;
10+
using global::Microsoft.AspNetCore.Components;
11+
#line default
12+
#line hidden
13+
#nullable restore
14+
public partial class TestComponent : global::Microsoft.AspNetCore.Components.ComponentBase
15+
#nullable disable
16+
{
17+
#pragma warning disable 1998
18+
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
19+
{
20+
{
21+
global::__Blazor.Test.TestComponent.TypeInference.CreateMyComponent_0_CaptureParameters(
22+
#nullable restore
23+
#line (1,21)-(1,48) "x:\dir\subdir\Test\TestComponent.cshtml"
24+
new MyClass<IMyInterface>()
25+
26+
#line default
27+
#line hidden
28+
#nullable disable
29+
, out var __typeInferenceArg_0___arg0);
30+
global::__Blazor.Test.TestComponent.TypeInference.CreateMyComponent_0(__builder, 0, 1, __typeInferenceArg_0___arg0);
31+
__typeInferenceArg_0___arg0 = default;
32+
}
33+
}
34+
#pragma warning restore 1998
35+
}
36+
}
37+
namespace __Blazor.Test.TestComponent
38+
{
39+
#line hidden
40+
internal static class TypeInference
41+
{
42+
public static void CreateMyComponent_0<T>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, global::Test.MyClass<T> __arg0)
43+
where T : global::Test.IMyInterface
44+
{
45+
__builder.OpenComponent<global::Test.MyComponent<T>>(seq);
46+
__builder.AddComponentParameter(__seq0, nameof(global::Test.MyComponent<T>.
47+
#nullable restore
48+
#line (1,14)-(1,19) "x:\dir\subdir\Test\TestComponent.cshtml"
49+
Param
50+
51+
#line default
52+
#line hidden
53+
#nullable disable
54+
), __arg0);
55+
__builder.CloseComponent();
56+
}
57+
58+
public static void CreateMyComponent_0_CaptureParameters<T>(global::Test.MyClass<T> __arg0, out global::Test.MyClass<T> __arg0_out)
59+
where T : global::Test.IMyInterface
60+
{
61+
__arg0_out = __arg0;
62+
}
63+
}
64+
}
65+
#pragma warning restore 1591
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Source Location: (20:0,20 [27] x:\dir\subdir\Test\TestComponent.cshtml)
2+
|new MyClass<IMyInterface>()|
3+
Generated Location: (857:23,0 [27] )
4+
|new MyClass<IMyInterface>()|
5+
6+
Source Location: (13:0,13 [5] x:\dir\subdir\Test\TestComponent.cshtml)
7+
|Param|
8+
Generated Location: (1843:48,0 [5] )
9+
|Param|
10+

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/Components/ComponentNodeWriter.cs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,19 +153,7 @@ protected void WriteComponentTypeInferenceMethod(CodeRenderingContext context, C
153153

154154
writer.Write(")");
155155

156-
// Writes out a list of generic type constraints with indentation
157-
// public void Foo<T, U>(T t, U u)
158-
// where T: new()
159-
// where U: Foo, notnull
160-
foreach (var constraint in node.GenericTypeConstraints)
161-
{
162-
writer.WriteLine();
163-
writer.Indent(writer.CurrentIndent + writer.TabSize);
164-
writer.Write(constraint);
165-
166-
}
167-
168-
writer.WriteLine();
156+
writeConstraints(writer, node);
169157

170158
writer.WriteLine("{");
171159

@@ -319,7 +307,10 @@ protected void WriteComponentTypeInferenceMethod(CodeRenderingContext context, C
319307
writer.Write("_out");
320308
}
321309

322-
writer.WriteLine(")");
310+
writer.Write(")");
311+
312+
writeConstraints(writer, node);
313+
323314
writer.WriteLine("{");
324315
foreach (var parameter in parameters.Where(p => p.UsedForTypeInference))
325316
{
@@ -331,6 +322,22 @@ protected void WriteComponentTypeInferenceMethod(CodeRenderingContext context, C
331322
}
332323
writer.WriteLine("}");
333324
}
325+
326+
static void writeConstraints(CodeWriter writer, ComponentTypeInferenceMethodIntermediateNode node)
327+
{
328+
// Writes out a list of generic type constraints with indentation
329+
// public void Foo<T, U>(T t, U u)
330+
// where T: new()
331+
// where U: Foo, notnull
332+
foreach (var constraint in node.GenericTypeConstraints)
333+
{
334+
writer.WriteLine();
335+
writer.Indent(writer.CurrentIndent + writer.TabSize);
336+
writer.Write(constraint);
337+
}
338+
339+
writer.WriteLine();
340+
}
334341
}
335342

336343
protected static void WriteComponentAttributeName(CodeRenderingContext context, ComponentAttributeIntermediateNode attribute, bool allowNameof = true)

0 commit comments

Comments
 (0)