@@ -241,62 +241,69 @@ private static void ConvertToPartialProperty(
241241 SyntaxEditor syntaxEditor ,
242242 string ? defaultValueExpression )
243243 {
244- // Update the attribute to insert with the default value, if present
245- generatedDependencyPropertyAttributeList = UpdateGeneratedDependencyPropertyAttributeList (
246- document ,
247- semanticModel ,
248- generatedDependencyPropertyAttributeList ,
249- defaultValueExpression ) ;
244+ // Replace the property with the partial property using the attribute. Note that it's important to use the
245+ // lambda 'ReplaceNode' overload here, rather than creating a modifier property declaration syntax node and
246+ // replacing the original one. Doing that would cause the following 'ReplaceNode' call to adjust the leading
247+ // trivia of trailing members after the fields being removed to not work incorrectly, and fail to be resolved.
248+ syntaxEditor . ReplaceNode ( propertyDeclaration , ( node , _ ) =>
249+ {
250+ PropertyDeclarationSyntax propertyDeclaration = ( PropertyDeclarationSyntax ) node ;
250251
251- // Start setting up the updated attribute lists
252- SyntaxList < AttributeListSyntax > attributeLists = propertyDeclaration . AttributeLists ;
252+ // Update the attribute to insert with the default value, if present
253+ generatedDependencyPropertyAttributeList = UpdateGeneratedDependencyPropertyAttributeList (
254+ document ,
255+ semanticModel ,
256+ generatedDependencyPropertyAttributeList ,
257+ defaultValueExpression ) ;
253258
254- if ( attributeLists is [ AttributeListSyntax firstAttributeListSyntax , ..] )
255- {
256- // Remove the trivia from the original first attribute
257- attributeLists = attributeLists . Replace (
258- nodeInList : firstAttributeListSyntax ,
259- newNode : firstAttributeListSyntax . WithoutTrivia ( ) ) ;
259+ // Start setting up the updated attribute lists
260+ SyntaxList < AttributeListSyntax > attributeLists = propertyDeclaration . AttributeLists ;
260261
261- // If the property has at least an attribute list, move the trivia from it to the new attribute
262- generatedDependencyPropertyAttributeList = generatedDependencyPropertyAttributeList . WithTriviaFrom ( firstAttributeListSyntax ) ;
262+ if ( attributeLists is [ AttributeListSyntax firstAttributeListSyntax , ..] )
263+ {
264+ // Remove the trivia from the original first attribute
265+ attributeLists = attributeLists . Replace (
266+ nodeInList : firstAttributeListSyntax ,
267+ newNode : firstAttributeListSyntax . WithoutTrivia ( ) ) ;
263268
264- // Insert the new attribute
265- attributeLists = attributeLists . Insert ( 0 , generatedDependencyPropertyAttributeList ) ;
266- }
267- else
268- {
269- // Otherwise (there are no attribute lists), transfer the trivia to the new (only) attribute list
270- generatedDependencyPropertyAttributeList = generatedDependencyPropertyAttributeList . WithTriviaFrom ( propertyDeclaration ) ;
269+ // If the property has at least an attribute list, move the trivia from it to the new attribute
270+ generatedDependencyPropertyAttributeList = generatedDependencyPropertyAttributeList . WithTriviaFrom ( firstAttributeListSyntax ) ;
271271
272- // Save the new attribute list
273- attributeLists = attributeLists . Add ( generatedDependencyPropertyAttributeList ) ;
274- }
272+ // Insert the new attribute
273+ attributeLists = attributeLists . Insert ( 0 , generatedDependencyPropertyAttributeList ) ;
274+ }
275+ else
276+ {
277+ // Otherwise (there are no attribute lists), transfer the trivia to the new (only) attribute list
278+ generatedDependencyPropertyAttributeList = generatedDependencyPropertyAttributeList . WithTriviaFrom ( propertyDeclaration ) ;
275279
276- // Get a new property that is partial and with semicolon token accessors
277- PropertyDeclarationSyntax updatedPropertyDeclaration =
278- propertyDeclaration
279- . AddModifiers ( Token ( SyntaxKind . PartialKeyword ) )
280- . WithoutLeadingTrivia ( )
281- . WithAttributeLists ( attributeLists )
282- . WithAdditionalAnnotations ( Formatter . Annotation )
283- . WithAccessorList ( AccessorList ( List (
284- [
285- // Keep the accessors (so we can easily keep all trivia, modifiers, attributes, etc.) but make them semicolon only
286- propertyDeclaration . AccessorList ! . Accessors [ 0 ]
287- . WithBody ( null )
288- . WithExpressionBody ( null )
289- . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) )
290- . WithAdditionalAnnotations ( Formatter . Annotation ) ,
291- propertyDeclaration . AccessorList ! . Accessors [ 1 ]
292- . WithBody ( null )
293- . WithExpressionBody ( null )
294- . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) )
295- . WithTrailingTrivia ( propertyDeclaration . AccessorList . Accessors [ 1 ] . GetTrailingTrivia ( ) )
296- . WithAdditionalAnnotations ( Formatter . Annotation )
297- ] ) ) . WithTrailingTrivia ( propertyDeclaration . AccessorList . GetTrailingTrivia ( ) ) ) ;
280+ // Save the new attribute list
281+ attributeLists = attributeLists . Add ( generatedDependencyPropertyAttributeList ) ;
282+ }
298283
299- syntaxEditor . ReplaceNode ( propertyDeclaration , updatedPropertyDeclaration ) ;
284+ // Get a new property that is partial and with semicolon token accessors
285+ return
286+ propertyDeclaration
287+ . AddModifiers ( Token ( SyntaxKind . PartialKeyword ) )
288+ . WithoutLeadingTrivia ( )
289+ . WithAttributeLists ( attributeLists )
290+ . WithAdditionalAnnotations ( Formatter . Annotation )
291+ . WithAccessorList ( AccessorList ( List (
292+ [
293+ // Keep the accessors (so we can easily keep all trivia, modifiers, attributes, etc.) but make them semicolon only
294+ propertyDeclaration . AccessorList ! . Accessors [ 0 ]
295+ . WithBody ( null )
296+ . WithExpressionBody ( null )
297+ . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) )
298+ . WithAdditionalAnnotations ( Formatter . Annotation ) ,
299+ propertyDeclaration . AccessorList ! . Accessors [ 1 ]
300+ . WithBody ( null )
301+ . WithExpressionBody ( null )
302+ . WithSemicolonToken ( Token ( SyntaxKind . SemicolonToken ) )
303+ . WithTrailingTrivia ( propertyDeclaration . AccessorList . Accessors [ 1 ] . GetTrailingTrivia ( ) )
304+ . WithAdditionalAnnotations ( Formatter . Annotation )
305+ ] ) ) . WithTrailingTrivia ( propertyDeclaration . AccessorList . GetTrailingTrivia ( ) ) ) ;
306+ } ) ;
300307
301308 // Special handling for the leading trivia of members following the field declaration we are about to remove.
302309 // There is an edge case that can happen when a type declaration is as follows:
0 commit comments