Skip to content

Commit c552a4b

Browse files
authored
fix(42829) ignore preceeding jsx whitespace (#43452)
1 parent 1a41e19 commit c552a4b

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

src/services/refactors/extractSymbol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ namespace ts.refactor.extractSymbol {
275275
}
276276
const cursorRequest = length === 0 && invoked;
277277

278-
const startToken = getTokenAtPosition(sourceFile, span.start);
278+
const startToken = findFirstNonJsxWhitespaceToken(sourceFile, span.start);
279279
const endToken = findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span));
280280
/* If the refactoring command is invoked through a keyboard action it's safe to assume that the user is actively looking for
281281
refactoring actions at the span location. As they may not know the exact range that will trigger a refactoring, we expand the

src/services/utilities.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,20 @@ namespace ts {
11411141
}
11421142
}
11431143

1144+
/**
1145+
* Returns the first token where position is in [start, end),
1146+
* excluding `JsxText` tokens containing only whitespace.
1147+
*/
1148+
export function findFirstNonJsxWhitespaceToken(sourceFile: SourceFile, position: number): Node | undefined {
1149+
let tokenAtPosition = getTokenAtPosition(sourceFile, position);
1150+
while (isWhiteSpaceOnlyJsxText(tokenAtPosition)) {
1151+
const nextToken = findNextToken(tokenAtPosition, tokenAtPosition.parent, sourceFile);
1152+
if (!nextToken) return;
1153+
tokenAtPosition = nextToken;
1154+
}
1155+
return tokenAtPosition;
1156+
}
1157+
11441158
/**
11451159
* The token on the left of the position is the token that strictly includes the position
11461160
* or sits to the left of the cursor if it is on a boundary. For example
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// Repro https://github.com/Microsoft/TypeScript/issues/42829
4+
5+
// @jsx: preserve
6+
// @filename: a.tsx
7+
////export default function ComponentThatExhibitsIssue() {
8+
//// return <div>
9+
//// /*a*/ <div className="some-nested-data">
10+
//// hello from my nested component
11+
//// </div>
12+
////
13+
//// /*b*/
14+
//// </div>
15+
16+
goTo.file("a.tsx");
17+
goTo.select("a", "b");
18+
edit.applyRefactor({
19+
refactorName: "Extract Symbol",
20+
actionName: "function_scope_1",
21+
actionDescription: "Extract to function in module scope",
22+
newContent:
23+
`export default function ComponentThatExhibitsIssue() {
24+
return <div>
25+
{newFunction()}
26+
27+
28+
</div>
29+
30+
function /*RENAME*/newFunction() {
31+
return <div className="some-nested-data">
32+
hello from my nested component
33+
</div>;
34+
}
35+
`
36+
});

0 commit comments

Comments
 (0)