diff --git a/packages/compiler-cli/src/ngtsc/transform/src/transform.ts b/packages/compiler-cli/src/ngtsc/transform/src/transform.ts index 4e369d0d23..c648b29198 100644 --- a/packages/compiler-cli/src/ngtsc/transform/src/transform.ts +++ b/packages/compiler-cli/src/ngtsc/transform/src/transform.ts @@ -16,6 +16,7 @@ import {VisitListEntryResult, Visitor, visit} from '../../util/src/visitor'; import {CompileResult} from './api'; import {IvyCompilation} from './compilation'; +import {addImports} from './utils'; const NO_DECORATORS = new Set(); @@ -201,25 +202,8 @@ function transformIvySourceFile( // to the ImportManager. const constants = constantPool.statements.map(stmt => translateStatement(stmt, importManager)); - // Generate the import statements to prepend. - const addedImports = importManager.getAllImports(file.fileName).map(i => { - return ts.createImportDeclaration( - undefined, undefined, - ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(i.as))), - ts.createLiteral(i.name)); - }); - - // Filter out the existing imports and the source file body. All new statements - // will be inserted between them. - const existingImports = sf.statements.filter(stmt => isImportStatement(stmt)); - const body = sf.statements.filter(stmt => !isImportStatement(stmt)); - - // Prepend imports if needed. - if (addedImports.length > 0) { - sf.statements = - ts.createNodeArray([...existingImports, ...addedImports, ...constants, ...body]); - } - return sf; + // Add new imports for this file. + return addImports(importManager, sf, constants); } function maybeFilterDecorator( @@ -238,8 +222,3 @@ function maybeFilterDecorator( function isFromAngularCore(decorator: Decorator): boolean { return decorator.import !== null && decorator.import.from === '@angular/core'; } - -function isImportStatement(stmt: ts.Statement): boolean { - return ts.isImportDeclaration(stmt) || ts.isImportEqualsDeclaration(stmt) || - ts.isNamespaceImport(stmt); -} diff --git a/packages/compiler-cli/src/ngtsc/transform/src/utils.ts b/packages/compiler-cli/src/ngtsc/transform/src/utils.ts new file mode 100644 index 0000000000..e4c802db16 --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/transform/src/utils.ts @@ -0,0 +1,44 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +import * as ts from 'typescript'; + +import { ImportManager } from '../../translator'; + +/** + * Adds extra imports in the import manage for this source file, after the existing imports + * and before the module body. + * Can optionally add extra statements (e.g. new constants) before the body as well. + */ +export function addImports(importManager: ImportManager, sf: ts.SourceFile, + extraStatements: ts.Statement[] = []): ts.SourceFile { + + // Generate the import statements to prepend. + const addedImports = importManager.getAllImports(sf.fileName).map(i => { + return ts.createImportDeclaration( + undefined, undefined, + ts.createImportClause(undefined, ts.createNamespaceImport(ts.createIdentifier(i.as))), + ts.createLiteral(i.name)); + }); + + // Filter out the existing imports and the source file body. All new statements + // will be inserted between them. + const existingImports = sf.statements.filter(stmt => isImportStatement(stmt)); + const body = sf.statements.filter(stmt => !isImportStatement(stmt)); + // Prepend imports if needed. + if (addedImports.length > 0) { + sf.statements = + ts.createNodeArray([...existingImports, ...addedImports, ...extraStatements, ...body]); + } + + return sf; +} + +function isImportStatement(stmt: ts.Statement): boolean { + return ts.isImportDeclaration(stmt) || ts.isImportEqualsDeclaration(stmt) || + ts.isNamespaceImport(stmt); +}