fix(42829) ignore preceeding jsx whitespace (#43452)

This commit is contained in:
Zak Miller 2021-04-22 18:12:05 -04:00 committed by GitHub
parent 1a41e19957
commit c552a4bf82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 1 deletions

View File

@ -275,7 +275,7 @@ namespace ts.refactor.extractSymbol {
}
const cursorRequest = length === 0 && invoked;
const startToken = getTokenAtPosition(sourceFile, span.start);
const startToken = findFirstNonJsxWhitespaceToken(sourceFile, span.start);
const endToken = findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span));
/* If the refactoring command is invoked through a keyboard action it's safe to assume that the user is actively looking for
refactoring actions at the span location. As they may not know the exact range that will trigger a refactoring, we expand the

View File

@ -1141,6 +1141,20 @@ namespace ts {
}
}
/**
* Returns the first token where position is in [start, end),
* excluding `JsxText` tokens containing only whitespace.
*/
export function findFirstNonJsxWhitespaceToken(sourceFile: SourceFile, position: number): Node | undefined {
let tokenAtPosition = getTokenAtPosition(sourceFile, position);
while (isWhiteSpaceOnlyJsxText(tokenAtPosition)) {
const nextToken = findNextToken(tokenAtPosition, tokenAtPosition.parent, sourceFile);
if (!nextToken) return;
tokenAtPosition = nextToken;
}
return tokenAtPosition;
}
/**
* The token on the left of the position is the token that strictly includes the position
* or sits to the left of the cursor if it is on a boundary. For example

View File

@ -0,0 +1,36 @@
/// <reference path='fourslash.ts' />
// Repro https://github.com/Microsoft/TypeScript/issues/42829
// @jsx: preserve
// @filename: a.tsx
////export default function ComponentThatExhibitsIssue() {
//// return <div>
//// /*a*/ <div className="some-nested-data">
//// hello from my nested component
//// </div>
////
//// /*b*/
//// </div>
goTo.file("a.tsx");
goTo.select("a", "b");
edit.applyRefactor({
refactorName: "Extract Symbol",
actionName: "function_scope_1",
actionDescription: "Extract to function in module scope",
newContent:
`export default function ComponentThatExhibitsIssue() {
return <div>
{newFunction()}
</div>
function /*RENAME*/newFunction() {
return <div className="some-nested-data">
hello from my nested component
</div>;
}
`
});