fix(ivy): ngcc - handle prototype pseudo-member from typings file in ESM5 host (#29158)
When processing a JavaScript program, TS may come across a symbol that has been imported from a TypeScript typings file. In this case the compiler may pass the ReflectionHost a `prototype` symbol as an export of the class. This pseudo-member symbol has no declarations, which previously caused the code in `Esm5ReflectionHost.reflectMembers()` to crash. Now we just quietly ignore such a symbol and leave `Esm2015ReflectionHost` to deal with it. (As it happens `Esm2015ReflectionHost` also quietly ignores this symbol). PR Close #29158
This commit is contained in:
parent
d4728c40d9
commit
142ac41cac
@ -775,6 +775,9 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
|||||||
|
|
||||||
const node = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
|
const node = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
// If the symbol has been imported from a TypeScript typings file then the compiler
|
||||||
|
// may pass the `prototype` symbol as an export of the class.
|
||||||
|
// But this has no declaration. In this case we just quietly ignore it.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost {
|
|||||||
protected reflectMembers(symbol: ts.Symbol, decorators?: Decorator[], isStatic?: boolean):
|
protected reflectMembers(symbol: ts.Symbol, decorators?: Decorator[], isStatic?: boolean):
|
||||||
ClassMember[]|null {
|
ClassMember[]|null {
|
||||||
const node = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
|
const node = symbol.valueDeclaration || symbol.declarations && symbol.declarations[0];
|
||||||
const propertyDefinition = getPropertyDefinition(node);
|
const propertyDefinition = node && getPropertyDefinition(node);
|
||||||
if (propertyDefinition) {
|
if (propertyDefinition) {
|
||||||
const members: ClassMember[] = [];
|
const members: ClassMember[] = [];
|
||||||
if (propertyDefinition.setter) {
|
if (propertyDefinition.setter) {
|
||||||
|
@ -520,6 +520,15 @@ const DECORATED_FILES = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const UNWANTED_PROTOTYPE_EXPORT_FILE = {
|
||||||
|
name: '/library.d.ts',
|
||||||
|
contents: `
|
||||||
|
export declare class SomeParam {
|
||||||
|
someInstanceMethod(): void;
|
||||||
|
static someStaticProp: any;
|
||||||
|
}`
|
||||||
|
};
|
||||||
|
|
||||||
describe('Esm5ReflectionHost', () => {
|
describe('Esm5ReflectionHost', () => {
|
||||||
|
|
||||||
describe('getDecoratorsOfDeclaration()', () => {
|
describe('getDecoratorsOfDeclaration()', () => {
|
||||||
@ -906,6 +915,16 @@ describe('Esm5ReflectionHost', () => {
|
|||||||
expect(decorators[0].args).toEqual([]);
|
expect(decorators[0].args).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ignore the prototype pseudo-static property on class imported from typings files',
|
||||||
|
() => {
|
||||||
|
const program = makeTestProgram(UNWANTED_PROTOTYPE_EXPORT_FILE);
|
||||||
|
const host = new Esm5ReflectionHost(false, program.getTypeChecker());
|
||||||
|
const classNode = getDeclaration(
|
||||||
|
program, UNWANTED_PROTOTYPE_EXPORT_FILE.name, 'SomeParam', ts.isClassDeclaration);
|
||||||
|
const members = host.getMembersOfClass(classNode);
|
||||||
|
expect(members.find(m => m.name === 'prototype')).toBeUndefined();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getConstructorParameters', () => {
|
describe('getConstructorParameters', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user