@@ -52,13 +52,39 @@ extension FixIt {
5252
5353// MARK: - Make missing
5454
55+ private  extension  FixIt . Change  { 
56+   /// Transfers the leading and trailing trivia of `nodes` to the previous token
57+   /// While doing this, it tries to be smart, merging trivia where it makes sense
58+   /// and refusing to add e.g. a space after punctuation, where it usually
59+   /// doesn't make sense.
60+   static  func  transferTriviaAtSides( from nodes:  [ Syntax ] )  ->  Self ? { 
61+     guard  let  first =  nodes. first,  let  last =  nodes. last else  { 
62+       preconditionFailure ( ) 
63+     } 
64+     let  removedTriviaAtSides  =  first. leadingTrivia. mergingCommonSuffix ( last. trailingTrivia) 
65+     guard  !removedTriviaAtSides. isEmpty,  let  previousToken =  first. previousToken ( viewMode:  . sourceAccurate)  else  { 
66+       return  nil 
67+     } 
68+     let  mergedTrivia  =  previousToken. trailingTrivia. mergingCommonPrefix ( removedTriviaAtSides) 
69+     // We merge with the common prefix instead of the common suffix to preserve the original shape of the previous
70+     // token's trailing trivia after merging.
71+     guard  !previousToken. tokenKind. isPunctuation || !mergedTrivia. allSatisfy ( \. isSpaceOrTab)  else  { 
72+       // Punctuation is generally not followed by spaces in Swift.
73+       // If this action would only add spaces to the punctuation, drop it.
74+       // This generally yields better results.
75+       return  nil 
76+     } 
77+     return  . replaceTrailingTrivia( token:  previousToken,  newTrivia:  mergedTrivia) 
78+   } 
79+ } 
80+ 
5581extension  FixIt . MultiNodeChange  { 
56-   /// Replaced a present token with a missing node .
82+   /// Replaced a present token with a missing token .
5783  ///
5884  /// If `transferTrivia` is `true`, the leading and trailing trivia of the
59-   /// removed node  will be transferred to the trailing trivia of the previous token.
85+   /// removed token  will be transferred to the trailing trivia of the previous token.
6086  static  func  makeMissing( _ token:  TokenSyntax ,  transferTrivia:  Bool  =  true )  ->  Self  { 
61-     return   makeMissing ( [ token] ,  transferTrivia:  transferTrivia) 
87+     self . makeMissing ( [ token] ,  transferTrivia:  transferTrivia) 
6288  } 
6389
6490  /// Replace present tokens with missing tokens.
@@ -68,57 +94,42 @@ extension FixIt.MultiNodeChange {
6894  /// tokens.
6995  static  func  makeMissing( _ tokens:  [ TokenSyntax ] ,  transferTrivia:  Bool  =  true )  ->  Self  { 
7096    precondition ( tokens. allSatisfy ( \. isPresent) ) 
71-     return  . makeMissing( tokens. map ( Syntax . init) ,  transferTrivia:  transferTrivia) 
97+     return  self . makeMissing ( tokens. map ( Syntax . init) ,  transferTrivia:  transferTrivia) 
7298  } 
7399
74100  /// If `transferTrivia` is `true`, the leading and trailing trivia of the
75101  /// removed node will be transferred to the trailing trivia of the previous token.
76102  static  func  makeMissing( _ node:  ( some  SyntaxProtocol ) ? ,  transferTrivia:  Bool  =  true )  ->  Self  { 
77-     guard  let  node =  node  else  { 
103+     guard  let  node else  { 
78104      return  FixIt . MultiNodeChange ( primitiveChanges:  [ ] ) 
79105    } 
80-     var  changes  =  [ FixIt . Change. replace ( oldNode:  Syntax ( node) ,  newNode:  MissingMaker ( ) . rewrite ( node,  detach:  true ) ) ] 
81-     if  transferTrivia { 
82-       changes +=  FixIt . MultiNodeChange. transferTriviaAtSides ( from:  [ node] ) . primitiveChanges
83-     } 
84-     return  FixIt . MultiNodeChange ( primitiveChanges:  changes) 
106+     return  self . makeMissing ( [ node] ,  transferTrivia:  transferTrivia) 
85107  } 
86108
87-   /// Transfers the leading and trailing trivia of `nodes` to the previous token
88-   /// While doing this, it tries to be smart, merging trivia where it makes sense
89-   /// and refusing to add e.g. a space after punctuation, where it usually
90-   /// doesn't make sense.
91-   private  static  func  transferTriviaAtSides( from nodes:  [ some  SyntaxProtocol ] )  ->  Self  { 
92-     let  removedTriviaAtSides  =  ( nodes. first? . leadingTrivia ??  [ ] ) . merging ( nodes. last? . trailingTrivia ??  [ ] ) 
93-     if  !removedTriviaAtSides. isEmpty,  let  previousToken =  nodes. first? . previousToken ( viewMode:  . sourceAccurate)  { 
94-       let  mergedTrivia  =  previousToken. trailingTrivia. merging ( removedTriviaAtSides) 
95-       if  previousToken. tokenKind. isPunctuation,  mergedTrivia. allSatisfy ( {  $0. isSpaceOrTab } )  { 
96-         // Punctuation is generally not followed by spaces in Swift.
97-         // If this action would only add spaces to the punctuation, drop it.
98-         // This generally yields better results.
99-         return  FixIt . MultiNodeChange ( ) 
100-       } 
101-       return  FixIt . MultiNodeChange ( . replaceTrailingTrivia( token:  previousToken,  newTrivia:  mergedTrivia) ) 
102-     }  else  { 
103-       return  FixIt . MultiNodeChange ( ) 
104-     } 
109+   /// Replace present nodes with missing nodes.
110+   ///
111+   /// If `transferTrivia` is `true`, the leading trivia of the first node and
112+   /// the trailing trivia of the last node will be transferred to their adjecent
113+   /// tokens.
114+   static  func  makeMissing( _ nodes:  [ some  SyntaxProtocol ] ,  transferTrivia:  Bool  =  true )  ->  Self  { 
115+     self . makeMissing ( nodes. map ( Syntax . init) ,  transferTrivia:  transferTrivia) 
105116  } 
106117
107118  /// Replace present nodes with their missing equivalents.
108119  ///
109120  /// If `transferTrivia` is `true`, the leading trivia of the first node and
110121  /// the trailing trivia of the last node will be transferred to their adjecent
111122  /// tokens.
112-   static  func  makeMissing( _ nodes:  [ Syntax ] ,  transferTrivia:  Bool  =  true )  ->  Self  { 
123+   private   static  func  makeMissing( _ nodes:  [ Syntax ] ,  transferTrivia:  Bool  =  true )  ->  Self  { 
113124    precondition ( !nodes. isEmpty) 
114125    var  changes  =  nodes. map  { 
115126      FixIt . Change. replace ( 
116127        oldNode:  $0, 
117128        newNode:  MissingMaker ( ) . rewrite ( $0,  detach:  true ) 
118129      ) 
119130    } 
120-     if  transferTrivia { 
121-       changes  +=   FixIt . MultiNodeChange . transferTriviaAtSides ( from :  nodes ) . primitiveChanges 
131+     if  transferTrivia,   let  transferredTrivia  =   FixIt . Change . transferTriviaAtSides ( from :  nodes )  { 
132+       changes. append ( transferredTrivia ) 
122133    } 
123134    return  FixIt . MultiNodeChange ( primitiveChanges:  changes) 
124135  } 
0 commit comments