-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Fix CA1869 false positive in top-level statements #51468
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
Conversation
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
...lyzers/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.CodeAnalysis.NetAnalyzers/src/RulesMissingDocumentation.md
Show resolved
Hide resolved
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.
Pull Request Overview
This PR fixes a false positive in CA1869 where the analyzer incorrectly warns about caching JsonSerializerOptions instances in top-level statements, which execute only once at program startup and therefore gain no benefit from caching.
Key changes:
- Modified the analyzer to skip diagnostics when code is within a top-level statements entry point method
- Added comprehensive test coverage for top-level statements scenarios
- Updated imports ordering in the analyzer file
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| AvoidSingleUseOfLocalJsonSerializerOptions.cs | Added logic to detect and skip top-level statements entry point methods; reorganized using directives |
| AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs | Added three test cases covering different patterns of JsonSerializerOptions usage in top-level statements |
| RulesMissingDocumentation.md | Removed documentation entries for unrelated analyzer rules |
| .git-blame-ignore-revs | Added commit SHA for the formatting change to exclude from git blame |
src/Microsoft.CodeAnalysis.NetAnalyzers/src/RulesMissingDocumentation.md
Show resolved
Hide resolved
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
|
/ba-g dead letter |
eiriktsarpalis
left a comment
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.
Thanks. I realize we're a bit late, but any chance we could try backporting this to 10 e.g. via servicing?
You can if you'd like. |
Paging @jeffhandley and @ericstj for a second opinion. This does not meet the bar for servicing by any measure, but it's a known quality of life issue that shows itself when using top-level statements in demo apps. |
|
This analyzer is shipped in the SDK, so you have more ship vehicles available. It could ship in 10.0.200 for example without any process churn, and backports for 10.0.200 are wide open with no bar aside from normal development checks, breaking change notifications, and so on. |
|
Awesome! What branch should I be targeting for a backport? |
|
release/10.0.2xx is the branch for that. In the SDK there are almost always two 'live' branches:
Codeflow is set up so that if you merge into the next feature band release your work will flow to main, so most folks working on the SDK will target the feature band release by default, unless the change is so impactful to only be safe for the next major, or if it requires other next-major-only features to light up. |
|
/backport to release/10.0.2xx |
|
Started backporting to |
Fix CA1869 false positive in top-level statements
Summary
This PR fixes CA1869 (AvoidSingleUseOfLocalJsonSerializerOptions) to not report false positives in top-level statements. The analyzer was incorrectly warning about single-use JsonSerializerOptions in top-level programs, where the code only executes once at startup and caching is less impactful.
Changes Made
Analyzer Fix: Added detection in
AvoidSingleUseOfLocalJsonSerializerOptions.csto check if the containing method is a top-level statements entry point usingIsTopLevelStatementsEntryPointMethod()Test Coverage: Added three test cases covering different top-level statement scenarios:
Code Quality: Formatted code according to repository standards
All 78 tests pass (75 existing + 3 new).
Original prompt
This section details on the original issue you should resolve
<issue_title>CA1869: "Cache and reuse 'JsonSerializerOptions' instances" - false positives in top-level programs</issue_title>
<issue_description>### Description
CA1869 is caused by a local instance of
JsonSerializerOptionsbeing created and used once as theoptionsargument of a Serialize or Deserialize call as this can cause performance degradation if the code is executed multiple times.I initially found this bug in a top-level program where there was only a single Deserialize call in the whole file, so I thought it was a little strange, but upon further investigation found that this bug extends to other situations.
Reproduction Steps
There are 3 versions, all very similar, but each with potentially different solutions.
Version 1 - Top-level program
Version 2 - In a class constructor:
Version 3 - In a loop inside a standard method:
Expected behavior
For version 1, I'm honestly not sure what should happen - maybe nothing, as the fix appears to make the code worse, not better.
For version 2, I could see the fixer creating a static variable to hold the options for use in each construction.
For version 3, I would hope the fixer would, at the very least, move the instance creation outside the loop, as duplicating it inside the loop doesn't improve the performance at all.
Actual behavior
After using the provided fixer, the following was produced:
Version 1 - Top-level program
Version 2 - In a class constructor:
Version 3 - In a loop inside a standard method:
Version 3 does also have an extra option, although after the one above, which alters the method to allow a
JsonSerializerOptionsinstance to be passed in as a parameter, which is much better.Regression?
The problem seems to also be in NET8, but not in NET7.
Known Workarounds
Ignore or suppress the rule.
Configuration
Using VS 17.13.0 Preview 4 in a NET9 console application, running on Windows 11 x64.
Other information
No response</issue_description>
<agent_instructions>Please check whether there are any unit tests for CA1869 in top-level statements. We do not want this analyzer to run in top-level statements. If it's issuing warnings, please fix it to not. Either way, ensure there's a test in place for this.</agent_instructions>
Comments on the Issue (you are @copilot in this section)
@eiriktsarpalis > After using the provided fixerI'm pretty sure the analyzer in question doesn't come with a fixer. Can you clarify which suggestion you applied that resulted in these changes? The recommendations I'm seeing are unrelated to the analyzer per se:
<comment_new>@eiriktsarpalis
It's unrelated. We intentionally didn'...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.