55using System . Threading ;
66using System . Threading . Tasks ;
77using Microsoft . CodeAnalysis ;
8- using System . Collections . Generic ;
98using System . Collections . Immutable ;
109using Microsoft . CodeAnalysis . CSharp ;
1110using Microsoft . CodeAnalysis . CodeFixes ;
@@ -43,32 +42,28 @@ private async Task<Document> UseNamedArgumentAsync(Document document, ArgumentSy
4342 {
4443 var semanticModel = await document . GetSemanticModelAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
4544 var root = await document . GetSyntaxRootAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
46-
47- // First, process any nested invocations within this argument
48- var processedRoot = ProcessNestedInvocations ( root , argument , semanticModel ) ;
49-
50- // Then process the current argument
45+
5146 var argumentList = argument . Parent as ArgumentListSyntax ;
5247 if ( argumentList == null )
53- return document . WithSyntaxRoot ( processedRoot ) ;
54-
48+ return document . WithSyntaxRoot ( root ) ;
49+
5550 var invocation = argumentList . Parent ;
56-
51+
5752 // Handle both direct invocations and object creation expressions
58- if ( invocation == null ||
59- ! ( invocation is InvocationExpressionSyntax ||
53+ if ( invocation == null ||
54+ ! ( invocation is InvocationExpressionSyntax ||
6055 invocation is ObjectCreationExpressionSyntax ) )
6156 {
62- return document . WithSyntaxRoot ( processedRoot ) ;
57+ return document . WithSyntaxRoot ( root ) ;
6358 }
6459
65- // Find the corresponding argument in the processed root
66- var currentArgument = FindCorrespondingNode ( processedRoot , argument ) ;
60+ // Find the corresponding argument in the current root
61+ var currentArgument = FindCorrespondingNode ( root , argument ) ;
6762 if ( currentArgument == null )
68- return document . WithSyntaxRoot ( processedRoot ) ;
63+ return document . WithSyntaxRoot ( root ) ;
6964
7065 IMethodSymbol methodSymbol = null ;
71-
66+
7267 if ( invocation is InvocationExpressionSyntax invocationExpr )
7368 {
7469 methodSymbol = semanticModel . GetSymbolInfo ( invocationExpr ) . Symbol as IMethodSymbol ;
@@ -80,29 +75,38 @@ private async Task<Document> UseNamedArgumentAsync(Document document, ArgumentSy
8075
8176 if ( methodSymbol == null )
8277 {
83- return document . WithSyntaxRoot ( processedRoot ) ;
78+ return document . WithSyntaxRoot ( root ) ;
8479 }
8580
8681 int parameterIndex = argumentList . Arguments . IndexOf ( argument ) ;
8782 if ( parameterIndex >= methodSymbol . Parameters . Length )
8883 {
89- return document . WithSyntaxRoot ( processedRoot ) ;
84+ return document . WithSyntaxRoot ( root ) ;
9085 }
9186
9287 var parameter = methodSymbol . Parameters [ parameterIndex ] ;
9388
9489 if ( parameter == null )
9590 {
96- return document . WithSyntaxRoot ( processedRoot ) ;
91+ return document . WithSyntaxRoot ( root ) ;
9792 }
9893
99- // Create a new argument node with a NameColon
94+ // Preserve the original trivia (whitespace, indentation, etc.)
95+ SyntaxTriviaList leadingTrivia = currentArgument . GetLeadingTrivia ( ) ;
96+ SyntaxTriviaList trailingTrivia = currentArgument . GetTrailingTrivia ( ) ;
97+
98+ // Create the name colon with no trivia - trivia will be applied to the entire argument
99+ var nameColon = SyntaxFactory . NameColon ( parameter . Name ) ;
100+
101+ // Create a new argument node with a NameColon, preserving original trivia
100102 var namedArgument = SyntaxFactory . Argument (
101- SyntaxFactory . NameColon ( parameter . Name ) ,
103+ nameColon ,
102104 currentArgument . RefOrOutKeyword ,
103- currentArgument . Expression ) ;
105+ currentArgument . Expression )
106+ . WithLeadingTrivia ( leadingTrivia )
107+ . WithTrailingTrivia ( trailingTrivia ) ;
104108
105- var newRoot = processedRoot . ReplaceNode ( currentArgument , namedArgument ) ;
109+ var newRoot = root . ReplaceNode ( currentArgument , namedArgument ) ;
106110
107111 return document . WithSyntaxRoot ( newRoot ) ;
108112 }
@@ -114,7 +118,7 @@ private ArgumentSyntax FindCorrespondingNode(SyntaxNode root, ArgumentSyntax ori
114118 var nodeAtSamePosition = root . FindNode ( originalNode . Span ) ;
115119 if ( nodeAtSamePosition is ArgumentSyntax arg )
116120 return arg ;
117-
121+
118122 // If location-based search failed, try finding by structure
119123 var parentList = originalNode . Parent as ArgumentListSyntax ;
120124 if ( parentList != null )
@@ -123,67 +127,15 @@ private ArgumentSyntax FindCorrespondingNode(SyntaxNode root, ArgumentSyntax ori
123127 var newParentList = root . DescendantNodes ( )
124128 . OfType < ArgumentListSyntax > ( )
125129 . FirstOrDefault ( a => a . Span . Contains ( parentList . Span ) ) ;
126-
130+
127131 if ( newParentList != null && index >= 0 && index < newParentList . Arguments . Count )
128132 return newParentList . Arguments [ index ] ;
129133 }
130-
131- return null ;
132- }
133134
134- // New method to process nested invocations
135- private SyntaxNode ProcessNestedInvocations ( SyntaxNode root , ArgumentSyntax argument , SemanticModel semanticModel )
136- {
137- // Find all nested invocations within this argument
138- var nestedInvocations = argument . DescendantNodes ( )
139- . OfType < InvocationExpressionSyntax > ( )
140- . ToList ( ) ;
141-
142- if ( nestedInvocations . Count == 0 )
143- return root ;
144-
145- // Process each nested invocation
146- return root . ReplaceNodes (
147- nestedInvocations ,
148- ( original , _ ) => ProcessNestedInvocation ( original , original , semanticModel ) ) ;
135+ return null ;
149136 }
150137
151- private SyntaxNode ProcessNestedInvocation ( SyntaxNode original , SyntaxNode rewritten , SemanticModel semanticModel )
152- {
153- var invocation = rewritten as InvocationExpressionSyntax ;
154- if ( invocation == null )
155- return rewritten ;
156-
157- var methodSymbol = semanticModel . GetSymbolInfo ( invocation ) . Symbol as IMethodSymbol ;
158- if ( methodSymbol == null )
159- return rewritten ;
160-
161- var argList = invocation . ArgumentList ;
162- var newArgs = new List < ArgumentSyntax > ( ) ;
163- bool changed = false ;
164-
165- for ( int i = 0 ; i < argList . Arguments . Count ; i ++ )
166- {
167- var arg = argList . Arguments [ i ] ;
168- if ( arg . NameColon == null && i < methodSymbol . Parameters . Length )
169- {
170- changed = true ;
171- newArgs . Add ( SyntaxFactory . Argument (
172- SyntaxFactory . NameColon ( methodSymbol . Parameters [ i ] . Name ) ,
173- arg . RefOrOutKeyword ,
174- arg . Expression ) ) ;
175- }
176- else
177- {
178- newArgs . Add ( arg ) ;
179- }
180- }
181-
182- if ( ! changed )
183- return rewritten ;
184-
185- return invocation . WithArgumentList (
186- SyntaxFactory . ArgumentList ( SyntaxFactory . SeparatedList ( newArgs ) ) ) ;
187- }
188138 }
139+
140+
189141}
0 commit comments