Skip to content

Call RenderTreeBuilder.AddComponentParameter#8286

Merged
jjonescz merged 16 commits into
dotnet:mainfrom
jjonescz:aspnetcore18042-ComponentAttributes
Mar 10, 2023
Merged

Call RenderTreeBuilder.AddComponentParameter#8286
jjonescz merged 16 commits into
dotnet:mainfrom
jjonescz:aspnetcore18042-ComponentAttributes

Conversation

@jjonescz
Copy link
Copy Markdown
Member

@jjonescz jjonescz commented Feb 16, 2023

Fixes dotnet/aspnetcore#18042.
Resolves #8258.

Calls new method RenderTreeBuilder.AddComponentParameter added in dotnet/aspnetcore#46562.

Old version: casting component attributes to object

Generates builder.AddAttribute(seq, name, (object)value); calls for component parameters. This avoids problems where value has implicit conversion to another primitive type (like string). Boxing is not a problem, it is actually required for component parameters, so this should allow the runtime to simplify their logic in RenderTreeBuilder.

Boolean parameters are excluded from the casting because they are more efficiently boxed inside RenderTreeBuilder (reusing boxed true and false values).

If method RenderTreeBuilder.AddComponentParameter is added in dotnet/aspnetcore#46562, changes in this PR can be revisited to call that overload instead. (Or we can do that immediately, I just wanted to investigate what changes are needed.)

CC: @MackinnonBuck

@jjonescz jjonescz marked this pull request as ready for review February 16, 2023 13:27
@jjonescz jjonescz requested a review from a team as a code owner February 16, 2023 13:27
Copy link
Copy Markdown
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general concept seems good to me.

@MackinnonBuck
Copy link
Copy Markdown
Member

dotnet/aspnetcore#46562 was just merged, which adds the RenderTreeBuilder.AddComponentParameter(int, string, object?) method. Could we modify this PR to call that method instead of performing the cast?

@jjonescz jjonescz changed the title Cast component attributes to object Call RenderTreeBuilder.AddComponentParameter Feb 23, 2023
@jjonescz jjonescz requested a review from 333fred February 23, 2023 12:28
@jjonescz jjonescz requested review from 333fred and chsienki February 28, 2023 09:11
public static readonly RazorLanguageVersion Version_7_0 = new RazorLanguageVersion(7, 0);

public static readonly RazorLanguageVersion Latest = Version_7_0;
public static readonly RazorLanguageVersion Version_8_0 = new RazorLanguageVersion(8, 0);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know whether the default is latest or 7? If the latter, where do we need to update the default?

Copy link
Copy Markdown
Member Author

@jjonescz jjonescz Mar 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default is latest as far as I can see in Razor (judging by C# references to RazorLanguageVersion and MSBuild property RazorLangVerision). We might need to update SDK, though? https://github.com/dotnet/sdk/blob/main/src/RazorSdk/Targets/Sdk.Razor.CurrentVersion.targets

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jjonescz jjonescz requested a review from 333fred March 3, 2023 09:00
@jjonescz
Copy link
Copy Markdown
Member Author

jjonescz commented Mar 8, 2023

@chsienki @dotnet/razor-compiler for the second review

public static global::Test.MyComponent<T> CreateMyComponent_0<T>(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder, int seq, int __seq0, global::System.Boolean __arg0, int __seq1, global::System.String __arg1, int __seq2, global::System.Delegate __arg2, int __seq3, global::System.Object __arg3, int __seq4, global::Test.MyClass<T> __arg4, int __seq5, global::Microsoft.AspNetCore.Components.EventCallback<global::Test.MyClass<T>> __arg5)
{
__builder.OpenComponent<global::Test.MyComponent<T>>(seq);
__builder.AddAttribute(__seq0, "BoolParameter", __arg0);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the reason for special casing bool in general?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the reason for special casing bool in general?

Same question from me. Keeping the old behavior for bool parameters means the bug still exists if the parameter value's type defines an implicit conversion operator to bool.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the reason for special casing bool in general?

That was meant as an optimization, because AddAttribute(..., bool) handles boxing of the bool more efficiently (it uses pre-computed BoxedTrue and BoxedFalse constants). Without special handling it, AddAttribute(..., (object)BoolArg) gets called - boxing true or false at the callsite.

Keeping the old behavior for bool parameters means the bug still exists if the parameter value's type defines an implicit conversion operator to bool.

That's a good catch, thanks. I will remove the special casing to fix this.

@jjonescz
Copy link
Copy Markdown
Member Author

jjonescz commented Mar 10, 2023

@333fred I removed bool special casing since your review - PTAL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants