From 0ec4d30a6e2ebbc87292c9829378d4e98de8ef43 Mon Sep 17 00:00:00 2001 From: navya9singh <108360753+navya9singh@users.noreply.github.com> Date: Sat, 2 Nov 2024 22:55:36 -0700 Subject: [PATCH] Fixing exception on unsaved file (#60362) --- src/server/session.ts | 2 + .../unittests/tsserver/pasteEdits.ts | 38 +++ .../tsserver/pasteEdits/should-not-error.js | 248 ++++++++++++++++++ 3 files changed, 288 insertions(+) create mode 100644 tests/baselines/reference/tsserver/pasteEdits/should-not-error.js diff --git a/src/server/session.ts b/src/server/session.ts index 2c2f2895f01..d03f18037a7 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -156,6 +156,7 @@ import { indent, isConfigFile, isConfiguredProject, + isDynamicFileName, isExternalProject, isInferredProject, ITypingsInstaller, @@ -2981,6 +2982,7 @@ export class Session implements EventSender { } private getPasteEdits(args: protocol.GetPasteEditsRequestArgs): protocol.PasteEditsAction | undefined { const { file, project } = this.getFileAndProject(args); + if (isDynamicFileName(file)) return undefined; const copiedFrom = args.copiedFrom ? { file: args.copiedFrom.file, range: args.copiedFrom.spans.map(copies => this.getRange({ file: args.copiedFrom!.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom!.file))!)) } : undefined; diff --git a/src/testRunner/unittests/tsserver/pasteEdits.ts b/src/testRunner/unittests/tsserver/pasteEdits.ts index 252ceb46c56..c722a772d40 100644 --- a/src/testRunner/unittests/tsserver/pasteEdits.ts +++ b/src/testRunner/unittests/tsserver/pasteEdits.ts @@ -46,4 +46,42 @@ const f = r + s;`; verifyGetErrRequest({ session, files: [target.path] }); baselineTsserverLogs("pasteEdits", "adds paste edits", session); }); + it("should not error", () => { + const file1: File = { + path: "/home/src/projects/project/file1.ts", + content: `export const r = 1; +console.log(r);`, + }; + const tsconfig: File = { + path: "/home/src/projects/project/tsconfig.json", + content: "{}", + }; + const host = TestServerHost.createServerHost([file1, tsconfig]); + const session = new TestSession(host); + session.executeCommandSeq({ + command: ts.server.protocol.CommandTypes.UpdateOpen, + arguments: { + changedFiles: [], + closedFiles: [], + openFiles: [ + { + file: "^/untitled/ts-nul-authority/Untitled-1", + fileContent: "function foo(){}\r\n \r\n", + scriptKindName: "TS", + }, + ], + }, + }); + session.executeCommandSeq({ + command: ts.server.protocol.CommandTypes.GetPasteEdits, + arguments: { + file: "^/untitled/ts-nul-authority/Untitled-1", + pastedText: ["console.log(r);"], + pasteLocations: [{ start: { line: 1, offset: 0 }, end: { line: 1, offset: 0 } }], + copiedFrom: { file: file1.path, spans: [{ start: { line: 2, offset: 0 }, end: { line: 2, offset: 13 } }] }, + }, + }); + verifyGetErrRequest({ session, files: ["^/untitled/ts-nul-authority/Untitled-1"] }); + baselineTsserverLogs("pasteEdits", "should not error", session); + }); }); diff --git a/tests/baselines/reference/tsserver/pasteEdits/should-not-error.js b/tests/baselines/reference/tsserver/pasteEdits/should-not-error.js new file mode 100644 index 00000000000..926e5a51c35 --- /dev/null +++ b/tests/baselines/reference/tsserver/pasteEdits/should-not-error.js @@ -0,0 +1,248 @@ +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 +Before request +//// [/home/src/projects/project/file1.ts] +export const r = 1; +console.log(r); + +//// [/home/src/projects/project/tsconfig.json] +{} + +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + + +Info seq [hh:mm:ss:mss] request: + { + "command": "updateOpen", + "arguments": { + "changedFiles": [], + "closedFiles": [], + "openFiles": [ + { + "file": "^/untitled/ts-nul-authority/Untitled-1", + "fileContent": "function foo(){}\r\n \r\n", + "scriptKindName": "TS" + } + ] + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: ^/untitled/ts-nul-authority/Untitled-1 ProjectRootPath: undefined:: Result: undefined +Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /home/src/Vscode/Projects/bin +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +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/Vscode/Projects/bin/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/bin/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/Projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /home/src/Vscode/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (2) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 "/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };" + ^/untitled/ts-nul-authority/Untitled-1 SVC-1-0 "function foo(){}\r\n \r\n" + + + ../../../tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + ^/untitled/ts-nul-authority/Untitled-1 + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (2) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: ^/untitled/ts-nul-authority/Untitled-1 ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] response: + { + "response": true, + "responseRequired": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After request + +PolledWatches:: +/home/src/Vscode/Projects/bin/node_modules/@types: *new* + {"pollingInterval":500} +/home/src/Vscode/Projects/node_modules/@types: *new* + {"pollingInterval":500} +/home/src/Vscode/node_modules/@types: *new* + {"pollingInterval":500} + +FsWatches:: +/home/src/tslibs/TS/Lib/lib.d.ts: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +^/untitled/ts-nul-authority/Untitled-1 (Dynamic) (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "getPasteEdits", + "arguments": { + "file": "^/untitled/ts-nul-authority/Untitled-1", + "pastedText": [ + "console.log(r);" + ], + "pasteLocations": [ + { + "start": { + "line": 1, + "offset": 0 + }, + "end": { + "line": 1, + "offset": 0 + } + } + ], + "copiedFrom": { + "file": "/home/src/projects/project/file1.ts", + "spans": [ + { + "start": { + "line": 2, + "offset": 0 + }, + "end": { + "line": 2, + "offset": 13 + } + } + ] + } + }, + "seq": 2, + "type": "request" + } +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": true + } +After request + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "geterr", + "arguments": { + "delay": 0, + "files": [ + "^/untitled/ts-nul-authority/Untitled-1" + ] + }, + "seq": 3, + "type": "request" + } +After request + +Timeout callback:: count: 1 +1: checkOne *new* + +Before running Timeout callback:: count: 1 +1: checkOne + +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "syntaxDiag", + "body": { + "file": "^/untitled/ts-nul-authority/Untitled-1", + "diagnostics": [] + } + } +After running Timeout callback:: count: 0 + +Immedidate callback:: count: 1 +1: semanticCheck *new* + +Before running Immedidate callback:: count: 1 +1: semanticCheck + +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "semanticDiag", + "body": { + "file": "^/untitled/ts-nul-authority/Untitled-1", + "diagnostics": [] + } + } +After running Immedidate callback:: count: 1 + +Immedidate callback:: count: 1 +2: suggestionCheck *new* + +Before running Immedidate callback:: count: 1 +2: suggestionCheck + +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "suggestionDiag", + "body": { + "file": "^/untitled/ts-nul-authority/Untitled-1", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "requestCompleted", + "body": { + "request_seq": 3, + "performanceData": { + "diagnosticsDuration": [ + { + "syntaxDiag": *, + "semanticDiag": *, + "suggestionDiag": *, + "file": "^/untitled/ts-nul-authority/Untitled-1" + } + ] + } + } + } +After running Immedidate callback:: count: 0