diff --git a/packages/compiler-cli/src/ngcc/src/parsing/esm2015_parser.ts b/packages/compiler-cli/src/ngcc/src/parsing/esm2015_parser.ts index a476365fc8..32fbcd344f 100644 --- a/packages/compiler-cli/src/ngcc/src/parsing/esm2015_parser.ts +++ b/packages/compiler-cli/src/ngcc/src/parsing/esm2015_parser.ts @@ -24,20 +24,24 @@ export class Esm2015FileParser implements FileParser { const moduleSymbol = this.checker.getSymbolAtLocation(file); const map = new Map(); if (moduleSymbol) { - const exportClasses = this.checker.getExportsOfModule(moduleSymbol) - .map(getOriginalSymbol(this.checker)) - .filter(exportSymbol => exportSymbol.flags & ts.SymbolFlags.Class); - - const classDeclarations = exportClasses.map(exportSymbol => exportSymbol.valueDeclaration) - .filter(isDefined) - .filter(ts.isClassDeclaration); + const exportedSymbols = + this.checker.getExportsOfModule(moduleSymbol).map(getOriginalSymbol(this.checker)); + const exportedDeclarations = + exportedSymbols.map(exportSymbol => exportSymbol.valueDeclaration).filter(isDefined); const decoratedClasses = - classDeclarations + exportedDeclarations .map(declaration => { - const decorators = this.host.getDecoratorsOfDeclaration(declaration); - return decorators && declaration.name && - new ParsedClass(declaration.name.text, declaration, decorators); + if (ts.isClassDeclaration(declaration) || ts.isVariableDeclaration(declaration)) { + const name = declaration.name && ts.isIdentifier(declaration.name) ? + declaration.name.text : + undefined; + const decorators = this.host.getDecoratorsOfDeclaration(declaration); + return decorators && isDefined(name) ? + new ParsedClass(name, declaration, decorators) : + undefined; + } + return undefined; }) .filter(isDefined); diff --git a/packages/compiler-cli/src/ngcc/test/parsing/esm2015_parser_spec.ts b/packages/compiler-cli/src/ngcc/test/parsing/esm2015_parser_spec.ts index 9c8385f898..5629c94c1b 100644 --- a/packages/compiler-cli/src/ngcc/test/parsing/esm2015_parser_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/parsing/esm2015_parser_spec.ts @@ -15,6 +15,7 @@ import {makeProgram} from '../helpers/utils'; const BASIC_FILE = { name: '/primary.js', contents: ` + import {Directive} from '@angular/core'; class A {} A.decorators = [ { type: Directive, args: [{ selector: '[a]' }] } @@ -31,12 +32,19 @@ const BASIC_FILE = { class C {} + let D = class D {} + D = tslib_1.__decorate([ + Directive({ selector: '[d]' }), + OtherD() + ], D); + export {D}; + export { A, x, C }; ` }; -describe('Esm2015PackageParser', () => { - describe('getDecoratedClasses()', () => { +describe('Esm2015FileParser', () => { + describe('parseFile()', () => { it('should return an array of object for each class that is exported and decorated', () => { const program = makeProgram(BASIC_FILE); const host = new Fesm2015ReflectionHost(program.getTypeChecker()); @@ -46,11 +54,19 @@ describe('Esm2015PackageParser', () => { expect(parsedFiles.length).toEqual(1); const decoratedClasses = parsedFiles[0].decoratedClasses; - expect(decoratedClasses.length).toEqual(1); - const decoratedClass = decoratedClasses[0]; - expect(decoratedClass.name).toEqual('A'); - expect(ts.isClassDeclaration(decoratedClass.declaration)).toBeTruthy(); - expect(decoratedClass.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + expect(decoratedClasses.length).toEqual(2); + + const decoratedClassA = decoratedClasses.find(c => c.name === 'A') !; + expect(decoratedClassA.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + expect(decoratedClassA.decorators.map( + decorator => decorator.args && decorator.args.map(arg => arg.getText()))) + .toEqual([[`{ selector: '[a]' }`]]); + + const decoratedClassD = decoratedClasses.find(c => c.name === 'D') !; + expect(decoratedClassD.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + expect(decoratedClassD.decorators.map( + decorator => decorator.args && decorator.args.map(arg => arg.getText()))) + .toEqual([[`{ selector: '[d]' }`]]); }); }); }); \ No newline at end of file