Match the MA0110 regex arguments by parameter instead of position - #1439
Merged
Merged
Conversation
Roslyn lists the arguments of an operation in evaluation order, so
reordered named arguments do not line up with the parameters. The
analyzer recorded fixed indices for the pattern, the options and the
match timeout, and the code fixer removed and lifted the arguments at
those indices, so `Regex.IsMatch(pattern: "a", input: "b")` was
converted to `MyRegex.IsMatch(pattern: "a")` with a `[GeneratedRegex("b")]`
attribute: the pattern was wrong and the generated call did not compile.
The analyzer now locates the pattern, the options and the match timeout
from `IArgumentOperation.Parameter`, and reports the resolved indices.
The constant check applies to those three arguments instead of relying
on their position, and an overload with an unknown parameter is no
longer reported, as the code fixer would silently drop the argument.
The code fixer keeps the surviving arguments in their source order with
their name colons, and validates the symbols, the operation and the
reported indices before registering the code actions.
meziantou
deleted the
feature/regex-conversion-argument-matching-2d263b
branch
September 8, 2026 16:08
This was referenced Sep 8, 2026
Merged
Closed
Closed
Closed
Closed
Bump Meziantou.Analyzer from 3.0.139 to 3.0.231
Analogy-LogViewer/Analogy.LogViewer.NLog.Targets#566
Closed
This was referenced Sep 16, 2026
Bump Meziantou.Analyzer from 3.0.139 to 3.0.259
Analogy-LogViewer/Analogy.LogViewer.NLog.Targets#574
Open
Open
Bump Meziantou.Analyzer from 3.0.139 to 3.0.259
Analogy-LogViewer/Analogy.AspNetCore.LogProvider#557
Open
Open
Open
Open
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Roslyn lists the arguments of an operation in evaluation order, so explicitly reordered named arguments do not line up with the parameters.
UseRegexSourceGeneratorAnalyzernevertheless recorded fixed indices for the pattern, the options and the match timeout, andUseRegexSourceGeneratorFixerremoved and lifted the arguments at those indices.For this valid input:
the fix produced:
The pattern was taken from the wrong argument, and the generated call does not compile (CS1501) even after the real Regex source generator runs. The constructor and every supported static
Regexmethod shared the same positional assumption. The analyzer's constant check was positional too, so it validatedinputinstead ofpattern.What changed
UseRegexSourceGeneratorAnalyzerIArgumentOperation.Parameter(pattern,options,matchTimeout) instead of a hardcoded position, and the resolved indices are what the diagnostic properties carry.Replace) loops.input,replacement,evaluator) is no longer reported: the code fixer would otherwise silently drop that argument.IsMatch/Match/Matches/SplitandReplacebranches collapse into a single path, as parameter identity makes the per-method shapes irrelevant.UseRegexSourceGeneratorFixerGetRemainingArgumentSyntaxeshelper used by both the type-declaration and the top-level-statement paths. It keeps the surviving arguments in their source (evaluation) order with theirname:colons intact, so the evaluation order of the runtime arguments is preserved.RegisterCodeFixesAsyncvalidates the semantic model, theRegex/GeneratedRegexAttribute/RegexOptionssymbols, the operation kind and the reported indices before registering either code action, following the fixer convention inAGENTS.md. Index lookups are bounds checked.No name translation is needed when switching from the static to the instance overload: the two sets of parameters use identical names (
input,replacement,evaluator). The tests compile the fixed code with the real source generator, so any mismatch would surface as CS1501.Tests
Six tests added to
UseRegexSourceGeneratorAnalyzerTests:RegexIsMatch_NamedArgumentsInReverseOrder(the reported case, partial method)RegexIsMatch_NamedArgumentsInReverseOrder_PartialProperty(the reported case, partial property)RegexIsMatch_Options_Timeout_NamedArgumentsInReverseOrder(all four arguments reversed)RegexReplace_NamedArgumentsInReverseOrderNewRegex_Options_Timeout_NamedArgumentsInReverseOrder(constructor)RegexIsMatch_NonConstantPatternPassedAsNamedArgument(no diagnostic; previously the positional check looked atinput)Verification
dotnet build— succeeded, 0 warnings.dotnet test tests/Meziantou.Analyzer.Test/Meziantou.Analyzer.Test.roslyn5.9.csproj— 4186/4186 passing.dotnet run --project src/DocumentationGenerator— exit code 0, no markdown changes (no rule metadata changed).