@@ -20,7 +20,6 @@ import {ErrorCode, FileSystem, ngErrorCode} from '@angular/compiler-cli';
20
20
import { DiagnosticCategoryLabel } from '@angular/compiler-cli/src/ngtsc/core/api' ;
21
21
import { ImportManager } from '@angular/compiler-cli/private/migrations' ;
22
22
import { applyImportManagerChanges } from '../../utils/tsurge/helpers/apply_import_manager' ;
23
- import { getLeadingLineWhitespaceOfNode } from '../../utils/tsurge/helpers/ast/leading_space' ;
24
23
25
24
/** Data produced by the migration for each compilation unit. */
26
25
export interface CompilationUnitData {
@@ -306,10 +305,14 @@ export class UnusedImportsMigration extends TsurgeFunnelMigration<
306
305
replacements . push (
307
306
new Replacement (
308
307
projectFile ( sourceFile , info ) ,
309
- getArrayElementRemovalUpdate ( node , parent , sourceText ) ,
308
+ getArrayElementRemovalUpdate ( node , sourceText ) ,
310
309
) ,
311
310
) ;
312
311
} ) ;
312
+
313
+ stripTrailingSameLineCommas ( parent , toRemove , sourceText ) ?. forEach ( ( update ) => {
314
+ replacements . push ( new Replacement ( projectFile ( sourceFile , info ) , update ) ) ;
315
+ } ) ;
313
316
} ) ;
314
317
315
318
// Attempt to clean up unused import declarations. Note that this isn't foolproof, because we
@@ -333,11 +336,7 @@ export class UnusedImportsMigration extends TsurgeFunnelMigration<
333
336
}
334
337
335
338
/** Generates a `TextUpdate` for the removal of an array element. */
336
- function getArrayElementRemovalUpdate (
337
- node : ts . Expression ,
338
- parent : ts . ArrayLiteralExpression ,
339
- sourceText : string ,
340
- ) : TextUpdate {
339
+ function getArrayElementRemovalUpdate ( node : ts . Expression , sourceText : string ) : TextUpdate {
341
340
let position = node . getStart ( ) ;
342
341
let end = node . getEnd ( ) ;
343
342
let toInsert = '' ;
@@ -358,25 +357,49 @@ function getArrayElementRemovalUpdate(
358
357
}
359
358
}
360
359
361
- // If we're removing the last element in the array, adjust the starting offset so that
362
- // it includes the previous comma on the same line. This avoids turning something like
363
- // `[One, Two, Three]` into `[One,]`. We only do this within the same like, because
364
- // trailing comma at the end of the line is fine.
365
- if ( parent . elements [ parent . elements . length - 1 ] === node ) {
366
- for ( let i = position - 1 ; i >= 0 ; i -- ) {
367
- const char = sourceText [ i ] ;
360
+ return new TextUpdate ( { position, end, toInsert} ) ;
361
+ }
362
+
363
+ /** Returns `TextUpdate`s that will remove any leftover trailing commas on the same line. */
364
+ function stripTrailingSameLineCommas (
365
+ node : ts . ArrayLiteralExpression ,
366
+ toRemove : Set < ts . Expression > ,
367
+ sourceText : string ,
368
+ ) {
369
+ let updates : TextUpdate [ ] | null = null ;
370
+
371
+ for ( let i = 0 ; i < node . elements . length ; i ++ ) {
372
+ // Skip over elements that are being removed already.
373
+ if ( toRemove . has ( node . elements [ i ] ) ) {
374
+ continue ;
375
+ }
376
+
377
+ // An element might have a trailing comma if all elements after it have been removed.
378
+ const mightHaveTrailingComma = node . elements . slice ( i + 1 ) . every ( ( e ) => toRemove . has ( e ) ) ;
379
+
380
+ if ( ! mightHaveTrailingComma ) {
381
+ continue ;
382
+ }
383
+
384
+ const position = node . elements [ i ] . getEnd ( ) ;
385
+ let end = position ;
386
+
387
+ // If the item might have a trailing comma, start looking after it until we hit a line break.
388
+ for ( let charIndex = position ; charIndex < node . getEnd ( ) ; charIndex ++ ) {
389
+ const char = sourceText [ charIndex ] ;
390
+
368
391
if ( char === ',' || char === ' ' ) {
369
- position -- ;
392
+ end ++ ;
370
393
} else {
371
- if ( whitespaceOrLineFeed . test ( char ) ) {
372
- // Replace the node with its leading whitespace to preserve the formatting.
373
- // This only needs to happen if we're breaking on a newline.
374
- toInsert = getLeadingLineWhitespaceOfNode ( node ) ;
394
+ if ( char !== '\n' && position !== end ) {
395
+ updates ??= [ ] ;
396
+ updates . push ( new TextUpdate ( { position, end, toInsert : '' } ) ) ;
375
397
}
398
+
376
399
break ;
377
400
}
378
401
}
379
402
}
380
403
381
- return new TextUpdate ( { position , end , toInsert } ) ;
404
+ return updates ;
382
405
}
0 commit comments