Skip to content

Fix MA0002 code fix inserting StringComparer at wrong argument position - #1252

Merged
meziantou merged 1 commit into
mainfrom
meziantou-fix-ma0002-comparer-insertion-position
Jul 29, 2026
Merged

Fix MA0002 code fix inserting StringComparer at wrong argument position#1252
meziantou merged 1 commit into
mainfrom
meziantou-fix-ma0002-comparer-insertion-position

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Fixes #1249 and #1250.

Problem

The UseStringComparerFixer (MA0002) was always appending the StringComparer argument at the end of the argument list. This broke the build when the target overload has the comparer parameter before other parameters:

Fix

The fix follows the existing UseIFormatProviderFixer pattern:

  1. Find the target overload using OverloadFinder.FindOverloadWithAdditionalParameterOfType
  2. Compute insertion index via a new TryGetComparerParameterInfo helper that:
    • Strips the implicit this parameter from extension methods (so the index aligns with the actual argument list, not the full parameter list)
    • Returns both the index and the parameter name (for named-argument fallback)
  3. Insert positionally when index <= currentArgCount, or use a named argument when the comparer falls beyond the current args (handles optional-params-before-comparer edge case)

The key insight for #1250 (extension methods): IInvocationOperation.TargetMethod returns the non-reduced extension method (including this in its parameters), but the argument list doesn't include the receiver. The new GetComparableParameters helper always strips this from extension methods regardless of form (reduced or not), ensuring the insertion index maps correctly to the argument list position.

The UseStringComparerFixer was always appending the StringComparer argument
at the end of the argument list, breaking the build when the target overload
has the comparer parameter before other parameters (e.g., a message or a
CancellationToken).

Fixes:
- Issue #1249: Assert.AreEqual(expected, actual, message) would become
  AreEqual(expected, actual, message, StringComparer.Ordinal) instead of
  AreEqual(expected, actual, StringComparer.Ordinal, message).
- Issue #1250: Extension method calls where the comparer comes before other
  parameters (e.g., CancellationToken).

The fix follows the UseIFormatProviderFixer pattern:
1. Find the target overload via OverloadFinder.
2. Determine the correct insertion index via TryGetComparerParameterInfo,
   which strips the implicit 'this' parameter from extension methods so
   the index aligns with the actual argument list.
3. Insert positionally when index <= current arg count, or use a named
   argument when the comparer falls beyond the current args (optional params).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@meziantou
meziantou merged commit 745444c into main Jul 29, 2026
14 checks passed
@meziantou
meziantou deleted the meziantou-fix-ma0002-comparer-insertion-position branch July 29, 2026 08:11
This was referenced Jul 29, 2026
This was referenced Aug 6, 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.

MA0002 autofix breaks the build on Assert.AreEqual with 3 parameters

1 participant