From b78f4668122b9d67d6fc4765b989cdd51694f548 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 21 Jan 2025 11:10:51 -0800 Subject: [PATCH] Fix ESM/CJS resolution cache collision in non-nodenext resolution modes (#60910) --- src/compiler/moduleNameResolver.ts | 2 +- .../unittests/tsserver/inferredProjects.ts | 23 ++ .../reference/resolutionModeCache.errors.txt | 35 ++ .../reference/resolutionModeCache.symbols | 29 ++ .../reference/resolutionModeCache.trace.json | 112 +++++++ .../reference/resolutionModeCache.types | 37 +++ .../closing-file-with-shared-resolutions.js | 310 ++++++++++++++++++ .../moduleResolution/resolutionModeCache.ts | 31 ++ 8 files changed, 578 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/resolutionModeCache.errors.txt create mode 100644 tests/baselines/reference/resolutionModeCache.symbols create mode 100644 tests/baselines/reference/resolutionModeCache.trace.json create mode 100644 tests/baselines/reference/resolutionModeCache.types create mode 100644 tests/baselines/reference/tsserver/inferredProjects/closing-file-with-shared-resolutions.js create mode 100644 tests/cases/conformance/moduleResolution/resolutionModeCache.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 5a4b5bd1c931a..c0808eeafd80d 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -2989,7 +2989,7 @@ function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string, } function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { - const mode = state.features === 0 ? undefined : state.features & NodeResolutionFeatures.EsmMode ? ModuleKind.ESNext : ModuleKind.CommonJS; + const mode = state.features === 0 ? undefined : (state.features & NodeResolutionFeatures.EsmMode || state.conditions.includes("import")) ? ModuleKind.ESNext : ModuleKind.CommonJS; // Do (up to) two passes through node_modules: // 1. For each ancestor node_modules directory, try to find: // i. TS/DTS files in the implementation package diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index a1b9c2cf2fcd5..e184f1a9de4ee 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -322,4 +322,27 @@ describe("unittests:: tsserver:: inferredProjects::", () => { }], session); baselineTsserverLogs("inferredProjects", "when existing inferred project has no root files", session); }); + + it("closing file with shared resolutions", () => { + const host = TestServerHost.createServerHost({ + "/user/username/projects/myproject/unrelated.ts": dedent` + export {}; + `, + "/user/username/projects/myproject/app.ts": dedent` + import type { y } from "pkg" assert { "resolution-mode": "require" }; + import type { x } from "pkg" assert { "resolution-mode": "import" }; + `, + }); + const session = new TestSession(host); + openFilesForSession([{ + file: "/user/username/projects/myproject/unrelated.ts", + projectRootPath: "/user/username/projects/myproject", + }], session); + openFilesForSession([{ + file: "/user/username/projects/myproject/app.ts", + projectRootPath: "/user/username/projects/myproject", + }], session); + closeFilesForSession(["/user/username/projects/myproject/app.ts"], session); + baselineTsserverLogs("inferredProjects", "closing file with shared resolutions", session); + }); }); diff --git a/tests/baselines/reference/resolutionModeCache.errors.txt b/tests/baselines/reference/resolutionModeCache.errors.txt new file mode 100644 index 0000000000000..655de941e4c5a --- /dev/null +++ b/tests/baselines/reference/resolutionModeCache.errors.txt @@ -0,0 +1,35 @@ +/index.ts(3,1): error TS1361: 'pkgRequire' cannot be used as a value because it was imported using 'import type'. +/index.ts(4,1): error TS1361: 'pkgImport' cannot be used as a value because it was imported using 'import type'. + + +==== /node_modules/pkg/package.json (0 errors) ==== + { + "name": "pkg", + "version": "1.0.0", + "exports": { + ".": { + "import": "./index.mjs", + "require": "./index.js" + } + } + } + +==== /node_modules/pkg/index.d.mts (0 errors) ==== + declare const _default: "esm"; + export default _default; + +==== /node_modules/pkg/index.d.ts (0 errors) ==== + declare const _exports: "cjs"; + export = _exports; + +==== /index.ts (2 errors) ==== + import type pkgRequire from "pkg" with { "resolution-mode": "require" }; + import type pkgImport from "pkg" with { "resolution-mode": "import" }; + pkgRequire; + ~~~~~~~~~~ +!!! error TS1361: 'pkgRequire' cannot be used as a value because it was imported using 'import type'. +!!! related TS1376 /index.ts:1:8: 'pkgRequire' was imported here. + pkgImport; + ~~~~~~~~~ +!!! error TS1361: 'pkgImport' cannot be used as a value because it was imported using 'import type'. +!!! related TS1376 /index.ts:2:8: 'pkgImport' was imported here. \ No newline at end of file diff --git a/tests/baselines/reference/resolutionModeCache.symbols b/tests/baselines/reference/resolutionModeCache.symbols new file mode 100644 index 0000000000000..b1986c9d5d617 --- /dev/null +++ b/tests/baselines/reference/resolutionModeCache.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/moduleResolution/resolutionModeCache.ts] //// + +=== /node_modules/pkg/index.d.mts === +declare const _default: "esm"; +>_default : Symbol(_default, Decl(index.d.mts, 0, 13)) + +export default _default; +>_default : Symbol(_default, Decl(index.d.mts, 0, 13)) + +=== /node_modules/pkg/index.d.ts === +declare const _exports: "cjs"; +>_exports : Symbol(_exports, Decl(index.d.ts, 0, 13)) + +export = _exports; +>_exports : Symbol(_exports, Decl(index.d.ts, 0, 13)) + +=== /index.ts === +import type pkgRequire from "pkg" with { "resolution-mode": "require" }; +>pkgRequire : Symbol(pkgRequire, Decl(index.ts, 0, 6)) + +import type pkgImport from "pkg" with { "resolution-mode": "import" }; +>pkgImport : Symbol(pkgImport, Decl(index.ts, 1, 6)) + +pkgRequire; +>pkgRequire : Symbol(pkgRequire, Decl(index.ts, 0, 6)) + +pkgImport; +>pkgImport : Symbol(pkgImport, Decl(index.ts, 1, 6)) + diff --git a/tests/baselines/reference/resolutionModeCache.trace.json b/tests/baselines/reference/resolutionModeCache.trace.json new file mode 100644 index 0000000000000..55202615814e4 --- /dev/null +++ b/tests/baselines/reference/resolutionModeCache.trace.json @@ -0,0 +1,112 @@ +[ + "Found 'package.json' at '/node_modules/pkg/package.json'.", + "======== Resolving module 'pkg' from '/index.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Resolving in CJS mode with conditions 'require', 'types'.", + "File '/package.json' does not exist.", + "Loading module 'pkg' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "File '/node_modules/pkg/package.json' exists according to earlier cached lookups.", + "Entering conditional exports.", + "Saw non-matching condition 'import'.", + "Matched 'exports' condition 'require'.", + "Using 'exports' subpath '.' with target './index.js'.", + "File name '/node_modules/pkg/index.js' has a '.js' extension - stripping it.", + "File '/node_modules/pkg/index.ts' does not exist.", + "File '/node_modules/pkg/index.tsx' does not exist.", + "File '/node_modules/pkg/index.d.ts' exists - use it as a name resolution result.", + "'package.json' does not have a 'peerDependencies' field.", + "Resolved under condition 'require'.", + "Exiting conditional exports.", + "Resolving real path for '/node_modules/pkg/index.d.ts', result '/node_modules/pkg/index.d.ts'.", + "======== Module name 'pkg' was successfully resolved to '/node_modules/pkg/index.d.ts' with Package ID 'pkg/index.d.ts@1.0.0'. ========", + "======== Resolving module 'pkg' from '/index.ts'. ========", + "Explicitly specified module resolution kind: 'Bundler'.", + "Resolving in CJS mode with conditions 'import', 'types'.", + "File '/package.json' does not exist according to earlier cached lookups.", + "Loading module 'pkg' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "File '/node_modules/pkg/package.json' exists according to earlier cached lookups.", + "Entering conditional exports.", + "Matched 'exports' condition 'import'.", + "Using 'exports' subpath '.' with target './index.mjs'.", + "File name '/node_modules/pkg/index.mjs' has a '.mjs' extension - stripping it.", + "File '/node_modules/pkg/index.mts' does not exist.", + "File '/node_modules/pkg/index.d.mts' exists - use it as a name resolution result.", + "Resolved under condition 'import'.", + "Exiting conditional exports.", + "Resolving real path for '/node_modules/pkg/index.d.mts', result '/node_modules/pkg/index.d.mts'.", + "======== Module name 'pkg' was successfully resolved to '/node_modules/pkg/index.d.mts' with Package ID 'pkg/index.d.mts@1.0.0'. ========", + "======== Resolving module '@typescript/lib-es5' from '/.src/__lib_node_modules_lookup_lib.es5.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-es5'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-es5'", + "Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-es5' was not resolved. ========", + "======== Resolving module '@typescript/lib-decorators' from '/.src/__lib_node_modules_lookup_lib.decorators.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators'", + "Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-decorators' was not resolved. ========", + "======== Resolving module '@typescript/lib-decorators/legacy' from '/.src/__lib_node_modules_lookup_lib.decorators.legacy.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators/legacy'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-decorators/legacy'", + "Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-decorators/legacy' was not resolved. ========", + "======== Resolving module '@typescript/lib-dom' from '/.src/__lib_node_modules_lookup_lib.dom.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-dom'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-dom'", + "Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-dom' was not resolved. ========", + "======== Resolving module '@typescript/lib-webworker/importscripts' from '/.src/__lib_node_modules_lookup_lib.webworker.importscripts.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-webworker/importscripts'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-webworker/importscripts'", + "Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-webworker/importscripts' was not resolved. ========", + "======== Resolving module '@typescript/lib-scripthost' from '/.src/__lib_node_modules_lookup_lib.scripthost.d.ts__.ts'. ========", + "Explicitly specified module resolution kind: 'Node10'.", + "Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: TypeScript, Declaration.", + "Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-scripthost'", + "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", + "Scoped package detected, looking in 'typescript__lib-scripthost'", + "Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: JavaScript.", + "Searching all ancestor node_modules directories for fallback extensions: JavaScript.", + "Directory '/.src/node_modules' does not exist, skipping all lookups in it.", + "======== Module name '@typescript/lib-scripthost' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/resolutionModeCache.types b/tests/baselines/reference/resolutionModeCache.types new file mode 100644 index 0000000000000..289cb82f218a9 --- /dev/null +++ b/tests/baselines/reference/resolutionModeCache.types @@ -0,0 +1,37 @@ +//// [tests/cases/conformance/moduleResolution/resolutionModeCache.ts] //// + +=== /node_modules/pkg/index.d.mts === +declare const _default: "esm"; +>_default : "esm" +> : ^^^^^ + +export default _default; +>_default : "esm" +> : ^^^^^ + +=== /node_modules/pkg/index.d.ts === +declare const _exports: "cjs"; +>_exports : "cjs" +> : ^^^^^ + +export = _exports; +>_exports : "cjs" +> : ^^^^^ + +=== /index.ts === +import type pkgRequire from "pkg" with { "resolution-mode": "require" }; +>pkgRequire : any +> : ^^^ + +import type pkgImport from "pkg" with { "resolution-mode": "import" }; +>pkgImport : any +> : ^^^ + +pkgRequire; +>pkgRequire : "cjs" +> : ^^^^^ + +pkgImport; +>pkgImport : "esm" +> : ^^^^^ + diff --git a/tests/baselines/reference/tsserver/inferredProjects/closing-file-with-shared-resolutions.js b/tests/baselines/reference/tsserver/inferredProjects/closing-file-with-shared-resolutions.js new file mode 100644 index 0000000000000..184f3ed7a674a --- /dev/null +++ b/tests/baselines/reference/tsserver/inferredProjects/closing-file-with-shared-resolutions.js @@ -0,0 +1,310 @@ +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 +//// [/user/username/projects/myproject/unrelated.ts] +export {}; + + +//// [/user/username/projects/myproject/app.ts] +import type { y } from "pkg" assert { "resolution-mode": "require" }; +import type { x } from "pkg" assert { "resolution-mode": "import" }; + + +//// [/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": "open", + "arguments": { + "file": "/user/username/projects/myproject/unrelated.ts", + "projectRootPath": "/user/username/projects/myproject" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /user/username/projects/myproject/unrelated.ts ProjectRootPath: /user/username/projects/myproject:: Result: undefined +Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +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: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/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; };" + /user/username/projects/myproject/unrelated.ts SVC-1-0 "export {};\n" + + + ../../../../home/src/tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + unrelated.ts + 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: /user/username/projects/myproject/unrelated.ts ProjectRootPath: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 1, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After request + +PolledWatches:: +/user/username/projects/myproject/jsconfig.json: *new* + {"pollingInterval":2000} +/user/username/projects/myproject/node_modules/@types: *new* + {"pollingInterval":500} +/user/username/projects/myproject/tsconfig.json: *new* + {"pollingInterval":2000} +/user/username/projects/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* +/user/username/projects/myproject/unrelated.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/user/username/projects/myproject/app.ts", + "projectRootPath": "/user/username/projects/myproject" + }, + "seq": 2, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /user/username/projects/myproject/app.ts ProjectRootPath: /user/username/projects/myproject:: Result: undefined +Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject2*, currentDirectory: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject2* +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects 0 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects 0 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules 1 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules 1 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules 1 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules 1 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /dev/null/inferredProject2* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject2* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/node_modules/@types 1 undefined Project: /dev/null/inferredProject2* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject2* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/node_modules/@types 1 undefined Project: /dev/null/inferredProject2* WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject2* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject2*' (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; };" + /user/username/projects/myproject/app.ts SVC-1-0 "import type { y } from \"pkg\" assert { \"resolution-mode\": \"require\" };\nimport type { x } from \"pkg\" assert { \"resolution-mode\": \"import\" };\n" + + + ../../../../home/src/tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + app.ts + 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] Project '/dev/null/inferredProject2*' (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: /user/username/projects/myproject/unrelated.ts ProjectRootPath: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileName: /user/username/projects/myproject/app.ts ProjectRootPath: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject2* +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After request + +PolledWatches:: +/user/username/projects/myproject/jsconfig.json: + {"pollingInterval":2000} +/user/username/projects/myproject/node_modules: *new* + {"pollingInterval":500} +/user/username/projects/myproject/node_modules/@types: + {"pollingInterval":500} +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":2000} +/user/username/projects/node_modules: *new* + {"pollingInterval":500} +/user/username/projects/node_modules/@types: + {"pollingInterval":500} + +FsWatches:: +/home/src/tslibs/TS/Lib/lib.d.ts: + {} +/user/username/projects: *new* + {} +/user/username/projects/myproject: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false +/dev/null/inferredProject2* (Inferred) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *changed* + version: Text-1 + containingProjects: 2 *changed* + /dev/null/inferredProject1* + /dev/null/inferredProject2* *new* +/user/username/projects/myproject/app.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject2* *default* +/user/username/projects/myproject/unrelated.ts (Open) + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "close", + "arguments": { + "file": "/user/username/projects/myproject/app.ts" + }, + "seq": 3, + "type": "request" + } +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/app.ts 500 undefined WatchType: Closed Script info +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] Project '/dev/null/inferredProject2*' (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: /user/username/projects/myproject/unrelated.ts ProjectRootPath: /user/username/projects/myproject +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "close", + "request_seq": 3, + "success": true + } +After request + +PolledWatches:: +/user/username/projects/myproject/jsconfig.json: + {"pollingInterval":2000} +/user/username/projects/myproject/node_modules: + {"pollingInterval":500} +/user/username/projects/myproject/node_modules/@types: + {"pollingInterval":500} +/user/username/projects/myproject/tsconfig.json: + {"pollingInterval":2000} +/user/username/projects/node_modules: + {"pollingInterval":500} +/user/username/projects/node_modules/@types: + {"pollingInterval":500} + +FsWatches:: +/home/src/tslibs/TS/Lib/lib.d.ts: + {} +/user/username/projects: + {} +/user/username/projects/myproject: + {} +/user/username/projects/myproject/app.ts: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false +/dev/null/inferredProject2* (Inferred) *changed* + projectStateVersion: 2 *changed* + projectProgramVersion: 1 + dirty: true *changed* + isOrphan: true *changed* + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts + version: Text-1 + containingProjects: 2 + /dev/null/inferredProject1* + /dev/null/inferredProject2* +/user/username/projects/myproject/app.ts *changed* + open: false *changed* + version: SVC-1-0 + containingProjects: 0 *changed* + /dev/null/inferredProject2* *deleted* +/user/username/projects/myproject/unrelated.ts (Open) + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* diff --git a/tests/cases/conformance/moduleResolution/resolutionModeCache.ts b/tests/cases/conformance/moduleResolution/resolutionModeCache.ts new file mode 100644 index 0000000000000..ea7f92e87d12c --- /dev/null +++ b/tests/cases/conformance/moduleResolution/resolutionModeCache.ts @@ -0,0 +1,31 @@ +// @module: preserve +// @moduleResolution: bundler +// @noImplicitAny: true +// @noEmit: true +// @traceResolution: true + +// @Filename: /node_modules/pkg/package.json +{ + "name": "pkg", + "version": "1.0.0", + "exports": { + ".": { + "import": "./index.mjs", + "require": "./index.js" + } + } +} + +// @Filename: /node_modules/pkg/index.d.mts +declare const _default: "esm"; +export default _default; + +// @Filename: /node_modules/pkg/index.d.ts +declare const _exports: "cjs"; +export = _exports; + +// @Filename: /index.ts +import type pkgRequire from "pkg" with { "resolution-mode": "require" }; +import type pkgImport from "pkg" with { "resolution-mode": "import" }; +pkgRequire; +pkgImport; \ No newline at end of file