From b3c67d32020a3015fe068fbcb1dcfb18aedcaad3 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 15 Nov 2024 14:21:38 -0800 Subject: [PATCH] Move to file: fix detection of references to globals that shouldn't be moved (#60450) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Isabel Duan Co-authored-by: Mateusz BurzyƄski --- src/services/refactors/moveToFile.ts | 28 +- .../pasteEdits_globalAndLocal1.js | 368 +++++++++++++++++ .../pasteEdits_globalAndLocal2.js | 390 ++++++++++++++++++ .../codeFixClassImplementInterfaceGlobal.ts | 31 ++ .../moveToNewFile_globalAndLocal1.ts | 30 ++ .../moveToNewFile_globalAndLocal2.ts | 28 ++ .../moveToNewFile_globalAndLocal3.ts | 28 ++ .../moveToNewFile_globalAndLocal4.ts | 25 ++ .../moveToNewFile_globalAndLocal5.ts | 25 ++ .../moveToNewFile_globalAndLocal6.ts | 22 + .../moveToNewFile_importNameLikeGlobal1.ts | 24 ++ .../server/pasteEdits_globalAndLocal1.ts | 38 ++ .../server/pasteEdits_globalAndLocal2.ts | 40 ++ 13 files changed, 1061 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal2.js create mode 100644 tests/cases/fourslash/codeFixClassImplementInterfaceGlobal.ts create mode 100644 tests/cases/fourslash/moveToNewFile_globalAndLocal1.ts create mode 100644 tests/cases/fourslash/moveToNewFile_globalAndLocal2.ts create mode 100644 tests/cases/fourslash/moveToNewFile_globalAndLocal3.ts create mode 100644 tests/cases/fourslash/moveToNewFile_globalAndLocal4.ts create mode 100644 tests/cases/fourslash/moveToNewFile_globalAndLocal5.ts create mode 100644 tests/cases/fourslash/moveToNewFile_globalAndLocal6.ts create mode 100644 tests/cases/fourslash/moveToNewFile_importNameLikeGlobal1.ts create mode 100644 tests/cases/fourslash/server/pasteEdits_globalAndLocal1.ts create mode 100644 tests/cases/fourslash/server/pasteEdits_globalAndLocal2.ts diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 241e9adf2ad..6245fe4903d 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -26,6 +26,7 @@ import { emptyArray, EnumDeclaration, escapeLeadingUnderscores, + every, ExportDeclaration, ExportKind, Expression, @@ -885,24 +886,23 @@ export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[], const unusedImportsFromOldFile = new Set(); for (const statement of toMove) { forEachReference(statement, checker, enclosingRange, (symbol, isValidTypeOnlyUseSite) => { - if (!symbol.declarations || isGlobalType(checker, symbol)) { + if (!symbol.declarations) { return; } if (existingTargetLocals.has(skipAlias(symbol, checker))) { unusedImportsFromOldFile.add(symbol); return; } - for (const decl of symbol.declarations) { - if (isInImport(decl)) { - const prevIsTypeOnly = oldImportsNeededByTargetFile.get(symbol); - oldImportsNeededByTargetFile.set(symbol, [ - prevIsTypeOnly === undefined ? isValidTypeOnlyUseSite : prevIsTypeOnly && isValidTypeOnlyUseSite, - tryCast(decl, (d): d is codefix.ImportOrRequireAliasDeclaration => isImportSpecifier(d) || isImportClause(d) || isNamespaceImport(d) || isImportEqualsDeclaration(d) || isBindingElement(d) || isVariableDeclaration(d)), - ]); - } - else if (isTopLevelDeclaration(decl) && sourceFileOfTopLevelDeclaration(decl) === oldFile && !movedSymbols.has(symbol)) { - targetFileImportsFromOldFile.set(symbol, isValidTypeOnlyUseSite); - } + const importedDeclaration = find(symbol.declarations, isInImport); + if (importedDeclaration) { + const prevIsTypeOnly = oldImportsNeededByTargetFile.get(symbol); + oldImportsNeededByTargetFile.set(symbol, [ + prevIsTypeOnly === undefined ? isValidTypeOnlyUseSite : prevIsTypeOnly && isValidTypeOnlyUseSite, + tryCast(importedDeclaration, (d): d is codefix.ImportOrRequireAliasDeclaration => isImportSpecifier(d) || isImportClause(d) || isNamespaceImport(d) || isImportEqualsDeclaration(d) || isBindingElement(d) || isVariableDeclaration(d)), + ]); + } + else if (!movedSymbols.has(symbol) && every(symbol.declarations, decl => isTopLevelDeclaration(decl) && sourceFileOfTopLevelDeclaration(decl) === oldFile)) { + targetFileImportsFromOldFile.set(symbol, isValidTypeOnlyUseSite); } }); } @@ -946,10 +946,6 @@ export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[], } } -function isGlobalType(checker: TypeChecker, symbol: Symbol) { - return !!checker.resolveName(symbol.name, /*location*/ undefined, SymbolFlags.Type, /*excludeGlobals*/ false); -} - function makeUniqueFilename(proposedFilename: string, extension: string, inDirectory: string, host: LanguageServiceHost): string { let newFilename = proposedFilename; for (let i = 1;; i++) { diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal1.js new file mode 100644 index 00000000000..c7fe3c6eb02 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal1.js @@ -0,0 +1,368 @@ +Info seq [hh:mm:ss:mss] currentDirectory:: /home/src/Vscode/Projects/bin useCaseSensitiveFileNames:: false +Info seq [hh:mm:ss:mss] libs Location:: /home/src/tslibs/TS/Lib +Info seq [hh:mm:ss:mss] globalTypingsCacheLocation:: /home/src/Library/Caches/typescript +Info seq [hh:mm:ss:mss] Provided types map file "/home/src/tslibs/TS/Lib/typesMap.json" doesn't exist +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +lib.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/home/src/workspaces/project/globals.d.ts] +export {}; // Make this a module +declare global { + interface Disposable { + [Symbol.dispose](): void; + } +} + +//// [/home/src/workspaces/project/target.ts] + + +//// [/home/src/workspaces/project/test.ts] +export interface Disposable { + (): string; +} +export interface EditingService extends Disposable { } + +//// [/home/src/workspaces/project/tsconfig.json] +{ "files": ["target.ts", "globals.d.ts", "test.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/home/src/workspaces/project/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /home/src/workspaces/project/target.ts ProjectRootPath: undefined:: Result: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /home/src/workspaces/project/tsconfig.json, currentDirectory: /home/src/workspaces/project +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/tsconfig.json 2000 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] Config: /home/src/workspaces/project/tsconfig.json : { + "rootNames": [ + "/home/src/workspaces/project/target.ts", + "/home/src/workspaces/project/globals.d.ts", + "/home/src/workspaces/project/test.ts" + ], + "options": { + "configFilePath": "/home/src/workspaces/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/home/src/workspaces/project/tsconfig.json", + "reason": "Creating possible configured project for /home/src/workspaces/project/target.ts to open" + } + } +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/globals.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/test.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/home/src/workspaces/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /home/src/workspaces/project/target.ts SVC-1-0 "" + /home/src/workspaces/project/globals.d.ts Text-1 "export {}; // Make this a module\ndeclare global {\n interface Disposable {\n [Symbol.dispose](): void;\n }\n}" + /home/src/workspaces/project/test.ts Text-1 "export interface Disposable {\n (): string;\n}\nexport interface EditingService extends Disposable { }" + + + ../../tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + ../../tslibs/TS/Lib/lib.decorators.d.ts + Library referenced via 'decorators' from file '../../tslibs/TS/Lib/lib.d.ts' + ../../tslibs/TS/Lib/lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file '../../tslibs/TS/Lib/lib.d.ts' + target.ts + Part of 'files' list in tsconfig.json + globals.d.ts + Part of 'files' list in tsconfig.json + test.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/home/src/workspaces/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/home/src/workspaces/project/target.ts", + "configFile": "/home/src/workspaces/project/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/home/src/workspaces/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /home/src/workspaces/project/target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 0, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/globals.d.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/test.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/home/src/workspaces/node_modules: *new* + {} +/home/src/workspaces/node_modules/@types: *new* + {} +/home/src/workspaces/project/node_modules: *new* + {} +/home/src/workspaces/project/node_modules/@types: *new* + {} + +Projects:: +/home/src/workspaces/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/globals.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json *default* +/home/src/workspaces/project/test.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/home/src/workspaces/project/target.ts", + "pastedText": [ + "export interface EditingService extends Disposable { }" + ], + "pasteLocations": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + } + } + ], + "copiedFrom": { + "file": "/home/src/workspaces/project/test.ts", + "spans": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 55 + } + } + ] + } + }, + "command": "getPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/home/src/workspaces/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /home/src/workspaces/project/target.ts SVC-1-1 "export interface EditingService extends Disposable { }" + /home/src/workspaces/project/globals.d.ts Text-1 "export {}; // Make this a module\ndeclare global {\n interface Disposable {\n [Symbol.dispose](): void;\n }\n}" + /home/src/workspaces/project/test.ts Text-1 "export interface Disposable {\n (): string;\n}\nexport interface EditingService extends Disposable { }" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/home/src/workspaces/project/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { Disposable } from \"./test\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "export interface EditingService extends Disposable { }" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +After Request +Projects:: +/home/src/workspaces/project/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/globals.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json *default* +/home/src/workspaces/project/test.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal2.js new file mode 100644 index 00000000000..970e98dbdc2 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_globalAndLocal2.js @@ -0,0 +1,390 @@ +Info seq [hh:mm:ss:mss] currentDirectory:: /home/src/Vscode/Projects/bin useCaseSensitiveFileNames:: false +Info seq [hh:mm:ss:mss] libs Location:: /home/src/tslibs/TS/Lib +Info seq [hh:mm:ss:mss] globalTypingsCacheLocation:: /home/src/Library/Caches/typescript +Info seq [hh:mm:ss:mss] Provided types map file "/home/src/tslibs/TS/Lib/typesMap.json" doesn't exist +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +lib.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/home/src/workspaces/project/globals.d.ts] +export {}; // Make this a module +declare global { + interface Disposable { + [Symbol.dispose](): void; + } +} + +//// [/home/src/workspaces/project/lifecycle.ts] +export interface Disposable { + (): string; +} + +//// [/home/src/workspaces/project/target.ts] + + +//// [/home/src/workspaces/project/test.ts] +import { Disposable } from './lifecycle'; +export interface EditingService extends Disposable { } + +//// [/home/src/workspaces/project/tsconfig.json] +{ "files": ["target.ts", "globals.d.ts", "test.ts", "lifecycle.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/home/src/workspaces/project/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /home/src/workspaces/project/target.ts ProjectRootPath: undefined:: Result: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /home/src/workspaces/project/tsconfig.json, currentDirectory: /home/src/workspaces/project +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/tsconfig.json 2000 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] Config: /home/src/workspaces/project/tsconfig.json : { + "rootNames": [ + "/home/src/workspaces/project/target.ts", + "/home/src/workspaces/project/globals.d.ts", + "/home/src/workspaces/project/test.ts", + "/home/src/workspaces/project/lifecycle.ts" + ], + "options": { + "configFilePath": "/home/src/workspaces/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/home/src/workspaces/project/tsconfig.json", + "reason": "Creating possible configured project for /home/src/workspaces/project/target.ts to open" + } + } +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/globals.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/test.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/workspaces/project/lifecycle.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/project/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/workspaces/node_modules/@types 1 undefined Project: /home/src/workspaces/project/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/home/src/workspaces/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /home/src/workspaces/project/target.ts SVC-1-0 "" + /home/src/workspaces/project/globals.d.ts Text-1 "export {}; // Make this a module\ndeclare global {\n interface Disposable {\n [Symbol.dispose](): void;\n }\n}" + /home/src/workspaces/project/lifecycle.ts Text-1 "export interface Disposable {\n\t(): string;\n}" + /home/src/workspaces/project/test.ts Text-1 "import { Disposable } from './lifecycle';\nexport interface EditingService extends Disposable { }" + + + ../../tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + ../../tslibs/TS/Lib/lib.decorators.d.ts + Library referenced via 'decorators' from file '../../tslibs/TS/Lib/lib.d.ts' + ../../tslibs/TS/Lib/lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file '../../tslibs/TS/Lib/lib.d.ts' + target.ts + Part of 'files' list in tsconfig.json + globals.d.ts + Part of 'files' list in tsconfig.json + lifecycle.ts + Imported via './lifecycle' from file 'test.ts' + Part of 'files' list in tsconfig.json + test.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/home/src/workspaces/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/home/src/workspaces/project/target.ts", + "configFile": "/home/src/workspaces/project/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/home/src/workspaces/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /home/src/workspaces/project/target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 0, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/globals.d.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/lifecycle.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/test.ts: *new* + {"pollingInterval":500} +/home/src/workspaces/project/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/home/src/workspaces/node_modules: *new* + {} +/home/src/workspaces/node_modules/@types: *new* + {} +/home/src/workspaces/project/node_modules: *new* + {} +/home/src/workspaces/project/node_modules/@types: *new* + {} + +Projects:: +/home/src/workspaces/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/globals.d.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/lifecycle.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json *default* +/home/src/workspaces/project/test.ts *new* + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/home/src/workspaces/project/target.ts", + "pastedText": [ + "export interface EditingService extends Disposable { }" + ], + "pasteLocations": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + } + } + ], + "copiedFrom": { + "file": "/home/src/workspaces/project/test.ts", + "spans": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 55 + } + } + ] + } + }, + "command": "getPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /home/src/workspaces/project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/home/src/workspaces/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /home/src/workspaces/project/target.ts SVC-1-1 "export interface EditingService extends Disposable { }" + /home/src/workspaces/project/globals.d.ts Text-1 "export {}; // Make this a module\ndeclare global {\n interface Disposable {\n [Symbol.dispose](): void;\n }\n}" + /home/src/workspaces/project/lifecycle.ts Text-1 "export interface Disposable {\n\t(): string;\n}" + /home/src/workspaces/project/test.ts Text-1 "import { Disposable } from './lifecycle';\nexport interface EditingService extends Disposable { }" + +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, + "type": "response", + "command": "getPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/home/src/workspaces/project/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { Disposable } from './lifecycle';\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "export interface EditingService extends Disposable { }" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +After Request +Projects:: +/home/src/workspaces/project/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/globals.d.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/lifecycle.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json +/home/src/workspaces/project/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json *default* +/home/src/workspaces/project/test.ts + version: Text-1 + containingProjects: 1 + /home/src/workspaces/project/tsconfig.json diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceGlobal.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceGlobal.ts new file mode 100644 index 00000000000..4217fdb5ee4 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceGlobal.ts @@ -0,0 +1,31 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// import { Service } from './lifecycle'; +//// export class [|EditingService|] implements Service { } + +// @Filename: /src/lifecycle.ts +//// export interface Disposable { +//// (): string; +//// } +//// export interface Service { +//// d: Disposable; +//// } + +goTo.file('/src/test.ts'); +verify.codeFix({ + description: "Implement interface 'Service'", + newFileContent: +`import { Disposable, Service } from './lifecycle'; +export class EditingService implements Service { + d: Disposable; +}`, +}); diff --git a/tests/cases/fourslash/moveToNewFile_globalAndLocal1.ts b/tests/cases/fourslash/moveToNewFile_globalAndLocal1.ts new file mode 100644 index 00000000000..d1c9119d638 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_globalAndLocal1.ts @@ -0,0 +1,30 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// interface Disposable { +//// (): string; +//// } +//// export interface [|EditingService|] extends Disposable { } + + +verify.moveToNewFile({ + newFileContents: { + "/src/test.ts": +`export interface Disposable { + (): string; +} +`, + "/src/EditingService.ts": // Reference to Disposable is still from test +`import { Disposable } from "./test"; + +export interface EditingService extends Disposable { } +` +}}); diff --git a/tests/cases/fourslash/moveToNewFile_globalAndLocal2.ts b/tests/cases/fourslash/moveToNewFile_globalAndLocal2.ts new file mode 100644 index 00000000000..4fbcd80fbff --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_globalAndLocal2.ts @@ -0,0 +1,28 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// [|export interface Disposable { +//// (): string; +//// } +//// export interface EditingService extends Disposable { }|] + + +verify.moveToNewFile({ + newFileContents: { + "/src/test.ts": +``, + "/src/Disposable.ts": // Reference to Disposable is moved to new file from `test.ts` +`export interface Disposable { + (): string; +} +export interface EditingService extends Disposable { } +` +}}); diff --git a/tests/cases/fourslash/moveToNewFile_globalAndLocal3.ts b/tests/cases/fourslash/moveToNewFile_globalAndLocal3.ts new file mode 100644 index 00000000000..9a3ac8c3126 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_globalAndLocal3.ts @@ -0,0 +1,28 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// import { Disposable } from './lifecycle'; +//// export interface [|EditingService|] extends Disposable { } + +// @Filename: /src/lifecycle.ts +//// export interface Disposable { +//// (): string; +//// } + +verify.moveToNewFile({ + newFileContents: { + "/src/test.ts": ``, + "/src/EditingService.ts": // Reference to Disposable is still from lifecycle +`import { Disposable } from './lifecycle'; + +export interface EditingService extends Disposable { } +` +}}); diff --git a/tests/cases/fourslash/moveToNewFile_globalAndLocal4.ts b/tests/cases/fourslash/moveToNewFile_globalAndLocal4.ts new file mode 100644 index 00000000000..ca0e8f84769 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_globalAndLocal4.ts @@ -0,0 +1,25 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// export interface [|EditingService|] extends Disposable { } + +// @Filename: /src/lifecycle.ts +//// export interface Disposable { +//// (): string; +//// } + +verify.moveToNewFile({ + newFileContents: { + "/src/test.ts": ``, + "/src/EditingService.ts": // Reference to Disposable is still global +`export interface EditingService extends Disposable { } +` +}}); diff --git a/tests/cases/fourslash/moveToNewFile_globalAndLocal5.ts b/tests/cases/fourslash/moveToNewFile_globalAndLocal5.ts new file mode 100644 index 00000000000..a887373d902 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_globalAndLocal5.ts @@ -0,0 +1,25 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// const Disposable = 1; +//// export const [|EditingService|] = Disposable; + +verify.moveToNewFile({ + newFileContents: { + "/src/test.ts": +`export const Disposable = 1; +`, + "/src/EditingService.ts": // Reference to Disposable is still from `test.ts` +`import { Disposable } from "./test"; + +export const EditingService = Disposable; +` +}}); diff --git a/tests/cases/fourslash/moveToNewFile_globalAndLocal6.ts b/tests/cases/fourslash/moveToNewFile_globalAndLocal6.ts new file mode 100644 index 00000000000..b8ed8e520e9 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_globalAndLocal6.ts @@ -0,0 +1,22 @@ +/// + +// @Filename: /src/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /src/test.ts +//// [|const Disposable = 1; +//// export const EditingService = Disposable;|] + +verify.moveToNewFile({ + newFileContents: { + "/src/test.ts": ``, + "/src/Disposable.ts": // Reference to Disposable is moved from `test.ts` +`const Disposable = 1; +export const EditingService = Disposable; +` +}}); diff --git a/tests/cases/fourslash/moveToNewFile_importNameLikeGlobal1.ts b/tests/cases/fourslash/moveToNewFile_importNameLikeGlobal1.ts new file mode 100644 index 00000000000..018ca7dcfd0 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_importNameLikeGlobal1.ts @@ -0,0 +1,24 @@ +/// + +// @lib: dom + +// @Filename: /a.ts +//// export default class Event {} + +// @Filename: /b.ts +//// import Event from './a.js'; +//// [|export function test(test: Event): void {}|] + +verify.noErrors(); + +verify.moveToNewFile({ + newFileContents: { + "/b.ts": "", + + "/test.ts": +`import Event from './a'; + +export function test(test: Event): void { } +`, + }, +}); diff --git a/tests/cases/fourslash/server/pasteEdits_globalAndLocal1.ts b/tests/cases/fourslash/server/pasteEdits_globalAndLocal1.ts new file mode 100644 index 00000000000..492cdd90ef4 --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_globalAndLocal1.ts @@ -0,0 +1,38 @@ +/// + +// @Filename: /home/src/workspaces/project/target.ts +//// [||] + +// @Filename: /home/src/workspaces/project/test.ts +//// export interface Disposable { +//// (): string; +//// } +//// [|export interface EditingService extends Disposable { }|] + +// @Filename: /home/src/workspaces/project/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + + +// @Filename: /home/src/workspaces/project/tsconfig.json +////{ "files": ["target.ts", "globals.d.ts", "test.ts"] } + +const ranges = test.ranges(); +verify.pasteEdits({ + args: { + copiedFrom: { file: "/home/src/workspaces/project/test.ts", range: [ranges[1]] }, + pastedText: [ `export interface EditingService extends Disposable { }` ], + pasteLocations: [ranges[0]], + }, + newFileContents: { + "/home/src/workspaces/project/target.ts": +`import { Disposable } from "./test"; + +export interface EditingService extends Disposable { }` + + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_globalAndLocal2.ts b/tests/cases/fourslash/server/pasteEdits_globalAndLocal2.ts new file mode 100644 index 00000000000..6e0ec85ee24 --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_globalAndLocal2.ts @@ -0,0 +1,40 @@ +/// + +// @Filename: /home/src/workspaces/project/target.ts +//// [||] + +// @Filename: /home/src/workspaces/project/test.ts +//// import { Disposable } from './lifecycle'; +//// [|export interface EditingService extends Disposable { }|] + +// @Filename: /home/src/workspaces/project/lifecycle.ts +//// export interface Disposable { +//// (): string; +//// } + +// @Filename: /home/src/workspaces/project/globals.d.ts +//// export {}; // Make this a module +//// declare global { +//// interface Disposable { +//// [Symbol.dispose](): void; +//// } +//// } + +// @Filename: /home/src/workspaces/project/tsconfig.json +////{ "files": ["target.ts", "globals.d.ts", "test.ts", "lifecycle.ts"] } + +const ranges = test.ranges(); +verify.pasteEdits({ + args: { + copiedFrom: { file: "/home/src/workspaces/project/test.ts", range: [ranges[1]] }, + pastedText: [ `export interface EditingService extends Disposable { }` ], + pasteLocations: [ranges[0]], + }, + newFileContents: { + "/home/src/workspaces/project/target.ts": +`import { Disposable } from './lifecycle'; + +export interface EditingService extends Disposable { }` + + } +}); \ No newline at end of file