@scriptc/compiler 0.1.3 → 0.1.4
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 +200 -51
- package/dist/backend/c/async.d.ts +25 -0
- package/dist/backend/c/async.js +167 -0
- package/dist/backend/c/async.js.map +1 -1
- package/dist/backend/c/c-emitter.d.ts +10 -0
- package/dist/backend/c/c-emitter.js +14 -2
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.js +293 -51
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/types.js +2 -0
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/link-plan.d.ts +2 -1
- package/dist/backend/link-plan.js +2 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/emitter.js +20 -6
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +8 -8
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
- package/dist/backend/llvm/expr-callbacks.js +125 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +14 -2
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +30 -9
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
- package/dist/backend/llvm/expr-primitives.test.js +38 -0
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +69 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +68 -10
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +18 -2
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +156 -6
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +36 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +23 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +3 -0
- package/dist/backend/native-toolchain.js +3 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +28 -10
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +4 -0
- package/dist/backend/targets.js +13 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +8 -1
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/coverage/surface-manifest.js +8 -0
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/frontend/fork-target.d.ts +17 -0
- package/dist/frontend/fork-target.js +256 -0
- package/dist/frontend/fork-target.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
- package/dist/frontend/lowering/abstract-equality.js +250 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.js +71 -2
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +50 -23
- package/dist/frontend/lowering/lower-builtins.js +939 -106
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +29 -21
- package/dist/frontend/lowering/lower-calls.js +573 -121
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +39 -8
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.js +150 -0
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +212 -21
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +135 -83
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
- package/dist/frontend/lowering/lower-inspect.js +1 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +6 -3
- package/dist/frontend/lowering/lower-island.js +165 -6
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +6 -0
- package/dist/frontend/lowering/lower-modules.js +184 -38
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +7 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +1 -1
- package/dist/frontend/lowering/lower-server.js +130 -27
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +118 -15
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +7 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +86 -9
- package/dist/frontend/lowering/lowerer.js +412 -72
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +26 -0
- package/dist/frontend/lowering/surfaces.js +140 -77
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +4 -0
- package/dist/frontend/npm-static-declarations.js +56 -0
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +23 -2
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static.js +6 -5
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +15 -3
- package/dist/frontend/npm.js +80 -8
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +76 -9
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/program.js +92 -10
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.d.ts +6 -0
- package/dist/frontend/resolve.js +7 -4
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +5 -0
- package/dist/frontend/type-mapper.js +64 -24
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +24 -3
- package/dist/index.js.map +1 -1
- package/dist/ir/ir.d.ts +93 -47
- package/dist/ir/ir.js +63 -4
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +14 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +165 -13
- package/dist/ir/validate.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.test.js +5 -5
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +132 -38
|
@@ -19,20 +19,20 @@ import * as ts from "../ts7/adapter.js";
|
|
|
19
19
|
import { anyOpRequiresDynamicDiag, blockedBindingUseDiag, checkerPanicDiag, componentTypeDiag, isCheckerPanic, genericSignatureTypeDiag, indexSignatureTypeDiag, intersectionTypeDiag, noLoweringDiag, overloadedSignatureTypeDiag, recordShapeMismatchDiag, requiresDynamicApiDiag, requiresDynamicPackageDiag, requiresDynamicTypeDiag, unionMismatchDiag, unsupportedDiag, unsupportedTypeDiag, } from "../../diagnostics/diagnostic.js";
|
|
20
20
|
import { arrayOf, BOOL, canAdaptDynFuncTo, canConvertToDyn, canCrossIslandBoundary, canExitIslandToType, canMarshalTypedFuncIntoIsland, DYN, DYN_HANDLE_KINDS, F64, isDynTypedRefType, isJsonSafeType, isJsonStringifySafeType, isUndefinedArmedUnion, isUnitType, JSVAL, NULL_T, RUNTIME_ERROR_CLASSES, STRING, typeEquals, UNDEFINED_T, VOID } from "../../ir/ir.js";
|
|
21
21
|
import { provenanceActive } from "../provenance-registry.js";
|
|
22
|
-
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
22
|
+
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
23
23
|
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
24
24
|
import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
|
|
25
|
-
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules } from "./lower-modules.js";
|
|
25
|
+
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules } from "./lower-modules.js";
|
|
26
26
|
import { prepareCjsModuleGraph } from "./lower-node-module.js";
|
|
27
27
|
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorMessageArg, lowerNew, accessorCall } from "./lower-classes.js";
|
|
28
28
|
import { mixinCallClassInfoOf, mixinIntersectionInstanceType } from "./lower-mixins.js";
|
|
29
|
-
import { bindingNeverReassigned, bodyReadsArguments, implicitMonoFile, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, completeArgs, wrappedUndefined, undefinedArgFor, requireExactArityValue, bodyReturnType, declaredReturnType, collectSignature, collectSignatureInner, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, lowerCall, lowerFfiCall, lowerTimersMemberCall, lowerPromiseMethodCall, lowerFilterNarrowCall, isTopLevelFnSymbol, lowerNestedFunctionDecl, lambdaSignature, lowerLambda, lowerFunction, validateFfiImports } from "./lower-calls.js";
|
|
29
|
+
import { bindingNeverReassigned, bodyReadsArguments, funcTypeFromParamShapes, implicitMonoFile, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, completeArgs, wrappedUndefined, undefinedArgFor, requireExactArityValue, bodyReturnType, declaredReturnType, collectSignature, collectSignatureInner, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, lowerCall, lowerFfiCall, lowerTimersMemberCall, lowerPromiseMethodCall, lowerFilterNarrowCall, isTopLevelFnSymbol, lowerNestedFunctionDecl, lambdaSignature, lowerLambda, lowerFunction, validateFfiImports } from "./lower-calls.js";
|
|
30
30
|
import { lowerArrayMethodCall, lowerMapMethodCall, lowerMapForEachCall, buildMapForEachFn, lowerRecordOvfCaptureHelper, lowerEnvToPairsHelper, lowerSetMethodCall, lowerSetForEachCall, buildSetForEachFn } from "./lower-containers.js";
|
|
31
31
|
import { lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew } from "./containers/bytes.js";
|
|
32
32
|
import { lowerRegexMethodCall, lowerStringMethodCall } from "./containers/string-and-regexp.js";
|
|
33
33
|
import { lowerStreamModuleCall } from "./lower-stream.js";
|
|
34
34
|
import { lowerEmitOverrideSpec } from "./lower-event-emitter.js";
|
|
35
|
-
import { builtinImportOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireSpecOf, stripTypeCasts, lowerBuiltinModuleCall, lowerTimersPromisesSetInterval, lowerFsToUnixTimestampCall, lowerFsLadderCall, lowerChildArgsArg, lowerSpawnSyncCall, lowerSpawnCall, lowerExecSyncCall, recordToEnvPairs, lowerJsonMethodCall, fencedBuiltinImportOf, lowerCryptoComposedCall, lowerUrlMethodCall, lowerSearchParamsMethodCall, lowerStatsMethodCall, lowerChildMethodCall, lowerAtomicsCall, lowerBuiltinExtraProperty,
|
|
35
|
+
import { builtinImportOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireProgramModuleOf, createRequireSpecOf, stripTypeCasts, lowerBuiltinModuleCall, lowerNodeModuleCall, lowerTimersPromisesSetInterval, lowerFsToUnixTimestampCall, lowerFsLadderCall, lowerChildArgsArg, lowerSpawnSyncCall, lowerSpawnCall, lowerExecFileCall, lowerExecSyncCall, recordToEnvPairs, lowerJsonMethodCall, fencedBuiltinImportOf, lowerCryptoComposedCall, lowerUrlMethodCall, lowerSearchParamsMethodCall, lowerStatsMethodCall, lowerChildMethodCall, lowerAtomicsCall, lowerBuiltinExtraProperty, registerPromisifiedBuiltinDecl, lowerExecFileAsyncCall, execFileAsyncHelper, lowerStringDecoderMethodCall, strdecHelper, lowerReadlineMethodCall, lowerDcChannelMethodCall, lowerDcChannelProperty, lowerAlsMethodCall, lowerDcTracingChannelMethodCall, lowerDcTracingChannelProperty, lowerJsonProperty, lowerErrorCodeProperty, lowerProcessProperty, isProcessEnv, envValueType, lowerProcessEnvGet, lowerProcessMethodCall, lowerProcessOptionalMethodCall, lowerTimeoutMethodCall, envSnapshotHelper, isConsoleLog, consoleCallMember, lowerNumberStaticCall, lowerNumberStaticProperty, lowerDateCall, lowerTextCodecCall, lowerCryptoModuleCall, lowerFsConstantsProperty, lowerBuiltinConstantsProperty, builtinConstantBindingOf, builtinConstantsDestructureDecl, lowerProcessStreamProperty, lowerStringStaticCall, lowerStringLastIndexOfCall, lowerPromiseStaticCall, textCodecBindingClassOf } from "./lower-builtins.js";
|
|
36
36
|
import { fenceFetchObjectAssignment, fenceFetchObjectBinding, fenceStaticAbortControllerMemberRead, fenceStaticHeadersIteration, fenceStaticHeadersMember, fenceStaticReadableStreamMember, fenceStaticResponseMember, fenceUnsupportedFetchConstructorMember, isIslandExpr, islandFuncValueFence, islandRegexpOf, jsvalIn, requireDynamicApi, islandGlobalFnOf, lowerAbortControllerNew, lowerDynamicHeadersIteratorCall, lowerDynamicHeadersSpread, lowerDynamicImportCall, lowerFetchCall, lowerFetchElementMethodCall, lowerResponseNew, lowerStaticFetchCompanionCall, lowerStaticAbortControllerCall, lowerStaticAbortSignalListenerCall, lowerStaticReadableStreamCancelCall, lowerStaticReadableStreamControllerCall, lowerStaticReadableStreamNew, lowerStaticReadableStreamReaderCall, lowerStaticResponseCall, lowerIslandMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol } from "./lower-island.js";
|
|
37
37
|
import { lowerHttpHeadersElement, lowerNetModuleCall, lowerServerMethodCall, lowerServerProperty, lowerTlsRootCertificates } from "./lower-server.js";
|
|
38
38
|
import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js";
|
|
@@ -183,18 +183,31 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
183
183
|
const dynamic = options.dynamic ?? false;
|
|
184
184
|
const targetPlatform = options.targetPlatform ?? process.platform;
|
|
185
185
|
const startupCrash = options.startupCrash ?? null;
|
|
186
|
-
//
|
|
187
|
-
//
|
|
186
|
+
// Modules reachable only through literal import() of the program's own
|
|
187
|
+
// files join the compiled graph here, ONCE, before any
|
|
188
188
|
// pass constructs (nothing calls their %init at startup — the import()
|
|
189
189
|
// site's namespace builder does, on the engine microtask, Node's
|
|
190
190
|
// evaluation point for them). Inadmissible static cycles inside the
|
|
191
191
|
// added subgraph are minted here and handed to reachable emit after this
|
|
192
192
|
// extension of the shared array; no later pass re-walks the subgraph.
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
193
|
+
const extraModuleCycleDiags = [];
|
|
194
|
+
const cycleKeys = new Set();
|
|
195
|
+
const forkTargets = [];
|
|
196
|
+
const onExtraCycle = (cycle, reason) => {
|
|
197
|
+
const key = `${cycle}\0${reason}`;
|
|
198
|
+
if (cycleKeys.has(key))
|
|
199
|
+
return;
|
|
200
|
+
cycleKeys.add(key);
|
|
201
|
+
extraModuleCycleDiags.push(unsupportedDiag("SC1016", { file: entry.fileName, start: 0, end: 0 }, `circular imports (${cycle}; ${reason})`));
|
|
202
|
+
};
|
|
203
|
+
for (let pass = 0; pass < 32; pass++) {
|
|
204
|
+
const before = moduleOrder.length;
|
|
205
|
+
appendDynamicImportModules(program, moduleOrder, onExtraCycle);
|
|
206
|
+
appendForkModules(program, moduleOrder, forkTargets, onExtraCycle);
|
|
207
|
+
if (moduleOrder.length === before)
|
|
208
|
+
break;
|
|
209
|
+
if (pass === 31)
|
|
210
|
+
throw new Error("dynamic import and fork module discovery did not converge");
|
|
198
211
|
}
|
|
199
212
|
const ffiImports = options.ffiImports ?? [];
|
|
200
213
|
const libraryCallbacks = options.libraryCallbacks ?? false;
|
|
@@ -206,6 +219,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
206
219
|
startupCrash,
|
|
207
220
|
ffiImports,
|
|
208
221
|
libraryCallbacks,
|
|
222
|
+
forkTargets,
|
|
209
223
|
externalTypes,
|
|
210
224
|
externalTypeSpecifiersByFile,
|
|
211
225
|
});
|
|
@@ -223,11 +237,12 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
223
237
|
startupCrash,
|
|
224
238
|
ffiImports,
|
|
225
239
|
libraryCallbacks,
|
|
240
|
+
forkTargets,
|
|
226
241
|
externalTypes,
|
|
227
242
|
externalTypeSpecifiersByFile,
|
|
228
243
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
229
244
|
});
|
|
230
|
-
for (const d of
|
|
245
|
+
for (const d of extraModuleCycleDiags)
|
|
231
246
|
reachableEmit.pushDiag(d);
|
|
232
247
|
for (const d of ffiValidation.diagnostics)
|
|
233
248
|
reachableEmit.pushDiag(d);
|
|
@@ -250,11 +265,12 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
250
265
|
startupCrash,
|
|
251
266
|
ffiImports,
|
|
252
267
|
libraryCallbacks,
|
|
268
|
+
forkTargets,
|
|
253
269
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
254
270
|
externalTypes,
|
|
255
271
|
externalTypeSpecifiersByFile,
|
|
256
272
|
});
|
|
257
|
-
for (const d of
|
|
273
|
+
for (const d of extraModuleCycleDiags)
|
|
258
274
|
emit.pushDiag(d);
|
|
259
275
|
for (const d of ffiValidation.diagnostics)
|
|
260
276
|
emit.pushDiag(d);
|
|
@@ -271,6 +287,7 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
271
287
|
targetPlatform,
|
|
272
288
|
ffiImports,
|
|
273
289
|
libraryCallbacks,
|
|
290
|
+
forkTargets,
|
|
274
291
|
ffiBindingSymbols: ffiValidation.symbolsByName,
|
|
275
292
|
externalTypes,
|
|
276
293
|
externalTypeSpecifiersByFile,
|
|
@@ -305,6 +322,46 @@ export function importCallHandleType(expr) {
|
|
|
305
322
|
}
|
|
306
323
|
return null;
|
|
307
324
|
}
|
|
325
|
+
/** The native namespace type produced by a literal static import() of a
|
|
326
|
+
* compiled program module or supported Node builtin. This syntax-level
|
|
327
|
+
* fallback is used where the checker exposes an anonymous builtin-module
|
|
328
|
+
* object type with no stable module symbol (locals/globals are still
|
|
329
|
+
* represented nominally by the value they actually receive). */
|
|
330
|
+
export function staticImportNamespaceType(lowerer, expr) {
|
|
331
|
+
if (!expr || lowerer.dynamic)
|
|
332
|
+
return null;
|
|
333
|
+
let e = expr;
|
|
334
|
+
let awaited = false;
|
|
335
|
+
for (;;) {
|
|
336
|
+
if (ts.isParenthesizedExpression(e))
|
|
337
|
+
e = e.expression;
|
|
338
|
+
else if (ts.isAwaitExpression(e)) {
|
|
339
|
+
awaited = true;
|
|
340
|
+
e = e.expression;
|
|
341
|
+
}
|
|
342
|
+
else
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
if (!ts.isCallExpression(e) || e.expression.kind !== ts.SyntaxKind.ImportKeyword)
|
|
346
|
+
return null;
|
|
347
|
+
const arg = e.arguments[0];
|
|
348
|
+
if (!arg || !ts.isStringLiteralLike(arg))
|
|
349
|
+
return null;
|
|
350
|
+
const builtin = canonicalBuiltinModule(arg.text);
|
|
351
|
+
let moduleId = builtin === null ? null : `builtin:${builtin}`;
|
|
352
|
+
if (moduleId === null) {
|
|
353
|
+
const symbol = lowerer.checker.getSymbolAtLocation(arg);
|
|
354
|
+
const source = symbol && lowerer.checker.declarationsOf(symbol).find((decl) => ts.isSourceFile(decl) && !decl.isDeclarationFile);
|
|
355
|
+
if (source && !source.fileName.endsWith(".cts") && !isCjsJsFile(source) &&
|
|
356
|
+
lowerer.moduleOrder.includes(source)) {
|
|
357
|
+
moduleId = `file:${tsgoPath(resolve(source.fileName))}`;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (moduleId === null)
|
|
361
|
+
return null;
|
|
362
|
+
const ns = { kind: "moduleNs", moduleId };
|
|
363
|
+
return awaited ? ns : { kind: "promise", inner: ns };
|
|
364
|
+
}
|
|
308
365
|
/** True when `expr` is a call that resolved to an overload SIGNATURE of a
|
|
309
366
|
* source-implemented function whose implementation returns an island value
|
|
310
367
|
* (`any` under --dynamic): tsc never checks overload return types against
|
|
@@ -536,7 +593,24 @@ function jsFallbackFunctionType(lowerer, node, t) {
|
|
|
536
593
|
return null;
|
|
537
594
|
const params = sig.getParameters().map((p) => {
|
|
538
595
|
const pt = lowerer.checker.getTypeOfSymbolAtLocation(p, node);
|
|
539
|
-
|
|
596
|
+
let mapped = lowerer.mapTypeOf(pt) ?? DYN;
|
|
597
|
+
// The fallback must preserve the same completed ABI as mapType and
|
|
598
|
+
// lambdaSignature: a spelled optional/defaulted parameter accepts an
|
|
599
|
+
// omitted call, represented by an undefined arm in its fixed native
|
|
600
|
+
// slot. JS inference reports the body type (`boolean` for
|
|
601
|
+
// `enabled = true`) rather than that call-site type, so recover the
|
|
602
|
+
// syntactic optionality from the parameter declaration.
|
|
603
|
+
const decl = lowerer.checker.valueDeclarationOf(p);
|
|
604
|
+
const optional = decl !== undefined &&
|
|
605
|
+
ts.isParameter(decl) &&
|
|
606
|
+
(decl.questionToken !== undefined || decl.initializer !== undefined);
|
|
607
|
+
if (optional &&
|
|
608
|
+
mapped.kind !== "dyn" &&
|
|
609
|
+
mapped.kind !== "jsval" &&
|
|
610
|
+
!lowerer.bareUndefinedArmedUnion(mapped)) {
|
|
611
|
+
mapped = lowerer.withUndefinedArm(mapped);
|
|
612
|
+
}
|
|
613
|
+
return mapped;
|
|
540
614
|
});
|
|
541
615
|
const retT = lowerer.checker.getReturnTypeOfSignature(sig);
|
|
542
616
|
const ret = retT.flags & ts.TypeFlags.Void ? VOID : lowerer.mapTypeOf(retT) ?? DYN;
|
|
@@ -638,6 +712,10 @@ export class Lowerer {
|
|
|
638
712
|
checker;
|
|
639
713
|
diags = [];
|
|
640
714
|
fnSigsBySymbol = new Map();
|
|
715
|
+
/** Immutable callable aliases and compiler-generated adapters. The map
|
|
716
|
+
* is symbol-keyed, so shadowing and cross-module imports keep the same
|
|
717
|
+
* exact binding discipline as globals/functions. */
|
|
718
|
+
staticCallables = new Map();
|
|
641
719
|
genericFnsBySymbol = new Map();
|
|
642
720
|
/** Object-literal GENERIC methods (`{ m<T>(x: T) {...} }`), interned by
|
|
643
721
|
* their function-like node — instances ride the same monomorphization
|
|
@@ -1126,6 +1204,9 @@ export class Lowerer {
|
|
|
1126
1204
|
/** Synthetic array-HOF loop functions (map/filter/forEach desugar),
|
|
1127
1205
|
* interned per method + element/callback-result type: key → fn name. */
|
|
1128
1206
|
arrHofHelpers = new Map();
|
|
1207
|
+
/** Per-arm calls through union-typed class receivers, interned by the
|
|
1208
|
+
* receiver union, member, completed argument ABI, and result type. */
|
|
1209
|
+
unionCallHelpers = new Map();
|
|
1129
1210
|
/** Derived shape metadata that depends on another shape's declaration
|
|
1130
1211
|
* order. These settle before helper bodies rebuild from that metadata. */
|
|
1131
1212
|
shapeOrderMetadataFinalizers = [];
|
|
@@ -1175,11 +1256,6 @@ export class Lowerer {
|
|
|
1175
1256
|
* adapter helper MUST add its name here, or the identity guard silently
|
|
1176
1257
|
* reopens and the mismatch surfaces as a runtime release trap instead. */
|
|
1177
1258
|
freshClosureAdapters = new Set();
|
|
1178
|
-
/** Symbols bound by `const x = promisify(execFile)` — the one lowered
|
|
1179
|
-
* util.promisify shape. Declarations register here and emit nothing;
|
|
1180
|
-
* calls through the binding lower (lowerExecFileAsyncCall) and value
|
|
1181
|
-
* uses fence. */
|
|
1182
|
-
promisifiedExecFile = new Set();
|
|
1183
1259
|
/** Symbols bound by `const process = globalThis.process` (and the other
|
|
1184
1260
|
* stdlib-global snapshot spellings): pure alias plumbing — receiver
|
|
1185
1261
|
* checks resolve through this map (stdlibGlobalNameOf), declarations
|
|
@@ -1212,10 +1288,15 @@ export class Lowerer {
|
|
|
1212
1288
|
spHofHelpers = new Map();
|
|
1213
1289
|
/** The primitive-constructor VALUES (`String`/`Number`/`Boolean` as
|
|
1214
1290
|
* bare identifiers — CLI option tables store and compare them): one
|
|
1215
|
-
* synthesized coercion function per constructor
|
|
1216
|
-
* here
|
|
1217
|
-
*
|
|
1291
|
+
* synthesized coercion function per constructor and typed/dyn ABI,
|
|
1292
|
+
* interned here so references under one source-world ABI are the SAME
|
|
1293
|
+
* zero-capture closure (see primitiveCtorClosure). */
|
|
1218
1294
|
primitiveCtorFns = new Map();
|
|
1295
|
+
/** Builtin-module FUNCTIONS admitted as values by their surface-table
|
|
1296
|
+
* entries. The resolved runtime function plus ABI is the identity key,
|
|
1297
|
+
* so named imports, namespace reads, CommonJS bindings, and alias chains
|
|
1298
|
+
* all reuse one immortal zero-capture closure. */
|
|
1299
|
+
builtinCallableValueFns = new Map();
|
|
1219
1300
|
/** Optional-chain lowering state. While a chain body lowers, the guarded
|
|
1220
1301
|
* receiver NODE reads as a chainRecv (typed by the narrowed arm) instead
|
|
1221
1302
|
* of re-lowering, its checker type reads non-nullish (typeOf), and the
|
|
@@ -1301,8 +1382,15 @@ export class Lowerer {
|
|
|
1301
1382
|
* engine handle (a dynamic import's namespace object) — paramShape's
|
|
1302
1383
|
* early-out. */
|
|
1303
1384
|
jsvalParamOverrides = new Set();
|
|
1385
|
+
/** Inline Promise.then parameters whose contextual type is a builtin
|
|
1386
|
+
* module namespace anonymous object. The settled native token is the
|
|
1387
|
+
* ABI truth even when the checker type has no stable module symbol. */
|
|
1388
|
+
moduleNsParamOverrides = new Map();
|
|
1304
1389
|
/** File → qualifier prefix: "" for the entry, "%mI." otherwise. */
|
|
1305
1390
|
fileTag = new Map();
|
|
1391
|
+
/** Embedded fork roots and their private startup ids. */
|
|
1392
|
+
forkTargets;
|
|
1393
|
+
forkTargetIdByPath = new Map();
|
|
1306
1394
|
/** Namespace ModuleBlocks this program lowers, filled by splitFiles:
|
|
1307
1395
|
* "flattened" — an instantiated namespace whose body joined the file's
|
|
1308
1396
|
* parts (members resolve statically); "typeOnly" — a skipped
|
|
@@ -1506,6 +1594,10 @@ export class Lowerer {
|
|
|
1506
1594
|
this.startupCrash = mode.startupCrash ?? null;
|
|
1507
1595
|
this.ffiImports = mode.ffiImports ?? [];
|
|
1508
1596
|
this.libraryCallbacks = mode.libraryCallbacks ?? false;
|
|
1597
|
+
this.forkTargets = mode.forkTargets ?? [];
|
|
1598
|
+
this.forkTargets.forEach((sf, id) => {
|
|
1599
|
+
this.forkTargetIdByPath.set(tsgoPath(resolve(sf.fileName)), id);
|
|
1600
|
+
});
|
|
1509
1601
|
this.ffiImportsByName = new Map(this.ffiImports.map((entry) => [entry.name, entry]));
|
|
1510
1602
|
this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
|
|
1511
1603
|
this.externalTypes = mode.externalTypes ?? new Map();
|
|
@@ -1535,8 +1627,9 @@ export class Lowerer {
|
|
|
1535
1627
|
// fileTag is filled just below; the hook is only ever CALLED during
|
|
1536
1628
|
// lowering, long after the constructor completes.
|
|
1537
1629
|
isProgramFile: (sf) => this.fileTag.has(sf),
|
|
1630
|
+
moduleNamespaceId: (type) => this.moduleNamespaceIdOfType(type),
|
|
1538
1631
|
};
|
|
1539
|
-
//
|
|
1632
|
+
// Modules reachable only through literal import() joined
|
|
1540
1633
|
// moduleOrder BEFORE any pass constructed — lowerToIr runs
|
|
1541
1634
|
// appendDynamicImportModules once on the shared array (a per-pass run
|
|
1542
1635
|
// here would repeatedly extend the graph and duplicate cycle reports).
|
|
@@ -1552,6 +1645,35 @@ export class Lowerer {
|
|
|
1552
1645
|
registerBuiltinErrorClasses() {
|
|
1553
1646
|
return registerBuiltinErrorClasses(this);
|
|
1554
1647
|
}
|
|
1648
|
+
/** The nominal identity of a checker module-namespace type. Program
|
|
1649
|
+
* modules use their normalized absolute source name; supported builtins
|
|
1650
|
+
* use the lowering tables' canonical bare name. */
|
|
1651
|
+
moduleNamespaceIdOfType(type) {
|
|
1652
|
+
let sym = type.getSymbol();
|
|
1653
|
+
if (!sym)
|
|
1654
|
+
return null;
|
|
1655
|
+
if (sym.flags & ts.SymbolFlags.Alias)
|
|
1656
|
+
sym = this.checker.getAliasedSymbol(sym);
|
|
1657
|
+
for (const decl of this.checker.declarationsOf(sym)) {
|
|
1658
|
+
if (ts.isSourceFile(decl) && !decl.isDeclarationFile &&
|
|
1659
|
+
!decl.fileName.endsWith(".cts") && !isCjsJsFile(decl) &&
|
|
1660
|
+
this.moduleOrder.includes(decl)) {
|
|
1661
|
+
return `file:${tsgoPath(resolve(decl.fileName))}`;
|
|
1662
|
+
}
|
|
1663
|
+
if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) {
|
|
1664
|
+
const builtin = canonicalBuiltinModule(decl.name.text);
|
|
1665
|
+
if (builtin !== null)
|
|
1666
|
+
return `builtin:${builtin}`;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
return null;
|
|
1670
|
+
}
|
|
1671
|
+
sourceFileOfModuleNamespace(type) {
|
|
1672
|
+
if (type.kind !== "moduleNs" || !type.moduleId.startsWith("file:"))
|
|
1673
|
+
return null;
|
|
1674
|
+
const path = type.moduleId.slice("file:".length);
|
|
1675
|
+
return this.moduleOrder.find((sf) => tsgoPath(resolve(sf.fileName)) === path) ?? null;
|
|
1676
|
+
}
|
|
1555
1677
|
builtinErrorInfoOf(symbol) {
|
|
1556
1678
|
return builtinErrorInfoOf(this, symbol);
|
|
1557
1679
|
}
|
|
@@ -1588,34 +1710,35 @@ export class Lowerer {
|
|
|
1588
1710
|
if (ident.parent && ts.isShorthandPropertyAssignment(ident.parent) && ident.parent.name === ident) {
|
|
1589
1711
|
symbol = this.checker.getShorthandAssignmentValueSymbol(ident.parent) ?? symbol;
|
|
1590
1712
|
}
|
|
1713
|
+
// createRequire's return type is intentionally `any`, so tsgo does not
|
|
1714
|
+
// make the binding an import alias. When the target replaces
|
|
1715
|
+
// module.exports with one represented scalar/function/class value,
|
|
1716
|
+
// reconnect the binding to that export symbol explicitly; ordinary
|
|
1717
|
+
// identifier/call/new/global paths then apply unchanged.
|
|
1718
|
+
const createdWhole = this.createRequireWholeExportSymbolOf(ident);
|
|
1719
|
+
if (createdWhole)
|
|
1720
|
+
symbol = createdWhole;
|
|
1721
|
+
const createdMember = this.createRequireDestructuredExportSymbolOf(ident);
|
|
1722
|
+
if (createdMember)
|
|
1723
|
+
symbol = createdMember;
|
|
1591
1724
|
// tsgo synthesizes no expando symbol at a CJS MEMBER-EXPORT use site
|
|
1592
1725
|
// (`common.GREETING` where the exporter attached GREETING with
|
|
1593
1726
|
// `module.exports.GREETING = ...` — 5.9.3 answered the expando
|
|
1594
1727
|
// property symbol here), but the exporter's MODULE symbol still
|
|
1595
1728
|
// carries the member in its exports table; resolve through it so both
|
|
1596
1729
|
// ends of the export key one symbol identity, like 5.9.3's.
|
|
1597
|
-
if (
|
|
1730
|
+
if (ident.parent && ts.isPropertyAccessExpression(ident.parent) && ident.parent.name === ident) {
|
|
1598
1731
|
const recv = ident.parent.expression;
|
|
1599
1732
|
if (ts.isIdentifier(recv) && this.cjsLocalModuleBindingOf(recv)) {
|
|
1600
|
-
const
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
if (dep)
|
|
1610
|
-
symbol = this.cjsModuleExportSymbol(dep, ident.text);
|
|
1611
|
-
}
|
|
1612
|
-
else if (recvDecl && ts.isImportClause(recvDecl)) {
|
|
1613
|
-
// The DEFAULT-import spelling of the same binding: the dep is
|
|
1614
|
-
// the import declaration's resolved CJS module.
|
|
1615
|
-
const dep = this.cjsDefaultImportDepOf(recvDecl);
|
|
1616
|
-
if (dep)
|
|
1617
|
-
symbol = this.cjsModuleExportSymbol(dep, ident.text);
|
|
1618
|
-
}
|
|
1733
|
+
const dep = this.localModuleBindingDepOf(recv);
|
|
1734
|
+
const exported = dep ? this.cjsModuleExportSymbol(dep, ident.text) : undefined;
|
|
1735
|
+
// A createRequire call is typed as `any`, so tsgo can manufacture a
|
|
1736
|
+
// transient property symbol with no relation to the target module.
|
|
1737
|
+
// Prefer the real export-table symbol whenever the receiver is a
|
|
1738
|
+
// proven static module binding; ordinary direct require aliases
|
|
1739
|
+
// resolve to the same identity.
|
|
1740
|
+
if (exported)
|
|
1741
|
+
symbol = exported;
|
|
1619
1742
|
}
|
|
1620
1743
|
}
|
|
1621
1744
|
if (!symbol)
|
|
@@ -1911,7 +2034,17 @@ export class Lowerer {
|
|
|
1911
2034
|
* property symbol exists at the attachment/use sites). */
|
|
1912
2035
|
cjsModuleExportSymbol(sf, name) {
|
|
1913
2036
|
const moduleSym = this.checker.getSymbolAtLocation(sf);
|
|
1914
|
-
|
|
2037
|
+
const exports = moduleSym?.getExports();
|
|
2038
|
+
const direct = exports?.get(name);
|
|
2039
|
+
if (direct)
|
|
2040
|
+
return direct;
|
|
2041
|
+
// tsgo represents `module.exports = { ... }` as one `export=` symbol
|
|
2042
|
+
// and does not duplicate the object literal's properties into the
|
|
2043
|
+
// module export map. Resolve through that root type so createRequire's
|
|
2044
|
+
// any-typed namespace can recover the same property symbols an
|
|
2045
|
+
// ordinary direct require receives from checker inference.
|
|
2046
|
+
const root = exports?.get("export=");
|
|
2047
|
+
return root ? this.checker.getPropertyOfType(this.checker.getTypeOfSymbol(root), name) : undefined;
|
|
1915
2048
|
}
|
|
1916
2049
|
/** The local VALUE symbol behind a CJS export-table property symbol —
|
|
1917
2050
|
* see resolveValueSymbol. Null when `symbol` is not such a property (or
|
|
@@ -1999,6 +2132,88 @@ export class Lowerer {
|
|
|
1999
2132
|
return null;
|
|
2000
2133
|
return dep;
|
|
2001
2134
|
}
|
|
2135
|
+
/** The compiled module behind a require-like namespace binding: an
|
|
2136
|
+
* ordinary CommonJS require declaration, a canonical createRequire
|
|
2137
|
+
* declaration, or an ESM default import of CommonJS. One resolver keeps
|
|
2138
|
+
* member-symbol fallback and namespace classification in lockstep. */
|
|
2139
|
+
localModuleBindingDepOf(expr) {
|
|
2140
|
+
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2141
|
+
const decls = sym ? this.checker.declarationsOf(sym) : [];
|
|
2142
|
+
const decl = decls.find(ts.isImportClause) ?? decls[0];
|
|
2143
|
+
if (!decl)
|
|
2144
|
+
return null;
|
|
2145
|
+
if (ts.isImportClause(decl))
|
|
2146
|
+
return this.cjsDefaultImportDepOf(decl);
|
|
2147
|
+
if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2148
|
+
return null;
|
|
2149
|
+
const directSpec = requireSpecOf(decl.initializer);
|
|
2150
|
+
if (directSpec !== null) {
|
|
2151
|
+
return resolveImport(this.program, decl.getSourceFile(), directSpec) ??
|
|
2152
|
+
npmStaticDepSf7(this.program, decl.getSourceFile(), directSpec);
|
|
2153
|
+
}
|
|
2154
|
+
return createRequireProgramModuleOf(this, decl.initializer)?.dep ?? null;
|
|
2155
|
+
}
|
|
2156
|
+
/** The represented single value behind a createRequire binding, or null
|
|
2157
|
+
* when the target is a namespace/table module. Collection has already
|
|
2158
|
+
* registered executable exports before entry-module uses lower, so the
|
|
2159
|
+
* registries are the authority for whether the export= value exists in
|
|
2160
|
+
* static storage or callable/class metadata. */
|
|
2161
|
+
createRequireWholeExportSymbolOf(ident) {
|
|
2162
|
+
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2163
|
+
const decl = binding ? this.checker.declarationsOf(binding).find(ts.isVariableDeclaration) : undefined;
|
|
2164
|
+
if (!decl || !ts.isIdentifier(decl.name) || !decl.initializer)
|
|
2165
|
+
return null;
|
|
2166
|
+
const target = createRequireProgramModuleOf(this, decl.initializer);
|
|
2167
|
+
if (target === null)
|
|
2168
|
+
return null;
|
|
2169
|
+
const moduleSym = this.checker.getSymbolAtLocation(target.dep);
|
|
2170
|
+
let symbol = moduleSym?.getExports().get("export=");
|
|
2171
|
+
if (!symbol)
|
|
2172
|
+
return null;
|
|
2173
|
+
const wholeAssignment = this.checker.declarationsOf(symbol).find((d) => {
|
|
2174
|
+
if (!ts.isBinaryExpression(d) || !ts.isExpressionStatement(d.parent) || !ts.isSourceFile(d.parent.parent))
|
|
2175
|
+
return false;
|
|
2176
|
+
const exported = cjsExportAssignmentOf(d.parent);
|
|
2177
|
+
return exported?.kind === "table" && exported.obj === null && cjsExportDiscardReason(d.parent) === null;
|
|
2178
|
+
});
|
|
2179
|
+
if (wholeAssignment === undefined)
|
|
2180
|
+
return null;
|
|
2181
|
+
let rhs = wholeAssignment.right;
|
|
2182
|
+
while (ts.isParenthesizedExpression(rhs))
|
|
2183
|
+
rhs = rhs.expression;
|
|
2184
|
+
if (ts.isIdentifier(rhs)) {
|
|
2185
|
+
const value = this.checker.getSymbolAtLocation(rhs);
|
|
2186
|
+
if (value) {
|
|
2187
|
+
const resolved = value.flags & ts.SymbolFlags.Alias ? this.checker.getAliasedSymbol(value) : value;
|
|
2188
|
+
return resolved;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
if (symbol.flags & ts.SymbolFlags.Alias)
|
|
2192
|
+
symbol = this.checker.getAliasedSymbol(symbol);
|
|
2193
|
+
symbol = this.cjsExportValueSymbol(symbol) ?? symbol;
|
|
2194
|
+
return symbol;
|
|
2195
|
+
}
|
|
2196
|
+
/** The target export behind `const { member: local } = require("...")`
|
|
2197
|
+
* through createRequire. The binding is import-style alias plumbing;
|
|
2198
|
+
* plain identifiers, renames, and string-literal property names share the
|
|
2199
|
+
* target module's real export symbol. */
|
|
2200
|
+
createRequireDestructuredExportSymbolOf(ident) {
|
|
2201
|
+
const binding = this.checker.getSymbolAtLocation(ident);
|
|
2202
|
+
const element = binding ? this.checker.declarationsOf(binding).find(ts.isBindingElement) : undefined;
|
|
2203
|
+
if (!element || element.name === undefined || !ts.isIdentifier(element.name) || !ts.isObjectBindingPattern(element.parent))
|
|
2204
|
+
return null;
|
|
2205
|
+
const declaration = element.parent.parent;
|
|
2206
|
+
if (!ts.isVariableDeclaration(declaration) || !declaration.initializer)
|
|
2207
|
+
return null;
|
|
2208
|
+
const target = createRequireProgramModuleOf(this, declaration.initializer);
|
|
2209
|
+
if (target === null)
|
|
2210
|
+
return null;
|
|
2211
|
+
const property = element.propertyName;
|
|
2212
|
+
const name = property && (ts.isIdentifier(property) || ts.isStringLiteralLike(property))
|
|
2213
|
+
? property.text
|
|
2214
|
+
: ident.text;
|
|
2215
|
+
return this.cjsModuleExportSymbol(target.dep, name) ?? null;
|
|
2216
|
+
}
|
|
2002
2217
|
/** True when `expr` is an identifier bound by a top-level
|
|
2003
2218
|
* `const x = require("./local")` of a project module — relative,
|
|
2004
2219
|
* tsconfig-aliased, or package.json-mediated — or of a bare specifier
|
|
@@ -2013,26 +2228,10 @@ export class Lowerer {
|
|
|
2013
2228
|
if (!ts.isIdentifier(expr))
|
|
2014
2229
|
return false;
|
|
2015
2230
|
const sym = this.checker.getSymbolAtLocation(expr);
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
if (
|
|
2231
|
+
if (this.localModuleBindingDepOf(expr) === null)
|
|
2232
|
+
return false;
|
|
2233
|
+
if (this.createRequireWholeExportSymbolOf(expr) !== null)
|
|
2019
2234
|
return false;
|
|
2020
|
-
if (ts.isImportClause(decl)) {
|
|
2021
|
-
if (decl.name === undefined || this.cjsDefaultImportDepOf(decl) === null)
|
|
2022
|
-
return false;
|
|
2023
|
-
}
|
|
2024
|
-
else {
|
|
2025
|
-
if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name) || !decl.initializer) {
|
|
2026
|
-
return false;
|
|
2027
|
-
}
|
|
2028
|
-
const spec = requireSpecOf(decl.initializer);
|
|
2029
|
-
if (spec === null)
|
|
2030
|
-
return false;
|
|
2031
|
-
if (resolveImport(this.program, decl.getSourceFile(), spec) === null &&
|
|
2032
|
-
npmStaticDepSf7(this.program, decl.getSourceFile(), spec) === null) {
|
|
2033
|
-
return false;
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
2235
|
// SINGLE-VALUE exporters (`module.exports = Countdown` / `= double` /
|
|
2037
2236
|
// `= 42`): the requirer's binding IS the exported value, not a
|
|
2038
2237
|
// namespace over an export table — the alias resolves straight to the
|
|
@@ -2052,10 +2251,15 @@ export class Lowerer {
|
|
|
2052
2251
|
if (!init || !ts.isObjectLiteralExpression(init))
|
|
2053
2252
|
return false;
|
|
2054
2253
|
}
|
|
2055
|
-
//
|
|
2056
|
-
//
|
|
2057
|
-
//
|
|
2254
|
+
// A represented whole export declares AT the `module.exports =`
|
|
2255
|
+
// statement itself. Scalar/function/factory-call roots register one
|
|
2256
|
+
// snapshot global on that declaration; table/Proxy replacements do
|
|
2257
|
+
// not. A binding whose declaration owns such storage is therefore a
|
|
2258
|
+
// single VALUE, not a namespace whose members must appear in Node's
|
|
2259
|
+
// CJS lexer export table.
|
|
2058
2260
|
if (d && ts.isBinaryExpression(d)) {
|
|
2261
|
+
if (this.globalsByDeclNode.has(d))
|
|
2262
|
+
return false;
|
|
2059
2263
|
let r = d.right;
|
|
2060
2264
|
while (ts.isParenthesizedExpression(r))
|
|
2061
2265
|
r = r.expression;
|
|
@@ -2086,7 +2290,11 @@ export class Lowerer {
|
|
|
2086
2290
|
}
|
|
2087
2291
|
fnSigOf(ident) {
|
|
2088
2292
|
const symbol = this.resolveValueSymbol(ident);
|
|
2089
|
-
|
|
2293
|
+
if (!symbol)
|
|
2294
|
+
return null;
|
|
2295
|
+
const projection = this.staticCallables.get(symbol);
|
|
2296
|
+
return this.fnSigsBySymbol.get(symbol) ??
|
|
2297
|
+
(projection?.kind === "declared-function" ? projection.signature : null);
|
|
2090
2298
|
}
|
|
2091
2299
|
globalOf(ident) {
|
|
2092
2300
|
const symbol = this.resolveValueSymbol(ident);
|
|
@@ -3265,7 +3473,7 @@ export class Lowerer {
|
|
|
3265
3473
|
const module = this.diags.length > 0
|
|
3266
3474
|
? null
|
|
3267
3475
|
: {
|
|
3268
|
-
irVersion:
|
|
3476
|
+
irVersion: 11,
|
|
3269
3477
|
sourceFile: this.entry.fileName,
|
|
3270
3478
|
functions,
|
|
3271
3479
|
classes: artifacts.classes,
|
|
@@ -5414,8 +5622,9 @@ export class Lowerer {
|
|
|
5414
5622
|
const from = this.shapes.get(fromId);
|
|
5415
5623
|
if (!from || !from.tuple)
|
|
5416
5624
|
return null;
|
|
5625
|
+
const fields = [...from.fields].sort((a, b) => Number(a.name) - Number(b.name));
|
|
5417
5626
|
const lifts = [];
|
|
5418
|
-
for (const f of
|
|
5627
|
+
for (const f of fields) {
|
|
5419
5628
|
const lift = this.widthLiftPlan(f.type, toT.elem);
|
|
5420
5629
|
if (!lift)
|
|
5421
5630
|
return null;
|
|
@@ -5439,7 +5648,7 @@ export class Lowerer {
|
|
|
5439
5648
|
kind: "return",
|
|
5440
5649
|
value: {
|
|
5441
5650
|
kind: "arrayLit",
|
|
5442
|
-
elems:
|
|
5651
|
+
elems: fields.map((f, i) => this.applyWidthLift(lifts[i], { kind: "recordGet", obj: t, shapeId: fromId, field: f.name, type: f.type, loc }, toT.elem, loc)),
|
|
5443
5652
|
type: toT,
|
|
5444
5653
|
loc,
|
|
5445
5654
|
},
|
|
@@ -9046,6 +9255,13 @@ export class Lowerer {
|
|
|
9046
9255
|
* member access that IS a module in its own right (`fs.promises` — the
|
|
9047
9256
|
* same object as node:fs/promises, Node's rule). Null otherwise. */
|
|
9048
9257
|
builtinNamespaceModuleOf(expr) {
|
|
9258
|
+
const stored = ts.isIdentifier(expr)
|
|
9259
|
+
? (this.peekLocal(expr)?.type ?? this.globalOf(expr)?.type)
|
|
9260
|
+
: undefined;
|
|
9261
|
+
const mapped = stored ?? this.mapTypeOf(this.typeOf(expr));
|
|
9262
|
+
if (mapped?.kind === "moduleNs" && mapped.moduleId.startsWith("builtin:")) {
|
|
9263
|
+
return mapped.moduleId.slice("builtin:".length);
|
|
9264
|
+
}
|
|
9049
9265
|
if (ts.isIdentifier(expr)) {
|
|
9050
9266
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
9051
9267
|
const decl = symbol ? this.checker.declarationsOf(symbol)[0] : undefined;
|
|
@@ -9167,6 +9383,12 @@ export class Lowerer {
|
|
|
9167
9383
|
const bi = this.builtinMemberOf(access);
|
|
9168
9384
|
if (!bi)
|
|
9169
9385
|
return null;
|
|
9386
|
+
// child_process.execFile's callback forms are special-cased rather
|
|
9387
|
+
// than table-backed, but namespace imports share the named-import
|
|
9388
|
+
// implementation and runtime callback adapter.
|
|
9389
|
+
if (bi.module === "child_process" && bi.member === "execFile") {
|
|
9390
|
+
return this.lowerExecFileCall(call, locOf(access));
|
|
9391
|
+
}
|
|
9170
9392
|
// The timers spoke: `timers.setTimeout(...)` through a namespace or
|
|
9171
9393
|
// require binding IS the global (Node's timers module re-exports
|
|
9172
9394
|
// them) — the shared member lowering serves both spellings.
|
|
@@ -9223,6 +9445,9 @@ export class Lowerer {
|
|
|
9223
9445
|
const cryptoServed = this.lowerCryptoModuleCall(call, bi, locOf(access));
|
|
9224
9446
|
if (cryptoServed)
|
|
9225
9447
|
return cryptoServed;
|
|
9448
|
+
const nodeModuleServed = lowerNodeModuleCall(this, call, bi, locOf(access));
|
|
9449
|
+
if (nodeModuleServed)
|
|
9450
|
+
return nodeModuleServed;
|
|
9226
9451
|
const builtinFn = builtinModuleFnOf(this, bi.module, bi.member);
|
|
9227
9452
|
if (!builtinFn) {
|
|
9228
9453
|
this.noLowering(`${bi.module}.${bi.member}`, call, builtinFenceHintOf(bi.module, bi.member), this.checker.getSymbolAtLocation(access.name));
|
|
@@ -9273,6 +9498,14 @@ export class Lowerer {
|
|
|
9273
9498
|
if (roots)
|
|
9274
9499
|
return roots;
|
|
9275
9500
|
}
|
|
9501
|
+
// TypeScript builtin values admitted by an explicit surface-table
|
|
9502
|
+
// contract materialize as interned closures. JavaScript sources retain
|
|
9503
|
+
// their established builtin identity-token/fence policy.
|
|
9504
|
+
if (!isJsSourceFile(expr.getSourceFile())) {
|
|
9505
|
+
const callable = this.lowerBuiltinCallableValue(bi, loc);
|
|
9506
|
+
if (callable)
|
|
9507
|
+
return callable;
|
|
9508
|
+
}
|
|
9276
9509
|
if (bi.member === "constants" && bi.module === "fs") {
|
|
9277
9510
|
// A bare `fs.constants` read (not one of the baked bits above).
|
|
9278
9511
|
this.noLowering(`fs.constants`, expr, "F_OK, R_OK, W_OK, and X_OK are the lowered constants");
|
|
@@ -9282,6 +9515,110 @@ export class Lowerer {
|
|
|
9282
9515
|
}
|
|
9283
9516
|
this.noLowering(`${bi.module}.${bi.member}`, expr, builtinFenceHintOf(bi.module, bi.member), this.checker.getSymbolAtLocation(expr.name));
|
|
9284
9517
|
}
|
|
9518
|
+
/** Materialize one explicitly value-callable table entry as an interned
|
|
9519
|
+
* synthetic module function. Direct calls never use this path: they keep
|
|
9520
|
+
* their existing validated libCall lowering. The value descriptor is
|
|
9521
|
+
* deliberately narrower than table membership because many table rows
|
|
9522
|
+
* are only dispatch sentinels for call-site-specific lowering. */
|
|
9523
|
+
lowerBuiltinCallableValue(bi, loc) {
|
|
9524
|
+
const fn = builtinModuleFnOf(this, bi.module, bi.member);
|
|
9525
|
+
const valueParams = fn?.valueParams;
|
|
9526
|
+
if (!fn || !valueParams)
|
|
9527
|
+
return null;
|
|
9528
|
+
const shapes = valueParams.map((param) => {
|
|
9529
|
+
if (param.mode === "rest")
|
|
9530
|
+
return { mode: "rest", type: arrayOf(param.type) };
|
|
9531
|
+
if (param.mode === "optional") {
|
|
9532
|
+
return { mode: "omittable", type: this.withUndefinedArm(param.type), bodyType: param.type };
|
|
9533
|
+
}
|
|
9534
|
+
return { mode: "required", type: param.type };
|
|
9535
|
+
});
|
|
9536
|
+
const funcType = funcTypeFromParamShapes(shapes, fn.result);
|
|
9537
|
+
const adapterShape = valueParams
|
|
9538
|
+
.map((param) => param.mode === "optional" ? `${param.mode}:${param.defaultValue}` : param.mode)
|
|
9539
|
+
.join(",");
|
|
9540
|
+
const key = `${fn.fn}:${typeKey(funcType)}:${adapterShape}`;
|
|
9541
|
+
let fnName = this.builtinCallableValueFns.get(key);
|
|
9542
|
+
if (!fnName) {
|
|
9543
|
+
fnName = `%builtin.value.${fn.fn}.${this.builtinCallableValueFns.size}`;
|
|
9544
|
+
this.builtinCallableValueFns.set(key, fnName);
|
|
9545
|
+
const params = funcType.params.map((type, index) => ({
|
|
9546
|
+
localId: `arg.${index}`,
|
|
9547
|
+
name: `arg${index}`,
|
|
9548
|
+
type,
|
|
9549
|
+
}));
|
|
9550
|
+
const args = params.map((param, index) => {
|
|
9551
|
+
const valueParam = valueParams[index];
|
|
9552
|
+
if (!valueParam) {
|
|
9553
|
+
throw new InternalCompilerError(`builtin callable value '${bi.module}.${bi.member}' has a missing value parameter`);
|
|
9554
|
+
}
|
|
9555
|
+
const ref = {
|
|
9556
|
+
kind: "varRef",
|
|
9557
|
+
localId: param.localId,
|
|
9558
|
+
type: param.type,
|
|
9559
|
+
loc,
|
|
9560
|
+
};
|
|
9561
|
+
if (valueParam.mode !== "optional")
|
|
9562
|
+
return ref;
|
|
9563
|
+
if (valueParam.type.kind !== "string" || param.type.kind !== "union") {
|
|
9564
|
+
throw new InternalCompilerError(`builtin callable value '${bi.module}.${bi.member}' has an unsupported optional default`);
|
|
9565
|
+
}
|
|
9566
|
+
const undefTag = this.armTag(param.type.unionId, UNDEFINED_T);
|
|
9567
|
+
const valueTag = this.armTag(param.type.unionId, valueParam.type);
|
|
9568
|
+
if (undefTag < 0 || valueTag < 0) {
|
|
9569
|
+
throw new InternalCompilerError(`builtin callable value '${bi.module}.${bi.member}' has an invalid optional ABI`);
|
|
9570
|
+
}
|
|
9571
|
+
return {
|
|
9572
|
+
kind: "ternary",
|
|
9573
|
+
cond: {
|
|
9574
|
+
kind: "unionIsTag",
|
|
9575
|
+
unionId: param.type.unionId,
|
|
9576
|
+
tag: undefTag,
|
|
9577
|
+
negated: false,
|
|
9578
|
+
value: ref,
|
|
9579
|
+
type: BOOL,
|
|
9580
|
+
loc,
|
|
9581
|
+
},
|
|
9582
|
+
then: { kind: "strLit", value: valueParam.defaultValue, type: STRING, loc },
|
|
9583
|
+
else_: {
|
|
9584
|
+
kind: "unionNarrow",
|
|
9585
|
+
unionId: param.type.unionId,
|
|
9586
|
+
tag: valueTag,
|
|
9587
|
+
value: ref,
|
|
9588
|
+
type: valueParam.type,
|
|
9589
|
+
loc,
|
|
9590
|
+
},
|
|
9591
|
+
type: valueParam.type,
|
|
9592
|
+
loc,
|
|
9593
|
+
};
|
|
9594
|
+
});
|
|
9595
|
+
const call = { kind: "libCall", fn: fn.fn, args, type: fn.result, loc };
|
|
9596
|
+
const body = fn.result.kind === "void"
|
|
9597
|
+
? [
|
|
9598
|
+
{ kind: "exprStmt", expr: call, loc },
|
|
9599
|
+
{ kind: "return", value: null, loc },
|
|
9600
|
+
]
|
|
9601
|
+
: [{ kind: "return", value: call, loc }];
|
|
9602
|
+
this.liftedFns.push({
|
|
9603
|
+
name: fnName,
|
|
9604
|
+
params,
|
|
9605
|
+
returnType: fn.result,
|
|
9606
|
+
locals: params.map((param) => ({
|
|
9607
|
+
id: param.localId,
|
|
9608
|
+
name: param.name,
|
|
9609
|
+
type: param.type,
|
|
9610
|
+
mutable: false,
|
|
9611
|
+
})),
|
|
9612
|
+
body,
|
|
9613
|
+
loc,
|
|
9614
|
+
});
|
|
9615
|
+
}
|
|
9616
|
+
return { kind: "closure", fnName, captures: [], type: funcType, loc };
|
|
9617
|
+
}
|
|
9618
|
+
isBuiltinCallableValue(expr) {
|
|
9619
|
+
return expr.kind === "closure" &&
|
|
9620
|
+
[...this.builtinCallableValueFns.values()].some((name) => name === expr.fnName);
|
|
9621
|
+
}
|
|
9285
9622
|
lowerBuiltinModuleCall(expr, bi, fn, loc) {
|
|
9286
9623
|
return lowerBuiltinModuleCall(this, expr, bi, fn, loc);
|
|
9287
9624
|
}
|
|
@@ -9303,6 +9640,9 @@ export class Lowerer {
|
|
|
9303
9640
|
lowerSpawnCall(expr, loc) {
|
|
9304
9641
|
return lowerSpawnCall(this, expr, loc);
|
|
9305
9642
|
}
|
|
9643
|
+
lowerExecFileCall(expr, loc) {
|
|
9644
|
+
return lowerExecFileCall(this, expr, loc);
|
|
9645
|
+
}
|
|
9306
9646
|
lowerExecSyncCall(expr, shell, loc) {
|
|
9307
9647
|
return lowerExecSyncCall(this, expr, shell, loc);
|
|
9308
9648
|
}
|
|
@@ -9451,8 +9791,8 @@ export class Lowerer {
|
|
|
9451
9791
|
lowerTimeoutMethodCall(call, access) {
|
|
9452
9792
|
return lowerTimeoutMethodCall(this, call, access);
|
|
9453
9793
|
}
|
|
9454
|
-
|
|
9455
|
-
return
|
|
9794
|
+
registerPromisifiedBuiltinDecl(nameNode, init) {
|
|
9795
|
+
return registerPromisifiedBuiltinDecl(this, nameNode, init);
|
|
9456
9796
|
}
|
|
9457
9797
|
lowerExecFileAsyncCall(expr, loc) {
|
|
9458
9798
|
return lowerExecFileAsyncCall(this, expr, loc);
|