@@ -28,17 +28,32 @@ namespace ts.textChanges {
2828 }
2929
3030 export interface ConfigurableStart {
31- /** True to use getStart() (NB, not getFullStart()) without adjustment. */
32- useNonAdjustedStartPosition ?: boolean ;
31+ startPosition ?: LeadingTriviaOption ;
3332 }
3433 export interface ConfigurableEnd {
3534 /** True to use getEnd() without adjustment. */
36- useNonAdjustedEndPosition ?: boolean ;
35+ endPosition ?: TrailingTriviaOption ;
3736 }
3837
39- export enum Position {
40- FullStart ,
41- Start
38+ export enum LeadingTriviaOption {
39+ /** Exclude all leading trivia (use getStart()) */
40+ Exclude ,
41+ /** Include leading trivia (default behavior) */
42+ Include ,
43+ /** Include leading trivia and,
44+ * if there are no line breaks between the node and the previous token,
45+ * include all trivia between the node and the previous token
46+ */
47+ IncludeAll ,
48+ }
49+
50+ export enum TrailingTriviaOption {
51+ /** Exclude all leading trivia (use getEnd()) */
52+ Exclude ,
53+ /** TODO (default behavior) */
54+ IncludeIfLineBreak ,
55+ /** Include trailing trivia */
56+ Include ,
4257 }
4358
4459 function skipWhitespacesAndLineBreaks ( text : string , start : number ) {
@@ -73,8 +88,8 @@ namespace ts.textChanges {
7388 export interface ConfigurableStartEnd extends ConfigurableStart , ConfigurableEnd { }
7489
7590 export const useNonAdjustedPositions : ConfigurableStartEnd = {
76- useNonAdjustedStartPosition : true ,
77- useNonAdjustedEndPosition : true ,
91+ startPosition : LeadingTriviaOption . Exclude ,
92+ endPosition : TrailingTriviaOption . Exclude ,
7893 } ;
7994
8095 export interface InsertNodeOptions {
@@ -143,11 +158,12 @@ namespace ts.textChanges {
143158 }
144159
145160 function getAdjustedRange ( sourceFile : SourceFile , startNode : Node , endNode : Node , options : ConfigurableStartEnd ) : TextRange {
146- return { pos : getAdjustedStartPosition ( sourceFile , startNode , options , Position . Start ) , end : getAdjustedEndPosition ( sourceFile , endNode , options ) } ;
161+ return { pos : getAdjustedStartPosition ( sourceFile , startNode , options ) , end : getAdjustedEndPosition ( sourceFile , endNode , options ) } ;
147162 }
148163
149- function getAdjustedStartPosition ( sourceFile : SourceFile , node : Node , options : ConfigurableStart , position : Position ) {
150- if ( options . useNonAdjustedStartPosition ) {
164+ function getAdjustedStartPosition ( sourceFile : SourceFile , node : Node , options : ConfigurableStart ) {
165+ const { startPosition } = options ;
166+ if ( startPosition === LeadingTriviaOption . Exclude ) {
151167 return node . getStart ( sourceFile ) ;
152168 }
153169 const fullStart = node . getFullStart ( ) ;
@@ -165,7 +181,7 @@ namespace ts.textChanges {
165181 // fullstart
166182 // when b is replaced - we usually want to keep the leading trvia
167183 // when b is deleted - we delete it
168- return position === Position . Start ? start : fullStart ;
184+ return startPosition === LeadingTriviaOption . IncludeAll ? fullStart : start ;
169185 }
170186 // get start position of the line following the line that contains fullstart position
171187 // (but only if the fullstart isn't the very beginning of the file)
@@ -178,11 +194,12 @@ namespace ts.textChanges {
178194
179195 function getAdjustedEndPosition ( sourceFile : SourceFile , node : Node , options : ConfigurableEnd ) {
180196 const { end } = node ;
181- if ( options . useNonAdjustedEndPosition || isExpression ( node ) ) {
197+ const { endPosition } = options ;
198+ if ( endPosition === TrailingTriviaOption . Exclude || isExpression ( node ) ) {
182199 return end ;
183200 }
184201 const newEnd = skipTrivia ( sourceFile . text , end , /*stopAfterLineBreak*/ true ) ;
185- return newEnd !== end && isLineBreak ( sourceFile . text . charCodeAt ( newEnd - 1 ) )
202+ return newEnd !== end && ( endPosition === TrailingTriviaOption . Include || isLineBreak ( sourceFile . text . charCodeAt ( newEnd - 1 ) ) )
186203 ? newEnd
187204 : end ;
188205 }
@@ -240,15 +257,15 @@ namespace ts.textChanges {
240257 this . deleteRange ( sourceFile , { pos : modifier . getStart ( sourceFile ) , end : skipTrivia ( sourceFile . text , modifier . end , /*stopAfterLineBreak*/ true ) } ) ;
241258 }
242259
243- public deleteNodeRange ( sourceFile : SourceFile , startNode : Node , endNode : Node , options : ConfigurableStartEnd = { } ) : void {
244- const startPosition = getAdjustedStartPosition ( sourceFile , startNode , options , Position . FullStart ) ;
260+ public deleteNodeRange ( sourceFile : SourceFile , startNode : Node , endNode : Node , options : ConfigurableStartEnd = { startPosition : LeadingTriviaOption . IncludeAll } ) : void {
261+ const startPosition = getAdjustedStartPosition ( sourceFile , startNode , options ) ;
245262 const endPosition = getAdjustedEndPosition ( sourceFile , endNode , options ) ;
246263 this . deleteRange ( sourceFile , { pos : startPosition , end : endPosition } ) ;
247264 }
248265
249- public deleteNodeRangeExcludingEnd ( sourceFile : SourceFile , startNode : Node , afterEndNode : Node | undefined , options : ConfigurableStartEnd = { } ) : void {
250- const startPosition = getAdjustedStartPosition ( sourceFile , startNode , options , Position . FullStart ) ;
251- const endPosition = afterEndNode === undefined ? sourceFile . text . length : getAdjustedStartPosition ( sourceFile , afterEndNode , options , Position . FullStart ) ;
266+ public deleteNodeRangeExcludingEnd ( sourceFile : SourceFile , startNode : Node , afterEndNode : Node | undefined , options : ConfigurableStartEnd = { startPosition : LeadingTriviaOption . IncludeAll } ) : void {
267+ const startPosition = getAdjustedStartPosition ( sourceFile , startNode , options ) ;
268+ const endPosition = afterEndNode === undefined ? sourceFile . text . length : getAdjustedStartPosition ( sourceFile , afterEndNode , options ) ;
252269 this . deleteRange ( sourceFile , { pos : startPosition , end : endPosition } ) ;
253270 }
254271
@@ -307,7 +324,7 @@ namespace ts.textChanges {
307324 }
308325
309326 public insertNodeBefore ( sourceFile : SourceFile , before : Node , newNode : Node , blankLineBetween = false ) : void {
310- this . insertNodeAt ( sourceFile , getAdjustedStartPosition ( sourceFile , before , { } , Position . Start ) , newNode , this . getOptionsForInsertNodeBefore ( before , blankLineBetween ) ) ;
327+ this . insertNodeAt ( sourceFile , getAdjustedStartPosition ( sourceFile , before , { } ) , newNode , this . getOptionsForInsertNodeBefore ( before , blankLineBetween ) ) ;
311328 }
312329
313330 public insertModifierBefore ( sourceFile : SourceFile , modifier : SyntaxKind , before : Node ) : void {
@@ -427,7 +444,7 @@ namespace ts.textChanges {
427444 }
428445
429446 public insertNodeAtEndOfScope ( sourceFile : SourceFile , scope : Node , newNode : Node ) : void {
430- const pos = getAdjustedStartPosition ( sourceFile , scope . getLastToken ( ) ! , { } , Position . Start ) ;
447+ const pos = getAdjustedStartPosition ( sourceFile , scope . getLastToken ( ) ! , { } ) ;
431448 this . insertNodeAt ( sourceFile , pos , newNode , {
432449 prefix : isLineBreak ( sourceFile . text . charCodeAt ( scope . getLastToken ( ) ! . pos ) ) ? this . newLineCharacter : this . newLineCharacter + this . newLineCharacter ,
433450 suffix : this . newLineCharacter
@@ -736,7 +753,7 @@ namespace ts.textChanges {
736753
737754 // find first non-whitespace position in the leading trivia of the node
738755 function startPositionToDeleteNodeInList ( sourceFile : SourceFile , node : Node ) : number {
739- return skipTrivia ( sourceFile . text , getAdjustedStartPosition ( sourceFile , node , { } , Position . FullStart ) , /*stopAfterLineBreak*/ false , /*stopAtComments*/ true ) ;
756+ return skipTrivia ( sourceFile . text , getAdjustedStartPosition ( sourceFile , node , { startPosition : LeadingTriviaOption . IncludeAll } ) , /*stopAfterLineBreak*/ false , /*stopAtComments*/ true ) ;
740757 }
741758
742759 function getClassOrObjectBraceEnds ( cls : ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression , sourceFile : SourceFile ) : [ number , number ] {
@@ -1090,7 +1107,7 @@ namespace ts.textChanges {
10901107 case SyntaxKind . ImportDeclaration :
10911108 deleteNode ( changes , sourceFile , node ,
10921109 // For first import, leave header comment in place
1093- node === sourceFile . imports [ 0 ] . parent ? { useNonAdjustedStartPosition : true , useNonAdjustedEndPosition : false } : undefined ) ;
1110+ node === sourceFile . imports [ 0 ] . parent ? { startPosition : LeadingTriviaOption . Exclude , endPosition : TrailingTriviaOption . IncludeIfLineBreak } : undefined ) ;
10941111 break ;
10951112
10961113 case SyntaxKind . BindingElement :
@@ -1134,7 +1151,7 @@ namespace ts.textChanges {
11341151 deleteNodeInList ( changes , deletedNodesInLists , sourceFile , node ) ;
11351152 }
11361153 else {
1137- deleteNode ( changes , sourceFile , node , node . kind === SyntaxKind . SemicolonToken ? { useNonAdjustedEndPosition : true } : undefined ) ;
1154+ deleteNode ( changes , sourceFile , node , node . kind === SyntaxKind . SemicolonToken ? { endPosition : TrailingTriviaOption . Exclude } : undefined ) ;
11381155 }
11391156 }
11401157 }
@@ -1213,8 +1230,8 @@ namespace ts.textChanges {
12131230
12141231 /** Warning: This deletes comments too. See `copyComments` in `convertFunctionToEs6Class`. */
12151232 // Exported for tests only! (TODO: improve tests to not need this)
1216- export function deleteNode ( changes : ChangeTracker , sourceFile : SourceFile , node : Node , options : ConfigurableStartEnd = { } ) : void {
1217- const startPosition = getAdjustedStartPosition ( sourceFile , node , options , Position . FullStart ) ;
1233+ export function deleteNode ( changes : ChangeTracker , sourceFile : SourceFile , node : Node , options : ConfigurableStartEnd = { startPosition : LeadingTriviaOption . IncludeAll } ) : void {
1234+ const startPosition = getAdjustedStartPosition ( sourceFile , node , options ) ;
12181235 const endPosition = getAdjustedEndPosition ( sourceFile , node , options ) ;
12191236 changes . deleteRange ( sourceFile , { pos : startPosition , end : endPosition } ) ;
12201237 }
0 commit comments