diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 0434cf7106fd9..9b67d62e96576 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -1,4 +1,4 @@ -import { addRange } from "../compiler/core.js"; +import { findIndex } from "../compiler/core.js"; import { CancellationToken, Program, @@ -8,7 +8,6 @@ import { TextRange, UserPreferences, } from "../compiler/types.js"; -import { getLineOfLocalPosition } from "../compiler/utilities.js"; import { codefix, Debug, @@ -77,7 +76,19 @@ function pasteEdits( if (copiedFrom?.range) { Debug.assert(copiedFrom.range.length === pastedText.length); copiedFrom.range.forEach(copy => { - addRange(statements, copiedFrom.file.statements, getLineOfLocalPosition(copiedFrom.file, copy.pos), getLineOfLocalPosition(copiedFrom.file, copy.end) + 1); + const statementsInSourceFile = copiedFrom.file.statements; + const startNodeIndex = findIndex(statementsInSourceFile, s => s.end > copy.pos); + if (startNodeIndex === -1) return undefined; + let endNodeIndex = findIndex(statementsInSourceFile, s => s.end >= copy.end, startNodeIndex); + /** + * [|console.log(a); + * |] + * console.log(b); + */ + if (endNodeIndex !== -1 && copy.end <= statementsInSourceFile[endNodeIndex].getStart()) { + endNodeIndex--; + } + statements.push(...statementsInSourceFile.slice(startNodeIndex, endNodeIndex === -1 ? statementsInSourceFile.length : endNodeIndex + 1)); }); const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); Debug.assertIsDefined(originalProgram); diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_blankTargetFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_blankTargetFile.js index d363d15a81c1c..1fb90bbc74897 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_blankTargetFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_blankTargetFile.js @@ -5,7 +5,11 @@ export const abc = 10; //// [/b.ts] import { abc } from "./a"; -console.log(abc); + +console.log(abc); + + +console.log("abc"); //// [/c.ts] @@ -69,7 +73,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /c.ts SVC-1-0 "" /a.ts Text-1 "export const abc = 10;" - /b.ts Text-1 "import { abc } from \"./a\";\nconsole.log(abc);" + /b.ts Text-1 "import { abc } from \"./a\";\n\nconsole.log(abc);\n\n\nconsole.log(\"abc\");" lib.d.ts @@ -221,7 +225,22 @@ Info seq [hh:mm:ss:mss] request: "offset": 1 } } - ] + ], + "copiedFrom": { + "file": "b.ts", + "spans": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + } + } + ] + } }, "command": "getPasteEdits" } @@ -234,9 +253,11 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /c.ts SVC-1-1 "console.log(abc);" /a.ts Text-1 "export const abc = 10;" - /b.ts Text-1 "import { abc } from \"./a\";\nconsole.log(abc);" + /b.ts Text-1 "import { abc } from \"./a\";\n\nconsole.log(abc);\n\n\nconsole.log(\"abc\");" Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/cases/fourslash/server/pasteEdits_blankTargetFile.ts b/tests/cases/fourslash/server/pasteEdits_blankTargetFile.ts index 7d12562a84643..d4fd49c285960 100644 --- a/tests/cases/fourslash/server/pasteEdits_blankTargetFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_blankTargetFile.ts @@ -8,7 +8,11 @@ // @Filename: /b.ts //// import { abc } from "./a"; -//// console.log(abc); +//// +//// [|console.log(abc); +//// +//// |] +//// console.log("abc"); // @Filename: /tsconfig.json ////{ "files": ["c.ts", "a.ts", "b.ts"] } @@ -18,6 +22,7 @@ verify.pasteEdits({ args: { pastedText: [`console.log(abc);`], pasteLocations: [range[0]], + copiedFrom: { file: "b.ts", range: [range[1]] }, }, newFileContents: { "/c.ts":