fix(ngcc): override getInternalNameOfClass() and getAdjacentNameOfClass() for ES5 (#33533)

In ES5 the class consists of an outer variable declaration that is
initialised by an IIFE. Inside the IIFE the class is implemented by
an inner function declaration that is returned from the IIFE.
This inner declaration may have a different name to the outer
declaration.

This commit overrides `getInternalNameOfClass()` and
`getAdjacentNameOfClass()` in `Esm5ReflectionHost` with methods that
can find the correct inner declaration name identifier.

PR Close #33533
This commit is contained in:
Pete Bacon Darwin
2019-11-01 16:55:10 +00:00
committed by atscott
parent 90f33dd11d
commit 93a23b9ae0
5 changed files with 237 additions and 0 deletions

View File

@ -86,6 +86,23 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost {
return iife.parent.arguments[0];
}
getInternalNameOfClass(clazz: ClassDeclaration): ts.Identifier {
const innerClass = this.getInnerFunctionDeclarationFromClassDeclaration(clazz);
if (innerClass === undefined) {
throw new Error(
`getInternalNameOfClass() called on a non-ES5 class: expected ${clazz.name.text} to have an inner class declaration`);
}
if (innerClass.name === undefined) {
throw new Error(
`getInternalNameOfClass() called on a class with an anonymous inner declaration: expected a name on:\n${innerClass.getText()}`);
}
return innerClass.name;
}
getAdjacentNameOfClass(clazz: ClassDeclaration): ts.Identifier {
return this.getInternalNameOfClass(clazz);
}
/**
* In ES5, the implementation of a class is a function expression that is hidden inside an IIFE,
* whose value is assigned to a variable (which represents the class to the rest of the program).