Skip to content

Fix MA0158 code fix when the field is assigned in another document - #1478

Merged
meziantou merged 2 commits into
mainfrom
feature/inspiring-northcutt-e87459
Sep 12, 2026
Merged

meziantou merged 2 commits into
mainfrom
feature/inspiring-northcutt-e87459

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Problem

The MA0158 code fix changes the type of a field from object to System.Threading.Lock, then rewrites the new object() assignments of that field to new(). It only looked for those assignments in the document declaring the field, as it iterated editor.OriginalRoot.DescendantNodes().OfType<AssignmentExpressionSyntax>().

When the field was assigned in another document, the assignment was left unchanged and the fixed code failed with CS0029. Two cases:

  • a partial class whose constructor in another file does _lock = new object();
  • a private protected field assigned in a derived class in another file

Changes

The code fix is now solution wide:

  • It returns a Solution and uses a SolutionEditor. The references of the field are found with SymbolFinder.FindReferencesAsync, so the assignments are rewritten in every document of the solution.
  • A reference is rewritten only when it is the left side of an assignment (_lock or this._lock) and the right side creates a plain object. These are the same conditions as before, just no longer limited to one document.
  • Source generated documents are skipped, as they cannot be edited.
  • The declared symbol resolved in RegisterCodeFixesAsync is passed to the fix, so the fix no longer re-validates anything and can no longer return an unchanged document, per the "validate before registering" guidance of AGENTS.md.

Two regression tests with multiple documents cover the two cases above, the second one using this._lock to also cover a member access.

Notes for the reviewer

  • Both new tests fail against the previous code fix and pass with this change.
  • All 24 tests of the class pass on Roslyn 4.8, 4.14, 5.0, 5.6 and 5.9.
  • dotnet run --project src/DocumentationGenerator reports no change. docs/Rules/MA0158.md does not document how far the code fix reaches, so it needed no update.
  • One pre-existing gap is left out of scope, as it happens within a single document too: when the field is assigned something that is not a new object() (for example _lock = GetObject();), the code fix still changes the type and leaves that assignment failing to compile.

The code fix changes the type of the field from object to System.Threading.Lock
and rewrites the `new object()` assignments to `new()`, but it only looked for
assignments in the document declaring the field. When the field was assigned in
another document, such as another part of a partial class or a derived class,
the assignment was left unchanged and the fixed code failed with CS0029.

The fix now finds the references of the field with SymbolFinder and rewrites
the assignments in every document of the solution.
…thcutt-e87459

# Conflicts:
#	tests/Meziantou.Analyzer.Test/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzerTests.cs
@meziantou
meziantou merged commit db139d3 into main Sep 12, 2026
13 checks passed
@meziantou
meziantou deleted the feature/inspiring-northcutt-e87459 branch September 12, 2026 03:07
This was referenced Sep 12, 2026
This was referenced Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant