diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index 331e502b931..0242437c615 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -147,6 +147,7 @@ const _super = (function (geti, seti) { let startLexicalEnvironment: () => void; let endLexicalEnvironment: () => Statement[]; let getNodeEmitFlags: (node: Node) => NodeEmitFlags; + let setNodeEmitFlags: (node: Node, flags: NodeEmitFlags) => void; let isExpressionSubstitutionEnabled: (node: Node) => boolean; let isEmitNotificationEnabled: (node: Node) => boolean; let expressionSubstitution: (node: Expression) => Expression; @@ -209,6 +210,7 @@ const _super = (function (geti, seti) { startLexicalEnvironment = undefined; endLexicalEnvironment = undefined; getNodeEmitFlags = undefined; + setNodeEmitFlags = undefined; isExpressionSubstitutionEnabled = undefined; isEmitNotificationEnabled = undefined; expressionSubstitution = undefined; @@ -230,6 +232,7 @@ const _super = (function (geti, seti) { startLexicalEnvironment = context.startLexicalEnvironment; endLexicalEnvironment = context.endLexicalEnvironment; getNodeEmitFlags = context.getNodeEmitFlags; + setNodeEmitFlags = context.setNodeEmitFlags; isExpressionSubstitutionEnabled = context.isExpressionSubstitutionEnabled; isEmitNotificationEnabled = context.isEmitNotificationEnabled; expressionSubstitution = context.expressionSubstitution; @@ -1968,10 +1971,13 @@ const _super = (function (geti, seti) { } function tryEmitSubstitute(node: Node, substitution: (node: Node) => Node) { - const substitute = substitution ? substitution(node) : node; - if (substitute && substitute !== node) { - emitWorker(substitute); - return true; + if (substitution && (getNodeEmitFlags(node) & NodeEmitFlags.NoSubstitution) === 0) { + const substitute = substitution(node); + if (substitute !== node) { + setNodeEmitFlags(substitute, NodeEmitFlags.NoSubstitution); + emitWorker(substitute); + return true; + } } return false; diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 4db823266c9..11337d07264 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -1036,11 +1036,11 @@ namespace ts { // explicit initializer since downlevel codegen for destructuring will fail // in the absence of initializer so all binding elements will say uninitialized const name = node.name; - if (isBindingPattern(name) || node.initializer) { + if (isBindingPattern(name)) { return visitVariableDeclaration(node); } - if (shouldEmitExplicitInitializerForLetDeclaration(node)) { + if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) { const clone = getMutableClone(node); clone.initializer = createVoidZero(); return clone; @@ -1416,7 +1416,7 @@ namespace ts { // We are here either because SuperKeyword was used somewhere in the expression, or // because we contain a SpreadElementExpression. - const { target, thisArg } = createCallBinding(node); + const { target, thisArg } = createCallBinding(node.expression); if (node.transformFlags & TransformFlags.ContainsSpreadElementExpression) { // [source] // f(...a, b) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index da0f983298f..516e90af2dd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2809,6 +2809,7 @@ namespace ts { AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node. IsNotEmittedNode = 1 << 8, // Is a node that is not emitted but whose comments should be preserved if possible. EmitCommentsOfNotEmittedParent = 1 << 9, // Emits comments of missing parent nodes. + NoSubstitution = 1 << 10, // Disables further substitution of an expression. } /** Additional context provided to `visitEachChild` */