From 482dfb61bec9a3367b8e207e5bd15301344659d6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 14 Apr 2016 12:08:53 -0700 Subject: [PATCH] Fixed emit for decorated classes that eventually get exported. --- src/compiler/transformers/module/module.ts | 22 +++++++++++++++++++--- src/compiler/transformers/ts.ts | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 1fa1d0473db..7599281e142 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -561,8 +561,11 @@ namespace ts { function visitVariableStatement(node: VariableStatement): VisitResult { // If the variable is for a generated declaration, // we should maintain it and just strip off the 'export' modifier if necesary. - const original = getOriginalNode(node); - if (original.kind === SyntaxKind.EnumDeclaration || original.kind === SyntaxKind.ModuleDeclaration) { + const originalKind = getOriginalNode(node).kind; + if (originalKind === SyntaxKind.ModuleDeclaration || + originalKind === SyntaxKind.EnumDeclaration || + originalKind === SyntaxKind.ClassDeclaration) { + if (!hasModifier(node, ModifierFlags.Export)) { return node; } @@ -686,7 +689,10 @@ namespace ts { statements.push(node); } - if (node.name) { + // Decorators end up creating a series of assignment expressions which overwrite + // the local binding that we export, so we need to defer from exporting decorated classes + // until the decoration assignments take place. We do this when visiting expression-statements. + if (node.name && !(node.decorators && node.decorators.length)) { addExportMemberAssignments(statements, node.name); } @@ -696,9 +702,19 @@ namespace ts { function visitExpressionStatement(node: ExpressionStatement): VisitResult { const original = getOriginalNode(node); const origKind = original.kind; + if (origKind === SyntaxKind.EnumDeclaration || origKind === SyntaxKind.ModuleDeclaration) { return visitExpressionStatementForEnumOrNamespaceDeclaration(node, original); } + else if (origKind === SyntaxKind.ClassDeclaration) { + // The decorated assignment for a class name will need to be transformed. + const classDecl = original as ClassDeclaration; + if (classDecl.name) { + const statements = [node]; + addExportMemberAssignments(statements, classDecl.name); + return statements; + } + } return node; } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 115f1d681c9..001a08dca67 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1304,7 +1304,7 @@ namespace ts { function addConstructorDecorationStatement(statements: Statement[], node: ClassDeclaration, decoratedClassAlias: Identifier) { const expression = generateConstructorDecorationExpression(node, decoratedClassAlias); if (expression) { - statements.push(createStatement(expression)); + statements.push(setOriginalNode(createStatement(expression), node)); } }