fix(ngcc): support minified ES5 scenarios (#33777)

The reflection hosts have been updated to support the following
code forms, which were found in some minified library code:

* The class IIFE not being wrapped in parentheses.
* Calls to `__decorate()` being combined with the IIFE return statement.

PR Close #33777
This commit is contained in:
Pete Bacon Darwin
2019-11-13 08:40:51 +00:00
committed by Kara Erickson
parent e1df98be17
commit 49e517d049
6 changed files with 210 additions and 15 deletions

View File

@ -142,6 +142,16 @@ var EmptyClass = (function() {
}
return EmptyClass;
}());
var NoParensClass = function() {
function EmptyClass() {
}
return EmptyClass;
}();
var InnerParensClass = (function() {
function EmptyClass() {
}
return EmptyClass;
})();
var NoDecoratorConstructorClass = (function() {
function NoDecoratorConstructorClass(foo) {
}
@ -1855,6 +1865,40 @@ exports.ExternalModule = ExternalModule;
expect(innerSymbol.implementation).toBe(outerSymbol.implementation);
});
it('should return the class symbol for an ES5 class whose IIFE is not wrapped in parens',
() => {
loadTestFiles([SIMPLE_CLASS_FILE]);
const {program, host: compilerHost} = makeTestBundleProgram(SIMPLE_CLASS_FILE.name);
const host =
new CommonJsReflectionHost(new MockLogger(), false, program, compilerHost);
const outerNode = getDeclaration(
program, SIMPLE_CLASS_FILE.name, 'NoParensClass', isNamedVariableDeclaration);
const innerNode =
getIifeBody(outerNode) !.statements.find(isNamedFunctionDeclaration) !;
const classSymbol = host.getClassSymbol(outerNode);
expect(classSymbol).toBeDefined();
expect(classSymbol !.declaration.valueDeclaration).toBe(outerNode);
expect(classSymbol !.implementation.valueDeclaration).toBe(innerNode);
});
it('should return the class symbol for an ES5 class whose IIFE is not wrapped with inner parens',
() => {
loadTestFiles([SIMPLE_CLASS_FILE]);
const {program, host: compilerHost} = makeTestBundleProgram(SIMPLE_CLASS_FILE.name);
const host =
new CommonJsReflectionHost(new MockLogger(), false, program, compilerHost);
const outerNode = getDeclaration(
program, SIMPLE_CLASS_FILE.name, 'InnerParensClass', isNamedVariableDeclaration);
const innerNode =
getIifeBody(outerNode) !.statements.find(isNamedFunctionDeclaration) !;
const classSymbol = host.getClassSymbol(outerNode);
expect(classSymbol).toBeDefined();
expect(classSymbol !.declaration.valueDeclaration).toBe(outerNode);
expect(classSymbol !.implementation.valueDeclaration).toBe(innerNode);
});
it('should return undefined if node is not an ES5 class', () => {
loadTestFiles([FOO_FUNCTION_FILE]);
const {program, host: compilerHost} = makeTestBundleProgram(FOO_FUNCTION_FILE.name);