@@ -402,6 +402,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
402402 */
403403 argumentsName ?: string ;
404404
405+ /*
406+ * alias for 'this' from the calling code stack frame in case if this was used inside the converted loop
407+ */
408+ thisName ?: string ;
409+
405410 /*
406411 * list of non-block scoped variable declarations that appear inside converted loop
407412 * such variable declarations should be moved outside the loop body
@@ -1271,7 +1276,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
12711276 }
12721277 }
12731278
1274- function isBinaryOrOctalIntegerLiteral ( node : LiteralExpression , text : string ) : boolean {
1279+ function isBinaryOrOctalIntegerLiteral ( node : LiteralLikeNode , text : string ) : boolean {
12751280 if ( node . kind === SyntaxKind . NumericLiteral && text . length > 1 ) {
12761281 switch ( text . charCodeAt ( 1 ) ) {
12771282 case CharacterCodes . b :
@@ -1285,7 +1290,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
12851290 return false ;
12861291 }
12871292
1288- function emitLiteral ( node : LiteralExpression ) {
1293+ function emitLiteral ( node : LiteralExpression | TemplateLiteralFragment ) {
12891294 const text = getLiteralText ( node ) ;
12901295
12911296 if ( ( compilerOptions . sourceMap || compilerOptions . inlineSourceMap ) && ( node . kind === SyntaxKind . StringLiteral || isTemplateLiteralKind ( node . kind ) ) ) {
@@ -1300,7 +1305,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
13001305 }
13011306 }
13021307
1303- function getLiteralText ( node : LiteralExpression ) {
1308+ function getLiteralText ( node : LiteralExpression | TemplateLiteralFragment ) {
13041309 // Any template literal or string literal with an extended escape
13051310 // (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
13061311 if ( languageVersion < ScriptTarget . ES6 && ( isTemplateLiteralKind ( node . kind ) || node . hasExtendedUnicodeEscape ) ) {
@@ -1359,7 +1364,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
13591364 write ( `"${ text } "` ) ;
13601365 }
13611366
1362- function emitDownlevelTaggedTemplateArray ( node : TaggedTemplateExpression , literalEmitter : ( literal : LiteralExpression ) => void ) {
1367+ function emitDownlevelTaggedTemplateArray ( node : TaggedTemplateExpression , literalEmitter : ( literal : LiteralExpression | TemplateLiteralFragment ) => void ) {
13631368 write ( "[" ) ;
13641369 if ( node . template . kind === SyntaxKind . NoSubstitutionTemplateLiteral ) {
13651370 literalEmitter ( < LiteralExpression > node . template ) ;
@@ -1992,6 +1997,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
19921997 if ( resolver . getNodeCheckFlags ( node ) & NodeCheckFlags . LexicalThis ) {
19931998 write ( "_this" ) ;
19941999 }
2000+ else if ( convertedLoopState ) {
2001+ write ( convertedLoopState . thisName || ( convertedLoopState . thisName = makeUniqueName ( "this" ) ) ) ;
2002+ }
19952003 else {
19962004 write ( "this" ) ;
19972005 }
@@ -3322,6 +3330,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
33223330 convertedLoopState . argumentsName = convertedOuterLoopState . argumentsName ;
33233331 }
33243332
3333+ if ( convertedOuterLoopState . thisName ) {
3334+ // outer loop has already used 'this' so we've already have some name to alias it
3335+ // use the same name in all nested loops
3336+ convertedLoopState . thisName = convertedOuterLoopState . thisName ;
3337+ }
3338+
33253339 if ( convertedOuterLoopState . hoistedLocalVariables ) {
33263340 // we've already collected some non-block scoped variable declarations in enclosing loop
33273341 // use the same storage in nested loop
@@ -3351,6 +3365,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
33513365 writeLine ( ) ;
33523366 }
33533367 }
3368+ if ( convertedLoopState . thisName ) {
3369+ // if alias for this is set
3370+ if ( convertedOuterLoopState ) {
3371+ // pass it to outer converted loop
3372+ convertedOuterLoopState . thisName = convertedLoopState . thisName ;
3373+ }
3374+ else {
3375+ // this is top level converted loop so we need to create an alias for 'this' here
3376+ // NOTE:
3377+ // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
3378+ // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
3379+ write ( `var ${ convertedLoopState . thisName } = this;` ) ;
3380+ writeLine ( ) ;
3381+ }
3382+ }
33543383
33553384 if ( convertedLoopState . hoistedLocalVariables ) {
33563385 // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
@@ -5925,7 +5954,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
59255954
59265955 function emitSerializedTypeNode ( node : TypeNode ) {
59275956 if ( node ) {
5928-
59295957 switch ( node . kind ) {
59305958 case SyntaxKind . VoidKeyword :
59315959 write ( "void 0" ) ;
@@ -5951,7 +5979,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
59515979 return ;
59525980
59535981 case SyntaxKind . StringKeyword :
5954- case SyntaxKind . StringLiteral :
5982+ case SyntaxKind . StringLiteralType :
59555983 write ( "String" ) ;
59565984 return ;
59575985
@@ -7354,7 +7382,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
73547382 write ( `], function(${ exportFunctionForFile } ) {` ) ;
73557383 writeLine ( ) ;
73567384 increaseIndent ( ) ;
7357- const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ true ) ;
7385+ const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ true , /*ensureUseStrict*/ true ) ;
73587386 emitEmitHelpers ( node ) ;
73597387 emitCaptureThisForNodeIfNecessary ( node ) ;
73607388 emitSystemModuleBody ( node , dependencyGroups , startIndex ) ;
@@ -7457,7 +7485,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
74577485 writeModuleName ( node , emitRelativePathAsModuleName ) ;
74587486 emitAMDDependencies ( node , /*includeNonAmdDependencies*/ true , emitRelativePathAsModuleName ) ;
74597487 increaseIndent ( ) ;
7460- const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ true ) ;
7488+ const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ true , /*ensureUseStrict*/ true ) ;
74617489 emitExportStarHelper ( ) ;
74627490 emitCaptureThisForNodeIfNecessary ( node ) ;
74637491 emitLinesStartingAt ( node . statements , startIndex ) ;
@@ -7469,7 +7497,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
74697497 }
74707498
74717499 function emitCommonJSModule ( node : SourceFile ) {
7472- const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ false ) ;
7500+ const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ false , /*ensureUseStrict*/ true ) ;
74737501 emitEmitHelpers ( node ) ;
74747502 collectExternalModuleInfo ( node ) ;
74757503 emitExportStarHelper ( ) ;
@@ -7498,7 +7526,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
74987526})(` ) ;
74997527 emitAMDFactoryHeader ( dependencyNames ) ;
75007528 increaseIndent ( ) ;
7501- const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ true ) ;
7529+ const startIndex = emitDirectivePrologues ( node . statements , /*startWithNewLine*/ true , /*ensureUseStrict*/ true ) ;
75027530 emitExportStarHelper ( ) ;
75037531 emitCaptureThisForNodeIfNecessary ( node ) ;
75047532 emitLinesStartingAt ( node . statements , startIndex ) ;
@@ -7640,19 +7668,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
76407668 }
76417669 }
76427670
7643- function emitDirectivePrologues ( statements : Node [ ] , startWithNewLine : boolean ) : number {
7671+ function isUseStrictPrologue ( node : ExpressionStatement ) : boolean {
7672+ return ! ! ( node . expression as StringLiteral ) . text . match ( / u s e s t r i c t / ) ;
7673+ }
7674+
7675+ function ensureUseStrictPrologue ( startWithNewLine : boolean , writeUseStrict : boolean ) {
7676+ if ( writeUseStrict ) {
7677+ if ( startWithNewLine ) {
7678+ writeLine ( ) ;
7679+ }
7680+ write ( "\"use strict\";" ) ;
7681+ }
7682+ }
7683+
7684+ function emitDirectivePrologues ( statements : Node [ ] , startWithNewLine : boolean , ensureUseStrict ?: boolean ) : number {
7685+ let foundUseStrict = false ;
76447686 for ( let i = 0 ; i < statements . length ; ++ i ) {
76457687 if ( isPrologueDirective ( statements [ i ] ) ) {
7688+ if ( isUseStrictPrologue ( statements [ i ] as ExpressionStatement ) ) {
7689+ foundUseStrict = true ;
7690+ }
76467691 if ( startWithNewLine || i > 0 ) {
76477692 writeLine ( ) ;
76487693 }
76497694 emit ( statements [ i ] ) ;
76507695 }
76517696 else {
7697+ ensureUseStrictPrologue ( startWithNewLine || i > 0 , ! foundUseStrict && ensureUseStrict ) ;
76527698 // return index of the first non prologue directive
76537699 return i ;
76547700 }
76557701 }
7702+ ensureUseStrictPrologue ( startWithNewLine , ! foundUseStrict && ensureUseStrict ) ;
76567703 return statements . length ;
76577704 }
76587705
0 commit comments