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

Support Url and Message parameters in RequiresPreviewFeaturesAttribute #5502

Merged
merged 26 commits into from
Oct 7, 2021

Conversation

pgovind
Copy link
Contributor

@pgovind pgovind commented Sep 17, 2021

Customer Impact

Early usage of the RequiresPreviewFeaturesAttribute and the Preview Feature analyzer (CA2252) surfaced the desire for custom messages and Urls to be supported by the attribute and analyzer. This will allow preview features (such as Kestrel's Http3 support) to surface custom diagnostic messages with feature-specific Urls that guide users to learn more about those preview features.

dotnet/runtime#56938 added the Message and URL properties to RequiresPreviewFeaturesAttribute. This PR updates the RequiresPreviewFeaturesAnalyzer to support the new properties in the message diagnostic. Including this change in 6.0 GA will improve the initial customer experience of using preview features in .NET 6.0 by providing tailored messages and improved discoverability of documentation for our preview features.

For illustration, here's the current message for using HTTP/3 in Kestrel (without this change):

Using 'UseQuic' requires opting into preview features. See https://aka.ms/dotnet-warnings/preview-features for more information.

With this change, the emitted diagnostic message will be:

Kestrel HTTP/3 support for .NET 6 is in preview. Using 'UseQuic' requires opting into preview features. See https://aka.ms/aspnet/kestrel/http3reqs for more information.

This was originally requested in dotnet/runtime#56498 by @JamesNK. If approved for 6.0 GA, we will also update all Generic Math APIs to utilize the Message and URL such that those messages are shown as:

Generic Math is in preview. Using 'IAdditionOperators' requires opting into preview features. See https://aka.ms/dotnet-warnings/generic-math-preview for more information.

Testing

Unit tests were updated to validate that the diagnostics are reported using the custom properties when they are present. Manual testing was also conducted with a local build of the analyzer, validating against our existing preview attributes.

Risk

Moderate, but mitigated. This functionality is landing very late in the release, but that was anticipated when we received the suggestion for adding the custom properties to the attribute. Because of this timing, the PR takes a low-churn approach to the implementation. In theory, if we wanted to be more performant, we could fold the new ConcurrentDictionary into the existing SymbolIsAnnotatedAsPreview call. That would however mean changes to each caller and it would quickly mean touching every routine in the analyzer. Instead, we decided to just look for the Url and Message property once per symbol just before we report a diagnostic.

@pgovind pgovind requested a review from a team as a code owner September 17, 2021 22:11
@pgovind pgovind marked this pull request as draft September 17, 2021 22:11
@pgovind pgovind changed the title Support Url and Message parameters in RequiresPreviewFeaturesAttribute DO NOT REVIEW: Support Url and Message parameters in RequiresPreviewFeaturesAttribute Sep 17, 2021
@pgovind pgovind changed the title DO NOT REVIEW: Support Url and Message parameters in RequiresPreviewFeaturesAttribute Support Url and Message parameters in RequiresPreviewFeaturesAttribute Sep 20, 2021
@pgovind pgovind marked this pull request as ready for review September 20, 2021 22:22
@@ -96,7 +96,7 @@ public static class AdditionalMetadataReferences
"net6.0",
new PackageIdentity(
"Microsoft.NETCore.App.Ref",
"6.0.0-preview.6.21352.12"),
"6.0.0-rc.1.21451.13"),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The new Message and Url properties on RequiresPreviewFeatureAttribute shipped in RC1

}

infosBuilder.Clear();
var attributes = method.GetAttributes();
if (HasAnyGuardAttribute(attributes, out var mappedAttributes) && TryDecodeGuardAttributes(mappedAttributes, infosBuilder))
if (HasAnyGuardAttribute(attributes, version, out var mappedAttributes) && TryDecodeGuardAttributes(mappedAttributes, infosBuilder))
Copy link
Member

Choose a reason for hiding this comment

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

