@scriptc/compiler 0.2.0 → 0.2.1
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 +25 -15
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/llvm/classes.js +21 -5
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +5 -0
- package/dist/backend/llvm/dyn.js +166 -99
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +2 -2
- package/dist/backend/llvm/emitter.js +79 -20
- 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 +28 -17
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +1 -1
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +18 -9
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +11 -1
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +11 -3
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +125 -17
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +23 -3
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +45 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/shapes.js +8 -2
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +3 -6
- package/dist/backend/native-toolchain.js +53 -23
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +72 -0
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-native.js +4 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.test.js +1 -1
- package/dist/backend/targets.js +10 -6
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +7 -0
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/compat/fetch-profile.js +34 -4
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +2 -7
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
- package/dist/frontend/lowering/class-callbacks.js +26 -15
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +12 -0
- package/dist/frontend/lowering/class-construction.js +156 -0
- package/dist/frontend/lowering/class-construction.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +1 -0
- package/dist/frontend/lowering/class-descriptors.js +46 -5
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +11 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +403 -48
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +2 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +4 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.d.ts +4 -1
- package/dist/frontend/lowering/class-method-values.js +72 -7
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +5 -2
- package/dist/frontend/lowering/class-prototypes.js +121 -13
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
- package/dist/frontend/lowering/class-runtime-statics.js +66 -0
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +49 -13
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +19 -47
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/error-methods.d.ts +4 -1
- package/dist/frontend/lowering/error-methods.js +100 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js +3 -1
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +19 -11
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +38 -7
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
- package/dist/frontend/lowering/expressions/optional-chains.js +69 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/function-context.d.ts +11 -3
- package/dist/frontend/lowering/function-context.js +11 -5
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +39 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.d.ts +2 -0
- package/dist/frontend/lowering/lib-boundary.js +54 -1
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -1
- package/dist/frontend/lowering/lower-builtin-values.js +113 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +6 -5
- package/dist/frontend/lowering/lower-builtins.js +156 -41
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +8 -5
- package/dist/frontend/lowering/lower-calls.js +448 -83
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +13 -13
- package/dist/frontend/lowering/lower-classes.js +650 -176
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +9 -0
- package/dist/frontend/lowering/lower-containers.js +135 -36
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +3 -2
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +2 -2
- package/dist/frontend/lowering/lower-exprs.js +531 -126
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +12 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +2 -0
- package/dist/frontend/lowering/lower-island.js +32 -10
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +220 -17
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-modules.test.js +39 -0
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
- package/dist/frontend/lowering/lower-stmts.d.ts +7 -3
- package/dist/frontend/lowering/lower-stmts.js +135 -26
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +1 -1
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +27 -1
- package/dist/frontend/lowering/lowerer.js +172 -50
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +149 -3
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +2 -0
- package/dist/frontend/lowering/surfaces.js +25 -8
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.d.ts +2 -0
- package/dist/frontend/lowering/text-decoder-encoding.js +5 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
- package/dist/frontend/lowering/unregistered-class-types.test.js +3 -3
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +116 -34
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +8 -0
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/program.d.ts +1 -1
- package/dist/frontend/program.js +53 -24
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +18 -0
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/ts7/ast.js +4 -3
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.js +5 -10
- package/dist/frontend/ts7/semantic-json.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +9 -1
- package/dist/frontend/type-mapper.js +90 -13
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +23 -0
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend/union-discriminants.d.ts +1 -1
- package/dist/frontend/union-discriminants.js +2 -2
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/ir/analysis.js +2 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/ir.d.ts +52 -33
- package/dist/ir/ir.js +142 -42
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +35 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/serialize.js +15 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +5 -1
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/validate.js +80 -11
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +61 -1
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/native/sanitizer.js +3 -1
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/toolchain.d.ts +1 -1
- package/dist/native/toolchain.js +26 -6
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +53 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +56 -81
|
@@ -7,6 +7,7 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
7
7
|
import { builtinModules } from "node:module";
|
|
8
8
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
9
9
|
import * as ts from "../ts7/adapter.js";
|
|
10
|
+
import { lowerCheckedPredicateValue } from "./lower-builtin-values.js";
|
|
10
11
|
import { PoisonError, dynUndefinedExpr, ladderFenceExpr, nodeThrowExpr, own } from "./lowerer.js";
|
|
11
12
|
import { canonicalBuiltinModule, isCreateRequireBinding7, isJsSourceFile, isNodeEsmFile, locOf, npmStaticDepSf7, requireSpecOf, resolveImport } from "../program.js";
|
|
12
13
|
import { isRelativeSpecifier } from "../workspace-registry.js";
|
|
@@ -480,7 +481,7 @@ export function createRequireProgramModuleOf(lowerer, expr) {
|
|
|
480
481
|
const cr = createRequireSpecOf(lowerer, call);
|
|
481
482
|
if (cr === null || cr.spec === null || canonicalBuiltinModule(cr.spec) !== null)
|
|
482
483
|
return null;
|
|
483
|
-
const dep = resolveImport(lowerer.program, cr.baseFile, cr.spec) ??
|
|
484
|
+
const dep = resolveImport(lowerer.program, cr.baseFile, cr.spec, "require") ??
|
|
484
485
|
npmStaticDepSf7(lowerer.program, cr.baseFile, cr.spec, "require");
|
|
485
486
|
if (dep === null || dep.fileName.endsWith(".json"))
|
|
486
487
|
return null;
|
|
@@ -1161,6 +1162,9 @@ export function lowerFsToUnixTimestampCall(lowerer, expr, bi, loc) {
|
|
|
1161
1162
|
* after every validation passes, exactly Node's order. Null when this
|
|
1162
1163
|
* is not a claimed member/shape (the table or fence path stands). */
|
|
1163
1164
|
export function lowerFsLadderCall(lowerer, expr, bi, loc) {
|
|
1165
|
+
if (bi.module === "fs" && bi.member !== "rename" && builtinModuleFnOf(lowerer, bi.module, bi.member)?.fn === "fs.callbackCall") {
|
|
1166
|
+
return lowerer.lowerBuiltinModuleCall(expr, bi, { fn: "fs.callbackCall", params: [], result: DYN }, loc);
|
|
1167
|
+
}
|
|
1164
1168
|
if (bi.module !== "fs" && bi.module !== "fs/promises")
|
|
1165
1169
|
return null;
|
|
1166
1170
|
if (!isJsSourceFile(expr.getSourceFile()))
|
|
@@ -1410,6 +1414,12 @@ function lowerZlibModuleCall(lowerer, expr, bi, loc) {
|
|
|
1410
1414
|
}
|
|
1411
1415
|
export function lowerBuiltinModuleCall(lowerer, expr, bi, fn, loc) {
|
|
1412
1416
|
const name = expr.expression.getText();
|
|
1417
|
+
if (fn.fn === "fs.callbackCall" && bi.member !== "rename") {
|
|
1418
|
+
if (expr.arguments.some(ts.isSpreadElement))
|
|
1419
|
+
lowerer.noLowering("filesystem callback call with spread arguments", expr);
|
|
1420
|
+
const args = { kind: "dynArrLit", elems: expr.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc };
|
|
1421
|
+
return { kind: "libCall", fn: "fs.callbackCall", args: [{ kind: "strLit", value: bi.member, type: STRING, loc }, args], type: DYN, loc };
|
|
1422
|
+
}
|
|
1413
1423
|
// Numeric open flags are interpreted symbolically at the call site. The
|
|
1414
1424
|
// O_* bit values differ between Darwin and Linux, so emit a stable mask
|
|
1415
1425
|
// and let the target runtime select its own native constants.
|
|
@@ -2318,15 +2328,20 @@ export function lowerBuiltinModuleCall(lowerer, expr, bi, fn, loc) {
|
|
|
2318
2328
|
}
|
|
2319
2329
|
return { kind: "libCall", fn: fn.fn, args, type: fn.result, loc };
|
|
2320
2330
|
}
|
|
2321
|
-
/** Reflect.
|
|
2331
|
+
/** Reflect.ownKeys uses native computed-key reflection. Reflect.apply(target,
|
|
2332
|
+
* thisArg, argsList) where the TARGET is a builtin
|
|
2322
2333
|
* rest-parameter table fn (path.join / path.resolve — test/common
|
|
2323
2334
|
* fixtures.js's fixturesPath forwards its rest args exactly this way):
|
|
2324
2335
|
* the packed libCall over a validated string[] extraction of argsList.
|
|
2325
2336
|
* The builtins ignore the receiver, so thisArg must be an effect-free
|
|
2326
2337
|
* spelling (`this`, an identifier, a unit literal) whose dropped
|
|
2327
2338
|
* evaluation is unobservable; every other Reflect.apply keeps the
|
|
2328
|
-
* fence. Null when this isn't a Reflect
|
|
2329
|
-
export function
|
|
2339
|
+
* fence. Null when this isn't a supported Reflect call. */
|
|
2340
|
+
export function lowerReflectCall(lowerer, call, access) {
|
|
2341
|
+
if (!call.questionDotToken && !access.questionDotToken && lowerer.stdlibGlobalMember(access, "Reflect") === "ownKeys" &&
|
|
2342
|
+
call.arguments.length === 1 && !ts.isSpreadElement(call.arguments[0])) {
|
|
2343
|
+
return { kind: "libCall", fn: "dyn.ownKeys", args: [lowerer.lowerExprExpecting(call.arguments[0], DYN)], type: DYN, loc: locOf(call) };
|
|
2344
|
+
}
|
|
2330
2345
|
if (call.questionDotToken)
|
|
2331
2346
|
return null;
|
|
2332
2347
|
if (lowerer.stdlibGlobalMember(access, "Reflect") !== "apply")
|
|
@@ -2340,7 +2355,10 @@ export function lowerReflectApplyCall(lowerer, call, access) {
|
|
|
2340
2355
|
const bi = ts.isPropertyAccessExpression(targetNode) ? lowerer.builtinMemberOf(targetNode) : null;
|
|
2341
2356
|
const fn = bi ? builtinModuleFnOf(lowerer, bi.module, bi.member) : null;
|
|
2342
2357
|
if (!fn || fn.variadicPack !== true) {
|
|
2343
|
-
|
|
2358
|
+
const target = lowerer.lowerExprExpecting(targetNode, DYN);
|
|
2359
|
+
const receiver = lowerer.lowerExprExpecting(call.arguments[1], DYN);
|
|
2360
|
+
const argumentsList = lowerer.lowerExprExpecting(call.arguments[2], DYN);
|
|
2361
|
+
return { kind: "libCall", fn: "dyn.reflectApply", args: [target, receiver, argumentsList], type: DYN, loc };
|
|
2344
2362
|
}
|
|
2345
2363
|
const thisNode = call.arguments[1];
|
|
2346
2364
|
const effectFree = thisNode.kind === ts.SyntaxKind.ThisKeyword ||
|
|
@@ -2524,8 +2542,8 @@ export function lowerSpawnSyncCall(lowerer, expr, loc) {
|
|
|
2524
2542
|
};
|
|
2525
2543
|
}
|
|
2526
2544
|
/** `spawn(command, args?, options)` → one cp.spawn / cp.spawnOpts
|
|
2527
|
-
* libCall.
|
|
2528
|
-
*
|
|
2545
|
+
* libCall. Computed options use native runtime normalization. Inline
|
|
2546
|
+
* stdio accepts "ignore", "inherit", or "pipe" as the scalar,
|
|
2529
2547
|
* or the 3-tuple whose stdin pipe becomes child.stdin, stdout/stderr
|
|
2530
2548
|
* pipes become child.stdout/child.stderr, and output slots may also be
|
|
2531
2549
|
* number fds. Omitting stdio uses Node's default: all three piped. The
|
|
@@ -2559,7 +2577,11 @@ export function lowerSpawnCall(lowerer, expr, loc) {
|
|
|
2559
2577
|
optsNode = second;
|
|
2560
2578
|
}
|
|
2561
2579
|
if (optsNode !== undefined && !ts.isObjectLiteralExpression(optsNode)) {
|
|
2562
|
-
|
|
2580
|
+
return {
|
|
2581
|
+
kind: "libCall", fn: "cp.spawnDynamic",
|
|
2582
|
+
args: [cmd, lowerer.lowerChildArgsArg(argsNode, loc), lowerer.lowerExprExpecting(optsNode, DYN)],
|
|
2583
|
+
type: CHILD_T, loc,
|
|
2584
|
+
};
|
|
2563
2585
|
}
|
|
2564
2586
|
const emptyStr = { kind: "strLit", value: "", type: STRING, loc };
|
|
2565
2587
|
// Per-slot stdio modes (scr_child.c: 0 ignore, 1 inherit, 2 fd) and
|
|
@@ -4312,6 +4334,18 @@ export function lowerJsonMethodCall(lowerer, call, access) {
|
|
|
4312
4334
|
return { kind: "libCall", fn: "json.parseReviver", args: [text, callback], type: DYN, loc };
|
|
4313
4335
|
}
|
|
4314
4336
|
if (member === "stringify") {
|
|
4337
|
+
const replacerNode = call.arguments[1];
|
|
4338
|
+
const spaceNode = call.arguments[2];
|
|
4339
|
+
const runtimeOptions = replacerNode && !jsonNullishArgument(lowerer, replacerNode) &&
|
|
4340
|
+
lowerer.mapTypeOf(lowerer.typeOf(replacerNode))?.kind === "dyn" ||
|
|
4341
|
+
spaceNode && !jsonNullishArgument(lowerer, spaceNode) &&
|
|
4342
|
+
!ts.isNumericLiteral(spaceNode) && !ts.isStringLiteral(spaceNode) && !ts.isNoSubstitutionTemplateLiteral(spaceNode) &&
|
|
4343
|
+
!(ts.isPrefixUnaryExpression(spaceNode) && ts.isNumericLiteral(spaceNode.operand));
|
|
4344
|
+
if (runtimeOptions && call.arguments[0]) {
|
|
4345
|
+
const args = [0, 1, 2].map((index) => call.arguments[index]
|
|
4346
|
+
? lowerer.lowerExprExpecting(call.arguments[index], DYN) : dynUndefinedExpr(loc));
|
|
4347
|
+
return { kind: "libCall", fn: "json.stringifyValue", args, type: DYN, loc };
|
|
4348
|
+
}
|
|
4315
4349
|
const indent = stringifySpaceIndent(lowerer, call);
|
|
4316
4350
|
if (call.arguments.length === 0) {
|
|
4317
4351
|
return lowerer.wrappedUndefined(lowerer.withUndefinedArm(STRING), loc);
|
|
@@ -4516,6 +4550,12 @@ function jsonNullishArgument(lowerer, node) {
|
|
|
4516
4550
|
* refuse signatures that request one until that protocol is implemented. */
|
|
4517
4551
|
function lowerJsonCallback(lowerer, node, role) {
|
|
4518
4552
|
const callback = lowerer.lowerExpr(node);
|
|
4553
|
+
if (callback.type.kind === "dyn")
|
|
4554
|
+
return callback;
|
|
4555
|
+
if (callback.type.kind === "union" && lowerer.dynConvertible(callback.type) &&
|
|
4556
|
+
lowerer.unions.get(callback.type.unionId)?.arms.every((arm) => isUnitType(arm) || arm.kind === "func" &&
|
|
4557
|
+
arm.params.length <= 2 && (role !== "reviver" || (!arm.rest && !arm.argumentsAll))))
|
|
4558
|
+
return lowerer.coerceToExpected(callback, DYN);
|
|
4519
4559
|
if (callback.type.kind === "func" && callback.type.params.length <= 2 &&
|
|
4520
4560
|
(role !== "reviver" || (!callback.type.rest && !callback.type.argumentsAll)) &&
|
|
4521
4561
|
canBoxFuncIntoDyn(callback.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
@@ -4959,6 +4999,9 @@ export function lowerSearchParamsNew(lowerer, expr, loc) {
|
|
|
4959
4999
|
return acc;
|
|
4960
5000
|
}
|
|
4961
5001
|
const init = lowerer.lowerExpr(arg);
|
|
5002
|
+
if (init.type.kind === "dyn") {
|
|
5003
|
+
return { kind: "libCall", fn: "sp.newChecked", args: [init], type: SEARCH_PARAMS_T, loc };
|
|
5004
|
+
}
|
|
4962
5005
|
if (init.type.kind === "string") {
|
|
4963
5006
|
return { kind: "libCall", fn: "sp.parse", args: [init], type: SEARCH_PARAMS_T, loc };
|
|
4964
5007
|
}
|
|
@@ -5817,7 +5860,7 @@ export function lowerChildMethodCall(lowerer, call, access) {
|
|
|
5817
5860
|
if ((name === "on" || name === "once") && call.arguments.length === 2) {
|
|
5818
5861
|
const evT = lowerer.typeOf(call.arguments[0]);
|
|
5819
5862
|
const event = evT.isStringLiteralType() ? evT.value : null;
|
|
5820
|
-
if (event !== "exit" && event !== "close" && event !== "error" && event !== "message" && event !== "disconnect") {
|
|
5863
|
+
if (event !== "spawn" && event !== "exit" && event !== "close" && event !== "error" && event !== "message" && event !== "disconnect") {
|
|
5821
5864
|
lowerer.noLowering(`child.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, call.arguments[0], '"exit", "close", "error", "message", and "disconnect" are the supported child events (as literals)');
|
|
5822
5865
|
}
|
|
5823
5866
|
if (!ts.isExpressionStatement(call.parent)) {
|
|
@@ -5843,7 +5886,33 @@ export function lowerChildMethodCall(lowerer, call, access) {
|
|
|
5843
5886
|
loc,
|
|
5844
5887
|
};
|
|
5845
5888
|
}
|
|
5889
|
+
const listenerNode = stripTypeCasts(call.arguments[1]);
|
|
5890
|
+
if (isJsSourceFile(listenerNode.getSourceFile()) &&
|
|
5891
|
+
(ts.isArrowFunction(listenerNode) || ts.isFunctionExpression(listenerNode)) &&
|
|
5892
|
+
listenerNode.parameters.some((param) => param.dotDotDotToken) &&
|
|
5893
|
+
listenerNode.parameters.every((param) => !param.type) &&
|
|
5894
|
+
!/@(?:param|type)\b/.test(listenerNode.getSourceFile().text.slice(listenerNode.pos, listenerNode.getStart()))) {
|
|
5895
|
+
for (const param of listenerNode.parameters)
|
|
5896
|
+
lowerer.checkedCallbackParams.add(param);
|
|
5897
|
+
}
|
|
5846
5898
|
const cb = lowerer.lowerExpr(call.arguments[1]);
|
|
5899
|
+
if (cb.type.kind === "func" && cb.type.rest) {
|
|
5900
|
+
if (!canBoxFuncIntoDyn(cb.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
5901
|
+
lowerer.noLowering("child event rest listeners with non-representable parameters", call.arguments[1]);
|
|
5902
|
+
}
|
|
5903
|
+
return {
|
|
5904
|
+
kind: "libCall", fn: "child.onDyn",
|
|
5905
|
+
args: [receiver, { kind: "strLit", value: event, type: STRING, loc },
|
|
5906
|
+
{ kind: "dynFrom", value: cb, type: DYN, loc }],
|
|
5907
|
+
type: VOID, loc,
|
|
5908
|
+
};
|
|
5909
|
+
}
|
|
5910
|
+
if (event === "spawn") {
|
|
5911
|
+
if (cb.type.kind !== "func" || cb.type.params.length !== 0 || cb.type.ret.kind !== "void") {
|
|
5912
|
+
lowerer.noLowering("spawn event listeners with parameters or a returned value", call.arguments[1]);
|
|
5913
|
+
}
|
|
5914
|
+
return { kind: "libCall", fn: "child.onSpawn", args: [receiver, cb], type: VOID, loc };
|
|
5915
|
+
}
|
|
5847
5916
|
if (cb.type.kind !== "func" || cb.type.params.length > (event === "error" ? 1 : 2)) {
|
|
5848
5917
|
lowerer.unsupported("SC1090", call.arguments[1], event !== "error"
|
|
5849
5918
|
? `${event} listeners with more than two parameters (use (code, signal), (code), or ())`
|
|
@@ -5918,9 +5987,9 @@ export function lowerChildMethodCall(lowerer, call, access) {
|
|
|
5918
5987
|
// child.unref(): drops the child from the event loop's keep-alive set
|
|
5919
5988
|
// (the process may exit while the child runs — Node's semantics; the
|
|
5920
5989
|
// child is still reaped while the loop runs for other reasons).
|
|
5921
|
-
if (name === "unref" && call.arguments.length === 0) {
|
|
5990
|
+
if ((name === "unref" || name === "ref") && call.arguments.length === 0) {
|
|
5922
5991
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
5923
|
-
return { kind: "libCall", fn: "child.unref", args: [receiver], type: VOID, loc };
|
|
5992
|
+
return { kind: "libCall", fn: name === "ref" ? "child.ref" : "child.unref", args: [receiver], type: VOID, loc };
|
|
5924
5993
|
}
|
|
5925
5994
|
lowerer.noLowering(`ChildProcess.${name}`, call, "send(), connected, disconnect(), on/once(\"message\" | \"disconnect\" | \"exit\" | \"close\" | \"error\", cb), pid, exitCode, killed, kill(signal?), and unref() are supported", lowerer.checker.getSymbolAtLocation(access.name));
|
|
5926
5995
|
}
|
|
@@ -6259,10 +6328,10 @@ export function lowerFsConstantsProperty(lowerer, expr) {
|
|
|
6259
6328
|
const bi = lowerer.builtinImportOf(expr.expression);
|
|
6260
6329
|
if (!bi || bi.module !== "fs" || bi.member !== "constants")
|
|
6261
6330
|
return null;
|
|
6262
|
-
const MODES = { F_OK: 0, X_OK: 1, W_OK: 2, R_OK: 4 };
|
|
6331
|
+
const MODES = { F_OK: 0, X_OK: 1, W_OK: 2, R_OK: 4, COPYFILE_EXCL: 1, COPYFILE_FICLONE: 2, COPYFILE_FICLONE_FORCE: 4 };
|
|
6263
6332
|
const value = own(MODES, expr.name.text);
|
|
6264
6333
|
if (value === undefined) {
|
|
6265
|
-
lowerer.noLowering(`fs.constants.${expr.name.text}`, expr, "F_OK, R_OK, W_OK, and
|
|
6334
|
+
lowerer.noLowering(`fs.constants.${expr.name.text}`, expr, "F_OK, R_OK, W_OK, X_OK, and COPYFILE_* are the lowered constants");
|
|
6266
6335
|
}
|
|
6267
6336
|
return { kind: "numLit", value, type: F64, loc: locOf(expr) };
|
|
6268
6337
|
}
|
|
@@ -7777,7 +7846,7 @@ export function lowerDateCall(lowerer, call, access) {
|
|
|
7777
7846
|
export function lowerTextCodecNew(lowerer, ctor, cls) {
|
|
7778
7847
|
const args = ctor.arguments ?? [];
|
|
7779
7848
|
const loc = locOf(ctor);
|
|
7780
|
-
let encoding = -1;
|
|
7849
|
+
let encoding = { kind: "numLit", value: -1, type: F64, loc };
|
|
7781
7850
|
let label = null;
|
|
7782
7851
|
if (cls === "TextEncoder") {
|
|
7783
7852
|
if (args.length !== 0)
|
|
@@ -7786,17 +7855,39 @@ export function lowerTextCodecNew(lowerer, ctor, cls) {
|
|
|
7786
7855
|
else if (args.length !== 0) {
|
|
7787
7856
|
const labelT = lowerer.typeOf(args[0]);
|
|
7788
7857
|
const parsed = labelT.isStringLiteralType() ? staticTextDecoderEncoding(labelT.value) : null;
|
|
7789
|
-
if (args.length
|
|
7790
|
-
lowerer.noLowering("new TextDecoder with
|
|
7858
|
+
if (args.length > 2)
|
|
7859
|
+
lowerer.noLowering("new TextDecoder with extra arguments", ctor);
|
|
7860
|
+
if (parsed === null) {
|
|
7861
|
+
encoding = { kind: "libCall", fn: "text.decoderEncoding", args: [lowerer.lowerExprExpecting(args[0], DYN)], type: F64, loc };
|
|
7862
|
+
}
|
|
7863
|
+
else {
|
|
7864
|
+
encoding = { kind: "numLit", value: parsed.kind === "utf8" ? -1 : parsed.id, type: F64, loc };
|
|
7865
|
+
label = lowerer.lowerExprExpecting(args[0], STRING);
|
|
7866
|
+
}
|
|
7867
|
+
}
|
|
7868
|
+
const options = args[1] ? stripTypeCasts(args[1]) : null;
|
|
7869
|
+
const flags = new Map();
|
|
7870
|
+
for (const name of ["fatal", "ignoreBOM"])
|
|
7871
|
+
flags.set(name, { kind: "boolLit", value: false, type: BOOL, loc });
|
|
7872
|
+
if (options) {
|
|
7873
|
+
if (!ts.isObjectLiteralExpression(options))
|
|
7874
|
+
lowerer.noLowering("TextDecoder options outside an object literal", options);
|
|
7875
|
+
for (const property of options.properties) {
|
|
7876
|
+
if ((!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property)) ||
|
|
7877
|
+
!ts.isIdentifier(property.name) || !flags.has(property.name.text))
|
|
7878
|
+
lowerer.noLowering("unknown TextDecoder option", property);
|
|
7879
|
+
const value = ts.isPropertyAssignment(property) ? property.initializer : property.name;
|
|
7880
|
+
flags.set(property.name.text, lowerer.lowerExprExpecting(value, BOOL));
|
|
7791
7881
|
}
|
|
7792
|
-
encoding = parsed.kind === "utf8" ? -1 : parsed.id;
|
|
7793
|
-
label = lowerer.lowerExprExpecting(args[0], STRING);
|
|
7794
7882
|
}
|
|
7795
7883
|
const type = lowerer.mapTypeOf(lowerer.typeOf(ctor));
|
|
7796
7884
|
if (type?.kind !== "record")
|
|
7797
7885
|
lowerer.badType(ctor, lowerer.typeOf(ctor));
|
|
7798
7886
|
const result = {
|
|
7799
|
-
kind: "recordLit", fields: [{ name: `%${cls}`, value:
|
|
7887
|
+
kind: "recordLit", fields: [{ name: `%${cls}`, value: encoding }, ...(cls === "TextDecoder" ? [
|
|
7888
|
+
...[...flags].map(([name, value]) => ({ name: `%${name}`, value })),
|
|
7889
|
+
{ name: "%state", value: { kind: "dynObjLit", fields: [], type: DYN, loc } },
|
|
7890
|
+
] : [])], type, loc,
|
|
7800
7891
|
};
|
|
7801
7892
|
return label === null || label.kind === "strLit" ? result : {
|
|
7802
7893
|
kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: label, loc }], result, type, loc,
|
|
@@ -7814,17 +7905,32 @@ function lowerStoredTextCodecCall(lowerer, call, access) {
|
|
|
7814
7905
|
return null;
|
|
7815
7906
|
if (access.name.text !== (cls === "TextEncoder" ? "encode" : "decode"))
|
|
7816
7907
|
return null;
|
|
7817
|
-
if (call.arguments.length > 1) {
|
|
7818
|
-
lowerer.noLowering(cls
|
|
7908
|
+
if (call.arguments.length > (cls === "TextDecoder" ? 2 : 1)) {
|
|
7909
|
+
lowerer.noLowering(`${cls}.${access.name.text} with extra arguments`, call);
|
|
7819
7910
|
}
|
|
7820
7911
|
const loc = locOf(call);
|
|
7912
|
+
let stream = { kind: "boolLit", value: false, type: BOOL, loc };
|
|
7913
|
+
if (cls === "TextDecoder" && call.arguments[1]) {
|
|
7914
|
+
const options = stripTypeCasts(call.arguments[1]);
|
|
7915
|
+
if (!ts.isObjectLiteralExpression(options))
|
|
7916
|
+
lowerer.noLowering("TextDecoder.decode options outside an object literal", options);
|
|
7917
|
+
for (const property of options.properties) {
|
|
7918
|
+
if ((!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property)) ||
|
|
7919
|
+
!ts.isIdentifier(property.name) || property.name.text !== "stream")
|
|
7920
|
+
lowerer.noLowering("unknown TextDecoder.decode option", property);
|
|
7921
|
+
stream = lowerer.lowerExprExpecting(ts.isPropertyAssignment(property) ? property.initializer : property.name, BOOL);
|
|
7922
|
+
}
|
|
7923
|
+
}
|
|
7821
7924
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
7822
7925
|
if (receiver.type.kind !== "record")
|
|
7823
7926
|
lowerer.badType(access.expression, lowerer.typeOf(access.expression));
|
|
7824
|
-
|
|
7927
|
+
let arg = call.arguments.length === 0
|
|
7825
7928
|
? cls === "TextEncoder" ? strLit("", loc)
|
|
7826
7929
|
: { kind: "bytesNew", source: null, type: BYTES_U8, loc }
|
|
7827
7930
|
: cls === "TextEncoder" ? lowerer.lowerExprExpecting(call.arguments[0], STRING) : lowerer.lowerExpr(call.arguments[0]);
|
|
7931
|
+
if (cls === "TextDecoder" && (arg.type.kind === "dyn" || arg.type.kind === "bytes" && arg.type.elem !== "u8")) {
|
|
7932
|
+
arg = { kind: "libCall", fn: "bytes.bufferSource", args: [lowerer.coerceInto(call.arguments[0], arg, DYN)], type: BYTES_U8, loc };
|
|
7933
|
+
}
|
|
7828
7934
|
if (cls === "TextDecoder" && !(arg.type.kind === "bytes" && arg.type.elem === "u8")) {
|
|
7829
7935
|
lowerer.noLowering(`TextDecoder.decode of '${lowerer.fmt(arg.type)}' values`, call, "Uint8Array/Buffer input decodes (ArrayBuffer values have no representation)");
|
|
7830
7936
|
}
|
|
@@ -7837,22 +7943,22 @@ function lowerStoredTextCodecCall(lowerer, call, access) {
|
|
|
7837
7943
|
const input = varRef("input.0", arg.type, loc);
|
|
7838
7944
|
const result = cls === "TextEncoder"
|
|
7839
7945
|
? { kind: "libCall", fn: "buffer.fromStr", args: [input, { kind: "strLit", value: "utf8", type: STRING, loc }], type: BYTES_U8, loc }
|
|
7840
|
-
: {
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7946
|
+
: { kind: "libCall", fn: "text.decodeStream", args: [
|
|
7947
|
+
{ kind: "recordGet", obj: varRef("codec.0", recT, loc), shapeId: recT.shapeId, field: "%state", type: DYN, loc },
|
|
7948
|
+
input,
|
|
7949
|
+
{ kind: "recordGet", obj: varRef("codec.0", recT, loc), shapeId: recT.shapeId, field: "%TextDecoder", type: F64, loc },
|
|
7950
|
+
...["%fatal", "%ignoreBOM"].map((field) => ({ kind: "recordGet", obj: varRef("codec.0", recT, loc), shapeId: recT.shapeId, field, type: BOOL, loc })),
|
|
7951
|
+
varRef("stream.0", BOOL, loc),
|
|
7952
|
+
], type: STRING, loc };
|
|
7847
7953
|
lowerer.liftedFns.push({
|
|
7848
7954
|
name,
|
|
7849
|
-
params: [{ localId: "codec.0", name: "codec", type: recT }, { localId: "input.0", name: "input", type: arg.type }],
|
|
7955
|
+
params: [{ localId: "codec.0", name: "codec", type: recT }, { localId: "input.0", name: "input", type: arg.type }, { localId: "stream.0", name: "stream", type: BOOL }],
|
|
7850
7956
|
returnType: result.type,
|
|
7851
|
-
locals: [{ id: "codec.0", name: "codec", type: recT, mutable: false }, { id: "input.0", name: "input", type: arg.type, mutable: false }],
|
|
7957
|
+
locals: [{ id: "codec.0", name: "codec", type: recT, mutable: false }, { id: "input.0", name: "input", type: arg.type, mutable: false }, { id: "stream.0", name: "stream", type: BOOL, mutable: false }],
|
|
7852
7958
|
body: [{ kind: "return", value: result, loc }], loc,
|
|
7853
7959
|
});
|
|
7854
7960
|
}
|
|
7855
|
-
return { kind: "call", callee: name, args: [receiver, arg], type: cls === "TextEncoder" ? BYTES_U8 : STRING, loc };
|
|
7961
|
+
return { kind: "call", callee: name, args: [receiver, arg, stream], type: cls === "TextEncoder" ? BYTES_U8 : STRING, loc };
|
|
7856
7962
|
}
|
|
7857
7963
|
/** A direct construction of THE stdlib TextEncoder/TextDecoder, through
|
|
7858
7964
|
* type-only wrappers. Name alone is never enough: a user class with the
|
|
@@ -7893,6 +7999,8 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7893
7999
|
if (!lowerer.isStdlibMember(access))
|
|
7894
8000
|
return null;
|
|
7895
8001
|
const { cls, ctor: recv } = info;
|
|
8002
|
+
if (cls === "TextDecoder" && ((recv.arguments?.length ?? 0) > 1 || call.arguments.length > 1))
|
|
8003
|
+
return lowerStoredTextCodecCall(lowerer, call, access);
|
|
7896
8004
|
if (!(cls === "TextDecoder" && member === "decode") && !(cls === "TextEncoder" && member === "encode")) {
|
|
7897
8005
|
return null;
|
|
7898
8006
|
}
|
|
@@ -7909,7 +8017,7 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7909
8017
|
? staticTextDecoderEncoding(labelT.value)
|
|
7910
8018
|
: null;
|
|
7911
8019
|
if (ctorArgs.length > 1 || encoding === null) {
|
|
7912
|
-
lowerer
|
|
8020
|
+
return lowerStoredTextCodecCall(lowerer, call, access);
|
|
7913
8021
|
}
|
|
7914
8022
|
const labelEffect = ctorArgs.length === 1
|
|
7915
8023
|
? lowerer.lowerExprExpecting(ctorArgs[0], STRING)
|
|
@@ -7931,7 +8039,10 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7931
8039
|
lowerer.noLowering("decode with a stream option", call, "streaming decode has no lowering — decode whole buffers");
|
|
7932
8040
|
}
|
|
7933
8041
|
const argNode = call.arguments[0];
|
|
7934
|
-
|
|
8042
|
+
let arg = lowerer.lowerExpr(argNode);
|
|
8043
|
+
if (arg.type.kind === "dyn" || arg.type.kind === "bytes" && arg.type.elem !== "u8") {
|
|
8044
|
+
arg = { kind: "libCall", fn: "bytes.bufferSource", args: [lowerer.coerceInto(argNode, arg, DYN)], type: BYTES_U8, loc };
|
|
8045
|
+
}
|
|
7935
8046
|
if (!(arg.type.kind === "bytes" && arg.type.elem === "u8")) {
|
|
7936
8047
|
lowerer.noLowering(`TextDecoder.decode of '${lowerer.fmt(arg.type)}' values`, argNode, "Uint8Array/Buffer input decodes (ArrayBuffer values have no representation)");
|
|
7937
8048
|
}
|
|
@@ -8159,7 +8270,7 @@ export function lowerPromiseStaticCall(lowerer, call, access) {
|
|
|
8159
8270
|
// reads are the routed keyed ops). All-static tuples keep the
|
|
8160
8271
|
// typed fence hint below. --dynamic only by construction: jsval
|
|
8161
8272
|
// entries exist only there.
|
|
8162
|
-
if (elems.some((e) => e.type.kind === "jsval")) {
|
|
8273
|
+
if (lowerer.dynamic && elems.some((e) => e.type.kind === "jsval" || e.type.kind === "dyn")) {
|
|
8163
8274
|
const diagsBefore = lowerer.diags.length;
|
|
8164
8275
|
try {
|
|
8165
8276
|
const marshaled = argNode.elements.map((el, i) => lowerer.jsvalIn(elems[i], el));
|
|
@@ -8192,7 +8303,7 @@ export function lowerPromiseStaticCall(lowerer, call, access) {
|
|
|
8192
8303
|
// marshaled array (an 'any' value passes through; an `any[]` value
|
|
8193
8304
|
// lifts per element by reference), the result staying an island
|
|
8194
8305
|
// value the static side awaits through the island→static bridge.
|
|
8195
|
-
if (entries.type.kind === "jsval" ||
|
|
8306
|
+
if (entries.type.kind === "jsval" || lowerer.dynamic && entries.type.kind === "dyn" ||
|
|
8196
8307
|
(entries.type.kind === "array" && entries.type.elem.kind === "jsval")) {
|
|
8197
8308
|
const diagsBefore = lowerer.diags.length;
|
|
8198
8309
|
try {
|
|
@@ -8368,11 +8479,12 @@ export function lowerPromiseStaticCall(lowerer, call, access) {
|
|
|
8368
8479
|
return { kind: "intrinsic", name: "promise.resolve", args: [], type: { kind: "promise", inner: VOID }, loc };
|
|
8369
8480
|
}
|
|
8370
8481
|
if (resultT.inner.kind === "void") {
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8482
|
+
return {
|
|
8483
|
+
kind: "seqExpr",
|
|
8484
|
+
stmts: [lowerer.lowerExprStatement(argNode)],
|
|
8485
|
+
result: { kind: "intrinsic", name: "promise.resolve", args: [], type: resultT, loc },
|
|
8486
|
+
type: resultT, loc,
|
|
8487
|
+
};
|
|
8376
8488
|
}
|
|
8377
8489
|
if (isUnitType(resultT.inner)) {
|
|
8378
8490
|
// A unit payload (Promise<undefined>/Promise<null>) has no
|
|
@@ -8392,6 +8504,9 @@ export function lowerNumberStaticProperty(lowerer, expr) {
|
|
|
8392
8504
|
const member = lowerer.stdlibGlobalMember(expr, "Number");
|
|
8393
8505
|
if (member === null)
|
|
8394
8506
|
return null;
|
|
8507
|
+
const predicate = own(NUMBER_STATIC_PREDICATES, member);
|
|
8508
|
+
if (predicate)
|
|
8509
|
+
return lowerCheckedPredicateValue(lowerer, `Number.${member}`, "number", locOf(expr), predicate);
|
|
8395
8510
|
const value = own(NUMBER_CONSTANTS, member);
|
|
8396
8511
|
if (value === undefined)
|
|
8397
8512
|
return null;
|