-
Notifications
You must be signed in to change notification settings - Fork 458
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
Fix concurrency issue in CA1069 analyzer #5243
Conversation
Codecov Report
@@ Coverage Diff @@
## main #5243 +/- ##
=======================================
Coverage 95.58% 95.58%
=======================================
Files 1200 1200
Lines 276283 276350 +67
Branches 16623 16632 +9
=======================================
+ Hits 264078 264147 +69
+ Misses 10019 10017 -2
Partials 2186 2186 |
There was another PR attempting to fix the same issue #5170. |
{ | ||
Value1 = 1, | ||
Value2 = Value1, | ||
Value3 = Value2, |
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.
This is a behavior change. The idea here is that if you are going to explicitly include a duplicate, its initializer should reference the same "original". To fix this code the user should change Value3 = Value2
to Value3 = Value1
. I felt like this was in the spirit of the docs but I'm also fine with changing the behavior back so this test produces no diagnostics.
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 makes sense here, but might not for bitwise enums. I'll try to find an example.
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.
Consider MethodAttributes for example. The members PrivateScope
and ReuseSlot
have the same value; if another member were added to the end with the intended value Family | ReuseSlot
, it would be annoying to have a warning appearing saying you need to put Family | PrivateScope
instead (which is technically the same value, but clearly less meaningful).
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.
Have added a test for this scenario in 37d8ae9. It appears the diagnostics given have not changed from before this PR.
...ore/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EnumShouldNotHaveDuplicatedValues.cs
Outdated
Show resolved
Hide resolved
{ | ||
Value1 = null | ||
}", | ||
DiagnosticResult.CompilerError("CS0037").WithSpan(4, 14, 4, 18).WithArguments("int")); |
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.
💡 For this case I would normally just use markup syntax {|CS0037:...|}
since it's an expected part of the input.
Fixes #3871
I ended up revising the way this works pretty heavily.
Initially I tried to fix this by gathering up all the initializer operations into a
ConcurrentDictionary<IFieldSymbol, IFieldInitializerOperation>
, then enumerating the enum members at the end and looking up the initializers.It occurred to me that most enum values are probably not duplicates, though, and it would probably take less memory and fewer modifications on concurrent collections by instead using:
membersByValue
dictionary which is populated single-threaded and read concurrentlyduplicates
set which is read and written concurrently@jmarolf @sharwell