mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-18 07:29:16 -05:00
Fix over-aggressive transformation of super properties
This commit is contained in:
@@ -3439,64 +3439,71 @@ namespace ts {
|
||||
function visitCallExpressionWithPotentialCapturedThisAssignment(node: CallExpression, assignToCapturedThis: boolean): CallExpression | BinaryExpression {
|
||||
// We are here either because SuperKeyword was used somewhere in the expression, or
|
||||
// because we contain a SpreadElementExpression.
|
||||
if (node.transformFlags & TransformFlags.ContainsSpread ||
|
||||
node.expression.kind === SyntaxKind.SuperKeyword ||
|
||||
isSuperProperty(skipOuterExpressions(node.expression))) {
|
||||
|
||||
const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration);
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
setEmitFlags(thisArg, EmitFlags.NoSubstitution);
|
||||
}
|
||||
let resultingCall: CallExpression | BinaryExpression;
|
||||
if (node.transformFlags & TransformFlags.ContainsSpread) {
|
||||
// [source]
|
||||
// f(...a, b)
|
||||
// x.m(...a, b)
|
||||
// super(...a, b)
|
||||
// super.m(...a, b) // in static
|
||||
// super.m(...a, b) // in instance
|
||||
//
|
||||
// [output]
|
||||
// f.apply(void 0, a.concat([b]))
|
||||
// (_a = x).m.apply(_a, a.concat([b]))
|
||||
// _super.apply(this, a.concat([b]))
|
||||
// _super.m.apply(this, a.concat([b]))
|
||||
// _super.prototype.m.apply(this, a.concat([b]))
|
||||
const { target, thisArg } = createCallBinding(node.expression, hoistVariableDeclaration);
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
setEmitFlags(thisArg, EmitFlags.NoSubstitution);
|
||||
}
|
||||
|
||||
resultingCall = createFunctionApply(
|
||||
visitNode(target, callExpressionVisitor, isExpression),
|
||||
visitNode(thisArg, visitor, isExpression),
|
||||
transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// [source]
|
||||
// super(a)
|
||||
// super.m(a) // in static
|
||||
// super.m(a) // in instance
|
||||
//
|
||||
// [output]
|
||||
// _super.call(this, a)
|
||||
// _super.m.call(this, a)
|
||||
// _super.prototype.m.call(this, a)
|
||||
resultingCall = createFunctionCall(
|
||||
visitNode(target, callExpressionVisitor, isExpression),
|
||||
visitNode(thisArg, visitor, isExpression),
|
||||
visitNodes(node.arguments, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
let resultingCall: CallExpression | BinaryExpression;
|
||||
if (node.transformFlags & TransformFlags.ContainsSpread) {
|
||||
// [source]
|
||||
// f(...a, b)
|
||||
// x.m(...a, b)
|
||||
// super(...a, b)
|
||||
// super.m(...a, b) // in static
|
||||
// super.m(...a, b) // in instance
|
||||
//
|
||||
// [output]
|
||||
// f.apply(void 0, a.concat([b]))
|
||||
// (_a = x).m.apply(_a, a.concat([b]))
|
||||
// _super.apply(this, a.concat([b]))
|
||||
// _super.m.apply(this, a.concat([b]))
|
||||
// _super.prototype.m.apply(this, a.concat([b]))
|
||||
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const actualThis = createThis();
|
||||
setEmitFlags(actualThis, EmitFlags.NoSubstitution);
|
||||
const initializer =
|
||||
createLogicalOr(
|
||||
resultingCall,
|
||||
actualThis
|
||||
resultingCall = createFunctionApply(
|
||||
visitNode(target, callExpressionVisitor, isExpression),
|
||||
visitNode(thisArg, visitor, isExpression),
|
||||
transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)
|
||||
);
|
||||
resultingCall = assignToCapturedThis
|
||||
? createAssignment(createIdentifier("_this"), initializer)
|
||||
: initializer;
|
||||
}
|
||||
else {
|
||||
// [source]
|
||||
// super(a)
|
||||
// super.m(a) // in static
|
||||
// super.m(a) // in instance
|
||||
//
|
||||
// [output]
|
||||
// _super.call(this, a)
|
||||
// _super.m.call(this, a)
|
||||
// _super.prototype.m.call(this, a)
|
||||
resultingCall = createFunctionCall(
|
||||
visitNode(target, callExpressionVisitor, isExpression),
|
||||
visitNode(thisArg, visitor, isExpression),
|
||||
visitNodes(node.arguments, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const actualThis = createThis();
|
||||
setEmitFlags(actualThis, EmitFlags.NoSubstitution);
|
||||
const initializer =
|
||||
createLogicalOr(
|
||||
resultingCall,
|
||||
actualThis
|
||||
);
|
||||
resultingCall = assignToCapturedThis
|
||||
? createAssignment(createIdentifier("_this"), initializer)
|
||||
: initializer;
|
||||
}
|
||||
return setOriginalNode(resultingCall, node);
|
||||
}
|
||||
return setOriginalNode(resultingCall, node);
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user