From 4c78984ad26825851d78d6f0339d8e4cb7bf1e54 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 2 Jul 2021 12:33:51 +0200 Subject: [PATCH] fix(compiler-cli): support reflecting namespace declarations (#42728) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DTS bundling, will cause originally namespaced imports become namespace declarations within the same file. Example: Before bundling ```ts import * as i1 from './router'; export declare class RouterModule { constructor(guard: any, router: Router); static ɵmod: i0.ɵɵNgModuleDeclaration; } ``` After bundling ``` declare namespace i1 { export { RouterOutletContract, RouterOutlet } } export declare class RouterModule { constructor(guard: any, router: Router); static ɵmod: i0.ɵɵNgModuleDeclaration; } ``` And therefore this commit adds support for reflecting types that are defined in such namespace declarations. Closes #42064 PR Close #42728 --- .../src/ngtsc/reflection/src/typescript.ts | 2 ++ .../src/ngtsc/reflection/test/ts_host_spec.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts index a08a088a68..7c3ebc6e56 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts @@ -548,6 +548,8 @@ export function reflectTypeEntityToDeclaration( throw new Error(`Module specifier is not a string`); } return {node, from: importDecl.moduleSpecifier.text}; + } else if (ts.isModuleDeclaration(decl)) { + return {node, from: null}; } else { throw new Error(`Unknown import type?`); } diff --git a/packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts b/packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts index d298d2441c..fd5c7c7ffb 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts @@ -153,6 +153,30 @@ runInEachFileSystem(() => { expectParameter(args[0], 'bar', {moduleName: './bar', name: 'Bar'}); }); + it('should reflect an argument from a namespace declarations', () => { + const {program} = makeProgram([{ + name: _('/entry.ts'), + contents: ` + export declare class Bar {} + declare namespace i1 { + export { + Bar, + } + } + + class Foo { + constructor(bar: i1.Bar) {} + } + ` + }]); + const clazz = getDeclaration(program, _('/entry.ts'), 'Foo', isNamedClassDeclaration); + const checker = program.getTypeChecker(); + const host = new TypeScriptReflectionHost(checker); + const args = host.getConstructorParameters(clazz)!; + expect(args.length).toBe(1); + expectParameter(args[0], 'bar', 'i1.Bar'); + }); + it('should reflect an argument from a default import', () => { const {program} = makeProgram([ {