-
Notifications
You must be signed in to change notification settings - Fork 468
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 UseVolatileReadWriteAnalyzer #7043
Conversation
Thanks, though I thought the plan was to mark them as obsolete and then have a fixer associated with that diagnostic id? Or did that plan change? |
That was my understanding as well, however I couldn't figure out how to add tests without an analyzer emitting the diagnostic ID and I also thought it would benefit developers immediately instead of having to wait for the obsoletion of the APIs. But I am happy to delete the analyzer if someone can let me know how to configure the test. |
@CollinAlpert You can move the analyzer over to the test project and use it only for the tests. Add a comment + open a tracking issue to remove this analyzer in the future. Please do make sure that the code fixer and this test-only analyzer use the Diagnostic ID that will be used in the Obsolete attribute on the APIs - I am not sure if a CAxxxx diagnostic ID is appropriate to indicate obsoletion, maybe they should use a special prefix, I see we have https://learn.microsoft.com/en-us/dotnet/fundamentals/syslib-diagnostics/obsoletions-overview#reference. I think you should first confirm the diagnostic ID in the issue and ensure it doesn't get used by another feature. |
# Conflicts: # src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7043 +/- ##
========================================
Coverage 96.46% 96.47%
========================================
Files 1432 1436 +4
Lines 342185 342787 +602
Branches 11280 11289 +9
========================================
+ Hits 330104 330708 +604
+ Misses 9230 9225 -5
- Partials 2851 2854 +3 |
@mavasani What's missing here? I received no response in the issue, so I am assuming the diagnostic ID is okay. Is there anything else I need to do before this can be merged? |
# Conflicts: # src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@mavasani @stephentoub if the fixer should be fired for Obsoletion diagnostic ID is this repo is the correct place for the fixer? As far as I know most SYSLIB**** analyzer/fixers implemented in runtime, but I think the obsoletion analyzer is in roslyn repo. Adding the fixer here might still work though.
Sorry for delay @CollinAlpert, we can's assume the diagnostic ID used here is okay, anybody might use that ID for obsoleting other API (the rule is just grab next available ID I think). You would need assign the ID for this obsoletion and mark the related APIs with that check this https://github.com/dotnet/runtime/pull/84812/files for example. But we might not want to mark the APIs until the fixer is implemented, not sure, what you think @stephentoub? |
Actually with dotnet/roslyn-sdk#1117 being fixed seems now we can add the fixer here. Without having an anlyzer for testing only. |
So I would need to create a PR for dotnet/runtime first, adding the |
@CollinAlpert I pushed my WIP implementation of a fixer that uses no additional analyzer (with the fix from Roslyn SDK), see here: mpidash@39276c6#diff-b057b03b5cca1496dc3d962dd2593bfefe06119259299f588966b2c344a78ddeR20-R73 Feel free to copy anything you need. |
var codeAction = CodeAction.Create( | ||
MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle, | ||
_ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName)))), | ||
MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle |
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 (see #5431):
MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle | |
nameof(MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle) |
var codeAction = CodeAction.Create( | ||
MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle, | ||
_ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(writeAccess, CreateVolatileMemberAccess(context.Document, VolatileWriteMethodName)))), | ||
MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle |
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 (see #5431):
MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle | |
nameof(MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle) |
[ExportCodeFixProvider(LanguageNames.CSharp), Shared] | ||
internal sealed class CSharpUseVolatileReadWriteFixer : UseVolatileReadWriteFixer | ||
{ | ||
protected override bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess) |
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.
protected override bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess) | |
protected sealed override bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess) |
{ | ||
var codeAction = CodeAction.Create( | ||
MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle, | ||
_ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName)))), |
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.
I think this breaks with named arguments, as Volatile.Read
and Thread.VolatileRead
use different parameter names (location
and address
).
); | ||
} | ||
|
||
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; |
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.
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; | |
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; |
|
||
protected abstract bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess); | ||
|
||
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); |
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.
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); | |
public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); |
|
||
namespace Microsoft.NetCore.Analyzers.Usage.UnitTests | ||
{ | ||
public sealed class UseVolatileReadWriteTests |
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.
Tests checking if trivia and named arguments are preserved are missing.
In general yes, that includes adding the attributes to the APIs with the desired ID and message, find all usages and fix them, though having a fixer could help with fixing if there are many usages. Though, I would say it can be optional, add the attributes if you would like to, or continue implementing the fixer with |
Thank you very much @mpidash, implementing a fixer that uses no additional analyzer is the what we need here
Definitely |
# Conflicts: # src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@buyaa-n But doesn't |
@mpidash Thanks a lot, your WIP was extremely helpful! :) |
I don't really know the performance impact, but I would not expect perf overhead, @mavasani @sharwell could reply to that. I know that |
There should be no negative performance impact on using IOperation APIs in analyzers and fixers. We already have a whole ecosystem of IOperation based analyzers and fixers, and they all share the same IOperation trees. |
I switched to using I also had to disable the test |
Thanks, I believe you can use this extension method for that: roslyn-analyzers/src/Utilities/Compiler/Extensions/IOperationExtensions.cs Lines 884 to 888 in 7b1f39d
i.e. always populate the arguments in order |
@buyaa-n You mean when someone calls |
Yes, replacing with |
@buyaa-n Done. Unfortunately I still need the language-specific fixers, since |
OK, then |
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.
LGTM, thank you @CollinAlpert
This PR adds an analyzer which flags invocations to
Thread.VolatileRead
andThread.VolatileWrite
and a fixer which rewrites the calls toVolatile.Read
andVolatile.Write
respectively.Fixes dotnet/runtime#27997