Skip to content
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

Get TrimTest to 0 trim warnings #11407

Merged
merged 19 commits into from
Jun 5, 2024
Merged

Conversation

LakshanF
Copy link
Member

@LakshanF LakshanF commented May 20, 2024

Use the new ComponentModel type registration APIs to make the TrimTest project trim compatible.

  • Use a feature switch flag to use the new ComponentModel APIs (non-trimmed applications will continue to use the legacy ComponentModel APIs)
  • Some features of WinForms are not supported in trimming and are disabled via feature switches (a complete set can be seen in TrimTest project)
  • Primitive types (string, int, bool, double) are not registered with ComponentModel since these are assumed to be supported by default by ComponentModel
Microsoft Reviewers: Open in CodeFlow

@LakshanF LakshanF self-assigned this May 20, 2024
@LakshanF LakshanF requested a review from a team as a code owner May 20, 2024 22:14
@Tanya-Solyanik Tanya-Solyanik added the 📚 documentation Documentation bug or improvement label May 21, 2024
src/System.Windows.Forms/src/Resources/SR.resx Outdated Show resolved Hide resolved
@@ -18,7 +18,7 @@ internal unsafe partial class ComposedDataObject
{
[FeatureSwitchDefinition("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization")]
#pragma warning disable IDE0075 // Simplify conditional expression - the simpler expression is hard to read
private static bool EnableUnsafeBinaryFormatterInNativeObjectSerialization { get; } = AppContext.TryGetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", out bool isEnabled) ? isEnabled : true;
internal static bool EnableUnsafeBinaryFormatterInNativeObjectSerialization { get; } = AppContext.TryGetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", out bool isEnabled) ? isEnabled : true;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we need a new helper class that would store "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization" switch value.

@Tanya-Solyanik Tanya-Solyanik added the 📭 waiting-author-feedback The team requires more information from the author label May 21, 2024
src/System.Windows.Forms/src/Resources/SR.resx Outdated Show resolved Hide resolved
Comment on lines +1148 to +1150
{
throw new NotSupportedException(SR.BinaryFormatterNotSupported);
}
Copy link
Member

Choose a reason for hiding this comment

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

It feels weird to have a feature switch to control use of binary formatter which is also under a feature switch.

We annotated BinaryFormatter as RequiresUnreferencedCode, but at the same time we introduced a feature switch to disable it and defaulted it to "disabled" when trimming. Should we actually drop the RUC on BinaryFormatter? The rationale is that there is no behavioral difference between trimmed and untrimmed app (both throw) and we'll probably generate trimming warnings from BinaryFormatter internals should someone dare to enable the BinaryFormatter feature switch.

It doesn't feel right that people need to create feature switch for a feature switch.

(In a normal PublishTrimmed app, new BinaryFormatter().Deserialize(stream) below is going to throw a NotSupportedException anyway.)

Cc @eerhardt

Copy link
Member

Choose a reason for hiding this comment

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

It feels weird to have a feature switch to control use of binary formatter which is also under a feature switch.

DataObject.ComposedDataObject.EnableUnsafeBinaryFormatterInNativeObjectSerialization is just a wrapper over the existing System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization feature switch. It isn't a new feature switch itself.

Should we actually drop the RUC on BinaryFormatter?

Not until BinaryFormatter's logic is actually removed - dotnet/runtime#98245. Once it always throws everywhere - then yes I think we can drop the annotations. No use in giving trim/AOT warnings when it will always throw.

Copy link
Member

Choose a reason for hiding this comment

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

DataObject.ComposedDataObject.EnableUnsafeBinaryFormatterInNativeObjectSerialization is just a wrapper over the existing System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization feature switch. It isn't a new feature switch itself.

There's a comment on this saying it's not the right property to use, so I assume it will change: https://github.com/dotnet/winforms/pull/11407/files#r1607641253

Should we actually drop the RUC on BinaryFormatter?

Not until BinaryFormatter's logic is actually removed - dotnet/runtime#98245. Once it always throws everywhere - then yes I think we can drop the annotations. No use in giving trim/AOT warnings when it will always throw.

The point I'm trying to make is that we generate warnings when there's a difference between F5 Debug time and publish time. In the case of BinaryFormatter in default trimmed configuration, there's no behavior difference. It always throws. The way we've done this elsewhere is that we don't generate a warning and structure things so that if someone changes the feature switch default, then they get a warning (and the warning would be somewhere in the implementation details of it).

But the more I'm thinking about it the more it feels like that's not the right approach either - if someone is a library developer like in this case, they won't know the API could throw until someone uses the library in a trimmed app (it will not be caught in unit tests, etc.). To give a similar example, someone could be using DI with open generics in a library (another spot where we use feature switches to erase differences and make trim unsafe API "safe"), never get any warnings from an analyzer, and only get bug reports from users later that it doesn't work.

Copy link
Member Author

Choose a reason for hiding this comment

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

The feature switch, EnableUnsafeBinaryFormatterInNativeObjectSerialization, using the binary formatter feature switch, is used to control trim warnings related to using BinaryFormatter in WinForms trimming. The trimmer will generate a warning when set to true and will not generate a warning when set to false to work around the issue of the RUC on the BinaryFormatter as mentioned above.

@dotnet-policy-service dotnet-policy-service bot removed the 📭 waiting-author-feedback The team requires more information from the author label May 24, 2024
Copy link

codecov bot commented May 29, 2024

Codecov Report

Attention: Patch coverage is 42.01183% with 98 lines in your changes missing coverage. Please review.

Project coverage is 74.39904%. Comparing base (d8c60bf) to head (4b073f2).
Report is 38 commits behind head on main.

Additional details and impacted files
@@                 Coverage Diff                 @@
##                main      #11407         +/-   ##
===================================================
+ Coverage   74.28601%   74.39904%   +0.11302%     
===================================================
  Files           3026        3030          +4     
  Lines         627075      628039        +964     
  Branches       46755       46803         +48     
===================================================
+ Hits          465829      467255       +1426     
+ Misses        157900      157435        -465     
- Partials        3346        3349          +3     
Flag Coverage Δ
Debug 74.39904% <42.01183%> (+0.11302%) ⬆️
integration 17.98361% <9.65517%> (-0.01498%) ⬇️
production 47.22281% <33.10345%> (+0.20307%) ⬆️
test 96.98776% <95.83333%> (+0.00075%) ⬆️
unit 44.18112% <33.10345%> (+0.18569%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Tanya-Solyanik
Tanya-Solyanik previously approved these changes Jun 3, 2024
@LakshanF LakshanF merged commit f0811e2 into dotnet:main Jun 5, 2024
8 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 9.0 Preview6 milestone Jun 5, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jul 6, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
📚 documentation Documentation bug or improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants