-
Notifications
You must be signed in to change notification settings - Fork 35
Fixes creating constraint string from type parameter symbol #44
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// <auto-generated/> | ||
#pragma warning disable 1591 | ||
namespace Test | ||
{ | ||
#line hidden | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Components; | ||
public 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 System.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 2 "x:\dir\subdir\Test\TestComponent.cshtml" | ||
WeatherForecast | ||
|
||
#line default | ||
#line hidden | ||
#nullable disable | ||
); | ||
__o = | ||
#nullable restore | ||
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml" | ||
Array.Empty<WeatherForecast>() | ||
|
||
#line default | ||
#line hidden | ||
#nullable disable | ||
; | ||
__builder.AddAttribute(-1, "ColumnsTemplate", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => { | ||
global::__Blazor.Test.TestComponent.TypeInference.CreateColumn_0(__builder2, -1, default(WeatherForecast), -1, "", -1, "", -1, "", -1, ""); | ||
#nullable restore | ||
#line 5 "x:\dir\subdir\Test\TestComponent.cshtml" | ||
__o = typeof(global::Test.Column<>); | ||
|
||
#line default | ||
#line hidden | ||
#nullable disable | ||
} | ||
)); | ||
#nullable restore | ||
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" | ||
__o = typeof(global::Test.Grid<>); | ||
|
||
#line default | ||
#line hidden | ||
#nullable disable | ||
} | ||
#pragma warning restore 1998 | ||
} | ||
} | ||
namespace __Blazor.Test.TestComponent | ||
{ | ||
#line hidden | ||
internal static class TypeInference | ||
{ | ||
public static void CreateColumn_0<TItem>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, TItem __syntheticArg0, int __seq0, global::System.Object __arg0, int __seq1, global::System.String __arg1, int __seq2, global::System.Object __arg2, int __seq3, global::System.Object __arg3) | ||
where TItem : class | ||
{ | ||
__builder.OpenComponent<global::Test.Column<TItem>>(seq); | ||
__builder.AddAttribute(__seq0, "Title", __arg0); | ||
__builder.AddAttribute(__seq1, "FieldName", __arg1); | ||
__builder.AddAttribute(__seq2, "Format", __arg2); | ||
__builder.AddAttribute(__seq3, "Width", __arg3); | ||
__builder.CloseComponent(); | ||
} | ||
} | ||
} | ||
#pragma warning restore 1591 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
Document - | ||
NamespaceDeclaration - - Test | ||
UsingDirective - (3:1,1 [12] ) - System | ||
UsingDirective - (18:2,1 [32] ) - System.Collections.Generic | ||
UsingDirective - (53:3,1 [17] ) - System.Linq | ||
UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks | ||
UsingDirective - (104:5,1 [37] ) - Microsoft.AspNetCore.Components | ||
ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase - | ||
DesignTimeDirective - | ||
CSharpCode - | ||
IntermediateToken - - CSharp - #pragma warning disable 0414 | ||
CSharpCode - | ||
IntermediateToken - - CSharp - private static System.Object __o = null; | ||
CSharpCode - | ||
IntermediateToken - - CSharp - #pragma warning restore 0414 | ||
MethodDeclaration - - protected override - void - BuildRenderTree | ||
Component - (0:0,0 [205] x:\dir\subdir\Test\TestComponent.cshtml) - Grid | ||
ComponentChildContent - (80:3,4 [116] x:\dir\subdir\Test\TestComponent.cshtml) - ColumnsTemplate - context | ||
HtmlContent - (97:3,21 [10] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (97:3,21 [10] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n | ||
Component - (107:4,8 [65] x:\dir\subdir\Test\TestComponent.cshtml) - Column | ||
ComponentAttribute - - Title - - AttributeStructure.DoubleQuotes | ||
HtmlContent - (122:4,23 [4] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (122:4,23 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Date | ||
ComponentAttribute - (139:4,40 [4] x:\dir\subdir\Test\TestComponent.cshtml) - FieldName - FieldName - AttributeStructure.DoubleQuotes | ||
HtmlContent - (139:4,40 [4] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (139:4,40 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Date | ||
ComponentAttribute - - Format - - AttributeStructure.DoubleQuotes | ||
HtmlContent - (153:4,54 [1] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (153:4,54 [1] x:\dir\subdir\Test\TestComponent.cshtml) - Html - d | ||
ComponentAttribute - - Width - - AttributeStructure.DoubleQuotes | ||
HtmlContent - (163:4,64 [5] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (163:4,64 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Html - 10rem | ||
HtmlContent - (172:4,73 [6] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (172:4,73 [6] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n | ||
ComponentTypeArgument - (14:1,7 [15] x:\dir\subdir\Test\TestComponent.cshtml) - TItem | ||
LazyIntermediateToken - (14:1,7 [15] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - WeatherForecast | ||
ComponentAttribute - - Items - - AttributeStructure.DoubleQuotes | ||
CSharpExpression - (39:2,7 [33] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (41:2,9 [30] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Array.Empty<WeatherForecast>() | ||
HtmlContent - (205:6,7 [2] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (205:6,7 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n | ||
NamespaceDeclaration - - __Blazor.Test.TestComponent | ||
ClassDeclaration - - internal static - TypeInference - - | ||
ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateColumn_0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Source Location: (14:1,7 [15] x:\dir\subdir\Test\TestComponent.cshtml) | ||
|WeatherForecast| | ||
Generated Location: (902:25,7 [15] ) | ||
|WeatherForecast| | ||
|
||
Source Location: (41:2,9 [30] x:\dir\subdir\Test\TestComponent.cshtml) | ||
|Array.Empty<WeatherForecast>()| | ||
Generated Location: (1084:34,9 [30] ) | ||
|Array.Empty<WeatherForecast>()| | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// <auto-generated/> | ||
#pragma warning disable 1591 | ||
namespace Test | ||
{ | ||
#line hidden | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Components; | ||
public 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<global::Test.Grid<WeatherForecast>>(0); | ||
__builder.AddAttribute(1, "Items", | ||
#nullable restore | ||
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml" | ||
Array.Empty<WeatherForecast>() | ||
|
||
#line default | ||
#line hidden | ||
#nullable disable | ||
); | ||
__builder.AddAttribute(2, "ColumnsTemplate", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => { | ||
global::__Blazor.Test.TestComponent.TypeInference.CreateColumn_0(__builder2, 3, default(WeatherForecast), 4, "Date", 5, "Date", 6, "d", 7, "10rem"); | ||
} | ||
)); | ||
__builder.CloseComponent(); | ||
} | ||
#pragma warning restore 1998 | ||
} | ||
} | ||
namespace __Blazor.Test.TestComponent | ||
{ | ||
#line hidden | ||
internal static class TypeInference | ||
{ | ||
public static void CreateColumn_0<TItem>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, TItem __syntheticArg0, int __seq0, global::System.Object __arg0, int __seq1, global::System.String __arg1, int __seq2, global::System.Object __arg2, int __seq3, global::System.Object __arg3) | ||
where TItem : class | ||
{ | ||
__builder.OpenComponent<global::Test.Column<TItem>>(seq); | ||
__builder.AddAttribute(__seq0, "Title", __arg0); | ||
__builder.AddAttribute(__seq1, "FieldName", __arg1); | ||
__builder.AddAttribute(__seq2, "Format", __arg2); | ||
__builder.AddAttribute(__seq3, "Width", __arg3); | ||
__builder.CloseComponent(); | ||
} | ||
} | ||
} | ||
#pragma warning restore 1591 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
Document - | ||
NamespaceDeclaration - - Test | ||
UsingDirective - (3:1,1 [14] ) - System | ||
UsingDirective - (18:2,1 [34] ) - System.Collections.Generic | ||
UsingDirective - (53:3,1 [19] ) - System.Linq | ||
UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks | ||
UsingDirective - (104:5,1 [39] ) - Microsoft.AspNetCore.Components | ||
ClassDeclaration - - public partial - TestComponent - global::Microsoft.AspNetCore.Components.ComponentBase - | ||
MethodDeclaration - - protected override - void - BuildRenderTree | ||
Component - (0:0,0 [205] x:\dir\subdir\Test\TestComponent.cshtml) - Grid | ||
ComponentChildContent - (80:3,4 [116] x:\dir\subdir\Test\TestComponent.cshtml) - ColumnsTemplate - context | ||
Component - (107:4,8 [65] x:\dir\subdir\Test\TestComponent.cshtml) - Column | ||
ComponentAttribute - - Title - - AttributeStructure.DoubleQuotes | ||
HtmlContent - (122:4,23 [4] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (122:4,23 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Date | ||
ComponentAttribute - (139:4,40 [4] x:\dir\subdir\Test\TestComponent.cshtml) - FieldName - FieldName - AttributeStructure.DoubleQuotes | ||
HtmlContent - (139:4,40 [4] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (139:4,40 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - Date | ||
ComponentAttribute - - Format - - AttributeStructure.DoubleQuotes | ||
HtmlContent - (153:4,54 [1] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (153:4,54 [1] x:\dir\subdir\Test\TestComponent.cshtml) - Html - d | ||
ComponentAttribute - - Width - - AttributeStructure.DoubleQuotes | ||
HtmlContent - (163:4,64 [5] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (163:4,64 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Html - 10rem | ||
ComponentTypeArgument - (14:1,7 [15] x:\dir\subdir\Test\TestComponent.cshtml) - TItem | ||
LazyIntermediateToken - (14:1,7 [15] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - WeatherForecast | ||
ComponentAttribute - - Items - - AttributeStructure.DoubleQuotes | ||
CSharpExpression - (39:2,7 [33] x:\dir\subdir\Test\TestComponent.cshtml) | ||
LazyIntermediateToken - (41:2,9 [30] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Array.Empty<WeatherForecast>() | ||
NamespaceDeclaration - - __Blazor.Test.TestComponent | ||
ClassDeclaration - - internal static - TypeInference - - | ||
ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateColumn_0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -270,36 +270,35 @@ private void CreateTypeParameterProperty(TagHelperDescriptorBuilder builder, ITy | |
// things like constructor constraints and not null constraints in the | ||
// type parameter so we create a single string representation of all the constraints | ||
// here. | ||
var constraintString = new StringBuilder(); | ||
if (typeParameter.ConstraintTypes.Any()) | ||
var list = new List<string>(); | ||
for (var i = 0; i < typeParameter.ConstraintTypes.Length; i++) | ||
{ | ||
constraintString.Append(string.Join(", ", typeParameter.ConstraintTypes.Select(t => t.Name))); | ||
list.Add(typeParameter.ConstraintTypes[i].Name); | ||
} | ||
if (typeParameter.HasConstructorConstraint) | ||
{ | ||
constraintString.Append(", new()"); | ||
list.Add("new()"); | ||
} | ||
if (typeParameter.HasNotNullConstraint) | ||
{ | ||
constraintString.Append(", notnull"); | ||
list.Add("notnull"); | ||
} | ||
if (typeParameter.HasReferenceTypeConstraint) | ||
{ | ||
constraintString.Append(", class"); | ||
list.Add("class"); | ||
} | ||
if (typeParameter.HasUnmanagedTypeConstraint) | ||
{ | ||
constraintString.Append(", unmanaged"); | ||
list.Add("unmanaged"); | ||
} | ||
if (typeParameter.HasValueTypeConstraint) | ||
{ | ||
constraintString.Append(", struct"); | ||
list.Add("struct"); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue was that each block after the one above assumed that there was already a constraint and pre-pended a comma. Instead of doing that, we collect the constraints on a list and then join them together. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. Good fix. In the new baselines in this PR, I don't see any cases where constraints are joined with commas. Do we definitely have coverage of this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also the original issue that this fixes reports the following error:
The code above doesn't seem to ensure that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I've changed this after the fact, I've been adding more tests |
||
|
||
if (constraintString.Length > 0) | ||
if (list.Count > 0) | ||
{ | ||
constraintString.Insert(0, "where " + typeParameter.Name + " : "); | ||
pb.Metadata[ComponentMetadata.Component.TypeParameterConstraintsKey] = constraintString.ToString(); | ||
pb.Metadata[ComponentMetadata.Component.TypeParameterConstraintsKey] = $"where {typeParameter.Name} : {string.Join(", ", list)}"; | ||
} | ||
|
||
pb.Documentation = string.Format(CultureInfo.InvariantCulture, ComponentResources.ComponentTypeParameter_Documentation, typeParameter.Name, builder.Name); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove an allocation by lazily initializing this, assuming this code path is always called and not only if the parameter has some constraint. An alternative would to be add a
AppendToStringBuilder
that conditionally adds the commas to avoid the interim string allocation fromstring.Join
that happens later on in this method.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not going to remove the allocation unless we have prove that it matters in a benchmark. This code used to work and we broke it for the sake of removing the allocation without a clear benefit. Let's keep the code simple and understandable (and hopefully bug free)