Skip to content

Commit fe475ab

Browse files
committed
Semi-related: adjust node builtin module handling
1 parent aaceafe commit fe475ab

File tree

8 files changed

+91
-65
lines changed

8 files changed

+91
-65
lines changed

src/compiler/program.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ import {
323323
TypeChecker,
324324
typeDirectiveIsEqualTo,
325325
TypeReferenceDirectiveResolutionCache,
326+
unprefixedNodeCoreModules,
326327
VariableDeclaration,
327328
VariableStatement,
328329
Version,
@@ -1758,7 +1759,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
17581759
let sourceFileToPackageName = new Map<Path, string>();
17591760
// Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it.
17601761
let redirectTargetsMap = createMultiMap<Path, string>();
1761-
let usesUriStyleNodeCoreModules = false;
1762+
let usesUriStyleNodeCoreModules: boolean | undefined;
17621763

17631764
/**
17641765
* map with
@@ -3499,7 +3500,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
34993500
setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here
35003501
imports = append(imports, moduleNameExpr);
35013502
if (!usesUriStyleNodeCoreModules && currentNodeModulesDepth === 0 && !file.isDeclarationFile) {
3502-
usesUriStyleNodeCoreModules = startsWith(moduleNameExpr.text, "node:");
3503+
if (startsWith(moduleNameExpr.text, "node:")) {
3504+
// Presence of `node:` prefix takes precedence over unprefixed node core modules
3505+
usesUriStyleNodeCoreModules = true;
3506+
}
3507+
else if (usesUriStyleNodeCoreModules === undefined && unprefixedNodeCoreModules.has(moduleNameExpr.text)) {
3508+
// Avoid `unprefixedNodeCoreModules.has` for every import
3509+
usesUriStyleNodeCoreModules = false;
3510+
}
35033511
}
35043512
}
35053513
}

src/compiler/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4867,10 +4867,12 @@ export interface Program extends ScriptReferenceHost {
48674867
redirectTargetsMap: MultiMap<Path, string>;
48684868
/**
48694869
* Whether any (non-external, non-declaration) source files use `node:`-prefixed module specifiers.
4870+
* `false` indicates that an unprefixed builtin module was seen; `undefined` indicates that no
4871+
* builtin modules were seen.
48704872
*
48714873
* @internal
48724874
*/
4873-
readonly usesUriStyleNodeCoreModules: boolean;
4875+
readonly usesUriStyleNodeCoreModules: boolean | undefined;
48744876
/**
48754877
* Map from libFileName to actual resolved location of the lib
48764878
* @internal

src/compiler/utilities.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11784,3 +11784,62 @@ export function isSideEffectImport(node: Node): boolean {
1178411784
const ancestor = findAncestor(node, isImportDeclaration);
1178511785
return !!ancestor && !ancestor.importClause;
1178611786
}
11787+
11788+
/** @internal */
11789+
export const unprefixedNodeCoreModules = new Set([
11790+
"assert",
11791+
"assert/strict",
11792+
"async_hooks",
11793+
"buffer",
11794+
"child_process",
11795+
"cluster",
11796+
"console",
11797+
"constants",
11798+
"crypto",
11799+
"dgram",
11800+
"diagnostics_channel",
11801+
"dns",
11802+
"dns/promises",
11803+
"domain",
11804+
"events",
11805+
"fs",
11806+
"fs/promises",
11807+
"http",
11808+
"http2",
11809+
"https",
11810+
"inspector",
11811+
"inspector/promises",
11812+
"module",
11813+
"net",
11814+
"os",
11815+
"path",
11816+
"path/posix",
11817+
"path/win32",
11818+
"perf_hooks",
11819+
"process",
11820+
"punycode",
11821+
"querystring",
11822+
"readline",
11823+
"readline/promises",
11824+
"repl",
11825+
"stream",
11826+
"stream/consumers",
11827+
"stream/promises",
11828+
"stream/web",
11829+
"string_decoder",
11830+
"sys",
11831+
"test/mock_loader",
11832+
"timers",
11833+
"timers/promises",
11834+
"tls",
11835+
"trace_events",
11836+
"tty",
11837+
"url",
11838+
"util",
11839+
"util/types",
11840+
"v8",
11841+
"vm",
11842+
"wasi",
11843+
"worker_threads",
11844+
"zlib",
11845+
]);

src/jsTyping/jsTyping.ts

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
some,
2828
toFileNameLowerCase,
2929
TypeAcquisition,
30+
unprefixedNodeCoreModules,
3031
Version,
3132
versionMajorMinor,
3233
} from "./_namespaces/ts.js";
@@ -61,60 +62,15 @@ export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVers
6162
return availableVersion.compareTo(cachedTyping.version) <= 0;
6263
}
6364

