-
Notifications
You must be signed in to change notification settings - Fork 128
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
Add nowarn option #1303
Add nowarn option #1303
Conversation
@@ -162,12 +162,14 @@ TypeAnnotations BuildTypeAnnotations (TypeDefinition type) | |||
paramAnnotations[0] = methodMemberTypes; | |||
} | |||
} else if (methodMemberTypes != DynamicallyAccessedMemberTypes.None) { | |||
_context.LogWarning ($"The DynamicallyAccessedMembersAttribute is only allowed on method parameters, return value or generic parameters.", 2041, method); | |||
_context.LogWarning ($"The DynamicallyAccessedMembersAttribute is only allowed on method parameters, return value or generic parameters.", |
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.
Do we need to worry about localization?
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 currently don't localize any message outputted by the linker. I sincerely don't know how useful that would be, but might be a good next step after polishing the current messages that we have (#1275).
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 for .NET 5 - linker is not localized (at all). If we think it's important it would be a relatively non-trivial feature on its own (mostly because there's nothing in that space in linker, so we would have to introduce everything from scratch). So .NET 6 (if we think it's important).
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.
Are other parts of the tool chain localized? What happens for Csc.exe?
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.
Yeah, csc.exe is fully localized. Visual Studio requires localization in all core languages as a shipping criteria, so it was a hard requirement for us. That doesn't sound like the case for the linker, so let's come back to that in the 6.0 timeframe as Vitek suggests.
This should be a separate PR - mostly because of the dotnet/runtime impact it will have. I would like us to do a dry PR into runtime with these changes somehow hacked in, to validate we're not going to break dotnet/runtime. |
I think we need a different command line name - So we need a different command line switch name for this functionality. As for the SubCategories - I don't like introducing a new grouping. That is "analysis" maps to "UnrecognizedReflectionPattern", "UnreferencedCode" and "DynamicDependency". The current desire is to have something with which we can enable/disable "linker analysis for trim correctness" and going forward similarly "linker analysis for single-file correctness" and so on. So I would probably group the warnings to subcategories which match this intent. I don't see much value distinguishing between UnreferencedCode and DynamicDependency warnings - for end users these are all about the same thing. So we should group all of them into one subcategory - name is tricky - "TrimCorrectness"? (Not sure I like it...) @samsp-msft for ideas. |
return; | ||
|
||
case NoWarn.Analysis: | ||
if (MessageSubCategory.Analysis.Contains (message.SubCategory)) |
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.
Nit: Maybe use if (Array.IndexOf (MessageSubCategory.Analysis, message.SubCategory) > -1)
to not have to add Linq to the LinkContext? Also, IndexOf does a faster lookup but not much of a difference. I do get that this is more readable, so I'm also ok if you don't want to change it
Thanks for putting this together! I think we want warnings about unrecognized reflection patterns and RequiresUnreferencedCode to be off by default (and in the same set). We then need an opt-in mechanism for these. To throw out an idea: maybe we could call the option I don't think we need I also think that warnings about invalid attributes or unresolved parameters in these attributes should be on by default (devs will want to get warnings if they add attributes with invalid signatures). Regarding the set names: |
Why don't we just go with the same behavior as |
Just to be clear - what behavior do you mean - the fact that |
We can just default the So, in a <LinkerNoWarn Condition=" '$(LinkerNoWarn)' == '' ">2006;2026</LinkerNoWarn> Then when a dev wants to enable all warnings: <LinkerNoWarn></LinkerNoWarn> in the .csproj would enable them all. |
My take on this is that we should't disable warnings by default in MSBuild - unless it is a workload-specific default. <LinkerNoWarn></LinkerNoWarn> also feels strange as the recommended way to opt into a new feature. I'm curious why csc does it this way. Those disabled warnings look like they have to do with assembly unification - maybe that was a workaround for existing behavior they couldn't change? |
I don't have a problem with --nowarn if it supports the same syntax as csc.exe, but would also add the named uber-category as depedendyAnalysis as a grouping. --nowarn 2036,2037 would be valid, where dependencyAnalysis maps to the respective collection of warning numbers. If we want to have a default, it should be in msbuild files so it can be overridden in other rules, rather than as baked in behavior in the linker. msbuild rules today are/can be opinionated, but the exes should be neutral. |
I like this framing @samsp-msft. What should we consider to be the neutral behavior (analysis warnings on or off)? My thinking so far has been that the neutral behavior is for the analysis warnings to be off, which is also the behavior we want for the .NET Core SDK (at least in .NET5 where they'll be pretty noisy) - then other msbuild files from developers or SDK components can override this to turn them on. I can see it going the other way too. |
Following the compiler model - warnings are enabled by default - its showing something that we think is a problem. |
I agree with Sam on that the warnings should be produced by linker "by default" - we know they describe problems. It is somewhat noisy as the app might work regardless, but each one of them is potentially a problem. The reason we want them off by default for now is not the linker (I think we've done a good job in the linker for these), it's the libraries - our own and external as well. Hopefully the reason will change in future versions - but versions of the framework, not the linker. So for example building .NET 5 app with .NET 6 SDK should hopefully still disable them by default (even if we enable them by default for .NET 6 apps), because the problem is in the libraries, not the linker. Thanks a lot Sam for bringing this perspective to this discussion! |
I think it would be fine to have the warnings off by default if the conservative trimming mode is enabled (the one that we shipped with in 3.0). But if someone opts into more aggressive trimming, I would want them to see all the warnings by default. |
Just to be sure, by this you mean all warnings or analysis warnings? |
Summarizing a little bit the discussion:
Is this correct? |
A couple notes about warning behavior in
|
Also, consider the benefit of using the same property to disable a warning ID in the linker and Roslyn -- if we moved any capabilities to be Roslyn analyzers, then Roslyn would see the suppression already and already have that warning silenced. Also, because of analyzers, Roslyn simply ignores suppressions it doesn't understand, it doesn't fail on them. |
@mateoatr great summary. Some thoughts:
We've effectively said that the defaults are:
Since the disabled We still need a way to override the opinionated .NET5 default and opt into the warnings. |
I discussed some of this with @agocke offline - my opinions:
@agocke - would you know if/where is the discussion on using strings instead of numbers for warnings codes? |
I'm not sure there was recorded discussion, just a few conversations, but I agree that we should have some stuff written down, especially since this is going to be a broader .NET-wide issue. @terrajobst @jaredpar do know if we have any document outlining diagnostic ID recommendations? My opinion was that analyzers should generally pick descriptive diagnostic names, like CA_AvoidUnusedPrivateFields instead of opaque identifiers like CA1823. Does anyone disagree? |
I'm not aware of any recommendations for diagnostic IDs. In general though a descriptive string does seem preferrable to an opaque identifier. |
I believe the core issue with using descriptive names instead of opaque diagnostic IDs is Localization story. We need to figure out whether this means IDs should be localizable. I am presuming they ought to be, otherwise you are trading one problem for another - a descriptive string that is only useful for english speaking users is not a good option. If they are localizable, that would mean |
We don't localize the argument names like "nowarn" so I don't think we need to localize the values. |
If not localized, then using strings like |
I don't follow. First, I don't think there's an "until" -- we pick one and then have to stick with it forever. And I'm not following how we could possibly localize diagnostic IDs. The purpose of the diagnostic ID is to be fixed and immutable. If we followed your approach I think it would imply that we should localize C# language keywords as well, since those are also "English-only" strings. But we've never considered that to be a goal and I don't see why we would special-case diagnostic identifiers here. |
My point is using "descriptive names/strings" for diagnostic IDs has lot of pitfalls, because we cannot localize the ID due to lot of features that will break. We should stay with using opaque number based identifiers. |
Why is being more descriptive in one language worse than being less descriptive in all languages? Why is it OK for C# keywords to be English, and not random strings? |
That is not true or related. Language keywords are all documented, and parsed as a keyword by the compiler, hence not localized. On the other hand, the diagnostic ID shows up in lot of UX, such as error list, solution explorer, ruleset editor, etc., which is required to have localized strings for descriptions. For example, if I am a non-English speaking user, seeing error list entries with |
How is that different from editorconfig, which requires the string |
Additionally, I also don't understand why are we trying to push "descriptive text" into an "ID" field, while such a description is already part of the diagnostic title and message fields, which are already localized. Are we just missing surfacing these localized strings at a place where it is required? |
This is the linker, not Roslyn. There is no diagnostic infrastructure or localization of any kind. We're trying to decide what format we should adopt. |
I don't agree with that:
None of these are localized or even could be localized. It's a bit defeatist to say just because something won't be localized using a descriptive name in en-us has no value. That being said, I think using descriptive names has downsides as well:
|
Sure, each analyzer author is free to use whatever format for the ID as they prefer, as long as it is a valid identifier. That does not mean we should recommend analyzer authors to use |
At the moment, the linker warnings don't even appear in the VS error list, so I agree that's unfortunate but also something we probably need to address later 😄 |
However, if the .NET 5 analyzers are being shipped through the existing roslyn-analyzers framework, then the .NET approach is to use two-letter prefix + number. I'd rather us be consistent with the rest of .NET than carve our own path |
So "IL" + number sounds good. Any concerns? @terrajobst @mateoatr |
How would we feel if we start seeing |
This sounds good. Let's stick with this in the linker for now. |
This turns off the analysis warnings by default and adds the ability to turn off all warnings or a subset of them by specifying a warning "subcategory superset", this can be done either using the command line or the ILLink task.
A warning subcategory superset is a set of subcategories. The only such superset added in this PR is
analysis
, which contains the following subcategories:UnrecognizedReflectionPattern
,DynamicDependency
,PreserveDependency
UnreferencedCode
. As an example, by specifying--nowarn analysis
, the user would turn off all warnings that have their subcategory set to any of the subcategories aforementioned.Usage examples:
Turning off all warnings
Turning off warnings using a subcategory superset
Here's a table that summarizes all warnings that specify a subcategory:
I'd like some comments on whether or not these new subcategories make sense (DynamicDependency, PreserveDependency, UnreferencedCode) and if all warnings that use these should indeed be categorized as analysis warnings.
This PR also changes the logging behavior so that warnings and errors are always logged, no matter if the
--verbose
option isn't used./cc @eerhardt