This method is only called for OperatingSystem.IsXYZ() methods, the guard attributes added into OperatingSystem.IsXYZ() methods will not have a version, instead its version should be set the same as the version of the OperatingSystem.IsXYZVersionAtLeast(int,int,int,int) parameter. Therefore added an overload for HasAnyGuardAttribute(...) method which parses the attributes, the functionality is same as original method, just version is passed from OperatingSystem.IsXYZVersionAtLeast(int,int,int,int) parameter

@buyaa-n
Copy link
Member

buyaa-n commented Sep 23, 2021

if we wanted to be uber performant, I could fold the new ConcurrentDictionary into the existing SymbolIsAnnotatedAsPreview call. That would however mean changes to each caller and it would quickly mean touching every routine in the analyzer. Instead, I decided to just look for the Url and Message property once per symbol just before we report a diagnostic.

It seems to me you can use only one existing ConcurrentDictionary and keep all info (bool, url, message) together, by setting them once in SymbolIsAnnotatedAsPreview, doesn't seem need much change, but this is up to you.

I have more stronger feeling for manual message concatenation, better to add placeholder for message and url for each resource string, this is not optional comment 😉

And not sure if you are aware, somehow the build is still failing

Copy link
Member

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

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

Left a few NIT comments, overall LGTM

@pgovind
Copy link
Contributor Author

pgovind commented Sep 27, 2021

Thanks for the stamp Buyaa. I'm just waiting for a review from one of the analyzer folks to address all the feedback in 1 go and merge.

test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(2).WithArguments("AProperty"));
test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("AMethod", DetectPreviewFeatureAnalyzer.DefaultURL));
test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(1).WithArguments("Library", DetectPreviewFeatureAnalyzer.DefaultURL));
test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(2).WithArguments("AProperty", DetectPreviewFeatureAnalyzer.DefaultURL));
Copy link
Contributor

@jmarolf jmarolf Sep 28, 2021

Choose a reason for hiding this comment

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

Why are we mixing diagnostic styles here?

either we don't need the {||} parse holes in csCurrentAssemblyCode or we don't need to manually specify the diagnostics here right?

Copy link
Contributor Author

@pgovind pgovind Sep 28, 2021

Choose a reason for hiding this comment

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

Why are we mising diagnostic styles here?

What do diagnostic styles mean? I don't know that term :/

Hmm, not sure I completely understand, but the analyzer reports multiple diagnostics, so I need to use both the {| |} syntax and add the diagnostics explicitly in the ExpectedDiagnostics.Add method right? Is there another way?

Copy link
Contributor

Choose a reason for hiding this comment

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

but the analyzer reports multiple diagnostics

But the additional diagnostics have locations right? So you can do {|{||}|} to nest diagnostics whose locations overlap. I would prefer we use the brackets syntax as its easier to visually understand where the diagnostics are appearing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But the additional diagnostics have locations right?

Wait maybe I wasn't being clear. I meant that DetectPreviewFeaturesAnalyzer can report ~17 different diagnostics, not that it's reporting the same diagnostic in multiple places. So the only option in the unit tests is to use both the {| |} syntax and the ExpectedDiagnostics.Add method IIRC

Copy link
Member

Choose a reason for hiding this comment

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

So you can do {|{||}|} to nest diagnostics whose locations overlap.

@jmarolf I might be missing something, but i don't see such overlaps in the diagnostics

Copy link
Contributor

@jmarolf jmarolf left a comment

Choose a reason for hiding this comment

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

Have a few things that need fixing and then we are good to go. I also don't remember why we specify the diagnostic locations in the test twice using two separate approaches

Copy link
Member

@jeffhandley jeffhandley left a comment

Choose a reason for hiding this comment

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

I pushed commits to remove the quotes around the Urls and to improve a little formatting/indentation.

@jeffhandley
Copy link
Member

This was approved in tactics for 6.0 GA.

@buyaa-n
Copy link
Member

buyaa-n commented Oct 7, 2021

This was approved in tactics for 6.0 GA.

The PR got a conflict after @tannergooding's PR merged , resolved the conflict and gonna enable automerge

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

Successfully merging this pull request may close these issues.

None yet

6 participants