@@ -296,21 +296,21 @@ namespace ts {
296296 * If loop contains block scoped binding captured in some function then loop body is converted to a function.
297297 * Lexical bindings declared in loop initializer will be passed into the loop body function as parameters,
298298 * however if this binding is modified inside the body - this new value should be propagated back to the original binding.
299- * This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body.
299+ * This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body.
300300 * On every iteration this variable is initialized with value of corresponding binding.
301301 * At every point where control flow leaves the loop either explicitly (break/continue) or implicitly (at the end of loop body)
302302 * we copy the value inside the loop to the out parameter holder.
303- *
303+ *
304304 * for (let x;;) {
305305 * let a = 1;
306306 * let b = () => a;
307307 * x++
308308 * if (...) break;
309309 * ...
310310 * }
311- *
311+ *
312312 * will be converted to
313- *
313+ *
314314 * var out_x;
315315 * var loop = function(x) {
316316 * var a = 1;
@@ -326,7 +326,7 @@ namespace ts {
326326 * x = out_x;
327327 * if (state === "break") break;
328328 * }
329- *
329+ *
330330 * NOTE: values to out parameters are not copies if loop is abrupted with 'return' - in this case this will end the entire enclosing function
331331 * so nobody can observe this new value.
332332 */
@@ -379,6 +379,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
379379 const compilerOptions = host . getCompilerOptions ( ) ;
380380 const languageVersion = getEmitScriptTarget ( compilerOptions ) ;
381381 const modulekind = getEmitModuleKind ( compilerOptions ) ;
382+ const hasIndirectAccessToImportedIdentifiers = modulekind !== ModuleKind . ES6 && modulekind !== ModuleKind . System ;
382383 const sourceMapDataList : SourceMapData [ ] = compilerOptions . sourceMap || compilerOptions . inlineSourceMap ? [ ] : undefined ;
383384 const emitterDiagnostics = createDiagnosticCollection ( ) ;
384385 let emitSkipped = false ;
@@ -1575,7 +1576,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
15751576 if ( container ) {
15761577 if ( container . kind === SyntaxKind . SourceFile ) {
15771578 // Identifier references module export
1578- if ( modulekind !== ModuleKind . ES6 && modulekind !== ModuleKind . System ) {
1579+ if ( hasIndirectAccessToImportedIdentifiers ) {
15791580 write ( "exports." ) ;
15801581 }
15811582 }
@@ -2138,6 +2139,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
21382139 return container && container . kind !== SyntaxKind . SourceFile ;
21392140 }
21402141
2142+ // Return true if identifier resolves to an imported identifier
2143+ function isImportedReference ( node : Identifier ) {
2144+ const declaration = resolver . getReferencedImportDeclaration ( node ) ;
2145+ return declaration && ( declaration . kind === SyntaxKind . ImportClause || declaration . kind === SyntaxKind . ImportSpecifier ) ;
2146+ }
2147+
21412148 function emitShorthandPropertyAssignment ( node : ShorthandPropertyAssignment ) {
21422149 // The name property of a short-hand property assignment is considered an expression position, so here
21432150 // we manually emit the identifier to avoid rewriting.
@@ -2151,7 +2158,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
21512158 // let obj = { y };
21522159 // }
21532160 // Here we need to emit obj = { y : m.y } regardless of the output target.
2154- if ( modulekind !== ModuleKind . ES6 || isNamespaceExportReference ( node . name ) ) {
2161+ // The same rules apply for imported identifiers when targeting module formats with indirect access to
2162+ // the imported identifiers. For example, when targeting CommonJS:
2163+ //
2164+ // import {foo} from './foo';
2165+ // export const baz = { foo };
2166+ //
2167+ // Must be transformed into:
2168+ //
2169+ // const foo_1 = require('./foo');
2170+ // exports.baz = { foo: foo_1.foo };
2171+ //
2172+ if ( languageVersion < ScriptTarget . ES6 || ( hasIndirectAccessToImportedIdentifiers && isImportedReference ( node . name ) ) || isNamespaceExportReference ( node . name ) ) {
21552173 // Emit identifier as an identifier
21562174 write ( ": " ) ;
21572175 emit ( node . name ) ;
@@ -3073,7 +3091,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
30733091 }
30743092
30753093 writeLine ( ) ;
3076- // end of loop body -> copy out parameter
3094+ // end of loop body -> copy out parameter
30773095 copyLoopOutParameters ( convertedLoopState , CopyDirection . ToOutParameter , /*emitAsStatements*/ true ) ;
30783096
30793097 decreaseIndent ( ) ;
@@ -3572,7 +3590,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
35723590 }
35733591 else {
35743592 convertedLoopState . nonLocalJumps |= Jump . Continue ;
3575- // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
3593+ // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
35763594 write ( `"continue";` ) ;
35773595 }
35783596 }
@@ -7267,7 +7285,7 @@ const _super = (function (geti, seti) {
72677285 }
72687286
72697287 // text should be quoted string
7270- // for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
7288+ // for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
72717289 const key = text . substr ( 1 , text . length - 2 ) ;
72727290
72737291 if ( hasProperty ( groupIndices , key ) ) {
0 commit comments