Skip to content

Commit 6c63dd2

Browse files
author
Andy
authored
breakpoints: Fix invalid cast (#22153)
1 parent 0701ed5 commit 6c63dd2

File tree

1 file changed

+45
-47
lines changed

1 file changed

+45
-47
lines changed

src/services/breakpoints.ts

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace ts.BreakpointResolver {
7878
case SyntaxKind.VariableDeclaration:
7979
case SyntaxKind.PropertyDeclaration:
8080
case SyntaxKind.PropertySignature:
81-
return spanInVariableDeclaration(<VariableDeclaration>node);
81+
return spanInVariableDeclaration(<VariableDeclaration | PropertyDeclaration | PropertySignature>node);
8282

8383
case SyntaxKind.Parameter:
8484
return spanInParameterDeclaration(<ParameterDeclaration>node);
@@ -273,27 +273,26 @@ namespace ts.BreakpointResolver {
273273
}
274274

275275
if (node.kind === SyntaxKind.BinaryExpression) {
276-
const binaryExpression = <BinaryExpression>node;
276+
const { left, operatorToken } = <BinaryExpression>node;
277277
// Set breakpoint in destructuring pattern if its destructuring assignment
278278
// [a, b, c] or {a, b, c} of
279279
// [a, b, c] = expression or
280280
// {a, b, c} = expression
281-
if (isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) {
281+
if (isArrayLiteralOrObjectLiteralDestructuringPattern(left)) {
282282
return spanInArrayLiteralOrObjectLiteralDestructuringPattern(
283-
<ArrayLiteralExpression | ObjectLiteralExpression>binaryExpression.left);
283+
<ArrayLiteralExpression | ObjectLiteralExpression>left);
284284
}
285285

286-
if (binaryExpression.operatorToken.kind === SyntaxKind.EqualsToken &&
287-
isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) {
286+
if (operatorToken.kind === SyntaxKind.EqualsToken && isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
288287
// Set breakpoint on assignment expression element of destructuring pattern
289288
// a = expression of
290289
// [a = expression, b, c] = someExpression or
291290
// { a = expression, b, c } = someExpression
292291
return textSpan(node);
293292
}
294293

295-
if (binaryExpression.operatorToken.kind === SyntaxKind.CommaToken) {
296-
return spanInNode(binaryExpression.left);
294+
if (operatorToken.kind === SyntaxKind.CommaToken) {
295+
return spanInNode(left);
297296
}
298297
}
299298

@@ -327,52 +326,51 @@ namespace ts.BreakpointResolver {
327326
}
328327
}
329328

330-
// If this is name of property assignment, set breakpoint in the initializer
331-
if (node.parent.kind === SyntaxKind.PropertyAssignment &&
332-
(<PropertyDeclaration>node.parent).name === node &&
333-
!isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
334-
return spanInNode((<PropertyDeclaration>node.parent).initializer);
335-
}
336-
337-
// Breakpoint in type assertion goes to its operand
338-
if (node.parent.kind === SyntaxKind.TypeAssertionExpression && (<TypeAssertion>node.parent).type === node) {
339-
return spanInNextNode((<TypeAssertion>node.parent).type);
340-
}
341-
342-
// return type of function go to previous token
343-
if (isFunctionLike(node.parent) && (<FunctionLikeDeclaration>node.parent).type === node) {
344-
return spanInPreviousNode(node);
345-
}
346-
347-
// initializer of variable/parameter declaration go to previous node
348-
if ((node.parent.kind === SyntaxKind.VariableDeclaration ||
349-
node.parent.kind === SyntaxKind.Parameter)) {
350-
const paramOrVarDecl = <VariableDeclaration | ParameterDeclaration>node.parent;
351-
if (paramOrVarDecl.initializer === node ||
352-
paramOrVarDecl.type === node ||
353-
isAssignmentOperator(node.kind)) {
354-
return spanInPreviousNode(node);
329+
switch (node.parent.kind) {
330+
case SyntaxKind.PropertyAssignment:
331+
// If this is name of property assignment, set breakpoint in the initializer
332+
if ((<PropertyAssignment>node.parent).name === node &&
333+
!isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent.parent)) {
334+
return spanInNode((<PropertyAssignment>node.parent).initializer);
335+
}
336+
break;
337+
case SyntaxKind.TypeAssertionExpression:
338+
// Breakpoint in type assertion goes to its operand
339+
if ((<TypeAssertion>node.parent).type === node) {
340+
return spanInNextNode((<TypeAssertion>node.parent).type);
341+
}
342+
break;
343+
case SyntaxKind.VariableDeclaration:
344+
case SyntaxKind.Parameter: {
345+
// initializer of variable/parameter declaration go to previous node
346+
const { initializer, type } = <VariableDeclaration | ParameterDeclaration>node.parent;
347+
if (initializer === node || type === node || isAssignmentOperator(node.kind)) {
348+
return spanInPreviousNode(node);
349+
}
350+
break;
355351
}
356-
}
357-
358-
if (node.parent.kind === SyntaxKind.BinaryExpression) {
359-
const binaryExpression = <BinaryExpression>node.parent;
360-
if (isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left) &&
361-
(binaryExpression.right === node ||
362-
binaryExpression.operatorToken === node)) {
363-
// If initializer of destructuring assignment move to previous token
364-
return spanInPreviousNode(node);
352+
case SyntaxKind.BinaryExpression: {
353+
const { left } = <BinaryExpression>node.parent;
354+
if (isArrayLiteralOrObjectLiteralDestructuringPattern(left) && node !== left) {
355+
// If initializer of destructuring assignment move to previous token
356+
return spanInPreviousNode(node);
357+
}
358+
break;
365359
}
360+
default:
361+
// return type of function go to previous token
362+
if (isFunctionLike(node.parent) && node.parent.type === node) {
363+
return spanInPreviousNode(node);
364+
}
366365
}
367366

368367
// Default go to parent to set the breakpoint
369368
return spanInNode(node.parent);
370369
}
371370
}
372371

373-
function textSpanFromVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan {
374-
if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList &&
375-
variableDeclaration.parent.declarations[0] === variableDeclaration) {
372+
function textSpanFromVariableDeclaration(variableDeclaration: VariableDeclaration | PropertyDeclaration | PropertySignature): TextSpan {
373+
if (isVariableDeclarationList(variableDeclaration.parent) && variableDeclaration.parent.declarations[0] === variableDeclaration) {
376374
// First declaration - include let keyword
377375
return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
378376
}
@@ -382,7 +380,7 @@ namespace ts.BreakpointResolver {
382380
}
383381
}
384382

385-
function spanInVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan {
383+
function spanInVariableDeclaration(variableDeclaration: VariableDeclaration | PropertyDeclaration | PropertySignature): TextSpan {
386384
// If declaration of for in statement, just set the span in parent
387385
if (variableDeclaration.parent.parent.kind === SyntaxKind.ForInStatement) {
388386
return spanInNode(variableDeclaration.parent.parent);
@@ -401,7 +399,7 @@ namespace ts.BreakpointResolver {
401399
return textSpanFromVariableDeclaration(variableDeclaration);
402400
}
403401

404-
if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList &&
402+
if (isVariableDeclarationList(variableDeclaration.parent) &&
405403
variableDeclaration.parent.declarations[0] !== variableDeclaration) {
406404
// If we cannot set breakpoint on this declaration, set it on previous one
407405
// Because the variable declaration may be binding pattern and

0 commit comments

Comments
 (0)