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 df17011a79..e3c634b8f4 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 @@ -9,53 +9,67 @@ 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 {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator'; +import {ClassDeclaration, isNamedClassDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection'; import {NgccReflectionHost} from '../host/ngcc_host'; import {hasNameIdentifier, isDefined} from '../utils'; +/** + * A structure returned from `getModuleWithProvidersFunctions()` that describes functions + * that return ModuleWithProviders objects. + */ export interface ModuleWithProvidersInfo { /** - * The declaration (in the .d.ts file) of the function that returns - * a `ModuleWithProviders object, but has a signature that needs - * a type parameter adding. + * The name of the declared function. */ - declaration: ts.MethodDeclaration|ts.FunctionDeclaration; + name: string; /** - * The NgModule class declaration (in the .d.ts file) to add as a type parameter. + * The declaration of the function that returns the `ModuleWithProviders` object. */ - ngModule: ConcreteDeclaration; + 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: Reference; } export type ModuleWithProvidersAnalyses = Map; export const ModuleWithProvidersAnalyses = Map; export class ModuleWithProvidersAnalyzer { + private evaluator = new PartialEvaluator(this.host, this.typeChecker, null); + constructor( - private host: NgccReflectionHost, private referencesRegistry: ReferencesRegistry, - private processDts: boolean) {} + private host: NgccReflectionHost, private typeChecker: ts.TypeChecker, + private referencesRegistry: ReferencesRegistry, private processDts: boolean) {} analyzeProgram(program: ts.Program): ModuleWithProvidersAnalyses { - const analyses = new ModuleWithProvidersAnalyses(); + const analyses: ModuleWithProvidersAnalyses = new ModuleWithProvidersAnalyses(); const rootFiles = this.getRootFiles(program); rootFiles.forEach(f => { const fns = this.getModuleWithProvidersFunctions(f); fns && fns.forEach(fn => { - if (fn.ngModule.viaModule === null) { + if (fn.ngModule.bestGuessOwningModule === null) { // Record the usage of an internal module as it needs to become an exported symbol this.referencesRegistry.add(fn.ngModule.node, new Reference(fn.ngModule.node)); } // Only when processing the dts files do we need to determine which declaration to update. if (this.processDts) { - const dtsFn = this.getDtsDeclarationForFunction(fn); - const typeParam = dtsFn.type && ts.isTypeReferenceNode(dtsFn.type) && - dtsFn.type.typeArguments && dtsFn.type.typeArguments[0] || + const dtsFn = this.getDtsModuleWithProvidersFunction(fn); + const dtsFnType = dtsFn.declaration.type; + const typeParam = dtsFnType && ts.isTypeReferenceNode(dtsFnType) && + dtsFnType.typeArguments && dtsFnType.typeArguments[0] || null; if (!typeParam || isAnyKeyword(typeParam)) { - const ngModule = this.resolveNgModuleReference(fn); - const dtsFile = dtsFn.getSourceFile(); - const analysis = analyses.has(dtsFile) ? analyses.get(dtsFile) : []; - analysis.push({declaration: dtsFn, ngModule}); + const dtsFile = dtsFn.declaration.getSourceFile(); + const analysis = analyses.has(dtsFile) ? analyses.get(dtsFile)! : []; + analysis.push(dtsFn); analyses.set(dtsFile, analysis); } } @@ -68,11 +82,11 @@ export class ModuleWithProvidersAnalyzer { return program.getRootFileNames().map(f => program.getSourceFile(f)).filter(isDefined); } - private getModuleWithProvidersFunctions(f: ts.SourceFile): ModuleWithProvidersFunction[] { + private getModuleWithProvidersFunctions(f: ts.SourceFile): ModuleWithProvidersInfo[] { const exports = this.host.getExportsOfModule(f); if (!exports) return []; - const infos: ModuleWithProvidersFunction[] = []; - exports.forEach((declaration, name) => { + const infos: ModuleWithProvidersInfo[] = []; + exports.forEach((declaration) => { if (declaration.node === null) { return; } @@ -111,7 +125,7 @@ export class ModuleWithProvidersAnalyzer { */ private parseForModuleWithProviders( name: string, node: ts.Node|null, implementation: ts.Node|null = node, - container: ts.Declaration|null = null): ModuleWithProvidersFunction|null { + container: ts.Declaration|null = null): ModuleWithProvidersInfo|null { if (implementation === null || (!ts.isFunctionDeclaration(implementation) && !ts.isMethodDeclaration(implementation) && !ts.isFunctionExpression(implementation))) { @@ -122,47 +136,40 @@ export class ModuleWithProvidersAnalyzer { 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)) { + if (body === null || body.length === 0) { 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)) { + // Get hold of the return statement expression for the function + const lastStatement = body[body.length - 1]; + if (!ts.isReturnStatement(lastStatement) || lastStatement.expression === undefined) { 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)) { + // Evaluate this expression and extract the `ngModule` reference + const result = this.evaluator.evaluate(lastStatement.expression); + if (!(result instanceof Map) || !result.has('ngModule')) { return null; } - return { - name, - ngModule: ngModuleDeclaration as ConcreteDeclaration, - declaration, - container - }; + + const ngModuleRef = result.get('ngModule')!; + if (!(ngModuleRef instanceof Reference)) { + return null; + } + + if (!isNamedClassDeclaration(ngModuleRef.node) && + !isNamedVariableDeclaration(ngModuleRef.node)) { + throw new Error(`The identity given by ${ngModuleRef.debugName} referenced in "${ + declaration!.getText()}" doesn't appear to be a "class" declaration.`); + } + + const ngModule = ngModuleRef as Reference; + return {name, ngModule, declaration, container}; } - private getDtsDeclarationForFunction(fn: ModuleWithProvidersFunction) { + private getDtsModuleWithProvidersFunction(fn: ModuleWithProvidersInfo): ModuleWithProvidersInfo { let dtsFn: ts.Declaration|null = null; const containerClass = fn.container && this.host.getClassSymbol(fn.container); if (containerClass) { @@ -183,15 +190,16 @@ export class ModuleWithProvidersAnalyzer { throw new Error(`Matching type declaration for ${ fn.declaration.getText()} is not a function: ${dtsFn.getText()}`); } - return dtsFn; + const container = containerClass ? containerClass.declaration.valueDeclaration : null; + const ngModule = this.resolveNgModuleReference(fn); + return {name: fn.name, container, declaration: dtsFn, ngModule}; } - private resolveNgModuleReference(fn: ModuleWithProvidersFunction): - ConcreteDeclaration { + private resolveNgModuleReference(fn: ModuleWithProvidersInfo): Reference { const ngModule = fn.ngModule; // For external module references, use the declaration as is. - if (ngModule.viaModule !== null) { + if (ngModule.bestGuessOwningModule !== null) { return ngModule; } @@ -202,14 +210,13 @@ export class ModuleWithProvidersAnalyzer { throw new Error(`No typings declaration can be found for the referenced NgModule class in ${ fn.declaration.getText()}.`); } - if (!ts.isClassDeclaration(dtsNgModule) || !hasNameIdentifier(dtsNgModule)) { + if (!isNamedClassDeclaration(dtsNgModule)) { throw new Error(`The referenced NgModule in ${ fn.declaration .getText()} is not a named class declaration in the typings program; instead we get ${ dtsNgModule.getText()}`); } - - return {node: dtsNgModule, known: null, viaModule: null, identity: null}; + return new Reference(dtsNgModule, null); } } @@ -222,27 +229,3 @@ 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/packages/transformer.ts b/packages/compiler-cli/ngcc/src/packages/transformer.ts index 005482f3f7..eded53a9a9 100644 --- a/packages/compiler-cli/ngcc/src/packages/transformer.ts +++ b/packages/compiler-cli/ngcc/src/packages/transformer.ts @@ -156,8 +156,9 @@ export class Transformer { diagnostic => diagnostics.push(diagnostic), this.tsConfig); const decorationAnalyses = decorationAnalyzer.analyzeProgram(); - const moduleWithProvidersAnalyzer = - new ModuleWithProvidersAnalyzer(reflectionHost, referencesRegistry, bundle.dts !== null); + const moduleWithProvidersAnalyzer = new ModuleWithProvidersAnalyzer( + reflectionHost, bundle.src.program.getTypeChecker(), referencesRegistry, + bundle.dts !== null); const moduleWithProvidersAnalyses = moduleWithProvidersAnalyzer && moduleWithProvidersAnalyzer.analyzeProgram(bundle.src.program); diff --git a/packages/compiler-cli/ngcc/src/rendering/esm_rendering_formatter.ts b/packages/compiler-cli/ngcc/src/rendering/esm_rendering_formatter.ts index d2b1cae500..81739a50c1 100644 --- a/packages/compiler-cli/ngcc/src/rendering/esm_rendering_formatter.ts +++ b/packages/compiler-cli/ngcc/src/rendering/esm_rendering_formatter.ts @@ -196,7 +196,7 @@ export class EsmRenderingFormatter implements RenderingFormatter { const ngModuleName = info.ngModule.node.name.text; const declarationFile = absoluteFromSourceFile(info.declaration.getSourceFile()); const ngModuleFile = absoluteFromSourceFile(info.ngModule.node.getSourceFile()); - const importPath = info.ngModule.viaModule || + const importPath = info.ngModule.ownedByModuleGuess || (declarationFile !== ngModuleFile ? stripExtension(`./${relative(dirname(declarationFile), ngModuleFile)}`) : null); diff --git a/packages/compiler-cli/ngcc/test/analysis/module_with_providers_analyzer_spec.ts b/packages/compiler-cli/ngcc/test/analysis/module_with_providers_analyzer_spec.ts index a775dd4cc7..51ca221319 100644 --- a/packages/compiler-cli/ngcc/test/analysis/module_with_providers_analyzer_spec.ts +++ b/packages/compiler-cli/ngcc/test/analysis/module_with_providers_analyzer_spec.ts @@ -9,6 +9,7 @@ import * as ts from 'typescript'; import {absoluteFrom, AbsoluteFsPath, getSourceFileOrError} from '../../../src/ngtsc/file_system'; import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing'; +import {isNamedClassDeclaration} from '../../../src/ngtsc/reflection'; import {getDeclaration} from '../../../src/ngtsc/testing'; import {loadTestFiles} from '../../../test/helpers'; import {ModuleWithProvidersAnalyses, ModuleWithProvidersAnalyzer} from '../../src/analysis/module_with_providers_analyzer'; @@ -39,6 +40,7 @@ runInEachFileSystem(() => { export * from './implicit'; export * from './no-providers'; export * from './module'; + export * from './delegated'; ` }, { @@ -214,6 +216,89 @@ runInEachFileSystem(() => { } ` }, + { + name: _('/node_modules/test-package/src/delegated.js'), + contents: ` + import * as implicit from './implicit'; + import * as explicit from './explicit'; + import * as anyModule from './any'; + + export function delegatedImplicitInternalFunction() { + return implicit.implicitInternalFunction(); + } + export function delegatedImplicitExternalFunction() { + return implicit.implicitExternalFunction(); + } + export function delegatedImplicitLibraryFunction() { + return implicit.implicitLibraryFunction(); + } + export class DelegatedImplicitClass { + static implicitInternalMethod() { + return implicit.ImplicitClass.implicitInternalMethod(); + } + static implicitExternalMethod() { + return implicit.ImplicitClass.implicitExternalMethod(); + } + static implicitLibraryMethod() { + return implicit.ImplicitClass.implicitLibraryMethod(); + } + } + + export function delegatedExplicitInternalFunction() { + return explicit.explicitInternalFunction(); + } + export function delegatedExplicitExternalFunction() { + return explicit.explicitExternalFunction(); + } + export function delegatedExplicitLibraryFunction() { + return explicit.explicitLibraryFunction(); + } + export class DelegatedExplicitClass { + static explicitInternalMethod() { + return explicit.ExplicitClass.explicitInternalMethod(); + } + static explicitExternalMethod() { + return explicit.ExplicitClass.explicitExternalMethod(); + } + static explicitLibraryMethod() { + return explicit.ExplicitClass.explicitLibraryMethod(); + } + } + + export function delegatedAnyInternalFunction() { + return anyModule.anyInternalFunction(); + } + export function delegatedAnyExternalFunction() { + return anyModule.anyExternalFunction(); + } + export function delegatedAnyLibraryFunction() { + return anyModule.anyLibraryFunction(); + } + export class DelegatedAnyClass { + static anyInternalMethod() { + return anyModule.AnyClass.anyInternalMethod(); + } + static anyExternalMethod() { + return anyModule.AnyClass.anyExternalMethod(); + } + static anyLibraryMethod() { + return anyModule.AnyClass.anyLibraryMethod(); + } + } + + export function withParams(a: string) { + return explicit.explicitInternalFunction(); + } + + export function withOptionalParams(a: string = 'default') { + return explicit.explicitInternalFunction(); + } + + export function doubleDelegation(a: string = 'default') { + return withParams(a); + } + ` + }, { name: _('/node_modules/test-package/src/module.js'), contents: ` @@ -234,6 +319,7 @@ runInEachFileSystem(() => { export * from './implicit'; export * from './no-providers'; export * from './module'; + export * from './delegated'; ` }, { @@ -284,6 +370,47 @@ runInEachFileSystem(() => { } ` }, + { + name: _('/node_modules/test-package/typings/delegated.d.ts'), + contents: ` + // None of the ModuleWithProviders functions/methods in this file provide the + // necessary type parameters and so need to be processed by the analyzer. + // Each group of functions/methods here delegate their return values to other + // functions/methods that either explicitly provide a type parameter or need + // processing by the analyzer themselves. + + export declare function delegatedImplicitInternalFunction(): ModuleWithProviders; + export declare function delegatedImplicitExternalFunction(): ModuleWithProviders; + export declare function delegatedImplicitLibraryFunction(): ModuleWithProviders; + export declare class DelegatedImplicitClass { + static implicitInternalMethod(): ModuleWithProviders; + static implicitExternalMethod(): ModuleWithProviders; + static implicitLibraryMethod(): ModuleWithProviders; + } + + export declare function delegatedExplicitInternalFunction(): ModuleWithProviders; + export declare function delegatedExplicitExternalFunction(): ModuleWithProviders; + export declare function delegatedExplicitLibraryFunction(): ModuleWithProviders; + export declare class DelegatedExplicitClass { + static explicitInternalMethod(): ModuleWithProviders; + static explicitExternalMethod(): ModuleWithProviders; + static explicitLibraryMethod(): ModuleWithProviders; + } + + export declare function delegatedAnyInternalFunction(): ModuleWithProviders; + export declare function delegatedAnyExternalFunction(): ModuleWithProviders; + export declare function delegatedAnyLibraryFunction(): ModuleWithProviders; + export declare class DelegatedAnyClass { + static anyInternalMethod(): ModuleWithProviders; + static anyExternalMethod(): ModuleWithProviders; + static anyLibraryMethod(): ModuleWithProviders; + } + + export declare function withParams(a: string): ModuleWithProviders; + export declare function withOptionalParams(a: string = 'default'): ModuleWithProviders; + export declare function doubleDelegation(a: string = 'default'): ModuleWithProviders; + ` + }, { name: _('/node_modules/test-package/typings/no-providers.d.ts'), contents: ` @@ -338,7 +465,8 @@ runInEachFileSystem(() => { referencesRegistry = new NgccReferencesRegistry(host); const processDts = true; - const analyzer = new ModuleWithProvidersAnalyzer(host, referencesRegistry, processDts); + const analyzer = new ModuleWithProvidersAnalyzer( + host, bundle.src.program.getTypeChecker(), referencesRegistry, processDts); analyses = analyzer.analyzeProgram(program); }); @@ -354,9 +482,11 @@ runInEachFileSystem(() => { expect(anyAnalysis).toContain(['anyInternalFunction', 'AnyInternalModule', null]); expect(anyAnalysis).toContain(['anyExternalFunction', 'ExternalModule', null]); expect(anyAnalysis).toContain(['anyLibraryFunction', 'LibraryModule', 'some-library']); - expect(anyAnalysis).toContain(['anyInternalMethod', 'AnyInternalModule', null]); - expect(anyAnalysis).toContain(['anyExternalMethod', 'ExternalModule', null]); - expect(anyAnalysis).toContain(['anyLibraryMethod', 'LibraryModule', 'some-library']); + expect(anyAnalysis).toContain(['AnyClass.anyInternalMethod', 'AnyInternalModule', null]); + expect(anyAnalysis).toContain(['AnyClass.anyExternalMethod', 'ExternalModule', null]); + expect(anyAnalysis).toContain([ + 'AnyClass.anyLibraryMethod', 'LibraryModule', 'some-library' + ]); }); it('should track internal module references in the references registry', () => { @@ -377,9 +507,82 @@ runInEachFileSystem(() => { expect(anyAnalysis).toContain(['implicitInternalFunction', 'ImplicitInternalModule', null]); expect(anyAnalysis).toContain(['implicitExternalFunction', 'ExternalModule', null]); expect(anyAnalysis).toContain(['implicitLibraryFunction', 'LibraryModule', 'some-library']); - expect(anyAnalysis).toContain(['implicitInternalMethod', 'ImplicitInternalModule', null]); - expect(anyAnalysis).toContain(['implicitExternalMethod', 'ExternalModule', null]); - expect(anyAnalysis).toContain(['implicitLibraryMethod', 'LibraryModule', 'some-library']); + expect(anyAnalysis).toContain([ + 'ImplicitClass.implicitInternalMethod', 'ImplicitInternalModule', null + ]); + expect(anyAnalysis).toContain([ + 'ImplicitClass.implicitExternalMethod', 'ExternalModule', null + ]); + expect(anyAnalysis).toContain([ + 'ImplicitClass.implicitLibraryMethod', 'LibraryModule', 'some-library' + ]); + }); + + + it('should find declarations that delegate by calling another function', () => { + const delegatedAnalysis = getAnalysisDescription( + analyses, _('/node_modules/test-package/typings/delegated.d.ts')); + + expect(delegatedAnalysis).toContain([ + 'delegatedExplicitInternalFunction', 'ExplicitInternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'delegatedExplicitExternalFunction', 'ExternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'delegatedExplicitLibraryFunction', 'LibraryModule', 'some-library' + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedExplicitClass.explicitInternalMethod', 'ExplicitInternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedExplicitClass.explicitExternalMethod', 'ExternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedExplicitClass.explicitLibraryMethod', 'LibraryModule', 'some-library' + ]); + + expect(delegatedAnalysis).toContain([ + 'delegatedImplicitInternalFunction', 'ImplicitInternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'delegatedImplicitExternalFunction', 'ExternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'delegatedImplicitLibraryFunction', 'LibraryModule', 'some-library' + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedImplicitClass.implicitInternalMethod', 'ImplicitInternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedImplicitClass.implicitExternalMethod', 'ExternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedImplicitClass.implicitLibraryMethod', 'LibraryModule', 'some-library' + ]); + + expect(delegatedAnalysis).toContain([ + 'delegatedAnyInternalFunction', 'AnyInternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'delegatedAnyExternalFunction', 'ExternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'delegatedAnyLibraryFunction', 'LibraryModule', 'some-library' + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedAnyClass.anyInternalMethod', 'AnyInternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedAnyClass.anyExternalMethod', 'ExternalModule', null + ]); + expect(delegatedAnalysis).toContain([ + 'DelegatedAnyClass.anyLibraryMethod', 'LibraryModule', 'some-library' + ]); + + expect(delegatedAnalysis).toContain(['withParams', 'ExplicitInternalModule', null]); + expect(delegatedAnalysis).toContain(['withOptionalParams', 'ExplicitInternalModule', null]); + expect(delegatedAnalysis).toContain(['doubleDelegation', 'ExplicitInternalModule', null]); }); it('should find declarations that do not specify a `providers` property in the return type', @@ -416,11 +619,15 @@ runInEachFileSystem(() => { const analysis = analyses.get(file); return analysis ? analysis.map( info => - [info.declaration.name!.getText(), + [getName(info.container) + info.declaration.name!.getText(), (info.ngModule.node as ts.ClassDeclaration).name!.getText(), - info.ngModule.viaModule]) : + info.ngModule.ownedByModuleGuess]) : []; } + + function getName(node: ts.Declaration|null): string { + return node && isNamedClassDeclaration(node) ? `${node.name.text}.` : ''; + } }); }); @@ -540,7 +747,8 @@ runInEachFileSystem(() => { const referencesRegistry = new NgccReferencesRegistry(host); const processDts = true; - const analyzer = new ModuleWithProvidersAnalyzer(host, referencesRegistry, processDts); + const analyzer = new ModuleWithProvidersAnalyzer( + host, bundle.src.program.getTypeChecker(), referencesRegistry, processDts); const analyses = analyzer.analyzeProgram(program); const file = getSourceFileOrError( @@ -570,7 +778,8 @@ runInEachFileSystem(() => { const referencesRegistry = new NgccReferencesRegistry(host); const processDts = false; // Emulate the scenario where typings have already been processed - const analyzer = new ModuleWithProvidersAnalyzer(host, referencesRegistry, processDts); + const analyzer = new ModuleWithProvidersAnalyzer( + host, bundle.src.program.getTypeChecker(), referencesRegistry, processDts); const analyses = analyzer.analyzeProgram(program); expect(analyses.size).toBe(0); diff --git a/packages/compiler-cli/ngcc/test/rendering/dts_renderer_spec.ts b/packages/compiler-cli/ngcc/test/rendering/dts_renderer_spec.ts index 101427f31c..5ede7165f8 100644 --- a/packages/compiler-cli/ngcc/test/rendering/dts_renderer_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/dts_renderer_spec.ts @@ -78,7 +78,8 @@ function createTestRenderer( const decorationAnalyses = new DecorationAnalyzer(fs, bundle, host, referencesRegistry).analyzeProgram(); const moduleWithProvidersAnalyses = - new ModuleWithProvidersAnalyzer(host, referencesRegistry, true) + new ModuleWithProvidersAnalyzer( + host, bundle.src.program.getTypeChecker(), referencesRegistry, true) .analyzeProgram(bundle.src.program); const privateDeclarationsAnalyses = new PrivateDeclarationsAnalyzer(host, referencesRegistry).analyzeProgram(bundle.src.program); diff --git a/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts b/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts index 43f39e3080..d603411e60 100644 --- a/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts @@ -574,7 +574,8 @@ export { D }; const referencesRegistry = new NgccReferencesRegistry(host); const moduleWithProvidersAnalyses = - new ModuleWithProvidersAnalyzer(host, referencesRegistry, true) + new ModuleWithProvidersAnalyzer( + host, bundle.src.program.getTypeChecker(), referencesRegistry, true) .analyzeProgram(bundle.src.program); const typingsFile = getSourceFileOrError( bundle.dts!.program, _('/node_modules/test-package/typings/index.d.ts')); @@ -611,7 +612,8 @@ export { D }; const referencesRegistry = new NgccReferencesRegistry(host); const moduleWithProvidersAnalyses = - new ModuleWithProvidersAnalyzer(host, referencesRegistry, true) + new ModuleWithProvidersAnalyzer( + host, bundle.src.program.getTypeChecker(), referencesRegistry, true) .analyzeProgram(bundle.src.program); const typingsFile = getSourceFileOrError( bundle.dts!.program, _('/node_modules/test-package/typings/module.d.ts'));