Skip to content

Commit f13753d

Browse files
committed
Merge pull request microsoft#8069 from Microsoft/transforms-capture-this-in-computed-property-names-in-arrow-functions
[Transforms] Capture `this` in computed property names in arrow functions
2 parents d56ac44 + 0d5bf0e commit f13753d

4 files changed

Lines changed: 38 additions & 9 deletions

File tree

src/compiler/binder.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,6 +1910,17 @@ namespace ts {
19101910
// This is so that they can flow through PropertyName transforms unaffected.
19111911
// Instead, we mark the container as ES6, so that it can properly handle the transform.
19121912
transformFlags = TransformFlags.ContainsComputedPropertyName;
1913+
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
1914+
// A computed method name like `[this.getName()](x: string) { ... }` needs to
1915+
// distinguish itself from the normal case of a method body containing `this`:
1916+
// `this` inside a method doesn't need to be rewritten (the method provides `this`),
1917+
// whereas `this` inside a computed name *might* need to be rewritten if the class/object
1918+
// is inside an arrow function:
1919+
// `_this = this; () => class K { [_this.getName()]() { ... } }`
1920+
// To make this distinction, use ContainsLexicalThisInComputedPropertyName
1921+
// instead of ContainsLexicalThis for computed property names
1922+
transformFlags |= TransformFlags.ContainsLexicalThisInComputedPropertyName;
1923+
}
19131924
break;
19141925

19151926
case SyntaxKind.SpreadElementExpression:
@@ -1945,6 +1956,11 @@ namespace ts {
19451956
// is an ES6 node.
19461957
transformFlags = TransformFlags.AssertES6;
19471958
}
1959+
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
1960+
// A computed property name containing `this` might need to be rewritten,
1961+
// so propagate the ContainsLexicalThis flag upward.
1962+
transformFlags |= TransformFlags.ContainsLexicalThis;
1963+
}
19481964
break;
19491965

19501966
case SyntaxKind.CallExpression:
@@ -2256,6 +2272,11 @@ namespace ts {
22562272
|| hasModifier(node, ModifierFlags.Export)) {
22572273
transformFlags |= TransformFlags.AssertTypeScript;
22582274
}
2275+
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
2276+
// A computed property name containing `this` might need to be rewritten,
2277+
// so propagate the ContainsLexicalThis flag upward.
2278+
transformFlags |= TransformFlags.ContainsLexicalThis;
2279+
}
22592280

22602281
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ClassExcludes);
22612282
}
@@ -2272,6 +2293,11 @@ namespace ts {
22722293
| TransformFlags.ContainsDecorators)) {
22732294
transformFlags |= TransformFlags.AssertTypeScript;
22742295
}
2296+
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
2297+
// A computed property name containing `this` might need to be rewritten,
2298+
// so propagate the ContainsLexicalThis flag upward.
2299+
transformFlags |= TransformFlags.ContainsLexicalThis;
2300+
}
22752301

22762302
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ClassExcludes);
22772303
}

src/compiler/types.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,11 +2830,12 @@ namespace ts {
28302830
ContainsPropertyInitializer = 1 << 10,
28312831
ContainsLexicalThis = 1 << 11,
28322832
ContainsCapturedLexicalThis = 1 << 12,
2833-
ContainsDefaultValueAssignments = 1 << 13,
2834-
ContainsParameterPropertyAssignments = 1 << 14,
2835-
ContainsSpreadElementExpression = 1 << 15,
2836-
ContainsComputedPropertyName = 1 << 16,
2837-
ContainsBlockScopedBinding = 1 << 17,
2833+
ContainsLexicalThisInComputedPropertyName = 1 << 13,
2834+
ContainsDefaultValueAssignments = 1 << 14,
2835+
ContainsParameterPropertyAssignments = 1 << 15,
2836+
ContainsSpreadElementExpression = 1 << 16,
2837+
ContainsComputedPropertyName = 1 << 17,
2838+
ContainsBlockScopedBinding = 1 << 18,
28382839

28392840
HasComputedFlags = 1 << 31, // Transform flags have been computed.
28402841

@@ -2853,10 +2854,10 @@ namespace ts {
28532854
FunctionExcludes = ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding,
28542855
ConstructorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
28552856
MethodOrAccessorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
2856-
ClassExcludes = ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments,
2857+
ClassExcludes = ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments | ContainsLexicalThisInComputedPropertyName,
28572858
ModuleExcludes = ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
28582859
TypeExcludes = ~ContainsTypeScript,
2859-
ObjectLiteralExcludes = ContainsDecorators | ContainsComputedPropertyName,
2860+
ObjectLiteralExcludes = ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
28602861
ArrayLiteralOrCallOrNewExcludes = ContainsSpreadElementExpression,
28612862
}
28622863

tests/baselines/reference/computedPropertyNames29_ES5.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ var C = (function () {
1818
var _this = this;
1919
(function () {
2020
var obj = (_a = {},
21-
_a[_this.bar()] = function () { },
21+
_a[_this.bar()] = function () { } // needs capture
22+
,
2223
_a);
2324
var _a;
2425
});

tests/baselines/reference/computedPropertyNames31_ES5.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ var C = (function (_super) {
3838
var _this = this;
3939
(function () {
4040
var obj = (_a = {},
41-
_a[_super.prototype.bar.call(_this)] = function () { },
41+
_a[_super.prototype.bar.call(_this)] = function () { } // needs capture
42+
,
4243
_a);
4344
var _a;
4445
});

0 commit comments

Comments
 (0)