From e6b24437a9c0c368e2e6c716f825ba20dd6f3375 Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Mon, 11 Jul 2016 11:50:33 -0700 Subject: [PATCH] fix(compiler): Collector collects enum values. (#9967) Fixes: #9928 --- tools/@angular/tsc-wrapped/src/collector.ts | 40 +++++++++++++++++++ .../tsc-wrapped/test/collector.spec.ts | 33 ++++++++++++++- tools/tsc-watch/index.ts | 5 ++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/tools/@angular/tsc-wrapped/src/collector.ts b/tools/@angular/tsc-wrapped/src/collector.ts index 203bcea555..17d37a97fc 100644 --- a/tools/@angular/tsc-wrapped/src/collector.ts +++ b/tools/@angular/tsc-wrapped/src/collector.ts @@ -175,6 +175,46 @@ export class MetadataCollector { } // Otherwise don't record the function. break; + case ts.SyntaxKind.EnumDeclaration: + const enumDeclaration = node; + let enumValueHolder: {[name: string]: MetadataValue} = {}; + const enumName = enumDeclaration.name.text; + let nextDefaultValue: MetadataValue = 0; + let writtenMembers = 0; + for (const member of enumDeclaration.members) { + let enumValue: MetadataValue; + if (!member.initializer) { + enumValue = nextDefaultValue; + } else { + enumValue = evaluator.evaluateNode(member.initializer); + } + let name: string = undefined; + if (member.name.kind == ts.SyntaxKind.Identifier) { + const identifier = member.name; + name = identifier.text; + enumValueHolder[name] = enumValue; + writtenMembers++; + } + if (typeof enumValue === 'number') { + nextDefaultValue = enumValue + 1; + } else if (name) { + nextDefaultValue = { + __symbolic: 'binary', + operator: '+', + left: { + __symbolic: 'select', + expression: {__symbolic: 'reference', name: enumName}, name + } + } + } else { + nextDefaultValue = errorSym('Unsuppported enum member name', member.name); + }; + } + if (writtenMembers) { + if (!metadata) metadata = {}; + metadata[enumName] = enumValueHolder; + } + break; case ts.SyntaxKind.VariableStatement: const variableStatement = node; for (let variableDeclaration of variableStatement.declarationList.declarations) { diff --git a/tools/@angular/tsc-wrapped/test/collector.spec.ts b/tools/@angular/tsc-wrapped/test/collector.spec.ts index 4e76fd0113..3079154eb4 100644 --- a/tools/@angular/tsc-wrapped/test/collector.spec.ts +++ b/tools/@angular/tsc-wrapped/test/collector.spec.ts @@ -15,7 +15,8 @@ describe('Collector', () => { beforeEach(() => { host = new Host(FILES, [ '/app/app.component.ts', '/app/cases-data.ts', '/app/error-cases.ts', '/promise.ts', - '/unsupported-1.ts', '/unsupported-2.ts', 'import-star.ts', 'exported-functions.ts' + '/unsupported-1.ts', '/unsupported-2.ts', 'import-star.ts', 'exported-functions.ts', + 'exported-enum.ts', 'exported-consts.ts' ]); service = ts.createLanguageService(host, documentRegistry); program = service.getProgram(); @@ -316,6 +317,26 @@ describe('Collector', () => { {__symbolic: 'reference', module: 'angular2/common', name: 'NgFor'} ]); }); + + it('should be able to collect the value of an enum', () => { + let enumSource = program.getSourceFile('/exported-enum.ts'); + let metadata = collector.getMetadata(enumSource); + let someEnum: any = metadata.metadata['SomeEnum']; + expect(someEnum).toEqual({A: 0, B: 1, C: 100, D: 101}); + }); + + it('should be able to collect enums initialized from consts', () => { + let enumSource = program.getSourceFile('/exported-enum.ts'); + let metadata = collector.getMetadata(enumSource); + let complexEnum: any = metadata.metadata['ComplexEnum']; + expect(complexEnum).toEqual({ + A: 0, + B: 1, + C: 30, + D: 40, + E: {__symbolic: 'reference', module: './exported-consts', name: 'constValue'} + }); + }); }); // TODO: Do not use \` in a template literal as it confuses clang-format @@ -548,6 +569,16 @@ const FILES: Directory = { return !!window.history.pushState; } `, + 'exported-enum.ts': ` + import {constValue} from './exported-consts'; + + export const someValue = 30; + export enum SomeEnum { A, B, C = 100, D }; + export enum ComplexEnum { A, B, C = someValue, D = someValue + 10, E = constValue }; + `, + 'exported-consts.ts': ` + export const constValue = 100; + `, 'node_modules': { 'angular2': { 'core.d.ts': ` diff --git a/tools/tsc-watch/index.ts b/tools/tsc-watch/index.ts index 8011b498f0..4b817fe8fb 100644 --- a/tools/tsc-watch/index.ts +++ b/tools/tsc-watch/index.ts @@ -89,8 +89,9 @@ if (platform == 'node') { start: 'File change detected. Starting incremental compilation...', error: 'error', complete: 'Compilation complete. Watching for file changes.', - onChangeCmds: - [['node', 'dist/tools/cjs-jasmine/index-tools', '--', 'tsc-wrapped/**/*{_,.}spec.js']] + onChangeCmds: [[ + 'node', 'dist/tools/cjs-jasmine/index-tools', '--', '@angular/tsc-wrapped/**/*{_,.}spec.js' + ]] }); }