64-
const unprefixedNodeCoreModuleList = [
65-
"assert",
66-
"assert/strict",
67-
"async_hooks",
68-
"buffer",
69-
"child_process",
70-
"cluster",
71-
"console",
72-
"constants",
73-
"crypto",
74-
"dgram",
75-
"diagnostics_channel",
76-
"dns",
77-
"dns/promises",
78-
"domain",
79-
"events",
80-
"fs",
81-
"fs/promises",
82-
"http",
83-
"https",
84-
"http2",
85-
"inspector",
86-
"module",
87-
"net",
88-
"os",
89-
"path",
90-
"perf_hooks",
91-
"process",
92-
"punycode",
93-
"querystring",
94-
"readline",
95-
"repl",
96-
"stream",
97-
"stream/promises",
98-
"string_decoder",
99-
"timers",
100-
"timers/promises",
101-
"tls",
102-
"trace_events",
103-
"tty",
104-
"url",
105-
"util",
106-
"util/types",
107-
"v8",
108-
"vm",
109-
"wasi",
110-
"worker_threads",
111-
"zlib",
112-
];
113-
114-
const prefixedNodeCoreModuleList = unprefixedNodeCoreModuleList.map(name => `node:${name}`);
115-
11665
/** @internal */
117-
export const nodeCoreModuleList: readonly string[] = [...unprefixedNodeCoreModuleList, ...prefixedNodeCoreModuleList];
66+
export const nodeCoreModuleList: readonly string[] = [
67+
...unprefixedNodeCoreModules,
68+
...[...unprefixedNodeCoreModules].map(name => `node:${name}`),
69+
"node:sea",
70+
"node:sqlite",
71+
"node:test",
72+
"node:test/reporters",
73+
];
11874

11975
/** @internal */
12076
export const nodeCoreModules = new Set(nodeCoreModuleList);

src/services/exportInfoMap.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,10 @@ export function isImportable(
376376
): boolean {
377377
if (!toFile) {
378378
// Ambient module
379+
let useNodePrefix;
379380
const moduleName = stripQuotes(toModule.name);
380-
if (JsTyping.nodeCoreModules.has(moduleName) && startsWith(moduleName, "node:") !== shouldUseUriStyleNodeCoreModules(fromFile, program)) {
381-
return false;
381+
if (JsTyping.nodeCoreModules.has(moduleName) && (useNodePrefix = shouldUseUriStyleNodeCoreModules(fromFile, program)) !== undefined) {
382+
return useNodePrefix === startsWith(moduleName, "node:");
382383
}
383384
return !packageJsonFilter
384385
|| packageJsonFilter.allowsImportingAmbientModule(toModule, moduleSpecifierResolutionHost)

src/services/utilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4123,7 +4123,7 @@ export function isDeprecatedDeclaration(decl: Declaration) {
41234123
}
41244124

41254125
/** @internal */
4126-
export function shouldUseUriStyleNodeCoreModules(file: SourceFile | FutureSourceFile, program: Program): boolean {
4126+
export function shouldUseUriStyleNodeCoreModules(file: SourceFile | FutureSourceFile, program: Program): boolean | undefined {
41274127
const decisionFromFile = firstDefined(file.imports, node => {
41284128
if (JsTyping.nodeCoreModules.has(node.text)) {
41294129
return startsWith(node.text, "node:");

tests/cases/fourslash/importNameCodeFix_uriStyleNodeCoreModules2.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// @Filename: /index.ts
1515
//// writeFile/**/
1616

17-
verify.importFixModuleSpecifiers("", ["node:fs", "node:fs/promises", "fs", "fs/promises"]);
17+
verify.importFixModuleSpecifiers("", ["node:fs", "node:fs/promises"]);
1818

1919
goTo.file("/other.ts");
2020
edit.replaceLine(0, "\n");
@@ -26,4 +26,4 @@ goTo.file("/other.ts");
2626
edit.replaceLine(0, `import "node:fs/promises";\n`);
2727

2828
goTo.file("/index.ts");
29-
verify.importFixModuleSpecifiers("", ["node:fs", "node:fs/promises", "fs", "fs/promises"]);
29+
verify.importFixModuleSpecifiers("", ["node:fs", "node:fs/promises"]);

tests/cases/fourslash/importNameCodeFix_uriStyleNodeCoreModules3.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@
3131
//// import "path";
3232
//// writeFile/*mixed2*/
3333

34-
verify.importFixModuleSpecifiers("noPrefix", ["fs", "fs/promises", "node:fs", "node:fs/promises"]);
35-
verify.importFixModuleSpecifiers("prefix", ["node:fs", "node:fs/promises", "fs", "fs/promises"]);
34+
verify.importFixModuleSpecifiers("noPrefix", ["fs", "fs/promises"]);
35+
verify.importFixModuleSpecifiers("prefix", ["node:fs", "node:fs/promises"]);
3636

3737
// We're doing as little work as possible to decide which module specifiers
3838
// to use, so we just take the *first* recognized node core module in the file
3939
// and copy its style.
4040

41-
verify.importFixModuleSpecifiers("mixed1", ["fs", "fs/promises", "node:fs", "node:fs/promises"]);
42-
verify.importFixModuleSpecifiers("mixed2", ["node:fs", "node:fs/promises", "fs", "fs/promises"]);
41+
verify.importFixModuleSpecifiers("mixed1", ["fs", "fs/promises"]);
42+
verify.importFixModuleSpecifiers("mixed2", ["node:fs", "node:fs/promises"]);

0 commit comments

Comments
 (0)