-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Binding SG] Enable usage of private fields and properties in SetBinding path #23810
[Binding SG] Enable usage of private fields and properties in SetBinding path #23810
Conversation
47be94a
to
d607ba5
Compare
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.
This looks very promising! I left a few comments.
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_{{propertyName}}")] | ||
private static extern void SetUnsafeProperty{{id}}{{propertyName}}({{containingType}} source, {{memberType}} value); |
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.
What will happen when the property doesn't have a setter? I would expect the compilation of the generated code to fail in that case. Let's cover that with a unit test + ideally let's not generate the unsafe property setter at all when there isn't a setter.
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.
The compilation will not fail. UnsafeAccessor
can be used to modify a value of readonly fields / properties.
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.
But when the property doesn't have a setter, there won't be any set_{{propertyName}}
method 🤔 would that only crash at runtime if the unsafe setter method is called?
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.
Oh sorry. I was fixated on fields. It will crush on runtime I believe: https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUKgBgAJVMA6AJWmAEsBbAUzIGEB7OgBxoBsGwBlPgDcaAYwYBnANx5ZuPKgDMJdEQAirVngDeeIvqIcwNIQENgDEpmIAVBgA9gRbQHMGwKQF883+X6UqRMzOegYBqAAsRACyABQAlCG4BkS+vgrKGFYA7Dqh+gDaAKpQEqYAZgwAgqLiEhKsYLElZZU1dQ1gANI0UHBk0e4AFqxwMEQAcqaMRAC8RABEbsAA+naOC/EAugqYAGxEDhZgUFbEAOLuLRUMAApgrBx8wACe68CxGqxEDRBg4vEZH5iqUbu1JJ1mqC2rUIY0en0BsNRuMpjN5gsJO41kdNjt8PtDo4+KdIkRBMBrpV7o9nm8jp9ND9WH9xONSMQzNwIAxAfkiPyMKp+bpkikDGYwEQ4HMiFAGAB3dSaBJA8UGClUu4PJ5gV7vWJjRamUybNXqqwATliCwAGmo1Gb+WkgA===
|
||
namespace Microsoft.Maui.Controls.BindingSourceGen; | ||
|
||
public static class BindingCodeWriter | ||
{ | ||
private static readonly string NewLine = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "\r\n" : "\n"; |
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.
Could we use Enviornment.NewLine here instead? https://learn.microsoft.com/en-us/dotnet/api/system.environment.newline?view=net-8.0
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.
The symbol 'Environment' is banned for use by analyzers: Analyzers should not read their settings directly from environment variables(RS1035)
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.
At first, I was worried that we had to rely on [UnsafeAccessor]
for this.
But reviewing the code example:
private Button _button = new Button();
public MainPage()
{
SomeControl.SetBinding(Entry.TextProperty, static (MainPage mp) => mp._button.Text);
}
Without this change, you would have to do this:
private Button _button = new Button();
public Button Button => _button;
public MainPage()
{
SomeControl.SetBinding(Entry.TextProperty, static (MainPage mp) => mp.Button.Text);
}
From a developer's perspective, they wouldn't understand why they would have to do this. So, I think we have to support private members?
Reviewing the code, there are several tests, etc. Looks good to me. 👍
All failing tests are unrelated. |
Description of Change
The existing implementation of the SetBinding method cannot utilize private properties or fields in the getter, as the generated code is created in a separate class, making it unable to access these private members.
This PR addresses this limitation by introducing the capability to handle inaccessible fields and properties in the binding path through the generation of unsafe accessors.
Private Fields
Private Properties
Issues Fixed
Depends on #23671Fixes #23535
Limitations
This PR does NOT add support for usage of nested private types. This issue is tracked here: #23534. Currently unsafe accessors cannot be applied to private types. This may change with: dotnet/runtime#90081