@@ -258,6 +258,9 @@ namespace ts {
258258 case SyntaxKind . ClassDeclaration :
259259 return visitClassDeclaration ( < ClassDeclaration > node ) ;
260260
261+ case SyntaxKind . ExpressionStatement :
262+ return visitExpressionStatement ( < ExpressionStatement > node ) ;
263+
261264 default :
262265 // This visitor does not descend into the tree, as export/import statements
263266 // are only transformed at the top level of a file.
@@ -544,24 +547,33 @@ namespace ts {
544547 }
545548 }
546549
547- function addExportMemberAssignment ( statements : Statement [ ] , node : FunctionDeclaration | ClassDeclaration ) {
550+ function addExportMemberAssignment ( statements : Statement [ ] , node : DeclarationStatement ) {
548551 if ( hasModifier ( node , ModifierFlags . Default ) ) {
549- addExportDefault ( statements , node . name ? getSynthesizedClone ( node . name ) : getGeneratedNameForNode ( node ) , /*location*/ node ) ;
552+ addExportDefault ( statements , getDeclarationName ( node ) , /*location*/ node ) ;
550553 }
551554 else {
552555 statements . push (
553- startOnNewLine (
554- createStatement (
555- createExportAssignment ( node . name , node . name ) ,
556- /*location*/ node
557- )
558- )
556+ createExportStatement ( node . name , node . name , /*location*/ node )
559557 ) ;
560558 }
561559 }
562560
563561 function visitVariableStatement ( node : VariableStatement ) : VisitResult < Statement > {
564562 if ( hasModifier ( node , ModifierFlags . Export ) ) {
563+ // If the variable is for a declaration that has a local name,
564+ // do not elide the declaration.
565+ const original = getOriginalNode ( node ) ;
566+ if ( original . kind === SyntaxKind . EnumDeclaration
567+ || original . kind === SyntaxKind . ModuleDeclaration ) {
568+ return setOriginalNode (
569+ createVariableStatement (
570+ /*modifiers*/ undefined ,
571+ node . declarationList
572+ ) ,
573+ node
574+ ) ;
575+ }
576+
565577 const variables = getInitializedVariables ( node . declarationList ) ;
566578 if ( variables . length === 0 ) {
567579 // elide statement if there are no initialized variables
@@ -651,6 +663,87 @@ namespace ts {
651663 return singleOrMany ( statements ) ;
652664 }
653665
666+ function visitExpressionStatement ( node : ExpressionStatement ) : VisitResult < Statement > {
667+ const original = getOriginalNode ( node ) ;
668+ if ( hasModifier ( original , ModifierFlags . Export ) ) {
669+ switch ( original . kind ) {
670+ case SyntaxKind . EnumDeclaration :
671+ return visitExpressionStatementForEnumDeclaration ( node , < EnumDeclaration > original ) ;
672+
673+ case SyntaxKind . ModuleDeclaration :
674+ return visitExpressionStatementForModuleDeclaration ( node , < ModuleDeclaration > original ) ;
675+ }
676+ }
677+
678+ return node ;
679+ }
680+
681+ function visitExpressionStatementForEnumDeclaration ( node : ExpressionStatement , original : EnumDeclaration ) : VisitResult < Statement > {
682+ if ( isFirstDeclarationOfKind ( original , SyntaxKind . EnumDeclaration ) ) {
683+ const statements : Statement [ ] = [ node ] ;
684+ addVarForExportedEnumOrModule ( statements , original ) ;
685+ return statements ;
686+ }
687+
688+ return node ;
689+ }
690+
691+ function isModuleMergedWithES6Class ( node : ModuleDeclaration ) {
692+ return languageVersion === ScriptTarget . ES6
693+ && isMergedWithClass ( node ) ;
694+ }
695+
696+ function visitExpressionStatementForModuleDeclaration ( node : ExpressionStatement , original : ModuleDeclaration ) : VisitResult < Statement > {
697+ if ( isFirstDeclarationOfKind ( original , SyntaxKind . ModuleDeclaration ) ) {
698+ const statements : Statement [ ] = [ node ] ;
699+ if ( isModuleMergedWithES6Class ( original ) ) {
700+ addAssignmentForExportedModule ( statements , original ) ;
701+ }
702+ else {
703+ addVarForExportedEnumOrModule ( statements , original ) ;
704+ }
705+
706+ return statements ;
707+ }
708+
709+ return node ;
710+ }
711+
712+ /**
713+ * Adds a trailing VariableStatement for an enum or module declaration.
714+ */
715+ function addVarForExportedEnumOrModule ( statements : Statement [ ] , node : EnumDeclaration | ModuleDeclaration ) {
716+ statements . push (
717+ createVariableStatement (
718+ /*modifiers*/ undefined ,
719+ [ createVariableDeclaration (
720+ getDeclarationName ( node ) ,
721+ createPropertyAccess ( createIdentifier ( "exports" ) , getDeclarationName ( node ) )
722+ ) ] ,
723+ /*location*/ node
724+ )
725+ ) ;
726+ }
727+
728+ /**
729+ * Adds a trailing assignment for a module declaration.
730+ */
731+ function addAssignmentForExportedModule ( statements : Statement [ ] , node : ModuleDeclaration ) {
732+ statements . push (
733+ createStatement (
734+ createAssignment (
735+ getDeclarationName ( node ) ,
736+ createPropertyAccess ( createIdentifier ( "exports" ) , getDeclarationName ( node ) )
737+ ) ,
738+ /*location*/ node
739+ )
740+ ) ;
741+ }
742+
743+ function getDeclarationName ( node : DeclarationStatement ) {
744+ return node . name ? getSynthesizedClone ( node . name ) : getGeneratedNameForNode ( node ) ;
745+ }
746+
654747 function substituteExpression ( node : Expression ) {
655748 node = previousExpressionSubstitution ( node ) ;
656749 if ( isIdentifier ( node ) ) {
@@ -663,7 +756,7 @@ namespace ts {
663756 function substituteExpressionIdentifier ( node : Identifier ) : Expression {
664757 const original = getOriginalNode ( node ) ;
665758 if ( isIdentifier ( original ) ) {
666- const container = resolver . getReferencedExportContainer ( original ) ;
759+ const container = resolver . getReferencedExportContainer ( original , ( getNodeEmitFlags ( node ) & NodeEmitFlags . PrefixExportedLocal ) !== 0 ) ;
667760 if ( container ) {
668761 if ( container . kind === SyntaxKind . SourceFile ) {
669762 return createPropertyAccess (
@@ -760,6 +853,10 @@ namespace ts {
760853 return createCall ( createIdentifier ( "require" ) , args ) ;
761854 }
762855
856+ function createExportStatement ( name : Identifier , value : Expression , location ?: TextRange ) {
857+ return startOnNewLine ( createStatement ( createExportAssignment ( name , value ) , location ) ) ;
858+ }
859+
763860 function createExportAssignment ( name : Identifier , value : Expression ) {
764861 return createAssignment (
765862 name . originalKeywordKind && languageVersion === ScriptTarget . ES3
0 commit comments