Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 35537b5

Browse filesBrowse files
committed
Implement breakpoint spans of array destructuring pattern of destructuring assignment
1 parent 7146b48 commit 35537b5
Copy full SHA for 35537b5

4 files changed

+426-147Lines changed: 426 additions & 147 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/services/breakpoints.ts‎

Copy file name to clipboardExpand all lines: src/services/breakpoints.ts
+80-7Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}
Collapse file

‎src/services/utilities.ts‎

Copy file name to clipboardExpand all lines: src/services/utilities.ts
+28Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,34 @@ namespace ts {
608608
}
609609
return true;
610610
}
611+
612+
export function isArrayLiteralOrObjectLiteralDestructuringPattern(node: Node) {
613+
if (node.kind === SyntaxKind.ArrayLiteralExpression ||
614+
node.kind === SyntaxKind.ObjectLiteralExpression) {
615+
// [a,b,c] from:
616+
// [a, b, c] = someExpression;
617+
if (node.parent.kind === SyntaxKind.BinaryExpression &&
618+
(<BinaryExpression>node.parent).left === node &&
619+
(<BinaryExpression>node.parent).operatorToken.kind === SyntaxKind.EqualsToken) {
620+
return true;
621+
}
622+
623+
// [a, b, c] from:
624+
// for([a, b, c] of expression)
625+
if (node.parent.kind === SyntaxKind.ForOfStatement &&
626+
(<ForOfStatement>node.parent).initializer === node) {
627+
return true;
628+
}
629+
630+
// [a, b, c] of
631+
// [x, [a, b, c] ] = someExpression
632+
if (isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) {
633+
return true;
634+
}
635+
}
636+
637+
return false;
638+
}
611639
}
612640

613641
// Display-part writer helpers

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.