diff --git a/packages/compiler-cli/ngcc/src/analysis/module_with_providers_analyzer.ts b/packages/compiler-cli/ngcc/src/analysis/module_with_providers_analyzer.ts index f6b44cc90f..df17011a79 100644 --- a/packages/compiler-cli/ngcc/src/analysis/module_with_providers_analyzer.ts +++ b/packages/compiler-cli/ngcc/src/analysis/module_with_providers_analyzer.ts @@ -10,7 +10,7 @@ import * as ts from 'typescript'; import {ReferencesRegistry} from '../../../src/ngtsc/annotations'; import {Reference} from '../../../src/ngtsc/imports'; import {ClassDeclaration, ConcreteDeclaration} from '../../../src/ngtsc/reflection'; -import {ModuleWithProvidersFunction, NgccReflectionHost} from '../host/ngcc_host'; +import {NgccReflectionHost} from '../host/ngcc_host'; import {hasNameIdentifier, isDefined} from '../utils'; export interface ModuleWithProvidersInfo { @@ -38,7 +38,7 @@ export class ModuleWithProvidersAnalyzer { const analyses = new ModuleWithProvidersAnalyses(); const rootFiles = this.getRootFiles(program); rootFiles.forEach(f => { - const fns = this.host.getModuleWithProvidersFunctions(f); + const fns = this.getModuleWithProvidersFunctions(f); fns && fns.forEach(fn => { if (fn.ngModule.viaModule === null) { // Record the usage of an internal module as it needs to become an exported symbol @@ -68,6 +68,100 @@ export class ModuleWithProvidersAnalyzer { return program.getRootFileNames().map(f => program.getSourceFile(f)).filter(isDefined); } + private getModuleWithProvidersFunctions(f: ts.SourceFile): ModuleWithProvidersFunction[] { + const exports = this.host.getExportsOfModule(f); + if (!exports) return []; + const infos: ModuleWithProvidersFunction[] = []; + exports.forEach((declaration, name) => { + if (declaration.node === null) { + return; + } + if (this.host.isClass(declaration.node)) { + this.host.getMembersOfClass(declaration.node).forEach(member => { + if (member.isStatic) { + const info = this.parseForModuleWithProviders( + member.name, member.node, member.implementation, declaration.node); + if (info) { + infos.push(info); + } + } + }); + } else { + if (hasNameIdentifier(declaration.node)) { + const info = + this.parseForModuleWithProviders(declaration.node.name.text, declaration.node); + if (info) { + infos.push(info); + } + } + } + }); + return infos; + } + + /** + * Parse a function/method node (or its implementation), to see if it returns a + * `ModuleWithProviders` object. + * @param name The name of the function. + * @param node the node to check - this could be a function, a method or a variable declaration. + * @param implementation the actual function expression if `node` is a variable declaration. + * @param container the class that contains the function, if it is a method. + * @returns info about the function if it does return a `ModuleWithProviders` object; `null` + * otherwise. + */ + private parseForModuleWithProviders( + name: string, node: ts.Node|null, implementation: ts.Node|null = node, + container: ts.Declaration|null = null): ModuleWithProvidersFunction|null { + if (implementation === null || + (!ts.isFunctionDeclaration(implementation) && !ts.isMethodDeclaration(implementation) && + !ts.isFunctionExpression(implementation))) { + return null; + } + const declaration = implementation; + const definition = this.host.getDefinitionOfFunction(declaration); + if (definition === null) { + return null; + } + const body = definition.body; + const lastStatement = body && body[body.length - 1]; + const returnExpression = + lastStatement && ts.isReturnStatement(lastStatement) && lastStatement.expression || null; + const ngModuleProperty = returnExpression && ts.isObjectLiteralExpression(returnExpression) && + returnExpression.properties.find( + prop => + !!prop.name && ts.isIdentifier(prop.name) && prop.name.text === 'ngModule') || + null; + + if (!ngModuleProperty || !ts.isPropertyAssignment(ngModuleProperty)) { + return null; + } + + // The ngModuleValue could be of the form `SomeModule` or `namespace_1.SomeModule` + let ngModuleValue = ngModuleProperty.initializer; + if (ts.isPropertyAccessExpression(ngModuleValue)) { + ngModuleValue = ngModuleValue.expression; + } + + if (!ts.isIdentifier(ngModuleValue)) { + return null; + } + + const ngModuleDeclaration = this.host.getDeclarationOfIdentifier(ngModuleValue); + if (!ngModuleDeclaration || ngModuleDeclaration.node === null) { + throw new Error(`Cannot find a declaration for NgModule ${ + ngModuleValue.getText()} referenced in "${declaration!.getText()}"`); + } + if (!hasNameIdentifier(ngModuleDeclaration.node)) { + return null; + } + return { + name, + ngModule: ngModuleDeclaration as ConcreteDeclaration, + declaration, + container + }; + } + private getDtsDeclarationForFunction(fn: ModuleWithProvidersFunction) { let dtsFn: ts.Declaration|null = null; const containerClass = fn.container && this.host.getClassSymbol(fn.container); @@ -128,3 +222,27 @@ function isFunctionOrMethod(declaration: ts.Declaration): declaration is ts.Func function isAnyKeyword(typeParam: ts.TypeNode): typeParam is ts.KeywordTypeNode { return typeParam.kind === ts.SyntaxKind.AnyKeyword; } + +/** + * A structure returned from `getModuleWithProvidersFunction` that describes functions + * that return ModuleWithProviders objects. + */ +export interface ModuleWithProvidersFunction { + /** + * The name of the declared function. + */ + name: string; + /** + * The declaration of the function that returns the `ModuleWithProviders` object. + */ + declaration: ts.SignatureDeclaration; + /** + * Declaration of the containing class (if this is a method) + */ + container: ts.Declaration|null; + /** + * The declaration of the class that the `ngModule` property on the `ModuleWithProviders` object + * refers to. + */ + ngModule: ConcreteDeclaration; +} diff --git a/packages/compiler-cli/ngcc/src/host/delegating_host.ts b/packages/compiler-cli/ngcc/src/host/delegating_host.ts index d4d36fc96f..d1e7293feb 100644 --- a/packages/compiler-cli/ngcc/src/host/delegating_host.ts +++ b/packages/compiler-cli/ngcc/src/host/delegating_host.ts @@ -11,7 +11,7 @@ import * as ts from 'typescript'; import {ClassDeclaration, ClassMember, CtorParameter, Declaration, Decorator, FunctionDefinition, Import, ReflectionHost} from '../../../src/ngtsc/reflection'; import {isFromDtsFile} from '../../../src/ngtsc/util/src/typescript'; -import {ModuleWithProvidersFunction, NgccClassSymbol, NgccReflectionHost, SwitchableVariableDeclaration} from './ngcc_host'; +import {NgccClassSymbol, NgccReflectionHost, SwitchableVariableDeclaration} from './ngcc_host'; /** * A reflection host implementation that delegates reflector queries depending on whether they @@ -149,10 +149,6 @@ export class DelegatingReflectionHost implements NgccReflectionHost { return this.ngccHost.getDecoratorsOfSymbol(symbol); } - getModuleWithProvidersFunctions(sf: ts.SourceFile): ModuleWithProvidersFunction[] { - return this.ngccHost.getModuleWithProvidersFunctions(sf); - } - getSwitchableDeclarations(module: ts.Node): SwitchableVariableDeclaration[] { return this.ngccHost.getSwitchableDeclarations(module); } diff --git a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts index f95d8a4660..a401f6ea64 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -8,13 +8,13 @@ import * as ts from 'typescript'; -import {ClassDeclaration, ClassMember, ClassMemberKind, ConcreteDeclaration, CtorParameter, Declaration, Decorator, EnumMember, isDecoratorIdentifier, isNamedClassDeclaration, KnownDeclaration, reflectObjectLiteral, SpecialDeclarationKind, TypeScriptReflectionHost, TypeValueReference} from '../../../src/ngtsc/reflection'; +import {ClassDeclaration, ClassMember, ClassMemberKind, CtorParameter, Declaration, Decorator, EnumMember, isDecoratorIdentifier, isNamedClassDeclaration, KnownDeclaration, reflectObjectLiteral, SpecialDeclarationKind, TypeScriptReflectionHost, TypeValueReference} from '../../../src/ngtsc/reflection'; import {isWithinPackage} from '../analysis/util'; import {Logger} from '../logging/logger'; import {BundleProgram} from '../packages/bundle_program'; import {findAll, getNameText, hasNameIdentifier, isDefined, stripDollarSuffix} from '../utils'; -import {ClassSymbol, isSwitchableVariableDeclaration, ModuleWithProvidersFunction, NgccClassSymbol, NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration} from './ngcc_host'; +import {ClassSymbol, isSwitchableVariableDeclaration, NgccClassSymbol, NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration} from './ngcc_host'; import {stripParentheses} from './utils'; export const DECORATORS = 'decorators' as ts.__String; @@ -568,44 +568,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N return null; } - /** - * Search the given source file for exported functions and static class methods that return - * ModuleWithProviders objects. - * @param f The source file to search for these functions - * @returns An array of function declarations that look like they return ModuleWithProviders - * objects. - */ - getModuleWithProvidersFunctions(f: ts.SourceFile): ModuleWithProvidersFunction[] { - const exports = this.getExportsOfModule(f); - if (!exports) return []; - const infos: ModuleWithProvidersFunction[] = []; - exports.forEach((declaration, name) => { - if (declaration.node === null) { - return; - } - if (this.isClass(declaration.node)) { - this.getMembersOfClass(declaration.node).forEach(member => { - if (member.isStatic) { - const info = this.parseForModuleWithProviders( - member.name, member.node, member.implementation, declaration.node); - if (info) { - infos.push(info); - } - } - }); - } else { - if (isNamedDeclaration(declaration.node)) { - const info = - this.parseForModuleWithProviders(declaration.node.name.text, declaration.node); - if (info) { - infos.push(info); - } - } - } - }); - return infos; - } - getEndOfClass(classSymbol: NgccClassSymbol): ts.Node { let last: ts.Node = classSymbol.declaration.valueDeclaration; @@ -1711,65 +1673,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N } } - /** - * Parse a function/method node (or its implementation), to see if it returns a - * `ModuleWithProviders` object. - * @param name The name of the function. - * @param node the node to check - this could be a function, a method or a variable declaration. - * @param implementation the actual function expression if `node` is a variable declaration. - * @param container the class that contains the function, if it is a method. - * @returns info about the function if it does return a `ModuleWithProviders` object; `null` - * otherwise. - */ - protected parseForModuleWithProviders( - name: string, node: ts.Node|null, implementation: ts.Node|null = node, - container: ts.Declaration|null = null): ModuleWithProvidersFunction|null { - if (implementation === null || - (!ts.isFunctionDeclaration(implementation) && !ts.isMethodDeclaration(implementation) && - !ts.isFunctionExpression(implementation))) { - return null; - } - const declaration = implementation; - const definition = this.getDefinitionOfFunction(declaration); - if (definition === null) { - return null; - } - const body = definition.body; - const lastStatement = body && body[body.length - 1]; - const returnExpression = - lastStatement && ts.isReturnStatement(lastStatement) && lastStatement.expression || null; - const ngModuleProperty = returnExpression && ts.isObjectLiteralExpression(returnExpression) && - returnExpression.properties.find( - prop => - !!prop.name && ts.isIdentifier(prop.name) && prop.name.text === 'ngModule') || - null; - - if (!ngModuleProperty || !ts.isPropertyAssignment(ngModuleProperty)) { - return null; - } - - // The ngModuleValue could be of the form `SomeModule` or `namespace_1.SomeModule` - const ngModuleValue = ngModuleProperty.initializer; - if (!ts.isIdentifier(ngModuleValue) && !ts.isPropertyAccessExpression(ngModuleValue)) { - return null; - } - - const ngModuleDeclaration = this.getDeclarationOfExpression(ngModuleValue); - if (!ngModuleDeclaration || ngModuleDeclaration.node === null) { - throw new Error(`Cannot find a declaration for NgModule ${ - ngModuleValue.getText()} referenced in "${declaration!.getText()}"`); - } - if (!hasNameIdentifier(ngModuleDeclaration.node)) { - return null; - } - return { - name, - ngModule: ngModuleDeclaration as ConcreteDeclaration, - declaration, - container - }; - } - protected getDeclarationOfExpression(expression: ts.Expression): Declaration|null { if (ts.isIdentifier(expression)) { return this.getDeclarationOfIdentifier(expression); diff --git a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts index eb16f662ea..2d74d0532b 100644 --- a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts +++ b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts @@ -7,7 +7,7 @@ */ import * as ts from 'typescript'; -import {ClassDeclaration, ConcreteDeclaration, Declaration, Decorator, ReflectionHost} from '../../../src/ngtsc/reflection'; +import {ClassDeclaration, Declaration, Decorator, ReflectionHost} from '../../../src/ngtsc/reflection'; export const PRE_R3_MARKER = '__PRE_R3__'; export const POST_R3_MARKER = '__POST_R3__'; @@ -19,30 +19,6 @@ export function isSwitchableVariableDeclaration(node: ts.Node): ts.isIdentifier(node.initializer) && node.initializer.text.endsWith(PRE_R3_MARKER); } -/** - * A structure returned from `getModuleWithProviderInfo` that describes functions - * that return ModuleWithProviders objects. - */ -export interface ModuleWithProvidersFunction { - /** - * The name of the declared function. - */ - name: string; - /** - * The declaration of the function that returns the `ModuleWithProviders` object. - */ - declaration: ts.SignatureDeclaration; - /** - * Declaration of the containing class (if this is a method) - */ - container: ts.Declaration|null; - /** - * The declaration of the class that the `ngModule` property on the `ModuleWithProviders` object - * refers to. - */ - ngModule: ConcreteDeclaration; -} - /** * The symbol corresponding to a "class" declaration. I.e. a `ts.Symbol` whose `valueDeclaration` is * a `ClassDeclaration`. @@ -108,15 +84,6 @@ export interface NgccReflectionHost extends ReflectionHost { */ findClassSymbols(sourceFile: ts.SourceFile): NgccClassSymbol[]; - /** - * Search the given source file for exported functions and static class methods that return - * ModuleWithProviders objects. - * @param f The source file to search for these functions - * @returns An array of info items about each of the functions that return ModuleWithProviders - * objects. - */ - getModuleWithProvidersFunctions(f: ts.SourceFile): ModuleWithProvidersFunction[]; - /** * Find the last node that is relevant to the specified class. * diff --git a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts index bf8e27921f..3ead77cd2c 100644 --- a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts @@ -45,7 +45,6 @@ runInEachFileSystem(() => { let DECORATED_FILES: TestFile[]; let TYPINGS_SRC_FILES: TestFile[]; let TYPINGS_DTS_FILES: TestFile[]; - let MODULE_WITH_PROVIDERS_PROGRAM: TestFile[]; // Helpers const createHost = (bundle: BundleProgram, ngccHost: CommonJsReflectionHost) => { @@ -796,131 +795,6 @@ exports.MissingClass2 = MissingClass2; {name: _('/ep/typings/shadow-class.d.ts'), contents: `export declare class ShadowClass {}`}, {name: _('/an_external_lib/index.d.ts'), contents: 'export declare class ShadowClass {}'}, ]; - - MODULE_WITH_PROVIDERS_PROGRAM = [ - { - name: _('/src/index.js'), - contents: ` - var functions = require('./functions'); - var methods = require('./methods'); - var outer_aliased_class = require('./outer_aliased_class'); - var inner_aliased_class = require('./inner_aliased_class'); - ` - }, - { - name: _('/src/functions.js'), - contents: ` -var mod = require('./module'); -var SomeService = (function() { - function SomeService() {} - return SomeService; -}()); - -var InternalModule = (function() { - function InternalModule() {} - return InternalModule; -}()); - -function aNumber() { return 42; } -function aString() { return 'foo'; } -function emptyObject() { return {}; } -function ngModuleIdentifier() { return { ngModule: InternalModule }; } -function ngModuleWithEmptyProviders() { return { ngModule: InternalModule, providers: [] }; } -function ngModuleWithProviders() { return { ngModule: InternalModule, providers: [SomeService] }; } -function onlyProviders() { return { providers: [SomeService] }; } -function ngModuleNumber() { return { ngModule: 42 }; } -function ngModuleString() { return { ngModule: 'foo' }; } -function ngModuleObject() { return { ngModule: { foo: 42 } }; } -function externalNgModule() { return { ngModule: mod.ExternalModule }; } -// NOTE: We do not include the "namespaced" export tests in CommonJS as all CommonJS exports are already namespaced. -// function namespacedExternalNgModule() { return { ngModule: mod.ExternalModule }; } - -exports.aNumber = aNumber; -exports.aString = aString; -exports.emptyObject = emptyObject; -exports.ngModuleIdentifier = ngModuleIdentifier; -exports.ngModuleWithEmptyProviders = ngModuleWithEmptyProviders; -exports.ngModuleWithProviders = ngModuleWithProviders; -exports.onlyProviders = onlyProviders; -exports.ngModuleNumber = ngModuleNumber; -exports.ngModuleString = ngModuleString; -exports.ngModuleObject = ngModuleObject; -exports.externalNgModule = externalNgModule; -exports.SomeService = SomeService; -exports.InternalModule = InternalModule; -` - }, - { - name: _('/src/methods.js'), - contents: ` -var mod = require('./module'); -var SomeService = (function() { - function SomeService() {} - return SomeService; -}()); - -var InternalModule = (function() { - function InternalModule() {} - InternalModule.prototype = { - instanceNgModuleIdentifier: function() { return { ngModule: InternalModule }; }, - instanceNgModuleWithEmptyProviders: function() { return { ngModule: InternalModule, providers: [] }; }, - instanceNgModuleWithProviders: function() { return { ngModule: InternalModule, providers: [SomeService] }; }, - instanceExternalNgModule: function() { return { ngModule: mod.ExternalModule }; }, - }; - InternalModule.aNumber = function() { return 42; }; - InternalModule.aString = function() { return 'foo'; }; - InternalModule.emptyObject = function() { return {}; }; - InternalModule.ngModuleIdentifier = function() { return { ngModule: InternalModule }; }; - InternalModule.ngModuleWithEmptyProviders = function() { return { ngModule: InternalModule, providers: [] }; }; - InternalModule.ngModuleWithProviders = function() { return { ngModule: InternalModule, providers: [SomeService] }; }; - InternalModule.onlyProviders = function() { return { providers: [SomeService] }; }; - InternalModule.ngModuleNumber = function() { return { ngModule: 42 }; }; - InternalModule.ngModuleString = function() { return { ngModule: 'foo' }; }; - InternalModule.ngModuleObject = function() { return { ngModule: { foo: 42 } }; }; - InternalModule.externalNgModule = function() { return { ngModule: mod.ExternalModule }; }; - return InternalModule; -}()); - -exports.SomeService = SomeService; -exports.InternalModule = InternalModule; -` - }, - { - name: _('/src/outer_aliased_class.js'), - contents: ` -var AliasedModule = AliasedModule_1 = (function() { - function AliasedModule() {} - return AliasedModule; -}()); -AliasedModule.forRoot = function() { return { ngModule: AliasedModule_1 }; }; -exports.AliasedModule = AliasedModule; -var AliasedModule_1; - ` - }, - { - name: _('/src/inner_aliased_class.js'), - contents: ` -var AliasedModule = (function() { - function AliasedModule() {} - AliasedModule_1 = AliasedModule; - AliasedModule.forRoot = function() { return { ngModule: AliasedModule_1 }; }; - var AliasedModule_1; - return AliasedModule; -}()); -exports.AliasedModule = AliasedModule; -` - }, - { - name: _('/src/module.js'), - contents: ` -var ExternalModule = (function() { - function ExternalModule() {} - return ExternalModule; -}()); -exports.ExternalModule = ExternalModule; -` - }, - ]; }); describe('CommonJsReflectionHost', () => { @@ -2850,80 +2724,6 @@ exports.ExternalModule = ExternalModule; expect(host.getAdjacentNameOfClass(childClass).text).toEqual('InnerChildClass'); }); }); - - describe('getModuleWithProvidersFunctions', () => { - it('should find every exported function that returns an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = - createHost(bundle, new CommonJsReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/functions.js')); - const fns = host.getModuleWithProvidersFunctions(file); - expect(fns.map(fn => [fn.declaration.name!.getText(), fn.ngModule.node.name.text])) - .toEqual([ - ['ngModuleIdentifier', 'InternalModule'], - ['ngModuleWithEmptyProviders', 'InternalModule'], - ['ngModuleWithProviders', 'InternalModule'], - ['externalNgModule', 'ExternalModule'], - ]); - }); - - it('should find every static method on exported classes that return an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = - createHost(bundle, new CommonJsReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/methods.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - [ - 'function() { return { ngModule: InternalModule }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: InternalModule, providers: [] }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: InternalModule, providers: [SomeService] }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: mod.ExternalModule }; }', - 'ExternalModule', - ], - ]); - }); - - it('should resolve aliased module references to their original declaration (outer alias)', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = - createHost(bundle, new CommonJsReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/outer_aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - ['function() { return { ngModule: AliasedModule_1 }; }', 'AliasedModule'], - ]); - }); - - // https://github.com/angular/angular/issues/29078 - it('should resolve aliased module references to their original declaration (inner alias)', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = - createHost(bundle, new CommonJsReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/inner_aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - ['function() { return { ngModule: AliasedModule_1 }; }', 'AliasedModule'], - ]); - }); - }); }); }); }); diff --git a/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts b/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts index 8d3fbb580a..2319a5a8d2 100644 --- a/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts @@ -46,7 +46,6 @@ runInEachFileSystem(() => { let ARITY_CLASSES: TestFile[]; let TYPINGS_SRC_FILES: TestFile[]; let TYPINGS_DTS_FILES: TestFile[]; - let MODULE_WITH_PROVIDERS_PROGRAM: TestFile[]; let NAMESPACED_IMPORT_FILE: TestFile; let INDEX_SIGNATURE_PROP_FILE: TestFile; @@ -650,77 +649,6 @@ runInEachFileSystem(() => { {name: _('/an_external_lib/index.d.ts'), contents: 'export declare class ShadowClass {}'}, ]; - MODULE_WITH_PROVIDERS_PROGRAM = [ - { - name: _('/src/index.js'), - contents: ` - import * as functions from './functions'; - import * as methods from './methods'; - import * as aliased_class from './aliased_class'; - ` - }, - { - name: _('/src/functions.js'), - contents: ` - import {ExternalModule} from './module'; - import * as mod from './module'; - export class SomeService {} - export class InternalModule {} - export function aNumber() { return 42; } - export function aString() { return 'foo'; } - export function emptyObject() { return {}; } - export function ngModuleIdentifier() { return { ngModule: InternalModule }; } - export function ngModuleWithEmptyProviders() { return { ngModule: InternalModule, providers: [] }; } - export function ngModuleWithProviders() { return { ngModule: InternalModule, providers: [SomeService] }; } - export function onlyProviders() { return { providers: [SomeService] }; } - export function ngModuleNumber() { return { ngModule: 42 }; } - export function ngModuleString() { return { ngModule: 'foo' }; } - export function ngModuleObject() { return { ngModule: { foo: 42 } }; } - export function externalNgModule() { return { ngModule: ExternalModule }; } - export function namespacedExternalNgModule() { return { ngModule: mod.ExternalModule }; } - ` - }, - { - name: _('/src/methods.js'), - contents: ` - import {ExternalModule} from './module'; - import * as mod from './module'; - export class SomeService {} - export class InternalModule { - static aNumber() { return 42; } - static aString() { return 'foo'; } - static emptyObject() { return {}; } - static ngModuleIdentifier() { return { ngModule: InternalModule }; } - static ngModuleWithEmptyProviders() { return { ngModule: InternalModule, providers: [] }; } - static ngModuleWithProviders() { return { ngModule: InternalModule, providers: [SomeService] }; } - static onlyProviders() { return { providers: [SomeService] }; } - static ngModuleNumber() { return { ngModule: 42 }; } - static ngModuleString() { return { ngModule: 'foo' }; } - static ngModuleObject() { return { ngModule: { foo: 42 } }; } - static externalNgModule() { return { ngModule: ExternalModule }; } - static namespacedExternalNgModule() { return { ngModule: mod.ExternalModule }; } - - instanceNgModuleIdentifier() { return { ngModule: InternalModule }; } - instanceNgModuleWithEmptyProviders() { return { ngModule: InternalModule, providers: [] }; } - instanceNgModuleWithProviders() { return { ngModule: InternalModule, providers: [SomeService] }; } - instanceExternalNgModule() { return { ngModule: ExternalModule }; } - instanceNamespacedExternalNgModule() { return { ngModule: mod.ExternalModule }; } - } - ` - }, - { - name: _('/src/aliased_class.js'), - contents: ` - var AliasedModule_1; - let AliasedModule = AliasedModule_1 = class AliasedModule { - static forRoot() { return { ngModule: AliasedModule_1 }; } - }; - export { AliasedModule }; - ` - }, - {name: _('/src/module.js'), contents: 'export class ExternalModule {}'}, - ]; - NAMESPACED_IMPORT_FILE = { name: _('/some_directive.js'), contents: ` @@ -2432,56 +2360,6 @@ runInEachFileSystem(() => { }); }); - describe('getModuleWithProvidersFunctions()', () => { - it('should find every exported function that returns an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = - createHost(bundle, new Esm2015ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/functions.js')); - const fns = host.getModuleWithProvidersFunctions(file); - expect(fns.map(fn => [fn.declaration.name!.getText(), fn.ngModule.node.name.text])) - .toEqual([ - ['ngModuleIdentifier', 'InternalModule'], - ['ngModuleWithEmptyProviders', 'InternalModule'], - ['ngModuleWithProviders', 'InternalModule'], - ['externalNgModule', 'ExternalModule'], - ['namespacedExternalNgModule', 'ExternalModule'], - ]); - }); - - it('should find every static method on exported classes that return an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = - createHost(bundle, new Esm2015ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/methods.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.name!.getText(), fn.ngModule.node.name.text])) - .toEqual([ - ['ngModuleIdentifier', 'InternalModule'], - ['ngModuleWithEmptyProviders', 'InternalModule'], - ['ngModuleWithProviders', 'InternalModule'], - ['externalNgModule', 'ExternalModule'], - ['namespacedExternalNgModule', 'ExternalModule'], - ]); - }); - - // https://github.com/angular/angular/issues/29078 - it('should resolve aliased module references to their original declaration', () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = createHost(bundle, new Esm2015ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.name!.getText(), fn.ngModule.node.name.text])).toEqual([ - ['forRoot', 'AliasedModule'], - ]); - }); - }); - describe('getEndOfClass()', () => { it('should return the last static property of the class', () => { const testFile: TestFile = { diff --git a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts index bd28dd68d7..86a3372f69 100644 --- a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts @@ -47,7 +47,6 @@ runInEachFileSystem(() => { let UNWANTED_PROTOTYPE_EXPORT_FILE: TestFile; let TYPINGS_SRC_FILES: TestFile[]; let TYPINGS_DTS_FILES: TestFile[]; - let MODULE_WITH_PROVIDERS_PROGRAM: TestFile[]; let NAMESPACED_IMPORT_FILE: TestFile; // Helpers @@ -774,110 +773,6 @@ runInEachFileSystem(() => { {name: _('/an_external_lib/index.d.ts'), contents: 'export declare class ShadowClass {}'}, ]; - MODULE_WITH_PROVIDERS_PROGRAM = [ - { - name: _('/src/index.js'), - contents: ` - import * as functions from './functions'; - import * as methods from './methods'; - import * as outer_aliased_class from './outer_aliased_class'; - import * as inner_aliased_class from './inner_aliased_class'; - ` - }, - { - name: _('/src/functions.js'), - contents: ` - import {ExternalModule} from './module'; - import * as mod from './module'; - - var SomeService = (function() { - function SomeService() {} - return SomeService; - }()); - - var InternalModule = (function() { - function InternalModule() {} - return InternalModule; - }()); - export function aNumber() { return 42; } - export function aString() { return 'foo'; } - export function emptyObject() { return {}; } - export function ngModuleIdentifier() { return { ngModule: InternalModule }; } - export function ngModuleWithEmptyProviders() { return { ngModule: InternalModule, providers: [] }; } - export function ngModuleWithProviders() { return { ngModule: InternalModule, providers: [SomeService] }; } - export function onlyProviders() { return { providers: [SomeService] }; } - export function ngModuleNumber() { return { ngModule: 42 }; } - export function ngModuleString() { return { ngModule: 'foo' }; } - export function ngModuleObject() { return { ngModule: { foo: 42 } }; } - export function externalNgModule() { return { ngModule: ExternalModule }; } - export function namespacedExternalNgModule() { return { ngModule: mod.ExternalModule }; } - export {SomeService, InternalModule}; - ` - }, - { - name: _('/src/methods.js'), - contents: ` - import {ExternalModule} from './module'; - import * as mod from './module'; - var SomeService = (function() { - function SomeService() {} - return SomeService; - }()); - - var InternalModule = (function() { - function InternalModule() {} - InternalModule.prototype = { - instanceNgModuleIdentifier: function() { return { ngModule: InternalModule }; }, - instanceNgModuleWithEmptyProviders: function() { return { ngModule: InternalModule, providers: [] }; }, - instanceNgModuleWithProviders: function() { return { ngModule: InternalModule, providers: [SomeService] }; }, - instanceExternalNgModule: function() { return { ngModule: ExternalModule }; }, - namespacedExternalNgModule = function() { return { ngModule: mod.ExternalModule }; }, - }; - InternalModule.aNumber = function() { return 42; }; - InternalModule.aString = function() { return 'foo'; }; - InternalModule.emptyObject = function() { return {}; }; - InternalModule.ngModuleIdentifier = function() { return { ngModule: InternalModule }; }; - InternalModule.ngModuleWithEmptyProviders = function() { return { ngModule: InternalModule, providers: [] }; }; - InternalModule.ngModuleWithProviders = function() { return { ngModule: InternalModule, providers: [SomeService] }; }; - InternalModule.onlyProviders = function() { return { providers: [SomeService] }; }; - InternalModule.ngModuleNumber = function() { return { ngModule: 42 }; }; - InternalModule.ngModuleString = function() { return { ngModule: 'foo' }; }; - InternalModule.ngModuleObject = function() { return { ngModule: { foo: 42 } }; }; - InternalModule.externalNgModule = function() { return { ngModule: ExternalModule }; }; - InternalModule.namespacedExternalNgModule = function() { return { ngModule: mod.ExternalModule }; }; - return InternalModule; - }()); - export {SomeService, InternalModule}; - ` - }, - { - name: _('/src/outer_aliased_class.js'), - contents: ` - var AliasedModule = AliasedModule_1 = (function() { - function AliasedModule() {} - return AliasedModule; - }()); - AliasedModule.forRoot = function() { return { ngModule: AliasedModule_1 }; }; - export { AliasedModule }; - var AliasedModule_1; - ` - }, - { - name: _('/src/inner_aliased_class.js'), - contents: ` - var AliasedModule = (function() { - function AliasedModule() {} - AliasedModule_1 = AliasedModule; - AliasedModule.forRoot = function() { return { ngModule: AliasedModule_1 }; }; - var AliasedModule_1; - return AliasedModule; - }()); - export { AliasedModule }; - ` - }, - {name: _('/src/module.js'), contents: 'export class ExternalModule {}'}, - ]; - NAMESPACED_IMPORT_FILE = { name: _('/some_directive.js'), contents: ` @@ -2878,81 +2773,6 @@ runInEachFileSystem(() => { }); }); - describe('getModuleWithProvidersFunctions', () => { - it('should find every exported function that returns an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = createHost(bundle, new Esm5ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/functions.js')); - const fns = host.getModuleWithProvidersFunctions(file); - expect(fns.map(fn => [fn.declaration.name!.getText(), fn.ngModule.node.name.text])) - .toEqual([ - ['ngModuleIdentifier', 'InternalModule'], - ['ngModuleWithEmptyProviders', 'InternalModule'], - ['ngModuleWithProviders', 'InternalModule'], - ['externalNgModule', 'ExternalModule'], - ['namespacedExternalNgModule', 'ExternalModule'], - ]); - }); - - it('should find every static method on exported classes that return an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = createHost(bundle, new Esm5ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/methods.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - [ - 'function() { return { ngModule: InternalModule }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: InternalModule, providers: [] }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: InternalModule, providers: [SomeService] }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: ExternalModule }; }', - 'ExternalModule', - ], - [ - 'function() { return { ngModule: mod.ExternalModule }; }', - 'ExternalModule', - ], - ]); - }); - - it('should resolve aliased module references to their original declaration (outer alias)', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = createHost(bundle, new Esm5ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/outer_aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - ['function() { return { ngModule: AliasedModule_1 }; }', 'AliasedModule'], - ]); - }); - - // https://github.com/angular/angular/issues/29078 - it('should resolve aliased module references to their original declaration (inner alias)', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(_('/src/index.js')); - const host = createHost(bundle, new Esm5ReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/inner_aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - ['function() { return { ngModule: AliasedModule_1 }; }', 'AliasedModule'], - ]); - }); - }); - describe('getEndOfClass()', () => { it('should return the last static property of the class', () => { loadTestFiles([SOME_DIRECTIVE_FILE]); diff --git a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts index 7183693594..b5033c65dc 100644 --- a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts @@ -46,7 +46,6 @@ runInEachFileSystem(() => { let DECORATED_FILES: TestFile[]; let TYPINGS_SRC_FILES: TestFile[]; let TYPINGS_DTS_FILES: TestFile[]; - let MODULE_WITH_PROVIDERS_PROGRAM: TestFile[]; // Helpers const createHost = (bundle: BundleProgram, ngccHost: UmdReflectionHost) => { @@ -932,161 +931,6 @@ runInEachFileSystem(() => { {name: _('/ep/typings/shadow-class.d.ts'), contents: `export declare class ShadowClass {}`}, {name: _('/an_external_lib/index.d.ts'), contents: 'export declare class ShadowClass {}'}, ]; - - MODULE_WITH_PROVIDERS_PROGRAM = [ - { - name: _('/src/index.js'), - contents: ` - (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./functions'), require('./methods'), require('./outer_aliased_class'), require('./inner_aliased_class')) : - typeof define === 'function' && define.amd ? define('index', ['exports', './functions', './methods', './outer_aliased_class', './inner_aliased_class'], factory) : - (factory(global.index,global.functions,global.methods,global.outer_aliased_class,global.inner_aliased_class)); - }(this, (function (exports,functions,methods,outer_aliased_class,inner_aliased_class) { 'use strict'; - })))); - `, - }, - { - name: _('/src/functions.js'), - contents: ` - (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./module')) : - typeof define === 'function' && define.amd ? define('functions', ['exports', './module'], factory) : - (factory(global.functions,global.module)); - }(this, (function (exports,module) { 'use strict'; - var SomeService = (function() { - function SomeService() {} - return SomeService; - }()); - - var InternalModule = (function() { - function InternalModule() {} - return InternalModule; - }()); - - function aNumber() { return 42; } - function aString() { return 'foo'; } - function emptyObject() { return {}; } - function ngModuleIdentifier() { return { ngModule: InternalModule }; } - function ngModuleWithEmptyProviders() { return { ngModule: InternalModule, providers: [] }; } - function ngModuleWithProviders() { return { ngModule: InternalModule, providers: [SomeService] }; } - function onlyProviders() { return { providers: [SomeService] }; } - function ngModuleNumber() { return { ngModule: 42 }; } - function ngModuleString() { return { ngModule: 'foo' }; } - function ngModuleObject() { return { ngModule: { foo: 42 } }; } - function externalNgModule() { return { ngModule: module.ExternalModule }; } - // NOTE: We do not include the "namespaced" export tests in UMD as all UMD exports are already namespaced. - // function namespacedExternalNgModule() { return { ngModule: mod.ExternalModule }; } - - exports.aNumber = aNumber; - exports.aString = aString; - exports.emptyObject = emptyObject; - exports.ngModuleIdentifier = ngModuleIdentifier; - exports.ngModuleWithEmptyProviders = ngModuleWithEmptyProviders; - exports.ngModuleWithProviders = ngModuleWithProviders; - exports.onlyProviders = onlyProviders; - exports.ngModuleNumber = ngModuleNumber; - exports.ngModuleString = ngModuleString; - exports.ngModuleObject = ngModuleObject; - exports.externalNgModule = externalNgModule; - exports.SomeService = SomeService; - exports.InternalModule = InternalModule; - }))); - ` - }, - { - name: _('/src/methods.js'), - contents: ` - (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./module')) : - typeof define === 'function' && define.amd ? define('methods', ['exports', './module'], factory) : - (factory(global.methods,global.module)); - }(this, (function (exports,module) { 'use strict'; - var SomeService = (function() { - function SomeService() {} - return SomeService; - }()); - - var InternalModule = (function() { - function InternalModule() {} - InternalModule.prototype = { - instanceNgModuleIdentifier: function() { return { ngModule: InternalModule }; }, - instanceNgModuleWithEmptyProviders: function() { return { ngModule: InternalModule, providers: [] }; }, - instanceNgModuleWithProviders: function() { return { ngModule: InternalModule, providers: [SomeService] }; }, - instanceExternalNgModule: function() { return { ngModule: module.ExternalModule }; }, - }; - InternalModule.aNumber = function() { return 42; }; - InternalModule.aString = function() { return 'foo'; }; - InternalModule.emptyObject = function() { return {}; }; - InternalModule.ngModuleIdentifier = function() { return { ngModule: InternalModule }; }; - InternalModule.ngModuleWithEmptyProviders = function() { return { ngModule: InternalModule, providers: [] }; }; - InternalModule.ngModuleWithProviders = function() { return { ngModule: InternalModule, providers: [SomeService] }; }; - InternalModule.onlyProviders = function() { return { providers: [SomeService] }; }; - InternalModule.ngModuleNumber = function() { return { ngModule: 42 }; }; - InternalModule.ngModuleString = function() { return { ngModule: 'foo' }; }; - InternalModule.ngModuleObject = function() { return { ngModule: { foo: 42 } }; }; - InternalModule.externalNgModule = function() { return { ngModule: module.ExternalModule }; }; - return InternalModule; - }()); - - exports.SomeService = SomeService; - exports.InternalModule = InternalModule; - }))); - ` - }, - { - name: _('/src/outer_aliased_class.js'), - contents: ` - (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define('outer_aliased_class', ['exports'], factory) : - (factory(global.outer_aliased_class)); - }(this, (function (exports,module) { 'use strict'; - var AliasedModule = AliasedModule_1 = (function() { - function AliasedModule() {} - return AliasedModule; - }()); - AliasedModule.forRoot = function() { return { ngModule: AliasedModule_1 }; }; - exports.AliasedModule = AliasedModule; - var AliasedModule_1; - }))); - ` - }, - { - name: _('/src/inner_aliased_class.js'), - contents: ` - (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define('inner_aliased_class', ['exports'], factory) : - (factory(global.inner_aliased_class)); - }(this, (function (exports,module) { 'use strict'; - var AliasedModule = (function() { - function AliasedModule() {} - AliasedModule_1 = AliasedModule; - AliasedModule.forRoot = function() { return { ngModule: AliasedModule_1 }; }; - var AliasedModule_1; - return AliasedModule; - }()); - exports.AliasedModule = AliasedModule; - }))); - ` - }, - { - name: _('/src/module.js'), - contents: ` - (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define('module', ['exports'], factory) : - (factory(global.module)); - }(this, (function (exports,module) { 'use strict'; - var ExternalModule = (function() { - function ExternalModule() {} - return ExternalModule; - }()); - exports.ExternalModule = ExternalModule; - }))); - ` - }, - ]; }); describe('getDecoratorsOfDeclaration()', () => { @@ -3065,75 +2909,5 @@ runInEachFileSystem(() => { expect(host.getAdjacentNameOfClass(childClass).text).toEqual('InnerChildClass'); }); }); - - describe('getModuleWithProvidersFunctions', () => { - it('should find every exported function that returns an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = createHost(bundle, new UmdReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/functions.js')); - const fns = host.getModuleWithProvidersFunctions(file); - expect(fns.map(fn => [fn.declaration.name!.getText(), fn.ngModule.node.name.text])) - .toEqual([ - ['ngModuleIdentifier', 'InternalModule'], - ['ngModuleWithEmptyProviders', 'InternalModule'], - ['ngModuleWithProviders', 'InternalModule'], - ['externalNgModule', 'ExternalModule'], - ]); - }); - - it('should find every static method on exported classes that return an object that looks like a ModuleWithProviders object', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = createHost(bundle, new UmdReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/methods.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - [ - 'function() { return { ngModule: InternalModule }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: InternalModule, providers: [] }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: InternalModule, providers: [SomeService] }; }', - 'InternalModule', - ], - [ - 'function() { return { ngModule: module.ExternalModule }; }', - 'ExternalModule', - ], - ]); - }); - - it('should resolve aliased module references to their original declaration (outer alias)', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = createHost(bundle, new UmdReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/outer_aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - ['function() { return { ngModule: AliasedModule_1 }; }', 'AliasedModule'], - ]); - }); - - // https://github.com/angular/angular/issues/29078 - it('should resolve aliased module references to their original declaration (inner alias)', - () => { - loadTestFiles(MODULE_WITH_PROVIDERS_PROGRAM); - const bundle = makeTestBundleProgram(getRootFiles(MODULE_WITH_PROVIDERS_PROGRAM)[0]); - const host = createHost(bundle, new UmdReflectionHost(new MockLogger(), false, bundle)); - const file = getSourceFileOrError(bundle.program, _('/src/inner_aliased_class.js')); - const fn = host.getModuleWithProvidersFunctions(file); - expect(fn.map(fn => [fn.declaration.getText(), fn.ngModule.node.name.text])).toEqual([ - ['function() { return { ngModule: AliasedModule_1 }; }', 'AliasedModule'], - ]); - }); - }); }); });