@@ -97,7 +97,7 @@ namespace ts.BreakpointResolver {
9797 if ( isFunctionBlock ( node ) ) {
9898 return spanInFunctionBlock ( < Block > node ) ;
9999 }
100- // Fall through
100+ // Fall through
101101 case SyntaxKind . ModuleBlock :
102102 return spanInBlock ( < Block > node ) ;
103103
@@ -217,17 +217,17 @@ namespace ts.BreakpointResolver {
217217
218218 case SyntaxKind . CommaToken :
219219 return spanInPreviousNode ( node )
220-
220+
221221 case SyntaxKind . OpenBraceToken :
222222 return spanInOpenBraceToken ( node ) ;
223223
224224 case SyntaxKind . CloseBraceToken :
225225 return spanInCloseBraceToken ( node ) ;
226-
226+
227227 case SyntaxKind . CloseBracketToken :
228228 return spanInCloseBracketToken ( node ) ;
229229
230- case SyntaxKind . OpenParenToken :
230+ case SyntaxKind . OpenParenToken :
231231 return spanInOpenParenToken ( node ) ;
232232
233233 case SyntaxKind . CloseParenToken :
@@ -253,6 +253,42 @@ namespace ts.BreakpointResolver {
253253 return spanInOfKeyword ( node ) ;
254254
255255 default :
256+ // Destructuring pattern in destructuring assignment
257+ // [a, b, c] of
258+ // [a, b, c] = expression
259+ if ( isArrayLiteralOrObjectLiteralDestructuringPattern ( node ) ) {
260+ return spanInArrayLiteralOrObjectLiteralDestructuringPattern ( < DestructuringPattern > node ) ;
261+ }
262+
263+ // Set breakpoint on identifier element of destructuring pattern
264+ // a or ...c from
265+ // [a, b, ...c] or { a, b } from destructuring pattern
266+ if ( ( node . kind === SyntaxKind . Identifier || node . kind == SyntaxKind . SpreadElementExpression ) &&
267+ isArrayLiteralOrObjectLiteralDestructuringPattern ( node . parent ) ) {
268+ return textSpan ( node ) ;
269+ }
270+
271+ if ( node . kind === SyntaxKind . BinaryExpression ) {
272+ const binaryExpression = < BinaryExpression > node ;
273+ // Set breakpoint in destructuring pattern if its destructuring assignment
274+ // [a, b, c] or {a, b, c} of
275+ // [a, b, c] = expression or
276+ // {a, b, c} = expression
277+ if ( isArrayLiteralOrObjectLiteralDestructuringPattern ( binaryExpression . left ) ) {
278+ return spanInArrayLiteralOrObjectLiteralDestructuringPattern (
279+ < ArrayLiteralExpression | ObjectLiteralExpression > binaryExpression . left ) ;
280+ }
281+
282+ if ( binaryExpression . operatorToken . kind === SyntaxKind . EqualsToken &&
283+ isArrayLiteralOrObjectLiteralDestructuringPattern ( binaryExpression . parent ) ) {
284+ // Set breakpoint on assignment expression element of destructuring pattern
285+ // a = expression of
286+ // [a = expression, b, c] = someExpression or
287+ // { a = expression, b, c } = someExpression
288+ return textSpan ( node ) ;
289+ }
290+ }
291+
256292 if ( isExpression ( node ) ) {
257293 switch ( node . parent . kind ) {
258294 case SyntaxKind . DoStatement :
@@ -310,6 +346,16 @@ namespace ts.BreakpointResolver {
310346 }
311347 }
312348
349+ if ( node . parent . kind === SyntaxKind . BinaryExpression ) {
350+ const binaryExpression = < BinaryExpression > node . parent ;
351+ if ( isArrayLiteralOrObjectLiteralDestructuringPattern ( binaryExpression . left ) &&
352+ ( binaryExpression . right === node ||
353+ binaryExpression . operatorToken === node ) ) {
354+ // If initializer of destructuring assignment move to previous token
355+ return spanInPreviousNode ( node ) ;
356+ }
357+ }
358+
313359 // Default go to parent to set the breakpoint
314360 return spanInNode ( node . parent ) ;
315361 }
@@ -474,13 +520,34 @@ namespace ts.BreakpointResolver {
474520
475521 // Empty binding pattern of binding element, set breakpoint on binding element
476522 if ( bindingPattern . parent . kind === SyntaxKind . BindingElement ) {
477- return spanInNode ( bindingPattern . parent ) ;
523+ return textSpan ( bindingPattern . parent ) ;
478524 }
479525
480526 // Variable declaration is used as the span
481527 return textSpanFromVariableDeclaration ( < VariableDeclaration > bindingPattern . parent ) ;
482528 }
483529
530+ function spanInArrayLiteralOrObjectLiteralDestructuringPattern ( node : DestructuringPattern ) : TextSpan {
531+ Debug . assert ( node . kind !== SyntaxKind . ArrayBindingPattern && node . kind !== SyntaxKind . ObjectBindingPattern ) ;
532+ const elements : NodeArray < Expression | ObjectLiteralElement > =
533+ node . kind === SyntaxKind . ArrayLiteralExpression ?
534+ ( < ArrayLiteralExpression > node ) . elements :
535+ ( < ObjectLiteralExpression > node ) . properties ;
536+
537+ const firstBindingElement = forEach ( elements ,
538+ element => element . kind !== SyntaxKind . OmittedExpression ? element : undefined ) ;
539+
540+ if ( firstBindingElement ) {
541+ return spanInNode ( firstBindingElement ) ;
542+ }
543+
544+ // Could be ArrayLiteral from destructuring assignment or
545+ // just nested element in another destructuring assignment
546+ // set breakpoint on assignment when parent is destructuring assignment
547+ // Otherwise set breakpoint for this element
548+ return textSpan ( node . parent . kind === SyntaxKind . BinaryExpression ? node . parent : node ) ;
549+ }
550+
484551 // Tokens:
485552 function spanInOpenBraceToken ( node : Node ) : TextSpan {
486553 switch ( node . parent . kind ) {
@@ -548,10 +615,16 @@ namespace ts.BreakpointResolver {
548615 case SyntaxKind . ArrayBindingPattern :
549616 // Breakpoint in last binding element or binding pattern if it contains no elements
550617 let bindingPattern = < BindingPattern > node . parent ;
551- return spanInNode ( lastOrUndefined ( bindingPattern . elements ) || bindingPattern ) ;
618+ return textSpan ( lastOrUndefined ( bindingPattern . elements ) || bindingPattern ) ;
552619
553- // Default to parent node
554620 default :
621+ if ( isArrayLiteralOrObjectLiteralDestructuringPattern ( node . parent ) ) {
622+ // Breakpoint in last binding element or binding pattern if it contains no elements
623+ let arrayLiteral = < ArrayLiteralExpression > node . parent ;
624+ return textSpan ( lastOrUndefined ( arrayLiteral . elements ) || arrayLiteral ) ;
625+ }
626+
627+ // Default to parent node
555628 return spanInNode ( node . parent ) ;
556629 }
557630 }
0 commit comments