Merge pull request #8069 from Microsoft/transforms-capture-this-in-computed-property-names-in-arrow-functions

[Transforms] Capture `this` in computed property names in arrow functions
This commit is contained in:
Nathan Shively-Sanders 2016-04-14 09:52:20 -07:00
commit f13753d366
4 changed files with 38 additions and 9 deletions

View File

@ -1910,6 +1910,17 @@ namespace ts {
// This is so that they can flow through PropertyName transforms unaffected.
// Instead, we mark the container as ES6, so that it can properly handle the transform.
transformFlags = TransformFlags.ContainsComputedPropertyName;
if (subtreeFlags & TransformFlags.ContainsLexicalThis) {
// A computed method name like `[this.getName()](x: string) { ... }` needs to
// distinguish itself from the normal case of a method body containing `this`:
// `this` inside a method doesn't need to be rewritten (the method provides `this`),
// whereas `this` inside a computed name *might* need to be rewritten if the class/object
// is inside an arrow function:
// `_this = this; () => class K { [_this.getName()]() { ... } }`
// To make this distinction, use ContainsLexicalThisInComputedPropertyName
// instead of ContainsLexicalThis for computed property names
transformFlags |= TransformFlags.ContainsLexicalThisInComputedPropertyName;
}
break;
case SyntaxKind.SpreadElementExpression:
@ -1945,6 +1956,11 @@ namespace ts {
// is an ES6 node.
transformFlags = TransformFlags.AssertES6;
}
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
// A computed property name containing `this` might need to be rewritten,
// so propagate the ContainsLexicalThis flag upward.
transformFlags |= TransformFlags.ContainsLexicalThis;
}
break;
case SyntaxKind.CallExpression:
@ -2256,6 +2272,11 @@ namespace ts {
|| hasModifier(node, ModifierFlags.Export)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
// A computed property name containing `this` might need to be rewritten,
// so propagate the ContainsLexicalThis flag upward.
transformFlags |= TransformFlags.ContainsLexicalThis;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ClassExcludes);
}
@ -2272,6 +2293,11 @@ namespace ts {
| TransformFlags.ContainsDecorators)) {
transformFlags |= TransformFlags.AssertTypeScript;
}
if (subtreeFlags & TransformFlags.ContainsLexicalThisInComputedPropertyName) {
// A computed property name containing `this` might need to be rewritten,
// so propagate the ContainsLexicalThis flag upward.
transformFlags |= TransformFlags.ContainsLexicalThis;
}
return updateTransformFlags(node, subtreeFlags, transformFlags, TransformFlags.ClassExcludes);
}

View File

@ -2830,11 +2830,12 @@ namespace ts {
ContainsPropertyInitializer = 1 << 10,
ContainsLexicalThis = 1 << 11,
ContainsCapturedLexicalThis = 1 << 12,
ContainsDefaultValueAssignments = 1 << 13,
ContainsParameterPropertyAssignments = 1 << 14,
ContainsSpreadElementExpression = 1 << 15,
ContainsComputedPropertyName = 1 << 16,
ContainsBlockScopedBinding = 1 << 17,
ContainsLexicalThisInComputedPropertyName = 1 << 13,
ContainsDefaultValueAssignments = 1 << 14,
ContainsParameterPropertyAssignments = 1 << 15,
ContainsSpreadElementExpression = 1 << 16,
ContainsComputedPropertyName = 1 << 17,
ContainsBlockScopedBinding = 1 << 18,
HasComputedFlags = 1 << 31, // Transform flags have been computed.
@ -2853,10 +2854,10 @@ namespace ts {
FunctionExcludes = ContainsDecorators | ContainsDefaultValueAssignments | ContainsCapturedLexicalThis | ContainsLexicalThis | ContainsParameterPropertyAssignments | ContainsBlockScopedBinding,
ConstructorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
MethodOrAccessorExcludes = ContainsDefaultValueAssignments | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
ClassExcludes = ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments,
ClassExcludes = ContainsDecorators | ContainsPropertyInitializer | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsComputedPropertyName | ContainsParameterPropertyAssignments | ContainsLexicalThisInComputedPropertyName,
ModuleExcludes = ContainsDecorators | ContainsLexicalThis | ContainsCapturedLexicalThis | ContainsBlockScopedBinding,
TypeExcludes = ~ContainsTypeScript,
ObjectLiteralExcludes = ContainsDecorators | ContainsComputedPropertyName,
ObjectLiteralExcludes = ContainsDecorators | ContainsComputedPropertyName | ContainsLexicalThisInComputedPropertyName,
ArrayLiteralOrCallOrNewExcludes = ContainsSpreadElementExpression,
}

View File

@ -18,7 +18,8 @@ var C = (function () {
var _this = this;
(function () {
var obj = (_a = {},
_a[_this.bar()] = function () { },
_a[_this.bar()] = function () { } // needs capture
,
_a);
var _a;
});

View File

@ -38,7 +38,8 @@ var C = (function (_super) {
var _this = this;
(function () {
var obj = (_a = {},
_a[_super.prototype.bar.call(_this)] = function () { },
_a[_super.prototype.bar.call(_this)] = function () { } // needs capture
,
_a);
var _a;
});