mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
Fixes for review comments.
* rename _super to _superIndex and _superProps to _super. * reinstate early exit for transformers by marking super accesses as esnext/es2017 in `binder.ts`. * adjust comment in `checker.ts` to new emit.
This commit is contained in:
@@ -3445,7 +3445,9 @@ namespace ts {
|
||||
// ES6 syntax, and requires a lexical `this` binding.
|
||||
if (transformFlags & TransformFlags.Super) {
|
||||
transformFlags ^= TransformFlags.Super;
|
||||
transformFlags |= TransformFlags.ContainsSuper;
|
||||
// super inside of an async function requires hoisting the super access (ES2017).
|
||||
// same for super inside of an async generator, which is ESNext.
|
||||
transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
@@ -3461,7 +3463,9 @@ namespace ts {
|
||||
// ES6 syntax, and requires a lexical `this` binding.
|
||||
if (expressionFlags & TransformFlags.Super) {
|
||||
transformFlags &= ~TransformFlags.Super;
|
||||
transformFlags |= TransformFlags.ContainsSuper;
|
||||
// super inside of an async function requires hoisting the super access (ES2017).
|
||||
// same for super inside of an async generator, which is ESNext.
|
||||
transformFlags |= TransformFlags.ContainsSuper | TransformFlags.ContainsES2017 | TransformFlags.ContainsESNext;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
|
||||
@@ -16180,16 +16180,18 @@ namespace ts {
|
||||
// // js
|
||||
// ...
|
||||
// asyncMethod() {
|
||||
// const _super_asyncMethod = name => super.asyncMethod;
|
||||
// const _super = Object.create(null, {
|
||||
// asyncMethod: { get: () => super.asyncMethod },
|
||||
// });
|
||||
// return __awaiter(this, arguments, Promise, function *() {
|
||||
// let x = yield _super_asyncMethod.call(this);
|
||||
// let x = yield _super.asyncMethod.call(this);
|
||||
// return x;
|
||||
// });
|
||||
// }
|
||||
// ...
|
||||
//
|
||||
// The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
|
||||
// are legal in ES6, but also likely less frequent, we emit the same more complex helper for both scenarios:
|
||||
// are legal in ES6, but also likely less frequent, we only emit setters if there is an assignment:
|
||||
//
|
||||
// // ts
|
||||
// ...
|
||||
@@ -16201,17 +16203,18 @@ namespace ts {
|
||||
// // js
|
||||
// ...
|
||||
// asyncMethod(ar) {
|
||||
// const _super_a = {get value() { return super.a; }, set value(v) { super.a = v; }};
|
||||
// const _super_b = {get value() { return super.b; }, set value(v) { super.b = v; }};
|
||||
// const _super = Object.create(null, {
|
||||
// a: { get: () => super.a, set: (v) => super.a = v },
|
||||
// b: { get: () => super.b, set: (v) => super.b = v }
|
||||
// };
|
||||
// return __awaiter(this, arguments, Promise, function *() {
|
||||
// [_super_a.value, _super_b.value] = yield ar;
|
||||
// [_super.a, _super.b] = yield ar;
|
||||
// });
|
||||
// }
|
||||
// ...
|
||||
//
|
||||
// This helper creates an object with a "value" property that wraps the `super` property for both get and set. This is required for
|
||||
// destructuring assignments, as a call expression cannot be used as the target of a destructuring assignment while a property
|
||||
// access can.
|
||||
// Creating an object that has getter and setters instead of just an accessor funtion is required for destructuring assignments
|
||||
// as a call expression cannot be used as the target of a destructuring assignment while a property access can.
|
||||
//
|
||||
// For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations.
|
||||
if (container.kind === SyntaxKind.MethodDeclaration && hasModifier(container, ModifierFlags.Async)) {
|
||||
|
||||
@@ -62,6 +62,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) {
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
// ES2017 async modifier should be elided for targets < ES2017
|
||||
@@ -553,7 +556,7 @@ namespace ts {
|
||||
// Disable substitution in the generated super accessor itself.
|
||||
else if (enabledSubstitutions && substitutedSuperAccessors[getNodeId(node)]) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = 0 as NodeCheckFlags;
|
||||
enclosingSuperContainerFlags = 0;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
@@ -592,7 +595,7 @@ namespace ts {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createFileLevelUniqueName("_superProps"),
|
||||
createFileLevelUniqueName("_super"),
|
||||
node.name),
|
||||
node
|
||||
);
|
||||
@@ -642,7 +645,7 @@ namespace ts {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createFileLevelUniqueName("_super"),
|
||||
createFileLevelUniqueName("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
@@ -654,7 +657,7 @@ namespace ts {
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createFileLevelUniqueName("_super"),
|
||||
createFileLevelUniqueName("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
@@ -729,7 +732,7 @@ namespace ts {
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
createFileLevelUniqueName("_superProps"),
|
||||
createFileLevelUniqueName("_super"),
|
||||
/* type */ undefined,
|
||||
createCall(
|
||||
createPropertyAccess(
|
||||
@@ -794,14 +797,14 @@ namespace ts {
|
||||
name: "typescript:async-super",
|
||||
scoped: true,
|
||||
text: helperString`
|
||||
const ${"_super"} = name => super[name];`
|
||||
const ${"_superIndex"} = name => super[name];`
|
||||
};
|
||||
|
||||
export const advancedAsyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:advanced-async-super",
|
||||
scoped: true,
|
||||
text: helperString`
|
||||
const ${"_super"} = (function (geti, seti) {
|
||||
const ${"_superIndex"} = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`
|
||||
|
||||
@@ -61,6 +61,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node, noDestructuringValue: boolean): VisitResult<Node> {
|
||||
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AwaitExpression:
|
||||
return visitAwaitExpression(node as AwaitExpression);
|
||||
@@ -854,7 +857,7 @@ namespace ts {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createFileLevelUniqueName("_superProps"),
|
||||
createFileLevelUniqueName("_super"),
|
||||
node.name),
|
||||
node
|
||||
);
|
||||
@@ -904,7 +907,7 @@ namespace ts {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
createIdentifier("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
@@ -916,7 +919,7 @@ namespace ts {
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
createIdentifier("_superIndex"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user