fix(ngcc): handle imports in dts files when processing UMD (#34356)

When statically evalulating UMD code it is possible to find
that we are looking for the declaration of an identifier that
actually came from a typings file (rather than a UMD file).

Previously, the UMD reflection host would always try to use
a UMD specific algorithm for finding identifier declarations,
but when the id is actually in a typings file this resulted in the
returned declaration being the containing file of the declaration
rather than the declaration itself.

Now the UMD reflection host will check to see if the file containing
the identifier is a typings file and use the appropriate stategy.

PR Close #34356
This commit is contained in:
Pete Bacon Darwin 2019-12-11 17:00:47 +00:00 committed by Kara Erickson
parent 5f2897be0b
commit c77656e2dd
2 changed files with 39 additions and 1 deletions

View File

@ -36,7 +36,8 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
}
getDeclarationOfIdentifier(id: ts.Identifier): Declaration|null {
return this.getUmdImportedDeclaration(id) || super.getDeclarationOfIdentifier(id);
return (!id.getSourceFile().isDeclarationFile && this.getUmdImportedDeclaration(id)) ||
super.getDeclarationOfIdentifier(id);
}
getExportsOfModule(module: ts.Node): Map<string, Declaration>|null {

View File

@ -1777,6 +1777,43 @@ runInEachFileSystem(() => {
expect(actualDeclaration !.node).toBe(expectedDeclarationNode);
expect(actualDeclaration !.viaModule).toBe('@angular/core');
});
it('should return the correct declaration of an identifier imported in a typings file',
() => {
const FILES = [
{
name: _('/node_modules/test-package/index.d.ts'),
contents: `
import {SubModule} from 'sub_module';
export const x = SubModule;
`,
},
{
name: _('/node_modules/packages.json'),
contents: '{ "typings: "index.d.ts" }',
},
{
name: _('/node_modules/sub_module/index.d.ts'),
contents: `export class SubModule {}`,
}
];
loadTestFiles(FILES);
const {program, host: compilerHost} = makeTestBundleProgram(FILES[0].name);
const host = new UmdReflectionHost(new MockLogger(), false, program, compilerHost);
const expectedDeclaration =
getDeclaration(program, FILES[2].name, 'SubModule', isNamedClassDeclaration);
const x = getDeclaration(program, FILES[0].name, 'x', isNamedVariableDeclaration);
if (x.initializer === undefined || !ts.isIdentifier(x.initializer)) {
return fail('Expected constant `x` to have an identifer as an initializer.');
}
const decl = host.getDeclarationOfIdentifier(x.initializer);
if (decl === null) {
return fail('Expected to find a declaration for ' + x.initializer.getText());
}
expect(decl.viaModule).toEqual('sub_module');
expect(decl.node).toBe(expectedDeclaration);
});
});
describe('getExportsOfModule()', () => {