From 42600fa73fa04eb45e0592bb3a13e53a8dabcba5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 24 Apr 2017 14:46:58 -0700 Subject: [PATCH 1/2] ES2015 transforms accessors with captured `this` Previously, it did not, meaning that the emit for lexically captured `this` was incorrect. --- src/compiler/transformers/es2015.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 3ac5dc5d878..0dc6ed4a964 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3180,7 +3180,20 @@ namespace ts { const savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; const ancestorFacts = enterSubtree(HierarchyFacts.FunctionExcludes, HierarchyFacts.FunctionIncludes); - const updated = visitEachChild(node, visitor, context); + let updated: AccessorDeclaration; + if (node.transformFlags & TransformFlags.ContainsCapturedLexicalThis) { + const parameters = visitParameterList(node.parameters, visitor, context); + const body = transformFunctionBody(node); + if (node.kind === SyntaxKind.GetAccessor) { + updated = updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body); + } + else { + updated = updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body); + } + } + else { + updated = visitEachChild(node, visitor, context); + } exitSubtree(ancestorFacts, HierarchyFacts.PropagateNewTargetMask, HierarchyFacts.None); convertedLoopState = savedConvertedLoopState; return updated; From 00848fc46fa91cf558aa3aa412c1a6bedc2d88ac Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 24 Apr 2017 14:48:25 -0700 Subject: [PATCH 2/2] Test ES2015 transform of accessors w/captured this --- .../emitThisInObjectLiteralGetter.js | 15 +++++++++++++++ .../emitThisInObjectLiteralGetter.symbols | 13 +++++++++++++ .../emitThisInObjectLiteralGetter.types | 19 +++++++++++++++++++ .../compiler/emitThisInObjectLiteralGetter.ts | 6 ++++++ 4 files changed, 53 insertions(+) create mode 100644 tests/baselines/reference/emitThisInObjectLiteralGetter.js create mode 100644 tests/baselines/reference/emitThisInObjectLiteralGetter.symbols create mode 100644 tests/baselines/reference/emitThisInObjectLiteralGetter.types create mode 100644 tests/cases/compiler/emitThisInObjectLiteralGetter.ts diff --git a/tests/baselines/reference/emitThisInObjectLiteralGetter.js b/tests/baselines/reference/emitThisInObjectLiteralGetter.js new file mode 100644 index 00000000000..8c64f9e6045 --- /dev/null +++ b/tests/baselines/reference/emitThisInObjectLiteralGetter.js @@ -0,0 +1,15 @@ +//// [emitThisInObjectLiteralGetter.ts] +const example = { + get foo() { + return item => this.bar(item); + } +}; + + +//// [emitThisInObjectLiteralGetter.js] +var example = { + get foo() { + var _this = this; + return function (item) { return _this.bar(item); }; + } +}; diff --git a/tests/baselines/reference/emitThisInObjectLiteralGetter.symbols b/tests/baselines/reference/emitThisInObjectLiteralGetter.symbols new file mode 100644 index 00000000000..0de4890e8d1 --- /dev/null +++ b/tests/baselines/reference/emitThisInObjectLiteralGetter.symbols @@ -0,0 +1,13 @@ +=== tests/cases/compiler/emitThisInObjectLiteralGetter.ts === +const example = { +>example : Symbol(example, Decl(emitThisInObjectLiteralGetter.ts, 0, 5)) + + get foo() { +>foo : Symbol(foo, Decl(emitThisInObjectLiteralGetter.ts, 0, 17)) + + return item => this.bar(item); +>item : Symbol(item, Decl(emitThisInObjectLiteralGetter.ts, 2, 14)) +>item : Symbol(item, Decl(emitThisInObjectLiteralGetter.ts, 2, 14)) + } +}; + diff --git a/tests/baselines/reference/emitThisInObjectLiteralGetter.types b/tests/baselines/reference/emitThisInObjectLiteralGetter.types new file mode 100644 index 00000000000..3d8712b2afd --- /dev/null +++ b/tests/baselines/reference/emitThisInObjectLiteralGetter.types @@ -0,0 +1,19 @@ +=== tests/cases/compiler/emitThisInObjectLiteralGetter.ts === +const example = { +>example : { readonly foo: (item: any) => any; } +>{ get foo() { return item => this.bar(item); }} : { readonly foo: (item: any) => any; } + + get foo() { +>foo : (item: any) => any + + return item => this.bar(item); +>item => this.bar(item) : (item: any) => any +>item : any +>this.bar(item) : any +>this.bar : any +>this : any +>bar : any +>item : any + } +}; + diff --git a/tests/cases/compiler/emitThisInObjectLiteralGetter.ts b/tests/cases/compiler/emitThisInObjectLiteralGetter.ts new file mode 100644 index 00000000000..8927891bd98 --- /dev/null +++ b/tests/cases/compiler/emitThisInObjectLiteralGetter.ts @@ -0,0 +1,6 @@ +// @target: es5 +const example = { + get foo() { + return item => this.bar(item); + } +};