Skip to content

Commit dc86736

Browse files
committed
Merge pull request #4596 from Microsoft/jsxIndentation
fix 'findPrecedingToken' for jsxText
2 parents 4f4c8ee + 538d5b9 commit dc86736

File tree

3 files changed

+49
-14
lines changed

3 files changed

+49
-14
lines changed

src/services/utilities.ts

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ namespace ts {
360360
return find(startNode || sourceFile);
361361

362362
function findRightmostToken(n: Node): Node {
363-
if (isToken(n)) {
363+
if (isToken(n) || n.kind === SyntaxKind.JsxText) {
364364
return n;
365365
}
366366

@@ -371,24 +371,35 @@ namespace ts {
371371
}
372372

373373
function find(n: Node): Node {
374-
if (isToken(n)) {
374+
if (isToken(n) || n.kind === SyntaxKind.JsxText) {
375375
return n;
376376
}
377377

378-
let children = n.getChildren();
378+
const children = n.getChildren();
379379
for (let i = 0, len = children.length; i < len; i++) {
380380
let child = children[i];
381-
if (nodeHasTokens(child)) {
382-
if (position <= child.end) {
383-
if (child.getStart(sourceFile) >= position) {
384-
// actual start of the node is past the position - previous token should be at the end of previous child
385-
let candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i);
386-
return candidate && findRightmostToken(candidate)
387-
}
388-
else {
389-
// candidate should be in this node
390-
return find(child);
391-
}
381+
// condition 'position < child.end' checks if child node end after the position
382+
// in the example below this condition will be false for 'aaaa' and 'bbbb' and true for 'ccc'
383+
// aaaa___bbbb___$__ccc
384+
// after we found child node with end after the position we check if start of the node is after the position.
385+
// if yes - then position is in the trivia and we need to look into the previous child to find the token in question.
386+
// if no - position is in the node itself so we should recurse in it.
387+
// NOTE: JsxText is a weird kind of node that can contain only whitespaces (since they are not counted as trivia).
388+
// if this is the case - then we should assume that token in question is located in previous child.
389+
if (position < child.end && (nodeHasTokens(child) || child.kind === SyntaxKind.JsxText)) {
390+
const start = child.getStart(sourceFile);
391+
const lookInPreviousChild =
392+
(start >= position) || // cursor in the leading trivia
393+
(child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText
394+
395+
if (lookInPreviousChild) {
396+
// actual start of the node is past the position - previous token should be at the end of previous child
397+
let candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i);
398+
return candidate && findRightmostToken(candidate)
399+
}
400+
else {
401+
// candidate should be in this node
402+
return find(child);
392403
}
393404
}
394405
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
//@Filename: file.tsx
4+
////(function () {
5+
//// return (
6+
//// <div>
7+
//// <div>
8+
//// </div>
9+
//// /*indent2*/
10+
//// </div>
11+
//// )
12+
////})
13+
14+
15+
format.document();
16+
goTo.marker("indent2");
17+
verify.indentationIs(12);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="fourslash.ts"/>
2+
3+
//@Filename: file.tsx
4+
////<div>/*1*/
5+
goTo.marker("1");
6+
edit.insert("\n");
7+
verify.indentationIs(0);

0 commit comments

Comments
 (0)