88
99import ts from 'typescript' ;
1010import { ChangeTracker } from '../../utils/change_tracker' ;
11- import { getImportOfIdentifier , getImportSpecifier } from '../../utils/typescript/imports' ;
11+ import {
12+ getImportOfIdentifier ,
13+ getImportSpecifier ,
14+ getNamedImports ,
15+ } from '../../utils/typescript/imports' ;
1216
1317const CORE = '@angular/core' ;
1418const AFTER_RENDER_PHASE_ENUM = 'AfterRenderPhase' ;
@@ -22,57 +26,65 @@ export function migrateFile(
2226 rewriteFn : RewriteFn ,
2327) {
2428 const changeTracker = new ChangeTracker ( ts . createPrinter ( ) ) ;
29+ // Check if there are any imports of the `AfterRenderPhase` enum.
30+ const coreImports = getNamedImports ( sourceFile , CORE ) ;
31+ if ( ! coreImports ) {
32+ return ;
33+ }
2534 const phaseEnum = getImportSpecifier ( sourceFile , CORE , AFTER_RENDER_PHASE_ENUM ) ;
35+ if ( ! phaseEnum ) {
36+ return ;
37+ }
2638
27- // Check if there are any imports of the `AfterRenderPhase` enum.
28- if ( phaseEnum ) {
29- // Remove the `AfterRenderPhase` enum import.
30- changeTracker . removeNode ( phaseEnum ) ;
31- ts . forEachChild ( sourceFile , function visit ( node : ts . Node ) {
32- ts . forEachChild ( node , visit ) ;
39+ // Remove the `AfterRenderPhase` enum import.
40+ const newCoreImports = ts . factory . updateNamedImports ( coreImports , [
41+ ...coreImports . elements . filter ( ( current ) => phaseEnum !== current ) ,
42+ ] ) ;
43+ changeTracker . replaceNode ( coreImports , newCoreImports ) ;
44+ ts . forEachChild ( sourceFile , function visit ( node : ts . Node ) {
45+ ts . forEachChild ( node , visit ) ;
3346
34- // Check if this is a function call of `afterRender` or `afterNextRender`.
35- if (
36- ts . isCallExpression ( node ) &&
37- ts . isIdentifier ( node . expression ) &&
38- AFTER_RENDER_FNS . has ( getImportOfIdentifier ( typeChecker , node . expression ) ?. name || '' )
39- ) {
40- let phase : string | undefined ;
41- const [ callback , options ] = node . arguments ;
42- // Check if any `AfterRenderOptions` options were specified.
43- if ( ts . isObjectLiteralExpression ( options ) ) {
44- const phaseProp = options . properties . find ( ( p ) => p . name ?. getText ( ) === 'phase' ) ;
45- // Check if the `phase` options is set.
46- if (
47- phaseProp &&
48- ts . isPropertyAssignment ( phaseProp ) &&
49- ts . isPropertyAccessExpression ( phaseProp . initializer ) &&
50- phaseProp . initializer . expression . getText ( ) === AFTER_RENDER_PHASE_ENUM
51- ) {
52- phaseProp . initializer . expression ;
53- phase = phaseProp . initializer . name . getText ( ) ;
54- // Remove the `phase` option.
55- if ( options . properties . length === 1 ) {
56- changeTracker . removeNode ( options ) ;
57- } else {
58- const newOptions = ts . factory . createObjectLiteralExpression (
59- options . properties . filter ( ( p ) => p !== phaseProp ) ,
60- ) ;
61- changeTracker . replaceNode ( options , newOptions ) ;
62- }
47+ // Check if this is a function call of `afterRender` or `afterNextRender`.
48+ if (
49+ ts . isCallExpression ( node ) &&
50+ ts . isIdentifier ( node . expression ) &&
51+ AFTER_RENDER_FNS . has ( getImportOfIdentifier ( typeChecker , node . expression ) ?. name || '' )
52+ ) {
53+ let phase : string | undefined ;
54+ const [ callback , options ] = node . arguments ;
55+ // Check if any `AfterRenderOptions` options were specified.
56+ if ( ts . isObjectLiteralExpression ( options ) ) {
57+ const phaseProp = options . properties . find ( ( p ) => p . name ?. getText ( ) === 'phase' ) ;
58+ // Check if the `phase` options is set.
59+ if (
60+ phaseProp &&
61+ ts . isPropertyAssignment ( phaseProp ) &&
62+ ts . isPropertyAccessExpression ( phaseProp . initializer ) &&
63+ phaseProp . initializer . expression . getText ( ) === AFTER_RENDER_PHASE_ENUM
64+ ) {
65+ phaseProp . initializer . expression ;
66+ phase = phaseProp . initializer . name . getText ( ) ;
67+ // Remove the `phase` option.
68+ if ( options . properties . length === 1 ) {
69+ changeTracker . removeNode ( options ) ;
70+ } else {
71+ const newOptions = ts . factory . createObjectLiteralExpression (
72+ options . properties . filter ( ( p ) => p !== phaseProp ) ,
73+ ) ;
74+ changeTracker . replaceNode ( options , newOptions ) ;
6375 }
6476 }
65- // If we found a phase, update the callback.
66- if ( phase ) {
67- phase = phase . substring ( 0 , 1 ) . toLocaleLowerCase ( ) + phase . substring ( 1 ) ;
68- const spec = ts . factory . createObjectLiteralExpression ( [
69- ts . factory . createPropertyAssignment ( ts . factory . createIdentifier ( phase ) , callback ) ,
70- ] ) ;
71- changeTracker . replaceNode ( callback , spec ) ;
72- }
7377 }
74- } ) ;
75- }
78+ // If we found a phase, update the callback.
79+ if ( phase ) {
80+ phase = phase . substring ( 0 , 1 ) . toLocaleLowerCase ( ) + phase . substring ( 1 ) ;
81+ const spec = ts . factory . createObjectLiteralExpression ( [
82+ ts . factory . createPropertyAssignment ( ts . factory . createIdentifier ( phase ) , callback ) ,
83+ ] ) ;
84+ changeTracker . replaceNode ( callback , spec ) ;
85+ }
86+ }
87+ } ) ;
7688
7789 // Write the changes.
7890 for ( const changesInFile of changeTracker . recordChanges ( ) . values ( ) ) {
0 commit comments