-
Notifications
You must be signed in to change notification settings - Fork 1.7k
C#: Improve cs/missed-readonly-modifier
and to code-quality suite.
#19520
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
base: main
Are you sure you want to change the base?
Conversation
cs/missed-readonly-modifier
and to code-quality suite.
36998db
to
2c8fa06
Compare
2c8fa06
to
f1805b1
Compare
f1805b1
to
008d5b7
Compare
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 enhances the cs/missed-readonly-modifier
query to avoid changing semantics for mutable structs, eliminates additional false positives (non-public field assignments and static-field writes in instance constructors), and integrates the query into the code-quality suite.
- Exclude mutable struct types from readonly-modifier suggestions
- Refine detection to skip non-public argument-field assignments and static-field initializations
- Add the improved query to the
code-quality
suite and update tests
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunityBad.cs | Marked the bad-case field to trigger the new alert |
csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.qlref | Updated reference to include postprocessing for inline expectations |
csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.expected | Added new expected alerts for Bad3 , Left , and X fields |
csharp/ql/test/query-tests/Language Abuse/MissedReadonlyOpportunity/MissedReadonlyOpportunity.cs | Extended the test scenario with mutable/immutable structs, tree and static-fields cases |
csharp/ql/src/change-notes/2025-05-22-missed-readonly-modifier.md | Added changelog entry for the improved precision of the query |
csharp/ql/src/Language Abuse/MissedReadonlyOpportunity.ql | Updated the main QL predicate to exclude mutable structs and refine constructor checks |
csharp/ql/integration-tests/posix/query-suite/csharp-code-quality.qls.expected | Added MissedReadonlyOpportunity.ql to the code-quality suite |
--- | ||
category: minorAnalysis | ||
--- | ||
* The precision of the query `cs/missed-readonly-modifier` has been improved. Some false positives related to static fields and struct type fields have been removed. |
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.
[nitpick] Consider updating the changelog entry to also mention the fix for false positives when assigning non-public fields on arguments to give users a complete summary of all improvements.
* The precision of the query `cs/missed-readonly-modifier` has been improved. Some false positives related to static fields and struct type fields have been removed. | |
* The precision of the query `cs/missed-readonly-modifier` has been improved. Some false positives related to static fields, struct type fields, and assignments to non-public fields on arguments have been removed. |
Copilot uses AI. Check for mistakes.
predicate canBeReadonly(Field f) { | ||
exists(Type t | t = f.getType() | not t instanceof Struct or t.(Struct).isReadonly()) and |
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.
[nitpick] For clarity and to avoid any ambiguity around operator precedence, consider extracting the struct-check into a named predicate or adding explicit parentheses (e.g. (not t instanceof Struct) or t.(Struct).isReadonly()
) and document that this step excludes mutable structs.
predicate canBeReadonly(Field f) { | |
exists(Type t | t = f.getType() | not t instanceof Struct or t.(Struct).isReadonly()) and | |
/** | |
* Determines if a type is compatible with being readonly. | |
* A type is readonly-compatible if it is not a struct or if it is a readonly struct. | |
*/ | |
predicate isReadonlyCompatibleType(Type t) { | |
not t instanceof Struct or t.(Struct).isReadonly() | |
} | |
predicate canBeReadonly(Field f) { | |
exists(Type t | t = f.getType() | isReadonlyCompatibleType(t)) and |
Copilot uses AI. Check for mistakes.
In this PR we
cs/missed-readonly-modifier
. The reason is, that it can alter the semantics of the program for mutable structs. Example can be seen herecode-quality
suite.DCA looks good.