-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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 compiler support for UnconditionalSuppressMessage #51792
Conversation
src/Compilers/Core/CodeAnalysisTest/Diagnostics/SuppressMessageAttributeCompilerTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/Core/CodeAnalysisTest/Diagnostics/SuppressMessageAttributeCompilerTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/Core/Portable/DiagnosticAnalyzer/SuppressMessageAttributeState.cs
Outdated
Show resolved
Hide resolved
src/Compilers/Core/Portable/DiagnosticAnalyzer/SuppressMessageAttributeState.cs
Outdated
Show resolved
Hide resolved
public string Justification { get; set; } | ||
} | ||
}"; | ||
var mscorlibRef = new[] { TestBase.MscorlibRef }; |
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.
TestBase.MscorlibRef [](start = 38, length = 20)
How do we know this is the right version to use? #Closed
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 should be OK regardless: all 4.x+ corlibs should be unified, and I'm only using AttributeUsage, Attribute, and string. Those should always be present.
I looked at trying to find the references used by the workspaces layer, but the TestWorkspace was confusing and I couldn't figure out a good way to keep them in-sync.
src/EditorFeatures/Test/Diagnostics/SuppressMessageAttributeWorkspaceTests.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Test/Diagnostics/SuppressMessageAttributeWorkspaceTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/Core/CodeAnalysisTest/Diagnostics/SuppressMessageAttributeCompilerTests.cs
Outdated
Show resolved
Hide resolved
src/Compilers/Core/Portable/DiagnosticAnalyzer/SuppressMessageAttributeState.cs
Outdated
Show resolved
Hide resolved
src/Compilers/Core/Portable/DiagnosticAnalyzer/SuppressMessageAttributeState.cs
Outdated
Show resolved
Hide resolved
{ | ||
if (!_lazyUnconditionalSuppressMessageAttribute.HasValue) | ||
{ | ||
_lazyUnconditionalSuppressMessageAttribute = new(_compilation.GetTypeByMetadataName("System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute")); |
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.
_lazyUnconditionalSuppressMessageAttribute [](start = 20, length = 42)
Is this assignment thread-safe? #Closed
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 so, in the specific way I was using it -- but rather than guess I just changed it to something I'm certain is safe.
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 so, in the specific way I was using it
It looks like Optional is a struct with several fields, the assignment is not guaranteed to be atomic. What am I missing?
In reply to: 597090036 [](ancestors = 597090036)
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.
You're right, I the previous version wasn't thread safe. The path would be:
Thread 1:
_field.HasValue is false
retrieve Type
_field.HasValue <- true
--- interrupted here
Thread 2 (continuing at interruption):
_field.HasValue is true
return value is null (not correct)
src/Compilers/Core/Portable/DiagnosticAnalyzer/SuppressMessageAttributeState.cs
Outdated
Show resolved
Hide resolved
Done with review pass (commit 4) #Closed |
/azp run |
Azure Pipelines successfully started running 3 pipeline(s). |
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 (commit 5), assuming CI is passing
Looks like there was an infra break -- I don't think these were caused by my changes. |
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.
Looks good, just had a few small questions.
Is @dotnet/roslyn-ide sign-off needed for the EditorFeatures test changes?
private ISymbol? UnconditionalSuppressMessageAttribute | ||
{ | ||
get | ||
{ |
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.
Just checking my understanding: is the purpose of this StrongBox just to allow us to distinguish these cases:
- _lazySuppressMessageAttribute is not initialized
- _lazySuppressMessageAttribute is initialized, and its value is null
- _lazySuppressMessageAttribute is initialized, and its value is non-null
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.
Correct, although we don't really need to care whether the value is null or non null, just whether or not it's initialized.
var attributes = symbol.GetAttributes().Where(a => a.AttributeClass == this.SuppressMessageAttribute); | ||
var attributes = symbol.GetAttributes().Where(a => | ||
a.AttributeClass == this.SuppressMessageAttribute | ||
|| a.AttributeClass == this.UnconditionalSuppressMessageAttribute); | ||
DecodeGlobalSuppressMessageAttributes(compilation, symbol, globalSuppressions, attributes); |
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 this be called with an argument with a null AttributeClass
? I'm wondering if this API could give strange answers in the event that either SuppressMessageAttribute or UnconditionalSuppressMessageAttribute is null, and a.AttributeClass
is null.
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.
Heh, yeah I suppose that's possible. I think that's an existing bug. I'd rather not hold up the PR for it if you don't mind, but I can file a bug about it.
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 don't think it semantically matters because the diagnostic is only suppressed if the ID's match, but if the attribute doesn't exist, we won't be able to fetch the ID and they will never match).
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.
Filed #51972
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.
Sounds good.
@sharwell Anything else? I'd like to get this in for Preview 3 (snaps tomorrow) |
Send me a message tomorrow on teams so I don't miss it |
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.
Looks fine with the understanding that this will break for cases where a dependency declares a second copy of the attribute as internal
(even if there is no IVT access to it).
Are we good to merge this? @agocke do you have a preference for squash merge or merge commit? |
Squashed, thanks for the quick review everyone! |
Fixes #48885