Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
Loading
from

Conversation

michaelnebel
Copy link
Contributor

@michaelnebel michaelnebel commented May 19, 2025

In this PR we

  • Exclude potentially mutable struct types from being flagged by cs/missed-readonly-modifier. The reason is, that it can alter the semantics of the program for mutable structs. Example can be seen here
  • Fix false positive related to assigning non-public fields on arguments (if assigning on other instance of same type).
  • Fix false positive of assigning a static field from an instance constructor.
  • Add the query to the code-quality suite.

DCA looks good.

@github-actions github-actions bot added the C# label May 19, 2025
@michaelnebel michaelnebel changed the title C#: Improve cs/missed-readonly-modifier and to code-quality suite. C#: Improve cs/missed-readonly-modifier and to code-quality suite. May 19, 2025
@michaelnebel michaelnebel force-pushed the csharp/missedreadonly branch from 36998db to 2c8fa06 Compare May 20, 2025 12:40
@michaelnebel michaelnebel force-pushed the csharp/missedreadonly branch from 2c8fa06 to f1805b1 Compare May 21, 2025 12:32
@michaelnebel michaelnebel force-pushed the csharp/missedreadonly branch from f1805b1 to 008d5b7 Compare May 21, 2025 13:20
@michaelnebel michaelnebel marked this pull request as ready for review May 22, 2025 07:11
@Copilot Copilot AI review requested due to automatic review settings May 22, 2025 07:11
@michaelnebel michaelnebel requested a review from a team as a code owner May 22, 2025 07:11
Copy link
Contributor

@Copilot Copilot AI left a 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.
Copy link
Preview

Copilot AI May 22, 2025

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.

Suggested change
* 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.

Positive FeedbackNegative Feedback
Comment on lines 32 to +33
predicate canBeReadonly(Field f) {
exists(Type t | t = f.getType() | not t instanceof Struct or t.(Struct).isReadonly()) and
Copy link
Preview

Copilot AI May 22, 2025

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.

Suggested change
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.

Positive FeedbackNegative Feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
Morty Proxy This is a proxified and sanitized view of the page, visit original site.