@scriptc/compiler 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +104 -31
- package/ambient/scriptc.d.ts +2 -1
- package/dist/backend/build-cache.js.map +1 -1
- package/dist/backend/c/async.d.ts +5 -0
- package/dist/backend/c/async.js +81 -2
- package/dist/backend/c/async.js.map +1 -1
- package/dist/backend/c/c-emitter.d.ts +25 -10
- package/dist/backend/c/c-emitter.js +74 -22
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.d.ts +8 -1
- package/dist/backend/c/exprs.js +371 -18
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/island.js.map +1 -1
- package/dist/backend/c/may-throw.js.map +1 -1
- package/dist/backend/c/shapes.js +15 -13
- package/dist/backend/c/shapes.js.map +1 -1
- package/dist/backend/c/stmts.d.ts +3 -5
- package/dist/backend/c/stmts.js +58 -17
- package/dist/backend/c/stmts.js.map +1 -1
- package/dist/backend/c/types.d.ts +4 -0
- package/dist/backend/c/types.js +18 -1
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/c/types.test.js +8 -1
- package/dist/backend/c/types.test.js.map +1 -1
- package/dist/backend/c/walkers.js +63 -16
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/external-c.js.map +1 -1
- package/dist/backend/json-literal.d.ts +7 -0
- package/dist/backend/json-literal.js +17 -0
- package/dist/backend/json-literal.js.map +1 -0
- package/dist/backend/json-literal.test.d.ts +1 -0
- package/dist/backend/json-literal.test.js +17 -0
- package/dist/backend/json-literal.test.js.map +1 -0
- package/dist/backend/link-plan.d.ts +1 -1
- package/dist/backend/link-plan.js +5 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/linker.js.map +1 -1
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/classes.js +8 -7
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +4 -0
- package/dist/backend/llvm/common.js +6 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/common.test.d.ts +1 -0
- package/dist/backend/llvm/common.test.js +9 -0
- package/dist/backend/llvm/common.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +4 -0
- package/dist/backend/llvm/dyn.js +80 -16
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +132 -25
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +85 -3
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +5 -0
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +15 -3
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +8 -0
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +3 -3
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +222 -10
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +53 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +24 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +50 -5
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +64 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +6 -3
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/llvm/shapes.js +10 -8
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/unsupported.js.map +1 -1
- package/dist/backend/llvm/walkers.js +7 -5
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +2 -0
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info.d.ts +2 -1
- package/dist/backend/native-link-info.js +4 -0
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +24 -1
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +8 -6
- package/dist/backend/native-toolchain.js +28 -13
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +36 -1
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack-targets.test.js.map +1 -1
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +1 -0
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +5 -0
- package/dist/backend/targets.js +9 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +6 -1
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/backend/vendor-archives.js.map +1 -1
- package/dist/compat/fetch-profile.js +4 -2
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +13 -0
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +6 -5
- package/dist/diagnostics/diagnostic.js +10 -9
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +1 -0
- package/dist/executable/executable-cache.js +1 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +1 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/ffi/ffi-manifest.js.map +1 -1
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/dts-paths.js.map +1 -1
- package/dist/frontend/input-tracker.d.ts +10 -0
- package/dist/frontend/input-tracker.js +26 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +8 -1
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +4 -0
- package/dist/frontend/lowering/array-values.js +18 -2
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/callback-arg.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +31 -0
- package/dist/frontend/lowering/containers/bytes.js +1105 -0
- package/dist/frontend/lowering/containers/bytes.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
- package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
- package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
- package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.js +7 -2
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +16 -10
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
- package/dist/frontend/lowering/lower-async-iteration.js +657 -0
- package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +40 -21
- package/dist/frontend/lowering/lower-builtins.js +611 -115
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +21 -10
- package/dist/frontend/lowering/lower-calls.js +516 -75
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +7 -13
- package/dist/frontend/lowering/lower-classes.js +128 -35
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +1 -47
- package/dist/frontend/lowering/lower-containers.js +147 -1475
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +51 -5
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +0 -78
- package/dist/frontend/lowering/lower-exprs.js +503 -2353
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +18 -3
- package/dist/frontend/lowering/lower-generators.js +145 -9
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +10 -3
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +6 -0
- package/dist/frontend/lowering/lower-island.js +37 -5
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +60 -15
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
- package/dist/frontend/lowering/lower-node-module.js +302 -0
- package/dist/frontend/lowering/lower-node-module.js.map +1 -0
- package/dist/frontend/lowering/lower-server.js +1 -1
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +10 -28
- package/dist/frontend/lowering/lower-stmts.js +542 -259
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +4 -4
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +41 -38
- package/dist/frontend/lowering/lowerer.js +148 -62
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
- package/dist/frontend/lowering/optional-arguments.js +57 -0
- package/dist/frontend/lowering/optional-arguments.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +5 -3
- package/dist/frontend/lowering/surfaces.js +33 -13
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +35 -0
- package/dist/frontend/npm-static-declarations.js +519 -0
- package/dist/frontend/npm-static-declarations.js.map +1 -0
- package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
- package/dist/frontend/npm-static-declarations.test.js +132 -0
- package/dist/frontend/npm-static-declarations.test.js.map +1 -0
- package/dist/frontend/npm-static.d.ts +2 -0
- package/dist/frontend/npm-static.js +26 -10
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +60 -0
- package/dist/frontend/npm.js +38 -4
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.d.ts +1 -0
- package/dist/frontend/npm.test.js +50 -0
- package/dist/frontend/npm.test.js.map +1 -0
- package/dist/frontend/program.d.ts +3 -2
- package/dist/frontend/program.js +513 -70
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.d.ts +26 -3
- package/dist/frontend/resolve.js +166 -29
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.js +24 -1
- package/dist/frontend/resolve.test.js.map +1 -1
- package/dist/frontend/runtime-resolve.d.ts +22 -0
- package/dist/frontend/runtime-resolve.js +101 -0
- package/dist/frontend/runtime-resolve.js.map +1 -0
- package/dist/frontend/runtime-resolve.test.d.ts +1 -0
- package/dist/frontend/runtime-resolve.test.js +18 -0
- package/dist/frontend/runtime-resolve.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.js +12 -13
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/census-check.js +3 -3
- package/dist/frontend/ts7/census-check.js.map +1 -1
- package/dist/frontend/ts7/checker.d.ts +3 -0
- package/dist/frontend/ts7/checker.js +12 -3
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/program-adapter.js +42 -3
- package/dist/frontend/ts7/program-adapter.js.map +1 -1
- package/dist/frontend/type-mapper.js +171 -16
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +1 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/ir.d.ts +125 -52
- package/dist/ir/ir.js +136 -7
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/validate.js +120 -63
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/cache-reset.test.js.map +1 -1
- package/dist/library/compiler-self-identity.js.map +1 -1
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/library-cache.d.ts +1 -0
- package/dist/library/library-cache.js +1 -0
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +18 -5
- package/dist/library/library-cache.test.js.map +1 -1
- package/dist/library/library-profile.js.map +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.js.map +1 -1
- package/dist/startup-cache.js.map +1 -1
- package/dist/wasi-paths.js.map +1 -1
- package/package.json +18 -18
- package/surface-manifest.json +91 -20
package/dist/frontend/program.js
CHANGED
|
@@ -39,19 +39,20 @@
|
|
|
39
39
|
* JSON.parse's wording rather than tsc's, the one message-text delta on
|
|
40
40
|
* that path (no snapshot pins it). */
|
|
41
41
|
import { builtinModules } from "node:module";
|
|
42
|
-
import { dirname, resolve } from "node:path";
|
|
42
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
43
43
|
import * as ts from "./ts7/adapter.js";
|
|
44
44
|
import { commonJsModuleSyntaxDiag, invalidPackageConfigDiag, strictNullChecksFloorDiag, tscPassthroughDiag, unsupportedDiag, } from "../diagnostics/diagnostic.js";
|
|
45
|
-
import { isNodeModulesPath, nearestInvalidPackageJsonPath, nearestPackageType, nearestPkgJsonPath, projectDtsRuntimeSibling, resolveBareModule,
|
|
45
|
+
import { isNodeModulesPath, nearestInvalidPackageJsonPath, nearestPackageType, nearestPkgJsonPath, projectDtsRuntimeSibling, resolveBareModule, resolveProjectModule, resolveTypeDirective, setProjectPathMappings, setProjectRealm } from "./resolve.js";
|
|
46
46
|
import { probeNodeImportRefusal, probeNodeRequireRefusal } from "./npm.js";
|
|
47
|
-
import { isNpmStaticPackage, npmStaticActive, npmStaticFsShadow, npmStaticPackageOfPath, reportNpmStaticOffender, setNpmStaticPackages } from "./npm-static.js";
|
|
47
|
+
import { isNpmStaticPackage, npmStaticActive, npmStaticFsShadow, npmStaticPackageOfPath, reportNpmStaticOffender, setNpmStaticDeclarationOverloads, setNpmStaticPackages } from "./npm-static.js";
|
|
48
|
+
import { npmStaticDeclarationReexports, npmStaticRuntimeClassTargets, parseNpmStaticDeclarationOverloads, parseNpmStaticDeclarationProperties } from "./npm-static-declarations.js";
|
|
48
49
|
import { provenanceEntryFor, provenancePaths } from "./provenance-registry.js";
|
|
49
50
|
import { cjsLexerVisibleNames } from "./cjs-lexer.js";
|
|
50
51
|
import { ambientDtsPath, fallbackDtsPath, isNodeTypesPath, overridesDtsPath, tsgoPath, } from "./dts-paths.js";
|
|
51
52
|
import { builtinDefaultImportModule, canonicalBuiltinModule, SUPPORTED_NODE_MODULES, unsupportedModuleFeatureOf, } from "./builtin-modules.js";
|
|
52
|
-
import { clearWorkspacePackages, isRelativeSpecifier, isWorkspacePackageName, registerWorkspacePackage, workspacePackageOfPath, } from "./workspace-registry.js";
|
|
53
|
+
import { clearWorkspacePackages, isRelativeSpecifier, isWorkspacePackageName, npmPackageNameOf, registerWorkspacePackage, workspacePackageOfPath, } from "./workspace-registry.js";
|
|
53
54
|
import { ADOPTED_OPTIONS, isJsSourceFileName, JS_ANY_OPERATOR_CODES, JS_RELAXED_TSC_CODES, } from "./tsc-codes.js";
|
|
54
|
-
import { trackedFileExists } from "./input-tracker.js";
|
|
55
|
+
import { trackedFileExists, trackedReadFile, trackedRealpath } from "./input-tracker.js";
|
|
55
56
|
const BASE_OPTIONS = {
|
|
56
57
|
strict: true,
|
|
57
58
|
};
|
|
@@ -67,7 +68,10 @@ const FORCED_OPTIONS = {
|
|
|
67
68
|
// classification is intentionally independent below; this option is only
|
|
68
69
|
// the binder's scope decision.
|
|
69
70
|
moduleDetection: ts.ModuleDetectionKind.Force,
|
|
70
|
-
|
|
71
|
+
// Explicit resource management is an ESNext library slice in TS 7 even
|
|
72
|
+
// though Node 24 ships the runtime protocol. Include that focused lib
|
|
73
|
+
// without widening the rest of the standard-library target past ES2025.
|
|
74
|
+
lib: ["lib.es2025.d.ts", "lib.esnext.disposable.d.ts"],
|
|
71
75
|
types: [],
|
|
72
76
|
allowImportingTsExtensions: true,
|
|
73
77
|
allowJs: true,
|
|
@@ -142,6 +146,28 @@ function adoptProjectConfig7(host, entryPath) {
|
|
|
142
146
|
if (value !== undefined)
|
|
143
147
|
adopted[key] = value;
|
|
144
148
|
}
|
|
149
|
+
// TS 7 accepts `paths`, but no longer accepts `baseUrl` as a compiler
|
|
150
|
+
// option. Translate the established baseUrl+paths spelling into absolute
|
|
151
|
+
// targets: the synthesized config lives beside the entry rather than the
|
|
152
|
+
// real config, so preserving relative targets would silently change their
|
|
153
|
+
// meaning. The absolute map is also the own resolver's configuration.
|
|
154
|
+
const rawPaths = parsed.options["paths"];
|
|
155
|
+
if (rawPaths !== undefined && typeof rawPaths === "object" && rawPaths !== null) {
|
|
156
|
+
const configDir = dirname(configFile);
|
|
157
|
+
const rawBaseUrl = parsed.options["baseUrl"];
|
|
158
|
+
const base = typeof rawBaseUrl === "string"
|
|
159
|
+
? (isAbsolute(rawBaseUrl) ? rawBaseUrl : resolve(configDir, rawBaseUrl))
|
|
160
|
+
: configDir;
|
|
161
|
+
const paths = {};
|
|
162
|
+
for (const [key, targets] of Object.entries(rawPaths)) {
|
|
163
|
+
if (!Array.isArray(targets))
|
|
164
|
+
continue;
|
|
165
|
+
paths[key] = targets
|
|
166
|
+
.filter((target) => typeof target === "string")
|
|
167
|
+
.map((target) => isAbsolute(target) ? target : resolve(base, target));
|
|
168
|
+
}
|
|
169
|
+
adopted["paths"] = paths;
|
|
170
|
+
}
|
|
145
171
|
const nullChecks = adopted["strictNullChecks"] ?? adopted["strict"] ?? false;
|
|
146
172
|
if (nullChecks !== true) {
|
|
147
173
|
diags.push(strictNullChecksFloorDiag(configFile));
|
|
@@ -156,6 +182,94 @@ function resolveNodeTypes7(entryPath) {
|
|
|
156
182
|
const file = resolveTypeDirective("node", entryPath);
|
|
157
183
|
return file !== null && isNodeTypesPath(file) ? file : null;
|
|
158
184
|
}
|
|
185
|
+
function declarationReexportTarget(fromFile, specifier) {
|
|
186
|
+
const base = resolve(dirname(fromFile), specifier);
|
|
187
|
+
const candidates = [];
|
|
188
|
+
const extension = /\.(mjs|cjs|js)$/.exec(base)?.[1];
|
|
189
|
+
if (extension !== undefined) {
|
|
190
|
+
const stem = base.slice(0, -(extension.length + 1));
|
|
191
|
+
if (extension === "mjs")
|
|
192
|
+
candidates.push(`${stem}.d.mts`, `${stem}.d.ts`);
|
|
193
|
+
else if (extension === "cjs")
|
|
194
|
+
candidates.push(`${stem}.d.cts`, `${stem}.d.ts`);
|
|
195
|
+
else
|
|
196
|
+
candidates.push(`${stem}.d.ts`, `${stem}.d.mts`, `${stem}.d.cts`);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
candidates.push(base, `${base}.d.ts`, `${base}.d.mts`, `${base}.d.cts`);
|
|
200
|
+
}
|
|
201
|
+
candidates.push(resolve(base, "index.d.ts"), resolve(base, "index.d.mts"), resolve(base, "index.d.cts"));
|
|
202
|
+
return candidates.find((candidate) => trackedFileExists(candidate)) ?? null;
|
|
203
|
+
}
|
|
204
|
+
function runtimeReexportTarget(fromFile, specifier) {
|
|
205
|
+
const base = resolve(dirname(fromFile), specifier);
|
|
206
|
+
const candidates = [
|
|
207
|
+
base,
|
|
208
|
+
`${base}.js`,
|
|
209
|
+
`${base}.mjs`,
|
|
210
|
+
`${base}.cjs`,
|
|
211
|
+
resolve(base, "index.js"),
|
|
212
|
+
resolve(base, "index.mjs"),
|
|
213
|
+
resolve(base, "index.cjs"),
|
|
214
|
+
];
|
|
215
|
+
const target = candidates.find((candidate) => trackedFileExists(candidate) && isJsSourceFileName(candidate));
|
|
216
|
+
return target === undefined ? null : (trackedRealpath(target) ?? target);
|
|
217
|
+
}
|
|
218
|
+
/** Visits an opted package's own declaration entry and relative barrel
|
|
219
|
+
* closure. This is intentionally narrower than TypeScript module
|
|
220
|
+
* resolution: bare edges name other packages and never inherit trust. */
|
|
221
|
+
function visitNpmStaticDeclarationClosure(entryPath, onSource) {
|
|
222
|
+
const seen = new Set();
|
|
223
|
+
const packageJson = nearestPkgJsonPath(entryPath);
|
|
224
|
+
const packageRoot = (packageJson === null ? dirname(entryPath) : dirname(packageJson)).split("\\").join("/");
|
|
225
|
+
const visit = (path) => {
|
|
226
|
+
path = resolve(path);
|
|
227
|
+
const normalized = path.split("\\").join("/");
|
|
228
|
+
if (normalized !== packageRoot && !normalized.startsWith(packageRoot + "/"))
|
|
229
|
+
return;
|
|
230
|
+
if (seen.has(path))
|
|
231
|
+
return;
|
|
232
|
+
seen.add(path);
|
|
233
|
+
const source = trackedReadFile(path);
|
|
234
|
+
if (source === null)
|
|
235
|
+
return;
|
|
236
|
+
onSource(path, source);
|
|
237
|
+
for (const specifier of npmStaticDeclarationReexports(path, source)) {
|
|
238
|
+
const target = declarationReexportTarget(path, specifier);
|
|
239
|
+
if (target !== null)
|
|
240
|
+
visit(target);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
visit(entryPath);
|
|
244
|
+
}
|
|
245
|
+
function npmStaticDeclarationOverloadsOf(entryPath) {
|
|
246
|
+
const classes = new Map();
|
|
247
|
+
visitNpmStaticDeclarationClosure(entryPath, (path, source) => {
|
|
248
|
+
for (const [className, methods] of parseNpmStaticDeclarationOverloads(path, source)) {
|
|
249
|
+
const target = classes.get(className) ?? new Map();
|
|
250
|
+
classes.set(className, target);
|
|
251
|
+
for (const [methodName, signatures] of methods) {
|
|
252
|
+
if (!target.has(methodName))
|
|
253
|
+
target.set(methodName, signatures);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
return classes;
|
|
258
|
+
}
|
|
259
|
+
function npmStaticDeclarationPropertiesOf(entryPath) {
|
|
260
|
+
const classes = new Map();
|
|
261
|
+
visitNpmStaticDeclarationClosure(entryPath, (path, source) => {
|
|
262
|
+
for (const [className, properties] of parseNpmStaticDeclarationProperties(path, source)) {
|
|
263
|
+
const target = classes.get(className) ?? new Map();
|
|
264
|
+
classes.set(className, target);
|
|
265
|
+
for (const [propertyName, type] of properties) {
|
|
266
|
+
if (!target.has(propertyName))
|
|
267
|
+
target.set(propertyName, type);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
return classes;
|
|
272
|
+
}
|
|
159
273
|
/** True when a coverage mapping names one exact bare host module. TypeScript
|
|
160
274
|
* gives `paths` keys containing `*` pattern semantics, so accepting one here
|
|
161
275
|
* would silently broaden the mapping beyond the specifier the caller named. */
|
|
@@ -232,6 +346,10 @@ function externalTypeFileClosure7(program, externalTypes) {
|
|
|
232
346
|
}
|
|
233
347
|
function loadProgram7(host, entryPath, externalTypes = new Map()) {
|
|
234
348
|
const config = adoptProjectConfig7(host, entryPath);
|
|
349
|
+
const configuredPaths = config.options["paths"];
|
|
350
|
+
setProjectPathMappings(configuredPaths !== undefined && typeof configuredPaths === "object" && configuredPaths !== null
|
|
351
|
+
? configuredPaths
|
|
352
|
+
: null);
|
|
235
353
|
const nodeTypes = config.configFile ? resolveNodeTypes7(entryPath) : null;
|
|
236
354
|
// skipLibCheck is FORCED with @types/node in the program: checking a
|
|
237
355
|
// third-party lib's internals against OUR lib choice (es2025, no dyn) is
|
|
@@ -251,7 +369,10 @@ function loadProgram7(host, entryPath, externalTypes = new Map()) {
|
|
|
251
369
|
// driver against the package's real TypeScript, not its shipped .d.ts.
|
|
252
370
|
const provenance = provenancePaths();
|
|
253
371
|
if (provenance !== null || externalTypes.size > 0) {
|
|
254
|
-
const paths = {
|
|
372
|
+
const paths = {
|
|
373
|
+
...configuredPaths,
|
|
374
|
+
...(provenance ?? {}),
|
|
375
|
+
};
|
|
255
376
|
for (const [specifier, declarationPath] of externalTypes) {
|
|
256
377
|
paths[specifier] = [declarationPath];
|
|
257
378
|
}
|
|
@@ -303,7 +424,60 @@ export function loadProgram(entryPath, opts) {
|
|
|
303
424
|
}
|
|
304
425
|
externalTypes.set(specifier, declarationPath);
|
|
305
426
|
}
|
|
306
|
-
|
|
427
|
+
const npmStaticPackages = [...new Set(opts?.npmStatic ?? [])];
|
|
428
|
+
// Resolve authored declaration entries before enabling the JS-only
|
|
429
|
+
// package resolver. Safe overload metadata binds through the runtime
|
|
430
|
+
// entry to one exact implementation file; it never contributes values
|
|
431
|
+
// or executable module edges.
|
|
432
|
+
const declarationOverloads = new Map();
|
|
433
|
+
const declarationProperties = new Map();
|
|
434
|
+
for (const pkg of npmStaticPackages) {
|
|
435
|
+
const resolved = resolveBareModule(entryPath, pkg, "types-only");
|
|
436
|
+
if (resolved === null ||
|
|
437
|
+
resolved.packageName !== pkg ||
|
|
438
|
+
!/\.d\.(?:ts|mts|cts)$/.test(resolved.typesFile)) {
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
const overloads = npmStaticDeclarationOverloadsOf(resolved.typesFile);
|
|
442
|
+
const properties = npmStaticDeclarationPropertiesOf(resolved.typesFile);
|
|
443
|
+
const classNames = new Set([...overloads.keys(), ...properties.keys()]);
|
|
444
|
+
if (classNames.size === 0)
|
|
445
|
+
continue;
|
|
446
|
+
const runtime = resolveBareModule(entryPath, pkg, "js-only");
|
|
447
|
+
if (runtime === null || !isJsSourceFileName(runtime.typesFile))
|
|
448
|
+
continue;
|
|
449
|
+
const runtimeSource = trackedReadFile(runtime.typesFile);
|
|
450
|
+
if (runtimeSource === null)
|
|
451
|
+
continue;
|
|
452
|
+
const targets = npmStaticRuntimeClassTargets(runtime.typesFile, runtimeSource, classNames);
|
|
453
|
+
for (const [className, specifier] of targets) {
|
|
454
|
+
const methods = overloads.get(className);
|
|
455
|
+
const fields = properties.get(className);
|
|
456
|
+
if (methods === undefined && fields === undefined)
|
|
457
|
+
continue;
|
|
458
|
+
const target = specifier === null ? runtime.typesFile : runtimeReexportTarget(runtime.typesFile, specifier);
|
|
459
|
+
if (target === null)
|
|
460
|
+
continue;
|
|
461
|
+
const targetPackage = npmPackageNameOf(target);
|
|
462
|
+
const targetNorm = target.split("\\").join("/");
|
|
463
|
+
const insideWorkspace = runtime.workspaceDir !== undefined &&
|
|
464
|
+
targetNorm.startsWith(runtime.workspaceDir.split("\\").join("/") + "/");
|
|
465
|
+
if (targetPackage !== pkg && !insideWorkspace)
|
|
466
|
+
continue;
|
|
467
|
+
if (methods !== undefined) {
|
|
468
|
+
const byClass = new Map(declarationOverloads.get(targetNorm) ?? []);
|
|
469
|
+
byClass.set(className, methods);
|
|
470
|
+
declarationOverloads.set(targetNorm, byClass);
|
|
471
|
+
}
|
|
472
|
+
if (fields !== undefined) {
|
|
473
|
+
const byClass = new Map(declarationProperties.get(targetNorm) ?? []);
|
|
474
|
+
byClass.set(className, fields);
|
|
475
|
+
declarationProperties.set(targetNorm, byClass);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
setNpmStaticPackages(npmStaticPackages);
|
|
480
|
+
setNpmStaticDeclarationOverloads(declarationOverloads, declarationProperties);
|
|
307
481
|
// Workspace-package registrations reset per load (same discipline as the
|
|
308
482
|
// npm-static set), then the opted-in names are probed UP FRONT: a
|
|
309
483
|
// workspace-linked opt-in resolves to files whose realpaths carry no
|
|
@@ -1327,7 +1501,7 @@ export function makeCycleAdmission(program, edgesOf) {
|
|
|
1327
1501
|
* resolveImport) for the lowering: CommonJS require statements lower to
|
|
1328
1502
|
* guarded %init calls of exactly the module preflight resolved here. */
|
|
1329
1503
|
function resolveImport7(program, from, specifier) {
|
|
1330
|
-
const resolved =
|
|
1504
|
+
const resolved = resolveProjectModule(from.fileName, specifier);
|
|
1331
1505
|
if (resolved === null)
|
|
1332
1506
|
return null;
|
|
1333
1507
|
return program.getSourceFile(resolved) ?? null;
|
|
@@ -1342,7 +1516,7 @@ function resolveNpmImport7(fromFileName, specifier) {
|
|
|
1342
1516
|
return null;
|
|
1343
1517
|
}
|
|
1344
1518
|
// --provenance-sources: a registered specifier is NOT an npm import —
|
|
1345
|
-
// its attested source compiles as program modules (
|
|
1519
|
+
// its attested source compiles as program modules (resolveProjectModule
|
|
1346
1520
|
// answers the entry), so no island embed and no .d.ts type surface.
|
|
1347
1521
|
if (provenanceEntryFor(specifier) !== null)
|
|
1348
1522
|
return null;
|
|
@@ -1410,6 +1584,16 @@ function processModuleAliasRequire7(spec, decl) {
|
|
|
1410
1584
|
return false;
|
|
1411
1585
|
return decl === null || ts.isIdentifier(decl.name);
|
|
1412
1586
|
}
|
|
1587
|
+
/** `import process from 'node:process'`: the ESM spelling of the same
|
|
1588
|
+
* global-object alias as processModuleAliasRequire7. Keep this exemption
|
|
1589
|
+
* deliberately narrow: named and namespace imports need a represented
|
|
1590
|
+
* module namespace, while the default binding is exactly globalThis.process. */
|
|
1591
|
+
function processModuleAliasImport7(spec, stmt) {
|
|
1592
|
+
if (spec !== "process" && spec !== "node:process")
|
|
1593
|
+
return false;
|
|
1594
|
+
const clause = stmt.importClause;
|
|
1595
|
+
return clause !== undefined && clause.name !== undefined && clause.namedBindings === undefined;
|
|
1596
|
+
}
|
|
1413
1597
|
/** The whole TS7-lane lifecycle for one entry: spawn (or share) a tsgo
|
|
1414
1598
|
* host, build the lowering-world program, run the ported preflight, and
|
|
1415
1599
|
* dispose EVERYTHING before returning — the CLI process must exit promptly,
|
|
@@ -1788,7 +1972,8 @@ function preflight7(load) {
|
|
|
1788
1972
|
diags.push(externalHostModuleDiag7(fromSpec, stmt));
|
|
1789
1973
|
continue;
|
|
1790
1974
|
}
|
|
1791
|
-
|
|
1975
|
+
const projectReexport = resolveImport7(program, sf, fromSpec);
|
|
1976
|
+
if (!isRelativeSpecifier(fromSpec) && projectReexport === null) {
|
|
1792
1977
|
// NAMED re-exports from a SUPPORTED builtin pass (`export { ok }
|
|
1793
1978
|
// from "node:assert"` — a universal re-export facade facade): the
|
|
1794
1979
|
// statement binds nothing locally and evaluates nothing (builtins
|
|
@@ -1821,7 +2006,7 @@ function preflight7(load) {
|
|
|
1821
2006
|
diags.push(unsupportedDiag("SC1014", locOf7(stmt), "re-exports from packages or builtin modules"));
|
|
1822
2007
|
continue;
|
|
1823
2008
|
}
|
|
1824
|
-
const reDep =
|
|
2009
|
+
const reDep = projectReexport;
|
|
1825
2010
|
// `export * as ns from "./m"` re-exports the module NAMESPACE
|
|
1826
2011
|
// object under a name: importers' `x.ns.member` reads resolve
|
|
1827
2012
|
// statically through the same alias machinery as `import * as ns`
|
|
@@ -1888,9 +2073,15 @@ function preflight7(load) {
|
|
|
1888
2073
|
pos: stmt.getStart(sf),
|
|
1889
2074
|
});
|
|
1890
2075
|
};
|
|
2076
|
+
// Project modules win before npm fallback: this is the source graph
|
|
2077
|
+
// tsgo type-checked for tsconfig paths, package imports/self-references,
|
|
2078
|
+
// and provenance entries. Ordinary packages still answer null here.
|
|
2079
|
+
const projDep = isBare ? resolveImport7(program, sf, spec) : null;
|
|
1891
2080
|
// "#" specifiers can never name an npm package — they are the
|
|
1892
|
-
// imports-field family, resolved
|
|
1893
|
-
const npm = isBare && !spec.startsWith("#")
|
|
2081
|
+
// imports-field family, resolved by the project arm above.
|
|
2082
|
+
const npm = isBare && projDep === null && !spec.startsWith("#")
|
|
2083
|
+
? resolveNpmImport7(sf.fileName, spec)
|
|
2084
|
+
: null;
|
|
1894
2085
|
if (npm && isNodeTypesPath(npm.typesFile)) {
|
|
1895
2086
|
diags.push(unsupportedDiag("SC1010", locOf7(stmt), unsupportedModuleFeatureOf(spec)));
|
|
1896
2087
|
continue;
|
|
@@ -1922,24 +2113,23 @@ function preflight7(load) {
|
|
|
1922
2113
|
continue;
|
|
1923
2114
|
}
|
|
1924
2115
|
}
|
|
1925
|
-
// PROJECT imports: package.json-mediated specifiers
|
|
1926
|
-
// the program's own sources
|
|
1927
|
-
//
|
|
1928
|
-
//
|
|
1929
|
-
//
|
|
1930
|
-
//
|
|
1931
|
-
// exact message; what keeps a compile fence: the unsupported
|
|
1932
|
-
// builtin and the types-only resolution (Node-hostable or ambiguous
|
|
1933
|
-
// — scriptc's own limitations, named as such).
|
|
1934
|
-
let projDep = null;
|
|
2116
|
+
// PROJECT imports: tsconfig paths and package.json-mediated specifiers
|
|
2117
|
+
// that resolve to the program's own sources. A source answer is an
|
|
2118
|
+
// ordinary user-module edge, exactly like a relative import (the
|
|
2119
|
+
// checker resolved the bindings the same way); a refused resolution is
|
|
2120
|
+
// Node's startup crash with Node's exact message; what keeps a compile
|
|
2121
|
+
// fence is unsupported builtin or types-only surface.
|
|
1935
2122
|
if (isBare && npmStaticDep === null) {
|
|
1936
|
-
const resolved = resolveProjectImport(sf.fileName, spec);
|
|
1937
|
-
projDep = resolved !== null ? (program.getSourceFile(resolved) ?? null) : null;
|
|
1938
2123
|
if (projDep !== null && projDep.isDeclarationFile) {
|
|
1939
2124
|
diags.push(unsupportedDiag("SC1010", locOf7(stmt), `the '${spec}' import (it resolves only to type declarations — there is no runtime implementation to compile)`));
|
|
1940
2125
|
continue;
|
|
1941
2126
|
}
|
|
1942
2127
|
if (projDep === null) {
|
|
2128
|
+
// node:process's default export is the global process object. It
|
|
2129
|
+
// contributes no module-order edge; the imported binding lowers
|
|
2130
|
+
// through stdlibGlobalNameOf exactly like the bare global.
|
|
2131
|
+
if (processModuleAliasImport7(spec, stmt))
|
|
2132
|
+
continue;
|
|
1943
2133
|
const nodeBuiltin = spec.startsWith("node:") || nodeBuiltinNames.has(spec);
|
|
1944
2134
|
if (nodeBuiltin) {
|
|
1945
2135
|
diags.push(unsupportedDiag("SC1010", locOf7(stmt), unsupportedModuleFeatureOf(spec)));
|
|
@@ -2077,8 +2267,8 @@ function preflight7(load) {
|
|
|
2077
2267
|
}
|
|
2078
2268
|
}
|
|
2079
2269
|
const isRelative = isRelativeSpecifier(req.spec);
|
|
2080
|
-
let dep =
|
|
2081
|
-
if (!isRelative) {
|
|
2270
|
+
let dep = resolveImport7(program, sf, req.spec);
|
|
2271
|
+
if (dep === null && !isRelative) {
|
|
2082
2272
|
// --npm-static: a require() of an OPTED-IN package is a
|
|
2083
2273
|
// program-module edge exactly like the import-declaration
|
|
2084
2274
|
// form above (bundle dists require their workspace siblings —
|
|
@@ -2106,9 +2296,6 @@ function preflight7(load) {
|
|
|
2106
2296
|
continue;
|
|
2107
2297
|
}
|
|
2108
2298
|
}
|
|
2109
|
-
else {
|
|
2110
|
-
dep = resolveImport7(program, sf, req.spec);
|
|
2111
|
-
}
|
|
2112
2299
|
if (dep && dep.fileName.endsWith(".json")) {
|
|
2113
2300
|
diags.push(unsupportedDiag("SC1012", loc, "require() of JSON modules"));
|
|
2114
2301
|
continue;
|
|
@@ -2139,6 +2326,15 @@ function preflight7(load) {
|
|
|
2139
2326
|
if (load.externalTypes.has(spec)) {
|
|
2140
2327
|
continue;
|
|
2141
2328
|
}
|
|
2329
|
+
const projectDep = resolveImport7(program, sf, spec);
|
|
2330
|
+
if (projectDep !== null) {
|
|
2331
|
+
if (projectDep.fileName.endsWith(".json")) {
|
|
2332
|
+
diags.push(unsupportedDiag("SC1012", loc, "require() of JSON modules"));
|
|
2333
|
+
continue;
|
|
2334
|
+
}
|
|
2335
|
+
deps.push({ dep: projectDep });
|
|
2336
|
+
continue;
|
|
2337
|
+
}
|
|
2142
2338
|
if (!isRelativeSpecifier(spec)) {
|
|
2143
2339
|
// --npm-static: opted-in packages ride the program-module edge
|
|
2144
2340
|
// (the statement-level require branch above).
|
|
@@ -2158,13 +2354,6 @@ function preflight7(load) {
|
|
|
2158
2354
|
}
|
|
2159
2355
|
continue;
|
|
2160
2356
|
}
|
|
2161
|
-
const dep = resolveImport7(program, sf, spec);
|
|
2162
|
-
if (dep && dep.fileName.endsWith(".json")) {
|
|
2163
|
-
diags.push(unsupportedDiag("SC1012", loc, "require() of JSON modules"));
|
|
2164
|
-
continue;
|
|
2165
|
-
}
|
|
2166
|
-
if (dep)
|
|
2167
|
-
deps.push({ dep });
|
|
2168
2357
|
}
|
|
2169
2358
|
}
|
|
2170
2359
|
}
|
|
@@ -2263,7 +2452,9 @@ function preflight7(load) {
|
|
|
2263
2452
|
}
|
|
2264
2453
|
}
|
|
2265
2454
|
}
|
|
2266
|
-
const linkCrash = resolveCrash !== null
|
|
2455
|
+
const linkCrash = resolveCrash !== null
|
|
2456
|
+
? null
|
|
2457
|
+
: earlierLinkCrash(order, cjsNamedImportLinkCheck(program, entry, order, diags), esmNamedImportLinkCheck(program, entry, order, diags));
|
|
2267
2458
|
return { diags, moduleOrder: order, startupCrash: resolveCrash ?? linkCrash };
|
|
2268
2459
|
}
|
|
2269
2460
|
/** Walks the entry's ESM instantiate graph exactly as V8 does — children
|
|
@@ -2278,21 +2469,18 @@ function preflight7(load) {
|
|
|
2278
2469
|
* not modeled: those get a pointed fence instead. */
|
|
2279
2470
|
function cjsNamedImportLinkCheck(program, entry, moduleOrder, diags) {
|
|
2280
2471
|
const lexMemo = new Map();
|
|
2281
|
-
|
|
2282
|
-
//
|
|
2283
|
-
// — the same package.json-mediated edges preflight admits) join them so
|
|
2472
|
+
// Project specifiers resolve as ever; aliases and package.json-mediated
|
|
2473
|
+
// edges (#alias/self-name) join relative imports so
|
|
2284
2474
|
// a named import THROUGH one of a CommonJS module keeps Node's lexer
|
|
2285
2475
|
// check. Builtin/npm targets contribute nothing here — except opted-in
|
|
2286
2476
|
// --npm-static packages, whose CJS entries face Node's lexer exactly
|
|
2287
2477
|
// like program CJS files (their JS IS the program now).
|
|
2288
2478
|
const resolveEdge = (from, spec) => {
|
|
2289
|
-
|
|
2290
|
-
|
|
2479
|
+
const project = resolveImport7(program, from, spec);
|
|
2480
|
+
if (project !== null)
|
|
2481
|
+
return project;
|
|
2291
2482
|
const npmStatic = npmStaticDepSf7(program, from, spec);
|
|
2292
|
-
|
|
2293
|
-
return npmStatic;
|
|
2294
|
-
const p = resolveProjectImport(from.fileName, spec);
|
|
2295
|
-
return p !== null ? (program.getSourceFile(p) ?? null) : null;
|
|
2483
|
+
return npmStatic;
|
|
2296
2484
|
};
|
|
2297
2485
|
// Reexport targets union in only when they resolve to CommonJS program
|
|
2298
2486
|
// files (Node's cjsPreparseModuleExports rule).
|
|
@@ -2447,6 +2635,279 @@ function cjsNamedImportLinkCheck(program, entry, moduleOrder, diags) {
|
|
|
2447
2635
|
loc,
|
|
2448
2636
|
};
|
|
2449
2637
|
}
|
|
2638
|
+
/** Node's strip-only loader exposes an empty `default` export for a default
|
|
2639
|
+
* interface only when the `.ts` file is in an ambiguous (typeless) package
|
|
2640
|
+
* scope. Explicitly ESM files (`.mts` and `.mjs`) and `.ts` files in a
|
|
2641
|
+
* `"type": "module"` package do not get that placeholder. */
|
|
2642
|
+
function hasNodeTsDefaultInterfacePlaceholder7(sf) {
|
|
2643
|
+
return sf.fileName.endsWith(".ts") && nearestPackageType(sf.fileName) === null;
|
|
2644
|
+
}
|
|
2645
|
+
/** Finds the first native-ESM link failure in the static module graph rooted
|
|
2646
|
+
* at `entry`. This is used both for startup linking of the entry graph and
|
|
2647
|
+
* for dynamic imports: a dynamically loaded graph rejects its import promise
|
|
2648
|
+
* at this same link point instead of running any module body. */
|
|
2649
|
+
function analyzeEsmNamedImportLinks(program, entry) {
|
|
2650
|
+
const checker = program.getTypeChecker();
|
|
2651
|
+
const resolveEdge = (from, spec) => {
|
|
2652
|
+
const project = resolveImport7(program, from, spec);
|
|
2653
|
+
if (project !== null)
|
|
2654
|
+
return project;
|
|
2655
|
+
return npmStaticDepSf7(program, from, spec);
|
|
2656
|
+
};
|
|
2657
|
+
const runtimeExport = (dep, name, seenModules = new Set()) => {
|
|
2658
|
+
if (seenModules.has(dep))
|
|
2659
|
+
return undefined;
|
|
2660
|
+
const nextSeen = new Set(seenModules);
|
|
2661
|
+
nextSeen.add(dep);
|
|
2662
|
+
const module = checker.getSymbolAtLocation(dep);
|
|
2663
|
+
const exported = module?.getExports().get(name);
|
|
2664
|
+
if (exported !== undefined) {
|
|
2665
|
+
let resolved = exported;
|
|
2666
|
+
const seenSymbols = new Set();
|
|
2667
|
+
while ((resolved.flags & ts.SymbolFlags.Alias) !== 0 && !seenSymbols.has(resolved)) {
|
|
2668
|
+
seenSymbols.add(resolved);
|
|
2669
|
+
resolved = checker.getAliasedSymbol(resolved);
|
|
2670
|
+
}
|
|
2671
|
+
if (resolved.flags & ts.SymbolFlags.Value)
|
|
2672
|
+
return resolved;
|
|
2673
|
+
// Node's strip-only TypeScript loader materializes a direct `export
|
|
2674
|
+
// default interface X {}` as an empty default export in an ambiguous
|
|
2675
|
+
// `.ts` file. The checker correctly classifies the declaration as
|
|
2676
|
+
// type-only, but the native ESM linker sees the runtime placeholder.
|
|
2677
|
+
if (name === "default" &&
|
|
2678
|
+
hasNodeTsDefaultInterfacePlaceholder7(dep) &&
|
|
2679
|
+
checker.declarationsOf(resolved).some((declaration) => ts.isInterfaceDeclaration(declaration) &&
|
|
2680
|
+
ts.getModifiers(declaration)?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) === true &&
|
|
2681
|
+
ts.getModifiers(declaration)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) === true)) {
|
|
2682
|
+
return resolved;
|
|
2683
|
+
}
|
|
2684
|
+
return undefined;
|
|
2685
|
+
}
|
|
2686
|
+
// TypeScript 7's client-side module symbol exposes the module's own
|
|
2687
|
+
// export table but not names contributed by `export *`. Follow those
|
|
2688
|
+
// source edges explicitly, applying the ESM ambiguity rule: the same
|
|
2689
|
+
// resolved symbol may arrive through multiple stars, while distinct
|
|
2690
|
+
// symbols make the name unavailable. `default` never star-reexports.
|
|
2691
|
+
if (name === "default")
|
|
2692
|
+
return undefined;
|
|
2693
|
+
let starExport;
|
|
2694
|
+
for (const stmt of dep.statements) {
|
|
2695
|
+
if (!ts.isExportDeclaration(stmt) || stmt.isTypeOnly || stmt.exportClause !== undefined)
|
|
2696
|
+
continue;
|
|
2697
|
+
if (stmt.moduleSpecifier === undefined || !ts.isStringLiteral(stmt.moduleSpecifier))
|
|
2698
|
+
continue;
|
|
2699
|
+
const target = resolveEdge(dep, stmt.moduleSpecifier.text);
|
|
2700
|
+
if (target === null || target.fileName.endsWith(".json") || !isNodeEsmFile7(target))
|
|
2701
|
+
continue;
|
|
2702
|
+
const candidate = runtimeExport(target, name, nextSeen);
|
|
2703
|
+
if (candidate === undefined)
|
|
2704
|
+
continue;
|
|
2705
|
+
if (starExport !== undefined && starExport !== candidate)
|
|
2706
|
+
return undefined;
|
|
2707
|
+
starExport = candidate;
|
|
2708
|
+
}
|
|
2709
|
+
return starExport;
|
|
2710
|
+
};
|
|
2711
|
+
const firstMissingOf = (sf) => {
|
|
2712
|
+
const imports = [];
|
|
2713
|
+
for (const stmt of sf.statements) {
|
|
2714
|
+
if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier))
|
|
2715
|
+
continue;
|
|
2716
|
+
const clause = stmt.importClause;
|
|
2717
|
+
if (clause === undefined || clause.phaseModifier === ts.SyntaxKind.TypeKeyword)
|
|
2718
|
+
continue;
|
|
2719
|
+
const spec = stmt.moduleSpecifier.text;
|
|
2720
|
+
const dep = resolveEdge(sf, spec);
|
|
2721
|
+
if (dep === null || dep.fileName.endsWith(".json") || !isNodeEsmFile7(dep))
|
|
2722
|
+
continue;
|
|
2723
|
+
if (clause.name !== undefined) {
|
|
2724
|
+
imports.push({ local: clause.name.text, exportName: "default", spec, nameNode: clause.name, dep });
|
|
2725
|
+
}
|
|
2726
|
+
if (clause.namedBindings === undefined || !ts.isNamedImports(clause.namedBindings))
|
|
2727
|
+
continue;
|
|
2728
|
+
for (const element of clause.namedBindings.elements) {
|
|
2729
|
+
if (element.isTypeOnly)
|
|
2730
|
+
continue;
|
|
2731
|
+
const nameNode = element.propertyName ?? element.name;
|
|
2732
|
+
imports.push({
|
|
2733
|
+
local: element.name.text,
|
|
2734
|
+
exportName: nameNode.text,
|
|
2735
|
+
spec,
|
|
2736
|
+
nameNode,
|
|
2737
|
+
dep,
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
// Node checks regular named requests in local-binding order. Keeping the
|
|
2742
|
+
// same order as the CommonJS linker matters when one statement asks for
|
|
2743
|
+
// more than one erased TypeScript export.
|
|
2744
|
+
imports.sort((a, b) => (a.local < b.local ? -1 : a.local > b.local ? 1 : 0));
|
|
2745
|
+
for (const request of imports) {
|
|
2746
|
+
if (runtimeExport(request.dep, request.exportName) === undefined) {
|
|
2747
|
+
return {
|
|
2748
|
+
exportName: request.exportName,
|
|
2749
|
+
spec: request.spec,
|
|
2750
|
+
nameNode: request.nameNode,
|
|
2751
|
+
sf,
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
for (const stmt of sf.statements) {
|
|
2756
|
+
if (!ts.isExportDeclaration(stmt) || stmt.isTypeOnly)
|
|
2757
|
+
continue;
|
|
2758
|
+
const moduleSpecifier = stmt.moduleSpecifier;
|
|
2759
|
+
const exportClause = stmt.exportClause;
|
|
2760
|
+
if (moduleSpecifier === undefined || exportClause === undefined)
|
|
2761
|
+
continue;
|
|
2762
|
+
if (!ts.isStringLiteral(moduleSpecifier) || !ts.isNamedExports(exportClause))
|
|
2763
|
+
continue;
|
|
2764
|
+
const spec = moduleSpecifier.text;
|
|
2765
|
+
const dep = resolveEdge(sf, spec);
|
|
2766
|
+
if (dep === null || dep.fileName.endsWith(".json") || !isNodeEsmFile7(dep))
|
|
2767
|
+
continue;
|
|
2768
|
+
for (const element of exportClause.elements) {
|
|
2769
|
+
if (element.isTypeOnly)
|
|
2770
|
+
continue;
|
|
2771
|
+
const nameNode = element.propertyName ?? element.name;
|
|
2772
|
+
if (runtimeExport(dep, nameNode.text) === undefined) {
|
|
2773
|
+
return { exportName: nameNode.text, spec, nameNode, sf };
|
|
2774
|
+
}
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
return null;
|
|
2778
|
+
};
|
|
2779
|
+
// The ESM instantiate graph is the same depth-first graph used by the CJS
|
|
2780
|
+
// linker: dependencies are linked before the importing module, and a
|
|
2781
|
+
// CommonJS/JSON target is a leaf for this native-export check.
|
|
2782
|
+
const visited = new Set();
|
|
2783
|
+
const dfs = (sf) => {
|
|
2784
|
+
if (visited.has(sf))
|
|
2785
|
+
return null;
|
|
2786
|
+
visited.add(sf);
|
|
2787
|
+
for (const stmt of sf.statements) {
|
|
2788
|
+
if (!ts.isImportDeclaration(stmt) && !(ts.isExportDeclaration(stmt) && !stmt.isTypeOnly))
|
|
2789
|
+
continue;
|
|
2790
|
+
if (ts.isImportDeclaration(stmt) && stmt.importClause?.phaseModifier === ts.SyntaxKind.TypeKeyword)
|
|
2791
|
+
continue;
|
|
2792
|
+
const moduleSpecifier = stmt.moduleSpecifier;
|
|
2793
|
+
if (moduleSpecifier === undefined || !ts.isStringLiteral(moduleSpecifier))
|
|
2794
|
+
continue;
|
|
2795
|
+
const dep = resolveEdge(sf, moduleSpecifier.text);
|
|
2796
|
+
if (dep === null || dep.fileName.endsWith(".json") || !isNodeEsmFile7(dep))
|
|
2797
|
+
continue;
|
|
2798
|
+
const bad = dfs(dep);
|
|
2799
|
+
if (bad !== null)
|
|
2800
|
+
return bad;
|
|
2801
|
+
}
|
|
2802
|
+
return firstMissingOf(sf);
|
|
2803
|
+
};
|
|
2804
|
+
// Native ESM linking itself starts only from an ESM entry. The caller
|
|
2805
|
+
// supplies dynamic-only roots here too; each such root gets its own
|
|
2806
|
+
// promise rejection rather than a startup crash.
|
|
2807
|
+
const bad = isNodeEsmFile7(entry) ? dfs(entry) : null;
|
|
2808
|
+
if (bad !== null) {
|
|
2809
|
+
return {
|
|
2810
|
+
crash: {
|
|
2811
|
+
message: `The requested module '${bad.spec}' does not provide an export named '${bad.exportName}'`,
|
|
2812
|
+
className: "%SyntaxError",
|
|
2813
|
+
loc: locOf7(bad.nameNode),
|
|
2814
|
+
},
|
|
2815
|
+
visited,
|
|
2816
|
+
firstMissingOf,
|
|
2817
|
+
};
|
|
2818
|
+
}
|
|
2819
|
+
return { crash: null, visited, firstMissingOf };
|
|
2820
|
+
}
|
|
2821
|
+
export function esmNamedImportLinkCrash(program, entry) {
|
|
2822
|
+
return analyzeEsmNamedImportLinks(program, entry).crash;
|
|
2823
|
+
}
|
|
2824
|
+
function esmNamedImportLinkCheck(program, entry, moduleOrder, diags) {
|
|
2825
|
+
const analysis = analyzeEsmNamedImportLinks(program, entry);
|
|
2826
|
+
if (analysis.crash !== null)
|
|
2827
|
+
return analysis.crash;
|
|
2828
|
+
// A CommonJS entry can synchronously require an ESM graph. Node links that
|
|
2829
|
+
// graph at the require site, after the CommonJS module has already begun
|
|
2830
|
+
// evaluating, so this cannot use startupCrash (which would move the error
|
|
2831
|
+
// before earlier output). Keep the compile-time fence used by the CJS link
|
|
2832
|
+
// checker for the analogous mid-evaluation failure instead.
|
|
2833
|
+
for (const sf of moduleOrder) {
|
|
2834
|
+
if (!isNodeEsmFile7(sf) || analysis.visited.has(sf))
|
|
2835
|
+
continue;
|
|
2836
|
+
const childFailure = analysis.firstMissingOf(sf);
|
|
2837
|
+
if (childFailure !== null) {
|
|
2838
|
+
diags.push(unsupportedDiag("SC1013", locOf7(childFailure.nameNode), "a named import of an unavailable export in an ES module reached through require() (Node throws its SyntaxError mid-evaluation at that require; make the import match the module's runtime exports)"));
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
return null;
|
|
2842
|
+
}
|
|
2843
|
+
/** Both named-export link checks run independently because their export
|
|
2844
|
+
* questions are different (Node's CJS lexer versus TypeScript's value
|
|
2845
|
+
* symbols). Their first failures still share one Node instantiate order: the
|
|
2846
|
+
* module postorder established by preflight, then regular named imports by
|
|
2847
|
+
* local binding name, then source-order re-exports. Pick the earlier result
|
|
2848
|
+
* so a native ESM failure in a child cannot be hidden by a CJS failure in a
|
|
2849
|
+
* later parent. */
|
|
2850
|
+
function earlierLinkCrash(moduleOrder, first, second) {
|
|
2851
|
+
if (first === null)
|
|
2852
|
+
return second;
|
|
2853
|
+
if (second === null)
|
|
2854
|
+
return first;
|
|
2855
|
+
const moduleIndex = new Map(moduleOrder.map((sf, index) => [sf.fileName, index]));
|
|
2856
|
+
const firstIndex = moduleIndex.get(first.loc.file) ?? Number.MAX_SAFE_INTEGER;
|
|
2857
|
+
const secondIndex = moduleIndex.get(second.loc.file) ?? Number.MAX_SAFE_INTEGER;
|
|
2858
|
+
if (firstIndex !== secondIndex)
|
|
2859
|
+
return firstIndex < secondIndex ? first : second;
|
|
2860
|
+
if (first.loc.start !== second.loc.start) {
|
|
2861
|
+
const sf = moduleOrder[firstIndex];
|
|
2862
|
+
if (sf === undefined)
|
|
2863
|
+
return first.loc.start < second.loc.start ? first : second;
|
|
2864
|
+
const rank = (crash) => {
|
|
2865
|
+
const entries = [];
|
|
2866
|
+
for (const stmt of sf.statements) {
|
|
2867
|
+
if (ts.isImportDeclaration(stmt) && ts.isStringLiteral(stmt.moduleSpecifier)) {
|
|
2868
|
+
const clause = stmt.importClause;
|
|
2869
|
+
if (clause?.phaseModifier === ts.SyntaxKind.TypeKeyword)
|
|
2870
|
+
continue;
|
|
2871
|
+
if (clause?.namedBindings && ts.isNamedImports(clause.namedBindings)) {
|
|
2872
|
+
for (const element of clause.namedBindings.elements) {
|
|
2873
|
+
if (!element.isTypeOnly) {
|
|
2874
|
+
entries.push({
|
|
2875
|
+
local: element.name.text,
|
|
2876
|
+
start: (element.propertyName ?? element.name).getStart(sf),
|
|
2877
|
+
kind: 0,
|
|
2878
|
+
});
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
entries.sort((a, b) => (a.local < b.local ? -1 : a.local > b.local ? 1 : 0));
|
|
2885
|
+
const direct = entries.findIndex((entry) => entry.start === crash.loc.start);
|
|
2886
|
+
if (direct >= 0)
|
|
2887
|
+
return [0, direct];
|
|
2888
|
+
let reexport = 0;
|
|
2889
|
+
for (const stmt of sf.statements) {
|
|
2890
|
+
const exportClause = ts.isExportDeclaration(stmt) ? stmt.exportClause : undefined;
|
|
2891
|
+
if (!ts.isExportDeclaration(stmt) || stmt.isTypeOnly || exportClause === undefined || !ts.isNamedExports(exportClause))
|
|
2892
|
+
continue;
|
|
2893
|
+
for (const element of exportClause.elements) {
|
|
2894
|
+
if (!element.isTypeOnly && (element.propertyName ?? element.name).getStart(sf) === crash.loc.start) {
|
|
2895
|
+
return [1, reexport];
|
|
2896
|
+
}
|
|
2897
|
+
if (!element.isTypeOnly)
|
|
2898
|
+
reexport++;
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
return [2, crash.loc.start];
|
|
2902
|
+
};
|
|
2903
|
+
const firstRank = rank(first);
|
|
2904
|
+
const secondRank = rank(second);
|
|
2905
|
+
if (firstRank[0] !== secondRank[0])
|
|
2906
|
+
return firstRank[0] < secondRank[0] ? first : second;
|
|
2907
|
+
return firstRank[1] <= secondRank[1] ? first : second;
|
|
2908
|
+
}
|
|
2909
|
+
return first;
|
|
2910
|
+
}
|
|
2450
2911
|
/* node's builtin-module name list, for the SC1010 wording decision ("the
|
|
2451
2912
|
* 'fs' module" vs the generic package message) — shared verbatim with the
|
|
2452
2913
|
* retired 5.9.3 lane's builtinModules use. */
|
|
@@ -2521,16 +2982,11 @@ export function orderedImportsOf(program, sf) {
|
|
|
2521
2982
|
if (!stmt.moduleSpecifier || !ts.isStringLiteral(stmt.moduleSpecifier))
|
|
2522
2983
|
continue;
|
|
2523
2984
|
const spec = stmt.moduleSpecifier.text;
|
|
2524
|
-
|
|
2525
|
-
//
|
|
2526
|
-
//
|
|
2527
|
-
// edges) resolve to the same dep so the importer's %init header calls
|
|
2528
|
-
// theirs. Builtin and npm bare specifiers stay null (resolveProjectImport
|
|
2529
|
-
// answers only inside the project) — EXCEPT opted-in --npm-static
|
|
2985
|
+
// Every project edge (relative, tsconfig alias, #alias, or self-name)
|
|
2986
|
+
// resolves to the same dep so the importer's %init header calls theirs.
|
|
2987
|
+
// Builtin and npm bare specifiers stay null — EXCEPT opted-in --npm-static
|
|
2530
2988
|
// packages, whose entries are program modules the header must init.
|
|
2531
|
-
const dep =
|
|
2532
|
-
? resolveImport7(program, sf, spec)
|
|
2533
|
-
: (npmStaticDepSf7(program, sf, spec) ?? resolveProjectImportSf7(program, sf, spec));
|
|
2989
|
+
const dep = resolveImport7(program, sf, spec) ?? npmStaticDepSf7(program, sf, spec);
|
|
2534
2990
|
const isJson = dep !== null && dep.fileName.endsWith(".json");
|
|
2535
2991
|
out.push({ stmt, dep: isJson ? null : dep });
|
|
2536
2992
|
}
|
|
@@ -2553,19 +3009,6 @@ export function npmStaticDepSf7(program, sf, spec) {
|
|
|
2553
3009
|
return null;
|
|
2554
3010
|
return program.getSourceFile(npm.typesFile) ?? null;
|
|
2555
3011
|
}
|
|
2556
|
-
/** resolveProjectImport lifted to SourceFile answers: the program's file
|
|
2557
|
-
* for a `#alias`/self-name resolution, or null (unresolved, or resolved
|
|
2558
|
-
* outside the program — declaration files included; callers that admit
|
|
2559
|
-
* d.ts answers probe resolveProjectImport directly). */
|
|
2560
|
-
function resolveProjectImportSf7(program, sf, spec) {
|
|
2561
|
-
if (spec.startsWith("node:"))
|
|
2562
|
-
return null;
|
|
2563
|
-
const p = resolveProjectImport(sf.fileName, spec);
|
|
2564
|
-
if (p === null)
|
|
2565
|
-
return null;
|
|
2566
|
-
const dep = program.getSourceFile(p) ?? null;
|
|
2567
|
-
return dep !== null && !dep.isDeclarationFile ? dep : null;
|
|
2568
|
-
}
|
|
2569
3012
|
/** True when `expr` is the `module.exports` property access. */
|
|
2570
3013
|
export function isModuleExportsAccess(expr) {
|
|
2571
3014
|
return (ts.isPropertyAccessExpression(expr) &&
|