From a59f1292c8be7c0b87be463503a557148241ce72 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 4 Mar 2024 14:05:51 -0800 Subject: [PATCH] When using cached sourceFile from the info, make sure the scriptKind is same This is needed esp with externalFiles since they may not use actual scriptInfo and text at all Fixes #57631 --- src/services/documentRegistry.ts | 3 +- ...criptKind-changes-for-the-external-file.js | 386 ++++++++++++++++++ 2 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/tsserver/plugins/when-scriptKind-changes-for-the-external-file.js diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index e1061a8fc9d8f..fc42cacce7d5b 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -13,6 +13,7 @@ import { getKeyForCompilerOptions, getOrUpdate, getSetExternalModuleIndicator, + getSnapshotText, identity, IScriptSnapshot, isDeclarationFileName, @@ -300,7 +301,7 @@ export function createDocumentRegistryInternal(useCaseSensitiveFileNames?: boole let entry = bucketEntry && getDocumentRegistryEntry(bucketEntry, scriptKind); if (!entry && externalCache) { const sourceFile = externalCache.getDocument(keyWithMode, path); - if (sourceFile) { + if (sourceFile && sourceFile.scriptKind === scriptKind && sourceFile.text === getSnapshotText(scriptSnapshot)) { Debug.assert(acquiring); entry = { sourceFile, diff --git a/tests/baselines/reference/tsserver/plugins/when-scriptKind-changes-for-the-external-file.js b/tests/baselines/reference/tsserver/plugins/when-scriptKind-changes-for-the-external-file.js new file mode 100644 index 0000000000000..6e9d27e1cdbd8 --- /dev/null +++ b/tests/baselines/reference/tsserver/plugins/when-scriptKind-changes-for-the-external-file.js @@ -0,0 +1,386 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +Before request +//// [/user/username/projects/myproject/a.ts] +export const a = 10; + +//// [/user/username/projects/myproject/b.vue] +bVueFile + +//// [/user/username/projects/myproject/tsconfig.json] +{ + "compilerOptions": { + "composite": true + }, + "include": [ + "*.ts", + "*.vue" + ] +} + +//// [/a/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; } + + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/user/username/projects/myproject/b.vue" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] Search path: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] For info: /user/username/projects/myproject/b.vue :: Config file name: /user/username/projects/myproject/tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /user/username/projects/myproject/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/user/username/projects/myproject/tsconfig.json", + "reason": "Creating possible configured project for /user/username/projects/myproject/b.vue to open" + } + } +Info seq [hh:mm:ss:mss] Config: /user/username/projects/myproject/tsconfig.json : { + "rootNames": [ + "/user/username/projects/myproject/a.ts" + ], + "options": { + "composite": true, + "configFilePath": "/user/username/projects/myproject/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Config: /user/username/projects/myproject/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Config: /user/username/projects/myproject/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Loading global plugin myplugin +Info seq [hh:mm:ss:mss] Enabling plugin myplugin from candidate paths: /a/lib/tsc.js/../../.. +Info seq [hh:mm:ss:mss] Loading myplugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules) +Info seq [hh:mm:ss:mss] Plugin validation succeeded +getExternalFiles:: Getting new list of .vue files +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/a.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules/@types 1 undefined Project: /user/username/projects/myproject/tsconfig.json WatchType: Type roots +getExternalFiles:: Returning cached .vue files +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/user/username/projects/myproject/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (3) + /a/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; }" + /user/username/projects/myproject/a.ts Text-1 "export const a = 10;" + /user/username/projects/myproject/b.vue SVC-1-0 "import { y } from \"bVueFile\";" + + + ../../../../a/lib/lib.d.ts + Default library for target 'es5' + a.ts + Matched by include pattern '*.ts' in 'tsconfig.json' + b.vue + Matched by include pattern '*.vue' in 'tsconfig.json' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/user/username/projects/myproject/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "telemetry", + "body": { + "telemetryEventName": "projectInfo", + "payload": { + "projectId": "4a33d78ee40d836c4f4e64c59aed976628aea0013be9585c5ff171dfc41baf98", + "fileStats": { + "js": 0, + "jsSize": 0, + "jsx": 0, + "jsxSize": 0, + "ts": 1, + "tsSize": 20, + "tsx": 0, + "tsxSize": 0, + "dts": 1, + "dtsSize": 334, + "deferred": 0, + "deferredSize": 0 + }, + "compilerOptions": { + "composite": true + }, + "typeAcquisition": { + "enable": false, + "include": false, + "exclude": false + }, + "extends": false, + "files": false, + "include": true, + "exclude": false, + "compileOnSave": false, + "configFileName": "tsconfig.json", + "projectType": "configured", + "languageServiceEnabled": true, + "version": "FakeVersion" + } + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/user/username/projects/myproject/b.vue", + "configFile": "/user/username/projects/myproject/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Search path: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] For info: /user/username/projects/myproject/tsconfig.json :: No config files found. +Info seq [hh:mm:ss:mss] Project '/user/username/projects/myproject/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (3) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /user/username/projects/myproject/b.vue ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /user/username/projects/myproject/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +PolledWatches:: +/user/username/projects/myproject/node_modules: *new* + {"pollingInterval":500} +/user/username/projects/myproject/node_modules/@types: *new* + {"pollingInterval":500} +/user/username/projects/node_modules: *new* + {"pollingInterval":500} +/user/username/projects/node_modules/@types: *new* + {"pollingInterval":500} + +FsWatches:: +/a/lib/lib.d.ts: *new* + {} +/user/username/projects/myproject: *new* + {} +/user/username/projects/myproject/a.ts: *new* + {} +/user/username/projects/myproject/tsconfig.json: *new* + {} + +Projects:: +/user/username/projects/myproject/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/a/lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /user/username/projects/myproject/tsconfig.json +/user/username/projects/myproject/a.ts *new* + version: Text-1 + containingProjects: 1 + /user/username/projects/myproject/tsconfig.json +/user/username/projects/myproject/b.vue (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /user/username/projects/myproject/tsconfig.json *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "updateOpen", + "arguments": { + "changedFiles": [ + { + "fileName": "/user/username/projects/myproject/b.vue", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 9 + }, + "end": { + "line": 1, + "offset": 9 + }, + "newText": "Updated" + } + ] + } + ] + }, + "seq": 2, + "type": "request" + } +Info seq [hh:mm:ss:mss] response: + { + "response": true, + "responseRequired": true + } +After request + +Projects:: +/user/username/projects/myproject/tsconfig.json (Configured) *changed* + projectStateVersion: 2 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/a/lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /user/username/projects/myproject/tsconfig.json +/user/username/projects/myproject/a.ts + version: Text-1 + containingProjects: 1 + /user/username/projects/myproject/tsconfig.json +/user/username/projects/myproject/b.vue (Open) *changed* + version: SVC-1-1 *changed* + containingProjects: 1 + /user/username/projects/myproject/tsconfig.json *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "geterr", + "arguments": { + "delay": 0, + "files": [ + "/user/username/projects/myproject/b.vue" + ] + }, + "seq": 3, + "type": "request" + } +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +Timeout callback:: count: 1 +1: checkOne *new* + +Before running Timeout callback:: count: 1 +1: checkOne + +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json +getExternalFiles:: Returning cached .vue files +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /user/username/projects/myproject/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: true structureIsReused:: SafeModules Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/user/username/projects/myproject/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (3) + /a/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; }" + /user/username/projects/myproject/a.ts Text-1 "export const a = 10;" + /user/username/projects/myproject/b.vue SVC-1-1 "import { y } from \"bVueFileUpdated\";" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "syntaxDiag", + "body": { + "file": "/user/username/projects/myproject/b.vue", + "diagnostics": [] + } + } +After running Timeout callback:: count: 0 + +Immedidate callback:: count: 1 +1: semanticCheck *new* + +Projects:: +/user/username/projects/myproject/tsconfig.json (Configured) *changed* + projectStateVersion: 2 + projectProgramVersion: 2 *changed* + dirty: false *changed* + +Before running Immedidate callback:: count: 1 +1: semanticCheck + +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "semanticDiag", + "body": { + "file": "/user/username/projects/myproject/b.vue", + "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": "/user/username/projects/myproject/b.vue", + "diagnostics": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 16 + }, + "text": "'y' is declared but its value is never read.", + "code": 6133, + "category": "suggestion", + "reportsUnnecessary": true + } + ] + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "requestCompleted", + "body": { + "request_seq": 3 + } + } +After running Immedidate callback:: count: 0