From e50105bd9e35565f12f14c6d1cc39947dcd1382d Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 14 Sep 2016 13:33:06 -0700 Subject: [PATCH] Fix super in down-level async method --- src/compiler/transformers/es6.ts | 17 ++++++++++++---- .../reference/asyncMethodWithSuper_es5.js | 20 +++++++++---------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 44deac04279..51a6a088fb7 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -10,6 +10,7 @@ namespace ts { /** Enables substitutions for block-scoped bindings. */ BlockScopedBindings = 1 << 1, } + /** * If loop contains block scoped binding captured in some function then loop body is converted to a function. * Lexical bindings declared in loop initializer will be passed into the loop body function as parameters, @@ -166,6 +167,9 @@ namespace ts { let enclosingBlockScopeContainerParent: Node; let containingNonArrowFunction: FunctionLikeDeclaration | ClassElement; + /** Tracks the container that determines whether `super.x` is a static. */ + let superScopeContainer: FunctionLikeDeclaration | ClassElement; + /** * Used to track if we are emitting body of the converted loop */ @@ -203,6 +207,7 @@ namespace ts { function saveStateAndInvoke(node: Node, f: (node: Node) => T): T { const savedContainingNonArrowFunction = containingNonArrowFunction; + const savedSuperScopeContainer = superScopeContainer; const savedCurrentParent = currentParent; const savedCurrentNode = currentNode; const savedEnclosingBlockScopeContainer = enclosingBlockScopeContainer; @@ -219,6 +224,7 @@ namespace ts { convertedLoopState = savedConvertedLoopState; containingNonArrowFunction = savedContainingNonArrowFunction; + superScopeContainer = savedSuperScopeContainer; currentParent = savedCurrentParent; currentNode = savedCurrentNode; enclosingBlockScopeContainer = savedEnclosingBlockScopeContainer; @@ -414,13 +420,16 @@ namespace ts { } switch (currentParent.kind) { + case SyntaxKind.FunctionExpression: case SyntaxKind.Constructor: case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: containingNonArrowFunction = currentParent; + if (!(containingNonArrowFunction.emitFlags & NodeEmitFlags.AsyncFunctionBody)) { + superScopeContainer = containingNonArrowFunction; + } break; } } @@ -2820,9 +2829,9 @@ namespace ts { * Visits the `super` keyword */ function visitSuperKeyword(node: PrimaryExpression): LeftHandSideExpression { - return containingNonArrowFunction - && isClassElement(containingNonArrowFunction) - && !hasModifier(containingNonArrowFunction, ModifierFlags.Static) + return superScopeContainer + && isClassElement(superScopeContainer) + && !hasModifier(superScopeContainer, ModifierFlags.Static) && currentParent.kind !== SyntaxKind.CallExpression ? createPropertyAccess(createIdentifier("_super"), "prototype") : createIdentifier("_super"); diff --git a/tests/baselines/reference/asyncMethodWithSuper_es5.js b/tests/baselines/reference/asyncMethodWithSuper_es5.js index 87debbdc55c..21683eed637 100644 --- a/tests/baselines/reference/asyncMethodWithSuper_es5.js +++ b/tests/baselines/reference/asyncMethodWithSuper_es5.js @@ -69,11 +69,11 @@ var B = (function (_super) { var a, b; return __generator(this, function (_a) { // call with property access - _super.x.call(this); + _super.prototype.x.call(this); // call with element access - _super["x"].call(this); - a = _super.x; - b = _super["x"]; + _super.prototype["x"].call(this); + a = _super.prototype.x; + b = _super.prototype["x"]; return [2 /*return*/]; }); }); @@ -85,15 +85,15 @@ var B = (function (_super) { return __generator(this, function (_c) { f = function () { }; // call with property access - _super.x.call(this); + _super.prototype.x.call(this); // call with element access - _super["x"].call(this); - a = _super.x; - b = _super["x"]; + _super.prototype["x"].call(this); + a = _super.prototype.x; + b = _super.prototype["x"]; // property access (assign) - _super.x = f; + _super.prototype.x = f; // element access (assign) - _super["x"] = f; + _super.prototype["x"] = f; // destructuring assign with property access (_a = { f: f }, super.x = _a.f, _a); // destructuring assign with element access