@@ -178,14 +178,15 @@ export function updateObjectValueForKey(
178178 * If no update is needed, returns `null`.
179179 */
180180export function ensureArrayWithIdentifier (
181- identifier : ts . Identifier , arr ?: ts . ArrayLiteralExpression ) : ts . ArrayLiteralExpression | null {
181+ identifierText : string , expression : ts . Expression ,
182+ arr ?: ts . ArrayLiteralExpression ) : ts . ArrayLiteralExpression | null {
182183 if ( arr === undefined ) {
183- return ts . factory . createArrayLiteralExpression ( [ identifier ] ) ;
184+ return ts . factory . createArrayLiteralExpression ( [ expression ] ) ;
184185 }
185- if ( arr . elements . find ( v => ts . isIdentifier ( v ) && v . text === identifier . text ) ) {
186+ if ( arr . elements . find ( v => ts . isIdentifier ( v ) && v . text === identifierText ) ) {
186187 return null ;
187188 }
188- return ts . factory . updateArrayLiteralExpression ( arr , [ ...arr . elements , identifier ] ) ;
189+ return ts . factory . updateArrayLiteralExpression ( arr , [ ...arr . elements , expression ] ) ;
189190}
190191
191192export function moduleSpecifierPointsToFile (
@@ -316,26 +317,21 @@ export function standaloneTraitOrNgModule(
316317 * Returns the text changes, as well as the name with which the imported symbol can be referred to.
317318 */
318319export function updateImportsForTypescriptFile (
319- tsChecker : ts . TypeChecker , file : ts . SourceFile , newImport : PotentialImport ,
320+ tsChecker : ts . TypeChecker , file : ts . SourceFile , symbolName : string , moduleSpecifier : string ,
320321 tsFileToImport : ts . SourceFile ) : [ ts . TextChange [ ] , string ] {
321- // If the expression is already imported, we can just return its name.
322- if ( newImport . moduleSpecifier === undefined ) {
323- return [ [ ] , newImport . symbolName ] ;
324- }
325-
326322 // The trait might already be imported, possibly under a different name. If so, determine the
327323 // local name of the imported trait.
328324 const allImports = findAllMatchingNodes ( file , { filter : ts . isImportDeclaration } ) ;
329325 const existingImportName : string | null =
330- hasImport ( tsChecker , allImports , newImport . symbolName , tsFileToImport ) ;
326+ hasImport ( tsChecker , allImports , symbolName , tsFileToImport ) ;
331327 if ( existingImportName !== null ) {
332328 return [ [ ] , existingImportName ] ;
333329 }
334330
335331 // If the trait has not already been imported, we need to insert the new import.
336332 const existingImportDeclaration = allImports . find (
337333 decl => moduleSpecifierPointsToFile ( tsChecker , decl . moduleSpecifier , tsFileToImport ) ) ;
338- const importName = nonCollidingImportName ( allImports , newImport . symbolName ) ;
334+ const importName = nonCollidingImportName ( allImports , symbolName ) ;
339335
340336 if ( existingImportDeclaration !== undefined ) {
341337 // Update an existing import declaration.
@@ -347,7 +343,7 @@ export function updateImportsForTypescriptFile(
347343 return [ [ ] , '' ] ;
348344 }
349345 let span = { start : bindings . getStart ( ) , length : bindings . getWidth ( ) } ;
350- const updatedBindings = updateImport ( bindings , newImport . symbolName , importName ) ;
346+ const updatedBindings = updateImport ( bindings , symbolName , importName ) ;
351347 const importString = printNode ( updatedBindings , file ) ;
352348 return [ [ { span, newText : importString } ] , importName ] ;
353349 }
@@ -364,8 +360,7 @@ export function updateImportsForTypescriptFile(
364360 if ( lastImport as any !== null ) { // TODO: Why does the compiler insist this is null?
365361 span . start = lastImport ! . getStart ( ) + lastImport ! . getWidth ( ) ;
366362 }
367- const newImportDeclaration =
368- generateImport ( newImport . symbolName , importName , newImport . moduleSpecifier ) ;
363+ const newImportDeclaration = generateImport ( symbolName , importName , moduleSpecifier ) ;
369364 const importString = '\n' + printNode ( newImportDeclaration , file ) ;
370365 return [ [ { span, newText : importString } ] , importName ] ;
371366}
@@ -375,7 +370,8 @@ export function updateImportsForTypescriptFile(
375370 * `importName` to the list of imports on the decorator arguments.
376371 */
377372export function updateImportsForAngularTrait (
378- checker : TemplateTypeChecker , trait : ts . ClassDeclaration , importName : string ) : ts . TextChange [ ] {
373+ checker : TemplateTypeChecker , trait : ts . ClassDeclaration , importName : string ,
374+ forwardRefName : string | null ) : ts . TextChange [ ] {
379375 // Get the object with arguments passed into the primary Angular decorator for this trait.
380376 const decorator = checker . getPrimaryAngularDecorator ( trait ) ;
381377 if ( decorator === null ) {
@@ -393,7 +389,14 @@ export function updateImportsForAngularTrait(
393389 if ( oldValue && ! ts . isArrayLiteralExpression ( oldValue ) ) {
394390 return oldValue ;
395391 }
396- const newArr = ensureArrayWithIdentifier ( ts . factory . createIdentifier ( importName ) , oldValue ) ;
392+ const identifier = ts . factory . createIdentifier ( importName ) ;
393+ const expression = forwardRefName ?
394+ ts . factory . createCallExpression (
395+ ts . factory . createIdentifier ( forwardRefName ) , undefined ,
396+ [ ts . factory . createArrowFunction (
397+ undefined , undefined , [ ] , undefined , undefined , identifier ) ] ) :
398+ identifier ;
399+ const newArr = ensureArrayWithIdentifier ( importName , expression , oldValue ) ;
397400 updateRequired = newArr !== null ;
398401 return newArr ! ;
399402 } ) ;
0 commit comments