diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 3f52f4e9ee9..974c168c83b 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4301,6 +4301,7 @@ namespace ts { return getEffectiveLines( includeComments => getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter( firstChild.pos, + parentNode.pos, currentSourceFile!, includeComments)); } @@ -4358,6 +4359,7 @@ namespace ts { return getEffectiveLines( includeComments => getLinesBetweenPositionAndNextNonWhitespaceCharacter( lastChild.end, + parentNode.end, currentSourceFile!, includeComments)); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a5235eeae23..9dbfaf19c56 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4776,19 +4776,19 @@ namespace ts { return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos, /*stopAfterLineBreak*/ false, includeComments); } - export function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos: number, sourceFile: SourceFile, includeComments?: boolean) { + export function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean) { const startPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments); - const prevPos = getPreviousNonWhitespacePosition(startPos, sourceFile); + const prevPos = getPreviousNonWhitespacePosition(startPos, stopPos, sourceFile); return getLinesBetweenPositions(sourceFile, prevPos || 0, startPos); } - export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos: number, sourceFile: SourceFile, includeComments?: boolean) { + export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean) { const nextPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments); - return getLinesBetweenPositions(sourceFile, pos, nextPos); + return getLinesBetweenPositions(sourceFile, pos, Math.min(stopPos, nextPos)); } - function getPreviousNonWhitespacePosition(pos: number, sourceFile: SourceFile) { - while (pos-- > 0) { + function getPreviousNonWhitespacePosition(pos: number, stopPos = 0, sourceFile: SourceFile) { + while (pos-- > stopPos) { if (!isWhiteSpaceLike(sourceFile.text.charCodeAt(pos))) { return pos; } diff --git a/tests/cases/fourslash/textChangesPreserveNewlines8.ts b/tests/cases/fourslash/textChangesPreserveNewlines8.ts new file mode 100644 index 00000000000..e74aef6c9d0 --- /dev/null +++ b/tests/cases/fourslash/textChangesPreserveNewlines8.ts @@ -0,0 +1,29 @@ +// #37813 + +/// + +////function foo() { +//// /*1*/var x: number +//// +//// x = 10; +//// return x;/*2*/ +////} + +goTo.select("1", "2"); +edit.applyRefactor({ + refactorName: "Extract Symbol", + actionName: "function_scope_1", + actionDescription: "Extract to function in global scope", + newContent: +`function foo() { + return /*RENAME*/newFunction(); +} + +function newFunction() { + var x: number; + + x = 10; + return x; +} +` +});