@@ -4218,12 +4218,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
4218
4218
4219
4219
function emitVariableDeclaration ( node : VariableDeclaration ) {
4220
4220
if ( isBindingPattern ( node . name ) ) {
4221
- if ( languageVersion < ScriptTarget . ES6 ) {
4222
- emitDestructuring ( node , /*isAssignmentExpressionStatement*/ false ) ;
4223
- }
4224
- else {
4221
+ const isExported = getCombinedNodeFlags ( node ) & NodeFlags . Export ;
4222
+ if ( languageVersion >= ScriptTarget . ES6 && ( ! isExported || modulekind === ModuleKind . ES6 ) ) {
4223
+ // emit ES6 destructuring only if target module is ES6 or variable is not exported
4224
+ // exported variables in CJS/AMD are prefixed with 'exports.' so result javascript { exports.toString } = 1; is illegal
4225
+
4226
+ const isTopLevelDeclarationInSystemModule =
4227
+ modulekind === ModuleKind . System &&
4228
+ shouldHoistVariable ( node , /*checkIfSourceFileLevelDecl*/ true ) ;
4229
+
4230
+ if ( isTopLevelDeclarationInSystemModule ) {
4231
+ // In System modules top level variables are hoisted
4232
+ // so variable declarations with destructuring are turned into destructuring assignments.
4233
+ // As a result, they will need parentheses to disambiguate object binding assignments from blocks.
4234
+ write ( "(" ) ;
4235
+ }
4236
+
4225
4237
emit ( node . name ) ;
4226
4238
emitOptional ( " = " , node . initializer ) ;
4239
+
4240
+ if ( isTopLevelDeclarationInSystemModule ) {
4241
+ write ( ")" ) ;
4242
+ }
4243
+ }
4244
+ else {
4245
+ emitDestructuring ( node , /*isAssignmentExpressionStatement*/ false ) ;
4227
4246
}
4228
4247
}
4229
4248
else {
@@ -5278,9 +5297,11 @@ const _super = (function (geti, seti) {
5278
5297
5279
5298
function emitClassLikeDeclarationForES6AndHigher ( node : ClassLikeDeclaration ) {
5280
5299
let decoratedClassAlias : string ;
5281
- const thisNodeIsDecorated = nodeIsDecorated ( node ) ;
5300
+ const isHoistedDeclarationInSystemModule = shouldHoistDeclarationInSystemJsModule ( node ) ;
5301
+ const isDecorated = nodeIsDecorated ( node ) ;
5302
+ const rewriteAsClassExpression = isDecorated || isHoistedDeclarationInSystemModule ;
5282
5303
if ( node . kind === SyntaxKind . ClassDeclaration ) {
5283
- if ( thisNodeIsDecorated ) {
5304
+ if ( rewriteAsClassExpression ) {
5284
5305
// When we emit an ES6 class that has a class decorator, we must tailor the
5285
5306
// emit to certain specific cases.
5286
5307
//
@@ -5361,7 +5382,10 @@ const _super = (function (geti, seti) {
5361
5382
// [Example 4]
5362
5383
//
5363
5384
5364
- if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . ClassWithBodyScopedClassBinding ) {
5385
+ // NOTE: we reuse the same rewriting logic for cases when targeting ES6 and module kind is System.
5386
+ // Because of hoisting top level class declaration need to be emitted as class expressions.
5387
+ // Double bind case is only required if node is decorated.
5388
+ if ( isDecorated && resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . ClassWithBodyScopedClassBinding ) {
5365
5389
decoratedClassAlias = unescapeIdentifier ( makeUniqueName ( node . name ? node . name . text : "default" ) ) ;
5366
5390
decoratedClassAliases [ getNodeId ( node ) ] = decoratedClassAlias ;
5367
5391
write ( `let ${ decoratedClassAlias } ;` ) ;
@@ -5372,7 +5396,9 @@ const _super = (function (geti, seti) {
5372
5396
write ( "export " ) ;
5373
5397
}
5374
5398
5375
- write ( "let " ) ;
5399
+ if ( ! isHoistedDeclarationInSystemModule ) {
5400
+ write ( "let " ) ;
5401
+ }
5376
5402
emitDeclarationName ( node ) ;
5377
5403
if ( decoratedClassAlias !== undefined ) {
5378
5404
write ( ` = ${ decoratedClassAlias } ` ) ;
@@ -5416,7 +5442,7 @@ const _super = (function (geti, seti) {
5416
5442
// emit name if
5417
5443
// - node has a name
5418
5444
// - this is default export with static initializers
5419
- if ( node . name || ( node . flags & NodeFlags . Default && ( staticProperties . length > 0 || modulekind !== ModuleKind . ES6 ) && ! thisNodeIsDecorated ) ) {
5445
+ if ( node . name || ( node . flags & NodeFlags . Default && ( staticProperties . length > 0 || modulekind !== ModuleKind . ES6 ) && ! rewriteAsClassExpression ) ) {
5420
5446
write ( " " ) ;
5421
5447
emitDeclarationName ( node ) ;
5422
5448
}
@@ -5436,7 +5462,7 @@ const _super = (function (geti, seti) {
5436
5462
writeLine ( ) ;
5437
5463
emitToken ( SyntaxKind . CloseBraceToken , node . members . end ) ;
5438
5464
5439
- if ( thisNodeIsDecorated ) {
5465
+ if ( rewriteAsClassExpression ) {
5440
5466
decoratedClassAliases [ getNodeId ( node ) ] = undefined ;
5441
5467
write ( ";" ) ;
5442
5468
}
@@ -5476,7 +5502,7 @@ const _super = (function (geti, seti) {
5476
5502
// module), export it
5477
5503
if ( node . flags & NodeFlags . Default ) {
5478
5504
// if this is a top level default export of decorated class, write the export after the declaration.
5479
- if ( thisNodeIsDecorated ) {
5505
+ if ( isDecorated ) {
5480
5506
writeLine ( ) ;
5481
5507
write ( "export default " ) ;
5482
5508
emitDeclarationName ( node ) ;
0 commit comments