@@ -29,19 +29,12 @@ public sealed class CSharpAvoidRedundantRegexIsMatchBeforeMatchFixer : CodeFixPr
2929
3030 public sealed override async Task RegisterCodeFixesAsync ( CodeFixContext context )
3131 {
32- var root = await context . Document . GetSyntaxRootAsync ( context . CancellationToken ) . ConfigureAwait ( false ) ;
33- if ( root is null )
32+ if ( await context . Document . GetSyntaxRootAsync ( context . CancellationToken ) . ConfigureAwait ( false ) is not { } root ||
33+ await context . Document . GetSemanticModelAsync ( context . CancellationToken ) . ConfigureAwait ( false ) is not { } semanticModel )
3434 {
3535 return ;
3636 }
3737
38- var semanticModel = await context . Document . GetSemanticModelAsync ( context . CancellationToken ) . ConfigureAwait ( false ) ;
39- if ( semanticModel is null )
40- {
41- return ;
42- }
43-
44- var diagnostic = context . Diagnostics [ 0 ] ;
4538 var node = root . FindNode ( context . Span , getInnermostNodeForTie : true ) ;
4639
4740 if ( node is not InvocationExpressionSyntax isMatchInvocation )
@@ -61,7 +54,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
6154 NetCore . Analyzers . MicrosoftNetCoreAnalyzersResources . AvoidRedundantRegexIsMatchBeforeMatchFix ,
6255 ct => RemoveRedundantIsMatchAsync ( context . Document , root , ifStatement , isMatchInvocation , semanticModel , ct ) ,
6356 equivalenceKey : NetCore . Analyzers . MicrosoftNetCoreAnalyzersResources . AvoidRedundantRegexIsMatchBeforeMatchFix ) ,
64- diagnostic ) ;
57+ context . Diagnostics [ 0 ] ) ;
6558 }
6659
6760 private static async Task < Document > RemoveRedundantIsMatchAsync (
@@ -74,77 +67,55 @@ private static async Task<Document> RemoveRedundantIsMatchAsync(
7467 {
7568 var editor = await DocumentEditor . CreateAsync ( document , cancellationToken ) . ConfigureAwait ( false ) ;
7669
77- // Determine if this is a negated pattern (if (!IsMatch) { return; })
78- bool isNegated = ifStatement . Condition is PrefixUnaryExpressionSyntax { RawKind : ( int ) SyntaxKind . LogicalNotExpression } ;
79-
80- if ( isNegated && IsEarlyReturnPattern ( ifStatement ) )
70+ // Find the Match call in the body and use it to replace the condition
71+ var matchCall = FindMatchCallInBlock ( ifStatement . Statement , isMatchInvocation , semanticModel ) ;
72+
73+ if ( matchCall is not null )
8174 {
82- // For inverted early return pattern: remove the entire if statement
83- editor . RemoveNode ( ifStatement ) ;
84- }
85- else
86- {
87- // For normal pattern: transform the if statement
88- // Find the Match call in the body and use it to replace the condition
89- var matchCall = FindMatchCallInBlock ( ifStatement . Statement , isMatchInvocation , semanticModel ) ;
75+ // Create the new condition: Regex.Match(...) is { Success: true } variableName
76+ var matchDeclaration = matchCall . Parent ? . Parent as LocalDeclarationStatementSyntax ;
9077
91- if ( matchCall is not null )
78+ if ( matchDeclaration is not null )
9279 {
93- // Create the new condition: Regex.Match(...) is { Success: true } variableName
94- var matchDeclaration = matchCall . Parent ? . Parent as LocalDeclarationStatementSyntax ;
95-
96- if ( matchDeclaration is not null )
80+ var variableDeclarator = matchDeclaration . Declaration . Variables . First ( ) ;
81+ var variableName = variableDeclarator . Identifier . Text ;
82+
83+ // Create pattern: is { Success: true }
84+ var successPattern = SyntaxFactory . RecursivePattern ( )
85+ . WithPropertyPatternClause (
86+ SyntaxFactory . PropertyPatternClause (
87+ SyntaxFactory . SingletonSeparatedList < SubpatternSyntax > (
88+ SyntaxFactory . Subpattern (
89+ SyntaxFactory . NameColon ( "Success" ) ,
90+ SyntaxFactory . ConstantPattern (
91+ SyntaxFactory . LiteralExpression ( SyntaxKind . TrueLiteralExpression ) ) ) ) ) )
92+ . WithDesignation ( SyntaxFactory . SingleVariableDesignation ( SyntaxFactory . Identifier ( variableName ) ) ) ;
93+
94+ var newCondition = SyntaxFactory . IsPatternExpression (
95+ matchCall ,
96+ successPattern ) ;
97+
98+ // Remove the Match declaration from the body
99+ var newBody = ifStatement . Statement ;
100+ if ( ifStatement . Statement is BlockSyntax block )
97101 {
98- var variableDeclarator = matchDeclaration . Declaration . Variables . First ( ) ;
99- var variableName = variableDeclarator . Identifier . Text ;
100-
101- // Create pattern: is { Success: true }
102- var successPattern = SyntaxFactory . RecursivePattern ( )
103- . WithPropertyPatternClause (
104- SyntaxFactory . PropertyPatternClause (
105- SyntaxFactory . SingletonSeparatedList < SubpatternSyntax > (
106- SyntaxFactory . Subpattern (
107- SyntaxFactory . NameColon ( "Success" ) ,
108- SyntaxFactory . ConstantPattern (
109- SyntaxFactory . LiteralExpression ( SyntaxKind . TrueLiteralExpression ) ) ) ) ) )
110- . WithDesignation ( SyntaxFactory . SingleVariableDesignation ( SyntaxFactory . Identifier ( variableName ) ) ) ;
111-
112- var newCondition = SyntaxFactory . IsPatternExpression (
113- matchCall ,
114- successPattern ) ;
115-
116- // Remove the Match declaration from the body
117- var newBody = ifStatement . Statement ;
118- if ( ifStatement . Statement is BlockSyntax block )
119- {
120- var statements = block . Statements . Where ( s => s != matchDeclaration ) ;
121- newBody = block . WithStatements ( SyntaxFactory . List ( statements ) ) ;
122- }
102+ var statements = block . Statements . Where ( s => s != matchDeclaration ) ;
103+ newBody = block . WithStatements ( SyntaxFactory . List ( statements ) ) ;
104+ }
123105
124- // Create new if statement
125- var newIfStatement = ifStatement
126- . WithCondition ( newCondition . WithTriviaFrom ( ifStatement . Condition ) )
127- . WithStatement ( newBody )
128- . WithAdditionalAnnotations ( Formatter . Annotation ) ;
106+ // Create new if statement
107+ var newIfStatement = ifStatement
108+ . WithCondition ( newCondition . WithTriviaFrom ( ifStatement . Condition ) )
109+ . WithStatement ( newBody )
110+ . WithAdditionalAnnotations ( Formatter . Annotation ) ;
129111
130- editor . ReplaceNode ( ifStatement , newIfStatement ) ;
131- }
112+ editor . ReplaceNode ( ifStatement , newIfStatement ) ;
132113 }
133114 }
134115
135116 return editor . GetChangedDocument ( ) ;
136117 }
137118
138- private static bool IsEarlyReturnPattern ( IfStatementSyntax ifStatement )
139- {
140- if ( ifStatement . Statement is BlockSyntax block )
141- {
142- return block . Statements . Any ( s => s is ReturnStatementSyntax or ThrowStatementSyntax or BreakStatementSyntax or ContinueStatementSyntax ) ;
143- }
144-
145- return ifStatement . Statement is ReturnStatementSyntax or ThrowStatementSyntax or BreakStatementSyntax or ContinueStatementSyntax ;
146- }
147-
148119 private static InvocationExpressionSyntax ? FindMatchCallInBlock ( StatementSyntax statement , InvocationExpressionSyntax isMatchInvocation , SemanticModel semanticModel )
149120 {
150121 if ( statement is not BlockSyntax block )
0 commit comments