mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-12 20:25:48 -06:00
Fix compiler crash with object rest in catch binding (#31522)
This commit is contained in:
parent
b3dc32fec7
commit
c3055e585d
@ -30169,12 +30169,17 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isSymbolOfDestructuredElementOfCatchBinding(symbol: Symbol) {
|
||||
return isBindingElement(symbol.valueDeclaration)
|
||||
&& walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === SyntaxKind.CatchClause;
|
||||
}
|
||||
|
||||
function isSymbolOfDeclarationWithCollidingName(symbol: Symbol): boolean {
|
||||
if (symbol.flags & SymbolFlags.BlockScoped && !isSourceFile(symbol.valueDeclaration)) {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (links.isDeclarationWithCollidingName === undefined) {
|
||||
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
|
||||
if (isStatementWithLocals(container)) {
|
||||
if (isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) {
|
||||
const nodeLinks = getNodeLinks(symbol.valueDeclaration);
|
||||
if (resolveName(container.parent, symbol.escapedName, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) {
|
||||
// redeclaration - always should be renamed
|
||||
|
||||
@ -77,6 +77,8 @@ namespace ts {
|
||||
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return visitBinaryExpression(node as BinaryExpression, noDestructuringValue);
|
||||
case SyntaxKind.CatchClause:
|
||||
return visitCatchClause(node as CatchClause);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return visitVariableDeclaration(node as VariableDeclaration);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
@ -272,6 +274,28 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitCatchClause(node: CatchClause) {
|
||||
if (node.variableDeclaration &&
|
||||
isBindingPattern(node.variableDeclaration.name) &&
|
||||
node.variableDeclaration.name.transformFlags & TransformFlags.ContainsObjectRestOrSpread) {
|
||||
const name = getGeneratedNameForNode(node.variableDeclaration.name);
|
||||
const updatedDecl = updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*type*/ undefined, name);
|
||||
const visitedBindings = flattenDestructuringBinding(updatedDecl, visitor, context, FlattenLevel.ObjectRest);
|
||||
let block = visitNode(node.block, visitor, isBlock);
|
||||
if (some(visitedBindings)) {
|
||||
block = updateBlock(block, [
|
||||
createVariableStatement(/*modifiers*/ undefined, visitedBindings),
|
||||
...block.statements,
|
||||
]);
|
||||
}
|
||||
return updateCatchClause(
|
||||
node,
|
||||
updateVariableDeclaration(node.variableDeclaration, name, /*type*/ undefined, /*initializer*/ undefined),
|
||||
block);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a VariableDeclaration node with a binding pattern.
|
||||
*
|
||||
|
||||
21
tests/baselines/reference/objectRestCatchES5.js
Normal file
21
tests/baselines/reference/objectRestCatchES5.js
Normal file
@ -0,0 +1,21 @@
|
||||
//// [objectRestCatchES5.ts]
|
||||
let a = 1, b = 2;
|
||||
try {} catch ({ a, ...b }) {}
|
||||
|
||||
//// [objectRestCatchES5.js]
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
||||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
||||
t[p[i]] = s[p[i]];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var a = 1, b = 2;
|
||||
try { }
|
||||
catch (_a) {
|
||||
var a_1 = _a.a, b_1 = __rest(_a, ["a"]);
|
||||
}
|
||||
9
tests/baselines/reference/objectRestCatchES5.symbols
Normal file
9
tests/baselines/reference/objectRestCatchES5.symbols
Normal file
@ -0,0 +1,9 @@
|
||||
=== tests/cases/conformance/types/rest/objectRestCatchES5.ts ===
|
||||
let a = 1, b = 2;
|
||||
>a : Symbol(a, Decl(objectRestCatchES5.ts, 0, 3))
|
||||
>b : Symbol(b, Decl(objectRestCatchES5.ts, 0, 10))
|
||||
|
||||
try {} catch ({ a, ...b }) {}
|
||||
>a : Symbol(a, Decl(objectRestCatchES5.ts, 1, 15))
|
||||
>b : Symbol(b, Decl(objectRestCatchES5.ts, 1, 18))
|
||||
|
||||
11
tests/baselines/reference/objectRestCatchES5.types
Normal file
11
tests/baselines/reference/objectRestCatchES5.types
Normal file
@ -0,0 +1,11 @@
|
||||
=== tests/cases/conformance/types/rest/objectRestCatchES5.ts ===
|
||||
let a = 1, b = 2;
|
||||
>a : number
|
||||
>1 : 1
|
||||
>b : number
|
||||
>2 : 2
|
||||
|
||||
try {} catch ({ a, ...b }) {}
|
||||
>a : any
|
||||
>b : any
|
||||
|
||||
2
tests/cases/conformance/types/rest/objectRestCatchES5.ts
Normal file
2
tests/cases/conformance/types/rest/objectRestCatchES5.ts
Normal file
@ -0,0 +1,2 @@
|
||||
let a = 1, b = 2;
|
||||
try {} catch ({ a, ...b }) {}
|
||||
Loading…
x
Reference in New Issue
Block a user