@scriptc/compiler 0.0.10 → 0.0.12
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 +63 -15
- package/ambient/scriptc.d.ts +2 -2
- package/dist/backend/cc.d.ts +2 -2
- package/dist/backend/emission/emit-async.js +1 -1
- package/dist/backend/emission/emit-exprs.js +131 -54
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -1
- package/dist/backend/emission/emit-walkers.d.ts +14 -14
- package/dist/backend/emission/emit-walkers.js +44 -44
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +3 -3
- package/dist/backend/emission/emitter.js +33 -9
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/emission/may-throw.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +10 -10
- package/dist/backend/llvm/dyn.js +26 -26
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +156 -47
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -1
- package/dist/backend/llvm/walkers.js +2 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -2
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +21 -8
- package/dist/diagnostics/diagnostic.js +48 -14
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.js +5 -5
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +12 -12
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +63 -7
- package/dist/frontend/lowering/lower-builtins.js +327 -35
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -4
- package/dist/frontend/lowering/lower-calls.js +104 -70
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +7 -0
- package/dist/frontend/lowering/lower-classes.js +82 -6
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +9 -5
- package/dist/frontend/lowering/lower-containers.js +88 -26
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.d.ts +70 -3
- package/dist/frontend/lowering/lower-emitter.js +438 -31
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +87 -12
- package/dist/frontend/lowering/lower-exprs.js +630 -125
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +5 -5
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +12 -3
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +8 -5
- package/dist/frontend/lowering/lower-modules.js +157 -63
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +24 -0
- package/dist/frontend/lowering/lower-namespaces.js +158 -16
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.js +11 -11
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
- package/dist/frontend/lowering/lower-stmts.js +271 -36
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +171 -20
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +27 -10
- package/dist/frontend/lowering/lowerer.js +156 -54
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +44 -0
- package/dist/frontend/lowering/surfaces.js +236 -5
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm.d.ts +12 -0
- package/dist/frontend/npm.js +30 -0
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.d.ts +25 -0
- package/dist/frontend/program.js +145 -136
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/shared.d.ts +1 -1
- package/dist/frontend/shared.js +8 -8
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +2 -2
- package/dist/frontend/types.js +15 -15
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +169 -5
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +174 -106
- package/dist/ir/nodes.js +69 -24
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +55 -36
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/fence-eval.js +12 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.d.ts +119 -0
- package/dist/library/int-infer.js +1314 -0
- package/dist/library/int-infer.js.map +1 -0
- package/dist/library/int-infer.test.d.ts +1 -0
- package/dist/library/int-infer.test.js +279 -0
- package/dist/library/int-infer.test.js.map +1 -0
- package/dist/library/profile.d.ts +34 -5
- package/dist/library/profile.js +77 -13
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar-validate.js +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +24 -1
- package/dist/library/sidecar.js +163 -16
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +210 -12
|
@@ -19,14 +19,15 @@ import { arrayOf, BOOL, canAdaptDynFuncTo, canConvertToDyn, canCrossIslandBounda
|
|
|
19
19
|
import { provenanceActive } from "../provenance-registry.js";
|
|
20
20
|
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
21
21
|
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../types.js";
|
|
22
|
-
import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
|
|
22
|
+
import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
|
|
23
23
|
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules } from "./lower-modules.js";
|
|
24
24
|
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";
|
|
25
25
|
import { mixinCallClassInfoOf, mixinIntersectionInstanceType } from "./lower-mixins.js";
|
|
26
26
|
import { bindingNeverReassigned, bodyReadsArguments, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, completeArgs, wrappedUndefined, undefinedArgFor, requireExactArityValue, bodyReturnType, declaredReturnType, collectSignature, collectSignatureInner, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, lowerCall, lowerTimersMemberCall, lowerPromiseMethodCall, lowerFilterNarrowCall, isTopLevelFnSymbol, lowerNestedFunctionDecl, lambdaSignature, lowerLambda, lowerFunction } from "./lower-calls.js";
|
|
27
27
|
import { lowerArrayMethodCall, lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew, lowerMapMethodCall, lowerMapForEachCall, buildMapForEachFn, lowerRecordOvfCaptureHelper, lowerEnvToPairsHelper, lowerSetMethodCall, lowerSetForEachCall, buildSetForEachFn, lowerRegexMethodCall, lowerStringMethodCall } from "./lower-containers.js";
|
|
28
28
|
import { lowerStreamModuleCall } from "./lower-stream.js";
|
|
29
|
-
import {
|
|
29
|
+
import { lowerEmitOverrideSpec } from "./lower-emitter.js";
|
|
30
|
+
import { builtinImportOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireSpecOf, stripTypeCasts, lowerBuiltinModuleCall, lowerFsToUnixTimestampCall, lowerFsLadderCall, lowerChildArgsArg, lowerSpawnSyncCall, lowerSpawnCall, lowerExecSyncCall, recordToEnvPairs, lowerJsonMethodCall, fencedBuiltinImportOf, lowerCryptoComposedCall, lowerUrlMethodCall, lowerSearchParamsMethodCall, lowerStatsMethodCall, lowerChildMethodCall, lowerAtomicsCall, lowerBuiltinExtraProperty, promisifiedExecFileDecl, 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, lowerFsConstantsProperty, lowerHttp2ConstantsProperty, http2ConstantBindingOf, http2ConstantsDestructureDecl, lowerProcessStreamProperty, lowerStringStaticCall, lowerStringLastIndexOfCall, lowerPromiseStaticCall } from "./lower-builtins.js";
|
|
30
31
|
import { isIslandExpr, islandFuncValueFence, islandRegexpOf, jsvalIn, requireDynamicApi, islandGlobalFnOf, lowerDynamicImportCall, lowerFetchCall, lowerIslandMethodCall, lowerMathProperty, npmPackageOf, npmMemberFence, npmPackageOfSymbol } from "./lower-island.js";
|
|
31
32
|
import { lowerHttpHeadersElement, lowerNetModuleCall, lowerServerMethodCall, lowerServerProperty } from "./lower-server.js";
|
|
32
33
|
import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js";
|
|
@@ -148,8 +149,24 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
|
|
|
148
149
|
const dynamic = options.dynamic ?? false;
|
|
149
150
|
const targetPlatform = options.targetPlatform ?? process.platform;
|
|
150
151
|
const startupCrash = options.startupCrash ?? null;
|
|
152
|
+
// --dynamic: modules reachable only through dynamic import() of the
|
|
153
|
+
// program's own files join the compiled graph here, ONCE, before any
|
|
154
|
+
// pass constructs (nothing calls their %init at startup — the import()
|
|
155
|
+
// site's namespace builder does, on the engine microtask, Node's
|
|
156
|
+
// evaluation point for them). Inadmissible static cycles inside the
|
|
157
|
+
// added subgraph are minted here and handed to the EMIT pass: the
|
|
158
|
+
// discovery pass's diagnostics are discarded by design, and after this
|
|
159
|
+
// extension of the shared array no later pass re-walks the subgraph.
|
|
160
|
+
const dynamicCycleDiags = [];
|
|
161
|
+
if (dynamic) {
|
|
162
|
+
appendDynamicImportModules(program, moduleOrder, (cycle, reason) => {
|
|
163
|
+
dynamicCycleDiags.push(unsupportedDiag("SC1016", { file: entry.fileName, start: 0, end: 0 }, `circular imports (${cycle}; ${reason})`));
|
|
164
|
+
});
|
|
165
|
+
}
|
|
151
166
|
const reachable = new Lowerer(program, entry, moduleOrder, dynamic, { targetPlatform }).discover(options.libRoots);
|
|
152
167
|
const emit = new Lowerer(program, entry, moduleOrder, dynamic, { reachable, targetPlatform, startupCrash });
|
|
168
|
+
for (const d of dynamicCycleDiags)
|
|
169
|
+
emit.pushDiag(d);
|
|
153
170
|
const result = emit.run();
|
|
154
171
|
if (options.coverage !== true)
|
|
155
172
|
return result;
|
|
@@ -265,7 +282,7 @@ export function neverTaintedJsType(L, node, t) {
|
|
|
265
282
|
};
|
|
266
283
|
return walk(t, 4);
|
|
267
284
|
}
|
|
268
|
-
/** The
|
|
285
|
+
/** The dyn undefined value — what an uninitialized checked-dynamic
|
|
269
286
|
* binding holds (JS: declared bindings read `undefined` before any
|
|
270
287
|
* assignment). A NULL dyn slot is a trap, never a value, so every dyn
|
|
271
288
|
* binding that is READABLE before its first assignment must start here:
|
|
@@ -332,10 +349,10 @@ export function ladderFenceExpr(L, surface, node, hint) {
|
|
|
332
349
|
* only unmappable pieces are `any` (`(value: any) => value is string` —
|
|
333
350
|
* the arrow the binding holds lowers those params to dyn, so the binding
|
|
334
351
|
* keeps its func-ness with the same per-piece fallback). The honest
|
|
335
|
-
* static subset of `any` is a binding whose VALUES are
|
|
352
|
+
* static subset of `any` is a binding whose VALUES are dyn-representable:
|
|
336
353
|
* the binding is 'unknown' storage with the boundary conversions
|
|
337
354
|
* coerceToExpected already applies (dynFrom into the slot, validated
|
|
338
|
-
* dynCheck out) and per-site SC2011 fences for the operations the
|
|
355
|
+
* dynCheck out) and per-site SC2011 fences for the operations the checked-dynamic tree
|
|
339
356
|
* cannot carry JS-exactly (the island still lifts those). Every OTHER
|
|
340
357
|
* unmappable TS type keeps its own diagnostic — annotations exist there,
|
|
341
358
|
* and the fence names the real blocker. `--dynamic` builds never reach
|
|
@@ -359,8 +376,8 @@ export function dynFallbackType(L, node, t) {
|
|
|
359
376
|
((elem.flags & ts.TypeFlags.Never) !== 0 || neverTaintedJsType(L, node, elem));
|
|
360
377
|
const mappedElem = elem !== undefined && !elemTainted ? L.mapTypeOf(elem) : null;
|
|
361
378
|
// A mappable element keeps the static array; an unmappable one makes
|
|
362
|
-
// the WHOLE value dyn (the
|
|
363
|
-
// read through the keyed-
|
|
379
|
+
// the WHOLE value dyn (the checked-dynamic tree has real arrays — length/index/push
|
|
380
|
+
// read through the keyed-dyn paths; dyn-element STATIC arrays have no
|
|
364
381
|
// backend representation).
|
|
365
382
|
if (mappedElem)
|
|
366
383
|
return { kind: "array", elem: mappedElem };
|
|
@@ -583,6 +600,13 @@ export class Lowerer {
|
|
|
583
600
|
/** Synthetic array-HOF loop functions (map/filter/forEach desugar),
|
|
584
601
|
* interned per method + element/callback-result type: key → fn name. */
|
|
585
602
|
arrHofHelpers = new Map();
|
|
603
|
+
/** Emit-override specializations (`%C.emit:<event>` — lower-emitter.ts's
|
|
604
|
+
* emit-overrides block): interned names, the drive-loop queue, and the
|
|
605
|
+
* currently-lowering specialization's context (the super-forward
|
|
606
|
+
* interception reads it). */
|
|
607
|
+
emitSpecDone = new Set();
|
|
608
|
+
emitSpecQueue = [];
|
|
609
|
+
emitSpecCtx = null;
|
|
586
610
|
/** Width-coercion helpers (%rec.width.N / %arr.width.N), interned per
|
|
587
611
|
* (from, to) shape pair — see widthCoerce. */
|
|
588
612
|
widthHelpers = new Map();
|
|
@@ -704,6 +728,12 @@ export class Lowerer {
|
|
|
704
728
|
* `fileName\u0000specifier` (collectDynamicImports fills it during npm
|
|
705
729
|
* collection; lowerDynamicImportCall reads it per site). */
|
|
706
730
|
dynImports = new Map();
|
|
731
|
+
/** createRequire-require resolutions of BARE npm specifiers, keyed
|
|
732
|
+
* `fileName\u0000specifier` (collectCreateRequires fills it during npm
|
|
733
|
+
* collection under --dynamic — the require-condition entry key plus its
|
|
734
|
+
* embedded format; lowerCreateRequireCall reads it per site; "" marks a
|
|
735
|
+
* failed resolution already reported at collection). */
|
|
736
|
+
createRequireImports = new Map();
|
|
707
737
|
/** Module → the name of its synthesized namespace-BUILDER function
|
|
708
738
|
* (lowerOwnModuleImport): every `import()` of the same program module
|
|
709
739
|
* shares one builder. */
|
|
@@ -892,16 +922,12 @@ export class Lowerer {
|
|
|
892
922
|
// lowering, long after the constructor completes.
|
|
893
923
|
isProgramFile: (sf) => this.fileTag.has(sf),
|
|
894
924
|
};
|
|
895
|
-
// --dynamic: modules reachable only through dynamic import()
|
|
896
|
-
//
|
|
897
|
-
//
|
|
898
|
-
//
|
|
899
|
-
//
|
|
900
|
-
|
|
901
|
-
appendDynamicImportModules(program, this.moduleOrder, (cycle) => {
|
|
902
|
-
this.pushDiag(unsupportedDiag("SC1016", { file: entry.fileName, start: 0, end: 0 }, `circular imports (${cycle})`));
|
|
903
|
-
});
|
|
904
|
-
}
|
|
925
|
+
// --dynamic: modules reachable only through dynamic import() joined
|
|
926
|
+
// moduleOrder BEFORE any pass constructed — lowerToIr runs
|
|
927
|
+
// appendDynamicImportModules once on the shared array (a per-pass run
|
|
928
|
+
// here minted cycle refusals into the DISCOVERY pass, whose
|
|
929
|
+
// diagnostics are discarded by design, and the extended order left
|
|
930
|
+
// nothing for the emit pass to re-detect).
|
|
905
931
|
this.moduleOrder.forEach((sf, i) => {
|
|
906
932
|
this.fileTag.set(sf, sf === entry ? "" : `%m${i}.`);
|
|
907
933
|
});
|
|
@@ -1410,9 +1436,11 @@ export class Lowerer {
|
|
|
1410
1436
|
let ec = 0;
|
|
1411
1437
|
let gc = 0;
|
|
1412
1438
|
let gi = 0;
|
|
1439
|
+
let es = 0;
|
|
1413
1440
|
while (ec < this.exprClasses.length ||
|
|
1414
1441
|
gc < this.genericClassInstances.length ||
|
|
1415
|
-
gi < this.instantiationQueue.length
|
|
1442
|
+
gi < this.instantiationQueue.length ||
|
|
1443
|
+
es < this.emitSpecQueue.length) {
|
|
1416
1444
|
while (ec < this.exprClasses.length) {
|
|
1417
1445
|
functions.push(...this.lowerClassMembers(this.exprClasses[ec++]));
|
|
1418
1446
|
}
|
|
@@ -1433,6 +1461,20 @@ export class Lowerer {
|
|
|
1433
1461
|
throw e;
|
|
1434
1462
|
}
|
|
1435
1463
|
}
|
|
1464
|
+
// Emit-override specializations queued by the emit sites above (a
|
|
1465
|
+
// body can queue more — the super-forward chain — and generic
|
|
1466
|
+
// instances of its own; the joint fixpoint covers both).
|
|
1467
|
+
while (es < this.emitSpecQueue.length) {
|
|
1468
|
+
try {
|
|
1469
|
+
const fn = lowerEmitOverrideSpec(this, this.emitSpecQueue[es++]);
|
|
1470
|
+
if (fn)
|
|
1471
|
+
functions.push(fn);
|
|
1472
|
+
}
|
|
1473
|
+
catch (e) {
|
|
1474
|
+
if (!(e instanceof PoisonError))
|
|
1475
|
+
throw e;
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1436
1478
|
}
|
|
1437
1479
|
}
|
|
1438
1480
|
// Lambdas lifted while lowering any of the above (plus synthetic
|
|
@@ -1750,9 +1792,11 @@ export class Lowerer {
|
|
|
1750
1792
|
// the joint fixpoint).
|
|
1751
1793
|
let instLowered = 0;
|
|
1752
1794
|
let clsInstLowered = 0;
|
|
1795
|
+
let specLowered = 0;
|
|
1753
1796
|
const drainInstances = () => {
|
|
1754
1797
|
while (instLowered < this.instantiationQueue.length ||
|
|
1755
|
-
clsInstLowered < this.genericClassInstances.length
|
|
1798
|
+
clsInstLowered < this.genericClassInstances.length ||
|
|
1799
|
+
specLowered < this.emitSpecQueue.length) {
|
|
1756
1800
|
while (instLowered < this.instantiationQueue.length) {
|
|
1757
1801
|
const { info, inst } = this.instantiationQueue[instLowered++];
|
|
1758
1802
|
// Body-level poisons skip the instance here too (the emit pass
|
|
@@ -1769,6 +1813,18 @@ export class Lowerer {
|
|
|
1769
1813
|
while (clsInstLowered < this.genericClassInstances.length) {
|
|
1770
1814
|
this.lowerClassMembers(this.genericClassInstances[clsInstLowered++]);
|
|
1771
1815
|
}
|
|
1816
|
+
// Emit-override specialization bodies fire edges of their own
|
|
1817
|
+
// (the super-forward chain, closures, generic calls) — lower them
|
|
1818
|
+
// for discovery exactly like generic instances.
|
|
1819
|
+
while (specLowered < this.emitSpecQueue.length) {
|
|
1820
|
+
try {
|
|
1821
|
+
lowerEmitOverrideSpec(this, this.emitSpecQueue[specLowered++]);
|
|
1822
|
+
}
|
|
1823
|
+
catch (e) {
|
|
1824
|
+
if (!(e instanceof PoisonError))
|
|
1825
|
+
throw e;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1772
1828
|
}
|
|
1773
1829
|
};
|
|
1774
1830
|
parts.forEach((fp) => {
|
|
@@ -2261,7 +2317,7 @@ export class Lowerer {
|
|
|
2261
2317
|
// The reverse — a TYPED value flowing into an 'unknown' slot
|
|
2262
2318
|
// (`const u: unknown = 5`, an unknown-typed param/return) — IS tsc-clean
|
|
2263
2319
|
// and rejected here: a typed value has no dynamic representation
|
|
2264
|
-
// (constructing a
|
|
2320
|
+
// (constructing a dyn from static values is deliberately out this
|
|
2265
2321
|
// round; only JSON.parse results are dyn).
|
|
2266
2322
|
if (actual.kind === "dyn") {
|
|
2267
2323
|
this.unsupported("SC1100", node, `passing 'unknown' values where '${this.fmt(expected)}' is expected`);
|
|
@@ -2370,8 +2426,8 @@ export class Lowerer {
|
|
|
2370
2426
|
}
|
|
2371
2427
|
// A CHECKED-DYNAMIC (dyn/'unknown') value entering the island (the
|
|
2372
2428
|
// `isJson ? JSON.parse(text) : islandParser(text)` config ternary):
|
|
2373
|
-
// the
|
|
2374
|
-
//
|
|
2429
|
+
// the dyn tree deep-copies into engine values — data kinds only; a
|
|
2430
|
+
// dyn carrying a boxed function/handle/promise throws the catchable
|
|
2375
2431
|
// TypeError at runtime (trust-but-verify, like every boundary).
|
|
2376
2432
|
if (expr.type.kind === "dyn") {
|
|
2377
2433
|
return { kind: "jsMarshal", value: expr, type: JSVAL, loc: expr.loc };
|
|
@@ -2404,21 +2460,35 @@ export class Lowerer {
|
|
|
2404
2460
|
return expr;
|
|
2405
2461
|
}
|
|
2406
2462
|
if (expr.type.kind === "jsval" && expected.kind !== "jsval") {
|
|
2407
|
-
// The jsval→
|
|
2463
|
+
// The jsval→dyn crossing (the world unification's engine-handle
|
|
2408
2464
|
// kind): an 'any'-typed engine value flowing into an 'unknown'/
|
|
2409
|
-
// 'object'/JS-residue slot wraps BY REFERENCE as the
|
|
2410
|
-
// kind — engine scalars normalize to native
|
|
2411
|
-
// typeof/truthiness/String()/=== route to the engine, un-armed
|
|
2465
|
+
// 'object'/JS-residue slot wraps BY REFERENCE as the checked-dynamic tree's island
|
|
2466
|
+
// kind — engine scalars normalize to native dyn kinds at wrap time,
|
|
2467
|
+
// typeof/truthiness/String()/=== route to the engine, un-armed dyn
|
|
2412
2468
|
// walks fence loudly, and the value unwraps back identity-preserved
|
|
2413
2469
|
// (scr_jsval_from_dyn). Monotone under evolution/widening: a value
|
|
2414
2470
|
// wraps once at its first dyn edge and stays valid through every
|
|
2415
2471
|
// subsequent dyn slot; narrowing never changes representation.
|
|
2416
2472
|
// This wrap RETIRES the silent-wrong-answer fence-closure box for
|
|
2417
|
-
// jsval members of
|
|
2473
|
+
// jsval members of dyn object literals (lowerDynObjectLiteral's
|
|
2418
2474
|
// coercion lands here first).
|
|
2419
2475
|
if (expected.kind === "dyn") {
|
|
2420
2476
|
return { kind: "dynFromJsval", value: expr, type: DYN, loc: expr.loc };
|
|
2421
2477
|
}
|
|
2478
|
+
// An island value flowing into a PROMISE-typed slot (the inferred
|
|
2479
|
+
// `loadPlugins` return — `Promise.all(...)` lowered engine-side
|
|
2480
|
+
// against a Promise<any[]> inference): the island→static promise
|
|
2481
|
+
// bridge — the engine promise settles a fresh static promise (void
|
|
2482
|
+
// fulfillments drop, `any[]`-declared fulfillments exit
|
|
2483
|
+
// Array.isArray-gated by reference at the settle, 'any' parks as an
|
|
2484
|
+
// island handle). Only inner shapes the bridge can deliver take the
|
|
2485
|
+
// arm; the rest keep the exit fence with the type named.
|
|
2486
|
+
if (expected.kind === "promise" &&
|
|
2487
|
+
(expected.inner.kind === "void" ||
|
|
2488
|
+
expected.inner.kind === "jsval" ||
|
|
2489
|
+
(expected.inner.kind === "array" && expected.inner.elem.kind === "jsval"))) {
|
|
2490
|
+
return { kind: "jsBridgePromise", value: expr, type: expected, loc: expr.loc };
|
|
2491
|
+
}
|
|
2422
2492
|
// The exit set: everything round-trippable, plus bare undefined-armed
|
|
2423
2493
|
// unions of JSON-safe data arms (the engine's undefined takes the
|
|
2424
2494
|
// undefined arm before the JSON detour) — canExitIslandToType.
|
|
@@ -2429,10 +2499,10 @@ export class Lowerer {
|
|
|
2429
2499
|
}
|
|
2430
2500
|
// A TYPED value flowing into an 'unknown' slot (`const u: unknown = 5`,
|
|
2431
2501
|
// an unknown-typed param/return, a dyn-valued index slot): the
|
|
2432
|
-
// static→
|
|
2502
|
+
// static→dyn conversion — dynFrom, a DEEP COPY (the jsMarshal aliasing
|
|
2433
2503
|
// stance intoIndexValueSlot documents; SEMANTICS.md). Bare
|
|
2434
|
-
// undefined/null literals store the
|
|
2435
|
-
//
|
|
2504
|
+
// undefined/null literals store the dyn unit values. Types outside the
|
|
2505
|
+
// dyn's domain (bytes, classes, Maps, ...) fall through to
|
|
2436
2506
|
// requireExactShape's SC1101 fence.
|
|
2437
2507
|
// A promise flowing into a VOID-promise slot (an inferred
|
|
2438
2508
|
// Promise<never> return holding a `return Promise.reject(value)` the
|
|
@@ -2520,7 +2590,7 @@ export class Lowerer {
|
|
|
2520
2590
|
// JS func-into-func mismatches ride the checked-dynamic function
|
|
2521
2591
|
// boundary: box the value (dynFrom), adapt to the slot (dynCheck) —
|
|
2522
2592
|
// the thunk delivers JS arity exactly (extras ignored, missing args
|
|
2523
|
-
// the undefined
|
|
2593
|
+
// the undefined dyn value), so `return _return` fits _mustCallInner's
|
|
2524
2594
|
// inferred (unknown) => unknown slot even though the wrapper declares
|
|
2525
2595
|
// (). JS files only: TypeScript signatures keep the exact-shape
|
|
2526
2596
|
// fences (a mismatch there is a compile-time story, not a boundary).
|
|
@@ -2828,7 +2898,7 @@ export class Lowerer {
|
|
|
2828
2898
|
* arr — array into array whose element pair lifts (per-element
|
|
2829
2899
|
* copy loop, arrayWidthHelper)
|
|
2830
2900
|
* dynIn — a typed value into an 'unknown' (dyn) slot — the same
|
|
2831
|
-
* static→
|
|
2901
|
+
* static→dyn deep copy coerceToExpected applies top-level
|
|
2832
2902
|
* upcast — a derived class instance into a base-typed slot (the
|
|
2833
2903
|
* prefix-layout pointer reinterpret, no copy)
|
|
2834
2904
|
* funcAdapt — a function into a slot whose signature differs only by
|
|
@@ -2838,7 +2908,7 @@ export class Lowerer {
|
|
|
2838
2908
|
widthLiftPlan(src, dst) {
|
|
2839
2909
|
if (typeEquals(src, dst))
|
|
2840
2910
|
return { how: "copy" };
|
|
2841
|
-
// An 'unknown' (dyn) DESTINATION slot: the static→
|
|
2911
|
+
// An 'unknown' (dyn) DESTINATION slot: the static→dyn conversion —
|
|
2842
2912
|
// dynFrom, a DEEP COPY (`{ v: 5 }` into `{ v: unknown }`, `number[]`
|
|
2843
2913
|
// into `unknown[]` — tsc's top type over the width family's copies).
|
|
2844
2914
|
if (dst.kind === "dyn" && src.kind !== "dyn" && this.dynConvertible(src)) {
|
|
@@ -3100,7 +3170,7 @@ export class Lowerer {
|
|
|
3100
3170
|
// A target field MISSING on the source: legal exactly when it is
|
|
3101
3171
|
// optional-flavored (an undefined-armed union) — the unset field
|
|
3102
3172
|
// IS the undefined arm, the same rule literal completion applies
|
|
3103
|
-
// — or 'unknown' (a dyn slot holds the
|
|
3173
|
+
// — or 'unknown' (a dyn slot holds the dyn undefined, exactly
|
|
3104
3174
|
// the absent-property read: the options-record call shape
|
|
3105
3175
|
// against `{ plugins: unknown, ... }`). Never for tuples: a
|
|
3106
3176
|
// completed position would change .length and JSON where Node
|
|
@@ -3256,7 +3326,7 @@ export class Lowerer {
|
|
|
3256
3326
|
fields: to.fields.map((f) => {
|
|
3257
3327
|
const lift = plan.get(f.name);
|
|
3258
3328
|
if ("absentDyn" in lift) {
|
|
3259
|
-
// The unset 'unknown' field: the
|
|
3329
|
+
// The unset 'unknown' field: the dyn undefined — exactly
|
|
3260
3330
|
// the absent-property read's answer.
|
|
3261
3331
|
return { name: f.name, value: dynUndefinedExpr(loc) };
|
|
3262
3332
|
}
|
|
@@ -3841,7 +3911,7 @@ export class Lowerer {
|
|
|
3841
3911
|
if (typeEquals(src, dst))
|
|
3842
3912
|
return true;
|
|
3843
3913
|
// The island boundary joins the mechanical set: values that MARSHAL
|
|
3844
|
-
// in (units, the checked-dynamic
|
|
3914
|
+
// in (units, the checked-dynamic deep copy, JSON-safe data, liftable
|
|
3845
3915
|
// composites, marshalable closures — coerceToExpected's jsval-IN
|
|
3846
3916
|
// block) and island handles whose exits VALIDATE (boundaryExitSafe) —
|
|
3847
3917
|
// the `defaultFallback(cfg) { return { login, id, scopes } }` shape,
|
|
@@ -3926,7 +3996,7 @@ export class Lowerer {
|
|
|
3926
3996
|
// never-called mismatched callback is exact; divergence 38's stance
|
|
3927
3997
|
// extended to calls).
|
|
3928
3998
|
// - voidRet "dyn"/"jsval": calling yields JS's undefined — the exact
|
|
3929
|
-
// undefined
|
|
3999
|
+
// undefined dyn/engine value after the call's effects.
|
|
3930
4000
|
// - voidRet "strand": a void result where the slot promises a typed
|
|
3931
4001
|
// value — the call runs (a `never` thrower never comes back, so the
|
|
3932
4002
|
// trap is unreachable there), then the stranded TypeError.
|
|
@@ -4711,7 +4781,7 @@ export class Lowerer {
|
|
|
4711
4781
|
return { kind: "call", callee: helper, args: [e], type: JSVAL, loc };
|
|
4712
4782
|
}
|
|
4713
4783
|
// Checked-dynamic values and marshalable closures ride jsMarshal
|
|
4714
|
-
// directly (the
|
|
4784
|
+
// directly (the checked-dynamic tree deep copy / the host-function wrap).
|
|
4715
4785
|
if (e.type.kind === "dyn" || e.type.kind === "func") {
|
|
4716
4786
|
return { kind: "jsMarshal", value: e, type: JSVAL, loc };
|
|
4717
4787
|
}
|
|
@@ -5152,9 +5222,9 @@ export class Lowerer {
|
|
|
5152
5222
|
}
|
|
5153
5223
|
// An OBJECT LITERAL against a checked-dynamic slot in a JS file (the
|
|
5154
5224
|
// getSupportInfo options argument — a dyn-ABI param): the value's
|
|
5155
|
-
// world IS the
|
|
5225
|
+
// world IS the checked-dynamic tree — build the dyn literal directly, before the
|
|
5156
5226
|
// island gate could claim the checker's `any` context (an island
|
|
5157
|
-
// build could never land in the slot: no engine→
|
|
5227
|
+
// build could never land in the slot: no engine→dyn crossing).
|
|
5158
5228
|
if (expected?.kind === "dyn") {
|
|
5159
5229
|
let x = node;
|
|
5160
5230
|
while (ts.isParenthesizedExpression(x))
|
|
@@ -5204,7 +5274,7 @@ export class Lowerer {
|
|
|
5204
5274
|
}
|
|
5205
5275
|
/** A value flowing into an index-signature VALUE slot (an overflow
|
|
5206
5276
|
* literal entry, a dynamic-keyed record write). dyn slots (`unknown`
|
|
5207
|
-
* signatures — ModelPricing's) take a
|
|
5277
|
+
* signatures — ModelPricing's) take a dyn conversion: dyn values pass
|
|
5208
5278
|
* through, JSON-safe static values convert with dynFrom (a deep copy —
|
|
5209
5279
|
* the jsMarshal aliasing stance), everything else keeps the dyn-boundary
|
|
5210
5280
|
* fence. Typed slots ride the ordinary coercion path (union slots wrap
|
|
@@ -5214,12 +5284,12 @@ export class Lowerer {
|
|
|
5214
5284
|
return this.coerceInto(node, value, indexValue);
|
|
5215
5285
|
if (value.type.kind === "dyn")
|
|
5216
5286
|
return value;
|
|
5217
|
-
// Bare `undefined`/`null` literals store the
|
|
5287
|
+
// Bare `undefined`/`null` literals store the dyn unit values (JS keeps
|
|
5218
5288
|
// the key; JSON.stringify drops an undefined-valued one, like Node).
|
|
5219
5289
|
if (value.kind === "unitLit") {
|
|
5220
5290
|
return { kind: "dynFrom", value, type: DYN, loc: value.loc };
|
|
5221
5291
|
}
|
|
5222
|
-
// An ISLAND ('any') value: the by-reference jsval→
|
|
5292
|
+
// An ISLAND ('any') value: the by-reference jsval→dyn wrap — the same
|
|
5223
5293
|
// edge coerceToExpected converts (dyn slots accept engine values).
|
|
5224
5294
|
if (value.type.kind === "jsval") {
|
|
5225
5295
|
return { kind: "dynFromJsval", value, type: DYN, loc: value.loc };
|
|
@@ -5235,13 +5305,13 @@ export class Lowerer {
|
|
|
5235
5305
|
withUndefinedArmOf(t) {
|
|
5236
5306
|
return withUndefinedArmCanonical(t, this.unions);
|
|
5237
5307
|
}
|
|
5238
|
-
/** True when a static type converts to a dyn
|
|
5239
|
-
* walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the
|
|
5308
|
+
/** True when a static type converts to a dyn value (the dynFrom
|
|
5309
|
+
* walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
|
|
5240
5310
|
* bytes kind, payload copied; stdin chunks into unknown-typed helpers),
|
|
5241
5311
|
* an undefined-armed union whose other arms are JSON-safe — the
|
|
5242
|
-
* undefined arm becomes the undefined
|
|
5312
|
+
* undefined arm becomes the undefined dyn singleton — or a BOXABLE
|
|
5243
5313
|
* function type (the checked-dynamic function boundary: the closure
|
|
5244
|
-
* crosses as the
|
|
5314
|
+
* crosses as the checked-dynamic tree's callable kind, identity preserved). */
|
|
5245
5315
|
dynConvertible(t) {
|
|
5246
5316
|
return canConvertToDyn(t, (id) => this.shapes.get(id), (id) => this.unions.get(id));
|
|
5247
5317
|
}
|
|
@@ -5744,7 +5814,7 @@ export class Lowerer {
|
|
|
5744
5814
|
if (abi.kind === "dyn" || abi.kind === "jsval") {
|
|
5745
5815
|
// A DYNAMIC-TIER pattern source (`function f({} = a)` with
|
|
5746
5816
|
// `a: any` — jsval for island values, dyn for the checked-
|
|
5747
|
-
// dynamic
|
|
5817
|
+
// dynamic dyn): the slot holds its tier's undefined directly,
|
|
5748
5818
|
// so the default test is the runtime undefined test — then
|
|
5749
5819
|
// the pattern destructures the picked value.
|
|
5750
5820
|
const dflt = this.lowerExprExpecting(decl.initializer, abi);
|
|
@@ -5812,7 +5882,7 @@ export class Lowerer {
|
|
|
5812
5882
|
if (abi.kind === "dyn" || abi.kind === "jsval") {
|
|
5813
5883
|
// A DYNAMIC-TIER defaulted param (`function f(x = a)` with
|
|
5814
5884
|
// `a: any` — jsval for island values, dyn for the checked-
|
|
5815
|
-
// dynamic
|
|
5885
|
+
// dynamic dyn): the slot holds its tier's undefined directly —
|
|
5816
5886
|
// the body local picks the default on the runtime test.
|
|
5817
5887
|
const loc = locOf(decl);
|
|
5818
5888
|
const slot = this.declareHiddenLocal(name, abi);
|
|
@@ -5997,7 +6067,7 @@ export class Lowerer {
|
|
|
5997
6067
|
continue;
|
|
5998
6068
|
// dyn captures ride an UNTRACED obj-box (scr_dyn_retain_v/release_v
|
|
5999
6069
|
// — boxNewC): the mustCall wrapper closing over its implicit-any
|
|
6000
|
-
// `fn` param. A
|
|
6070
|
+
// `fn` param. A dyn tree is pure data except the function kind,
|
|
6001
6071
|
// whose closure edge the collector never sees — cycles through a
|
|
6002
6072
|
// captured dyn are uncollectable (leak, never dangle: trial
|
|
6003
6073
|
// deletion treats untraced edges as external roots). SEMANTICS.md.
|
|
@@ -6311,7 +6381,12 @@ export class Lowerer {
|
|
|
6311
6381
|
// out-of-block read would split the variable in two) — vars take the
|
|
6312
6382
|
// standard path and its own fences.
|
|
6313
6383
|
(ts.getCombinedNodeFlags(decl) & ts.NodeFlags.BlockScoped) !== 0 &&
|
|
6314
|
-
islandCandidate(decl.initializer)
|
|
6384
|
+
islandCandidate(decl.initializer) &&
|
|
6385
|
+
// createRequire's plumbing decls are COMPILE-TIME erasures (the
|
|
6386
|
+
// require binding and its builtin-namespace bindings) — never
|
|
6387
|
+
// island values; the standard path's skips own them.
|
|
6388
|
+
!createRequireBindingDecl(this, decl.name, decl.initializer) &&
|
|
6389
|
+
!createRequireNamespaceDecl(this, decl.name, decl.initializer)) {
|
|
6315
6390
|
const mapped = this.mapTypeOf(this.typeOf(decl.name));
|
|
6316
6391
|
const handleOnly = mapped === null ||
|
|
6317
6392
|
(mapped.kind !== "jsval" &&
|
|
@@ -6327,7 +6402,7 @@ export class Lowerer {
|
|
|
6327
6402
|
// The CHECKED-DYNAMIC twin of the handle rescue (the runtime-world
|
|
6328
6403
|
// local rule): an unmappable declared type over a dyn initializer
|
|
6329
6404
|
// (`const first = plugins[0]` — the checker spells 'string |
|
|
6330
|
-
// object' while the read is a
|
|
6405
|
+
// object' while the read is a dyn keyed read) keeps the binding
|
|
6331
6406
|
// dyn; typed use sites ride validated extractions and the routed
|
|
6332
6407
|
// engine ops, exactly the JSON.parse-binding story.
|
|
6333
6408
|
if (mapped === null && init.type.kind === "dyn") {
|
|
@@ -6702,10 +6777,21 @@ export class Lowerer {
|
|
|
6702
6777
|
if (!decl)
|
|
6703
6778
|
return null;
|
|
6704
6779
|
// The CommonJS twin: `const fs = require("fs")` binds the same
|
|
6705
|
-
// namespace surface as `import * as fs from "node:fs"
|
|
6780
|
+
// namespace surface as `import * as fs from "node:fs"` — and the
|
|
6781
|
+
// createRequire spelling (`const fs = require("node:fs")` through a
|
|
6782
|
+
// createRequire binding, the fallback-typed cast idiom stripped)
|
|
6783
|
+
// binds it too.
|
|
6706
6784
|
if (ts.isVariableDeclaration(decl) && ts.isIdentifier(decl.name) && decl.initializer) {
|
|
6707
6785
|
const spec = requireSpecOf(decl.initializer);
|
|
6708
|
-
|
|
6786
|
+
if (spec !== null)
|
|
6787
|
+
return canonicalBuiltinModule(spec);
|
|
6788
|
+
const init = stripTypeCasts(decl.initializer);
|
|
6789
|
+
if (ts.isCallExpression(init)) {
|
|
6790
|
+
const cr = createRequireSpecOf(this, init);
|
|
6791
|
+
if (cr !== null && cr.spec !== null)
|
|
6792
|
+
return canonicalBuiltinModule(cr.spec);
|
|
6793
|
+
}
|
|
6794
|
+
return null;
|
|
6709
6795
|
}
|
|
6710
6796
|
// A DESTRUCTURED sub-namespace binding — `const { promises } =
|
|
6711
6797
|
// fs` / `= require('fs')`: the member is itself a supported module
|
|
@@ -6738,6 +6824,17 @@ export class Lowerer {
|
|
|
6738
6824
|
if (spec !== null)
|
|
6739
6825
|
return canonicalBuiltinModule(spec);
|
|
6740
6826
|
}
|
|
6827
|
+
// The createRequire spelling of the same inline form:
|
|
6828
|
+
// `require("node:path").join(...)` through a createRequire binding
|
|
6829
|
+
// (the fallback-typed cast idiom strips: `(require("x") as T).m`).
|
|
6830
|
+
{
|
|
6831
|
+
const inner = stripTypeCasts(expr);
|
|
6832
|
+
if (ts.isCallExpression(inner)) {
|
|
6833
|
+
const cr = createRequireSpecOf(this, inner);
|
|
6834
|
+
if (cr !== null && cr.spec !== null)
|
|
6835
|
+
return canonicalBuiltinModule(cr.spec);
|
|
6836
|
+
}
|
|
6837
|
+
}
|
|
6741
6838
|
if (ts.isIdentifier(expr)) {
|
|
6742
6839
|
const symbol = this.checker.getSymbolAtLocation(expr);
|
|
6743
6840
|
const decl = symbol ? this.checker.declarationsOf(symbol)[0] : undefined;
|
|
@@ -6884,6 +6981,11 @@ export class Lowerer {
|
|
|
6884
6981
|
const c = builtinModuleConstOf(this, bi.module, bi.member);
|
|
6885
6982
|
if (c !== undefined)
|
|
6886
6983
|
return builtinConstLit(c, loc);
|
|
6984
|
+
// module.builtinModules through a namespace binding — the baked
|
|
6985
|
+
// Node v24 list, a fresh string[] per read.
|
|
6986
|
+
if (bi.module === "module" && bi.member === "builtinModules") {
|
|
6987
|
+
return builtinModulesArrayLit(loc);
|
|
6988
|
+
}
|
|
6887
6989
|
if (bi.member === "constants" && bi.module === "fs") {
|
|
6888
6990
|
// A bare `fs.constants` read (not one of the baked bits above).
|
|
6889
6991
|
this.noLowering(`fs.constants`, expr, "F_OK, R_OK, W_OK, and X_OK are the lowered constants");
|