Add compiler support for UnconditionalSuppressMessage#51792
Add compiler support for UnconditionalSuppressMessage#51792agocke merged 5 commits intodotnet:mainfrom
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.
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.
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.
_lazyUnconditionalSuppressMessageAttribute [](start = 20, length = 42)
Is this assignment thread-safe? #Closed
There was a problem hiding this comment.
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.
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.
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). |
AlekseyTs
left a comment
There was a problem hiding this comment.
LGTM (commit 5), assuming CI is passing
|
Looks like there was an infra break -- I don't think these were caused by my changes. |
RikkiGibson
left a comment
There was a problem hiding this comment.
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.
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.
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 | ||
| || a.AttributeClass == this.UnconditionalSuppressMessageAttribute); | ||
| DecodeGlobalSuppressMessageAttributes(compilation, symbol, globalSuppressions, attributes); |
There was a problem hiding this comment.
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.
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.
(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).
|
@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 |
sharwell
left a comment
There was a problem hiding this comment.
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