@scriptc/compiler 0.2.0 → 0.2.2
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 +84 -19
- 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 +8 -0
- package/dist/backend/llvm/dyn.js +247 -108
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +6 -3
- package/dist/backend/llvm/emitter.js +99 -25
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +9 -1
- package/dist/backend/llvm/emitter.test.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-containers.js +5 -0
- package/dist/backend/llvm/expr-containers.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 +47 -13
- 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 +187 -18
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +7 -57
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +41 -3
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +12 -9
- package/dist/backend/llvm/lib-filesystem.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 +80 -3
- 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/may-throw.js +4 -0
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +1 -1
- package/dist/backend/native-codegen.js +4 -3
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +11 -0
- package/dist/backend/native-codegen.test.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/target-diagnostics.d.ts +5 -0
- package/dist/backend/target-diagnostics.js +72 -1
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.d.ts +1 -0
- package/dist/backend/target-diagnostics.test.js +68 -0
- package/dist/backend/target-diagnostics.test.js.map +1 -0
- 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/coverage/surface-manifest.js +5 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +2 -7
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +7 -3
- package/dist/executable/executable-cache.js +47 -11
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +109 -2
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +1 -1
- package/dist/frontend/builtin-modules.js +1 -1
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/function-completion.d.ts +6 -0
- package/dist/frontend/function-completion.js +50 -0
- package/dist/frontend/function-completion.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.js +5 -1
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/checked-iterable-spread.d.ts +4 -0
- package/dist/frontend/lowering/checked-iterable-spread.js +30 -0
- package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -0
- package/dist/frontend/lowering/checked-promise-all.d.ts +5 -0
- package/dist/frontend/lowering/checked-promise-all.js +31 -0
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +4 -4
- package/dist/frontend/lowering/class-callbacks.js +29 -17
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +14 -0
- package/dist/frontend/lowering/class-construction.js +185 -0
- package/dist/frontend/lowering/class-construction.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +2 -1
- package/dist/frontend/lowering/class-descriptors.js +58 -10
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +36 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +965 -91
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +66 -3
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.d.ts +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +15 -42
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.d.ts +20 -1
- package/dist/frontend/lowering/class-method-values.js +120 -24
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +10 -3
- package/dist/frontend/lowering/class-prototypes.js +188 -21
- 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 +84 -0
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
- package/dist/frontend/lowering/class-static-data.d.ts +1 -0
- package/dist/frontend/lowering/class-static-data.js +6 -4
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +66 -17
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +24 -47
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.d.ts +13 -0
- package/dist/frontend/lowering/deferred-module-initializers.js +410 -0
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.d.ts +1 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.js +92 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -0
- 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 +68 -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 +72 -20
- 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 +10 -14
- package/dist/frontend/lowering/lower-builtins.js +443 -88
- 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 +717 -142
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +18 -13
- package/dist/frontend/lowering/lower-classes.js +1076 -188
- 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 +172 -51
- 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 +12 -8
- package/dist/frontend/lowering/lower-exprs.js +802 -232
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +17 -2
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +15 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +2 -0
- package/dist/frontend/lowering/lower-island.js +36 -10
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-island.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-island.test.js +51 -0
- package/dist/frontend/lowering/lower-island.test.js.map +1 -0
- package/dist/frontend/lowering/lower-modules.d.ts +1 -3
- package/dist/frontend/lowering/lower-modules.js +380 -73
- 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 +107 -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 +221 -47
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-stmts.test.js +77 -0
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -0
- package/dist/frontend/lowering/lower-stream.js +3 -1
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-url.d.ts +2 -1
- package/dist/frontend/lowering/lower-url.js +32 -9
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +53 -10
- package/dist/frontend/lowering/lowerer.js +390 -77
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +187 -3
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.d.ts +7 -0
- package/dist/frontend/lowering/module-namespace-elements.js +54 -0
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +4 -3
- package/dist/frontend/lowering/object-factory-new.js +27 -14
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +3 -0
- package/dist/frontend/lowering/surfaces.js +48 -19
- 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 +8 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.test.js +2 -1
- package/dist/frontend/lowering/text-decoder-encoding.test.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 +57 -26
- 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 +169 -23
- 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 +24 -9
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/index.js +16 -10
- package/dist/index.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 +74 -41
- package/dist/ir/ir.js +167 -43
- 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 +35 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +26 -1
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.d.ts +0 -3
- package/dist/ir/traverse.js +33 -20
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +136 -16
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +77 -1
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/compiler-self-identity.js +1 -1
- package/dist/library/compiler-self-identity.test.js +2 -2
- package/dist/library/compiler-self-identity.test.js.map +1 -1
- package/dist/library/int-infer.d.ts +2 -2
- package/dist/library/int-infer.js +10 -7
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +44 -0
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/prepare.js +2 -1
- package/dist/library/prepare.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 +170 -93
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { staticTextDecoderEncoding } from "./text-decoder-encoding.js";
|
|
2
|
+
import { checkedPromiseAll } from "./checked-promise-all.js";
|
|
2
3
|
import { InternalCompilerError } from "../../errors.js";
|
|
3
4
|
/* Builtin-surface lowering: node builtin-module calls (fs, path, os, url,
|
|
4
5
|
* crypto, child_process spawn/spawnSync and child/stats/spawn-result
|
|
@@ -7,6 +8,7 @@ import { InternalCompilerError } from "../../errors.js";
|
|
|
7
8
|
import { builtinModules } from "node:module";
|
|
8
9
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
9
10
|
import * as ts from "../ts7/adapter.js";
|
|
11
|
+
import { lowerCheckedPredicateValue } from "./lower-builtin-values.js";
|
|
10
12
|
import { PoisonError, dynUndefinedExpr, ladderFenceExpr, nodeThrowExpr, own } from "./lowerer.js";
|
|
11
13
|
import { canonicalBuiltinModule, isCreateRequireBinding7, isJsSourceFile, isNodeEsmFile, locOf, npmStaticDepSf7, requireSpecOf, resolveImport } from "../program.js";
|
|
12
14
|
import { isRelativeSpecifier } from "../workspace-registry.js";
|
|
@@ -480,7 +482,7 @@ export function createRequireProgramModuleOf(lowerer, expr) {
|
|
|
480
482
|
const cr = createRequireSpecOf(lowerer, call);
|
|
481
483
|
if (cr === null || cr.spec === null || canonicalBuiltinModule(cr.spec) !== null)
|
|
482
484
|
return null;
|
|
483
|
-
const dep = resolveImport(lowerer.program, cr.baseFile, cr.spec) ??
|
|
485
|
+
const dep = resolveImport(lowerer.program, cr.baseFile, cr.spec, "require") ??
|
|
484
486
|
npmStaticDepSf7(lowerer.program, cr.baseFile, cr.spec, "require");
|
|
485
487
|
if (dep === null || dep.fileName.endsWith(".json"))
|
|
486
488
|
return null;
|
|
@@ -1161,6 +1163,9 @@ export function lowerFsToUnixTimestampCall(lowerer, expr, bi, loc) {
|
|
|
1161
1163
|
* after every validation passes, exactly Node's order. Null when this
|
|
1162
1164
|
* is not a claimed member/shape (the table or fence path stands). */
|
|
1163
1165
|
export function lowerFsLadderCall(lowerer, expr, bi, loc) {
|
|
1166
|
+
if (bi.module === "fs" && bi.member !== "rename" && builtinModuleFnOf(lowerer, bi.module, bi.member)?.fn === "fs.callbackCall") {
|
|
1167
|
+
return lowerer.lowerBuiltinModuleCall(expr, bi, { fn: "fs.callbackCall", params: [], result: DYN }, loc);
|
|
1168
|
+
}
|
|
1164
1169
|
if (bi.module !== "fs" && bi.module !== "fs/promises")
|
|
1165
1170
|
return null;
|
|
1166
1171
|
if (!isJsSourceFile(expr.getSourceFile()))
|
|
@@ -1410,6 +1415,36 @@ function lowerZlibModuleCall(lowerer, expr, bi, loc) {
|
|
|
1410
1415
|
}
|
|
1411
1416
|
export function lowerBuiltinModuleCall(lowerer, expr, bi, fn, loc) {
|
|
1412
1417
|
const name = expr.expression.getText();
|
|
1418
|
+
if (bi.module === "process" && bi.member === "loadEnvFile")
|
|
1419
|
+
return lowerProcessLoadEnvFile(lowerer, expr);
|
|
1420
|
+
if (bi.module === "buffer" && ["isAscii", "isUtf8", "transcode"].includes(bi.member)) {
|
|
1421
|
+
if (expr.arguments.some(ts.isSpreadElement))
|
|
1422
|
+
lowerer.noLowering("buffer encoding call with spread arguments", expr);
|
|
1423
|
+
const arity = bi.member === "transcode" ? 3 : 1;
|
|
1424
|
+
const args = Array.from({ length: arity }, (_, index) => expr.arguments[index]
|
|
1425
|
+
? lowerer.lowerExprExpecting(stripTypeCasts(expr.arguments[index]), DYN) : dynUndefinedExpr(loc));
|
|
1426
|
+
if (expr.arguments.length > arity)
|
|
1427
|
+
lowerer.noLowering("buffer encoding call with extra arguments", expr);
|
|
1428
|
+
return { kind: "libCall", fn: fn.fn, args, type: fn.result, loc };
|
|
1429
|
+
}
|
|
1430
|
+
if (fn.fn === "fs.callbackCall" && bi.member !== "rename") {
|
|
1431
|
+
if (expr.arguments.some(ts.isSpreadElement))
|
|
1432
|
+
lowerer.noLowering("filesystem callback call with spread arguments", expr);
|
|
1433
|
+
const args = { kind: "dynArrLit", elems: expr.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN)), type: DYN, loc };
|
|
1434
|
+
return { kind: "libCall", fn: "fs.callbackCall", args: [{ kind: "strLit", value: bi.member, type: STRING, loc }, args], type: DYN, loc };
|
|
1435
|
+
}
|
|
1436
|
+
if (bi.module === "fs" && (bi.member === "readvSync" || bi.member === "writevSync" || bi.member === "ftruncateSync")) {
|
|
1437
|
+
const vector = bi.member !== "ftruncateSync";
|
|
1438
|
+
const required = vector ? 2 : 1;
|
|
1439
|
+
if (expr.arguments.length < required || expr.arguments.length > required + 1 || expr.arguments.some(ts.isSpreadElement))
|
|
1440
|
+
lowerer.noLowering(`${name} with this argument shape`, expr);
|
|
1441
|
+
const args = [lowerer.lowerExprExpecting(expr.arguments[0], F64)];
|
|
1442
|
+
if (vector)
|
|
1443
|
+
args.push(lowerer.lowerExprExpecting(expr.arguments[1], arrayOf(BYTES_U8)));
|
|
1444
|
+
const optional = expr.arguments[required];
|
|
1445
|
+
args.push(optional ? lowerBuiltinOptionalDefault(lowerer, optional, F64, numLit(vector ? -1 : 0, loc), vector) : numLit(vector ? -1 : 0, loc));
|
|
1446
|
+
return { kind: "libCall", fn: fn.fn, args, type: vector ? F64 : VOID, loc };
|
|
1447
|
+
}
|
|
1413
1448
|
// Numeric open flags are interpreted symbolically at the call site. The
|
|
1414
1449
|
// O_* bit values differ between Darwin and Linux, so emit a stable mask
|
|
1415
1450
|
// and let the target runtime select its own native constants.
|
|
@@ -2318,17 +2353,35 @@ export function lowerBuiltinModuleCall(lowerer, expr, bi, fn, loc) {
|
|
|
2318
2353
|
}
|
|
2319
2354
|
return { kind: "libCall", fn: fn.fn, args, type: fn.result, loc };
|
|
2320
2355
|
}
|
|
2321
|
-
/** Reflect.
|
|
2356
|
+
/** Reflect.ownKeys uses native computed-key reflection. Reflect.apply(target,
|
|
2357
|
+
* thisArg, argsList) where the TARGET is a builtin
|
|
2322
2358
|
* rest-parameter table fn (path.join / path.resolve — test/common
|
|
2323
2359
|
* fixtures.js's fixturesPath forwards its rest args exactly this way):
|
|
2324
2360
|
* the packed libCall over a validated string[] extraction of argsList.
|
|
2325
2361
|
* The builtins ignore the receiver, so thisArg must be an effect-free
|
|
2326
2362
|
* spelling (`this`, an identifier, a unit literal) whose dropped
|
|
2327
2363
|
* evaluation is unobservable; every other Reflect.apply keeps the
|
|
2328
|
-
* fence. Null when this isn't a Reflect
|
|
2329
|
-
export function
|
|
2364
|
+
* fence. Null when this isn't a supported Reflect call. */
|
|
2365
|
+
export function lowerReflectCall(lowerer, call, access) {
|
|
2366
|
+
if (!call.questionDotToken && !access.questionDotToken && lowerer.stdlibGlobalMember(access, "Reflect") === "ownKeys" &&
|
|
2367
|
+
call.arguments.length === 1 && !ts.isSpreadElement(call.arguments[0])) {
|
|
2368
|
+
return { kind: "libCall", fn: "dyn.ownKeys", args: [lowerer.lowerExprExpecting(call.arguments[0], DYN)], type: DYN, loc: locOf(call) };
|
|
2369
|
+
}
|
|
2330
2370
|
if (call.questionDotToken)
|
|
2331
2371
|
return null;
|
|
2372
|
+
const reflectMember = lowerer.stdlibGlobalMember(access, "Reflect");
|
|
2373
|
+
if (reflectMember === "get" || reflectMember === "set") {
|
|
2374
|
+
const required = reflectMember === "get" ? 2 : 3;
|
|
2375
|
+
if (call.arguments.length < required || call.arguments.length > required + 1 || call.arguments.some(ts.isSpreadElement)) {
|
|
2376
|
+
lowerer.noLowering(`Reflect.${reflectMember} with this argument shape`, call, `use Reflect.${reflectMember}(target, key${reflectMember === "set" ? ", value" : ""}, receiver?)`);
|
|
2377
|
+
}
|
|
2378
|
+
const loc = locOf(call);
|
|
2379
|
+
const args = call.arguments.map((arg) => lowerer.lowerExprExpecting(arg, DYN));
|
|
2380
|
+
const target = call.arguments.length === required ? lowerer.declareHiddenLocal("%reflectTarget", DYN) : null;
|
|
2381
|
+
const operation = { kind: "libCall", fn: reflectMember === "get" ? "dyn.reflectGet" : "dyn.reflectSet",
|
|
2382
|
+
args: target ? [varRef(target.id, DYN, loc), ...args.slice(1), varRef(target.id, DYN, loc)] : args, type: reflectMember === "get" ? DYN : BOOL, loc };
|
|
2383
|
+
return target ? { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: target.id, init: args[0], loc }], result: operation, type: operation.type, loc } : operation;
|
|
2384
|
+
}
|
|
2332
2385
|
if (lowerer.stdlibGlobalMember(access, "Reflect") !== "apply")
|
|
2333
2386
|
return null;
|
|
2334
2387
|
const loc = locOf(call);
|
|
@@ -2340,7 +2393,10 @@ export function lowerReflectApplyCall(lowerer, call, access) {
|
|
|
2340
2393
|
const bi = ts.isPropertyAccessExpression(targetNode) ? lowerer.builtinMemberOf(targetNode) : null;
|
|
2341
2394
|
const fn = bi ? builtinModuleFnOf(lowerer, bi.module, bi.member) : null;
|
|
2342
2395
|
if (!fn || fn.variadicPack !== true) {
|
|
2343
|
-
|
|
2396
|
+
const target = lowerer.lowerExprExpecting(targetNode, DYN);
|
|
2397
|
+
const receiver = lowerer.lowerExprExpecting(call.arguments[1], DYN);
|
|
2398
|
+
const argumentsList = lowerer.lowerExprExpecting(call.arguments[2], DYN);
|
|
2399
|
+
return { kind: "libCall", fn: "dyn.reflectApply", args: [target, receiver, argumentsList], type: DYN, loc };
|
|
2344
2400
|
}
|
|
2345
2401
|
const thisNode = call.arguments[1];
|
|
2346
2402
|
const effectFree = thisNode.kind === ts.SyntaxKind.ThisKeyword ||
|
|
@@ -2524,8 +2580,8 @@ export function lowerSpawnSyncCall(lowerer, expr, loc) {
|
|
|
2524
2580
|
};
|
|
2525
2581
|
}
|
|
2526
2582
|
/** `spawn(command, args?, options)` → one cp.spawn / cp.spawnOpts
|
|
2527
|
-
* libCall.
|
|
2528
|
-
*
|
|
2583
|
+
* libCall. Computed options use native runtime normalization. Inline
|
|
2584
|
+
* stdio accepts "ignore", "inherit", or "pipe" as the scalar,
|
|
2529
2585
|
* or the 3-tuple whose stdin pipe becomes child.stdin, stdout/stderr
|
|
2530
2586
|
* pipes become child.stdout/child.stderr, and output slots may also be
|
|
2531
2587
|
* number fds. Omitting stdio uses Node's default: all three piped. The
|
|
@@ -2559,7 +2615,11 @@ export function lowerSpawnCall(lowerer, expr, loc) {
|
|
|
2559
2615
|
optsNode = second;
|
|
2560
2616
|
}
|
|
2561
2617
|
if (optsNode !== undefined && !ts.isObjectLiteralExpression(optsNode)) {
|
|
2562
|
-
|
|
2618
|
+
return {
|
|
2619
|
+
kind: "libCall", fn: "cp.spawnDynamic",
|
|
2620
|
+
args: [cmd, lowerer.lowerChildArgsArg(argsNode, loc), lowerer.lowerExprExpecting(optsNode, DYN)],
|
|
2621
|
+
type: CHILD_T, loc,
|
|
2622
|
+
};
|
|
2563
2623
|
}
|
|
2564
2624
|
const emptyStr = { kind: "strLit", value: "", type: STRING, loc };
|
|
2565
2625
|
// Per-slot stdio modes (scr_child.c: 0 ignore, 1 inherit, 2 fd) and
|
|
@@ -4166,13 +4226,8 @@ function isStringDecoderTyped(lowerer, node) {
|
|
|
4166
4226
|
return lowerer.checker.declarationsOf(sym).some((d) => (ts.isClassDeclaration(d) || ts.isInterfaceDeclaration(d)) &&
|
|
4167
4227
|
lowerer.isStdlibFile(d.getSourceFile()));
|
|
4168
4228
|
}
|
|
4169
|
-
/**
|
|
4170
|
-
|
|
4171
|
-
* sequence; `d.end()` flushes the buffered partial as its replacement
|
|
4172
|
-
* chars — Node's utf8 StringDecoder exactly (SEMANTICS.md), through the
|
|
4173
|
-
* interned %strdec helpers over the packed-f64 pending field. end(buf)
|
|
4174
|
-
* and the rest of @types/node's surface fence per member. Null for
|
|
4175
|
-
* non-decoder receivers. */
|
|
4229
|
+
/** StringDecoder writes preserve pending bytes; end(input) performs the
|
|
4230
|
+
* final write and flushes the state. String input passes through unchanged. */
|
|
4176
4231
|
export function lowerStringDecoderMethodCall(lowerer, call, access) {
|
|
4177
4232
|
if (call.questionDotToken || access.questionDotToken)
|
|
4178
4233
|
return null;
|
|
@@ -4182,29 +4237,37 @@ export function lowerStringDecoderMethodCall(lowerer, call, access) {
|
|
|
4182
4237
|
return null;
|
|
4183
4238
|
const name = access.name.text;
|
|
4184
4239
|
const loc = locOf(call);
|
|
4185
|
-
if (name
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
lowerer.badType(access.expression, lowerer.typeOf(access.expression));
|
|
4189
|
-
let chunk = lowerBuiltinValuePreservingUndefined(lowerer, call.arguments[0]);
|
|
4190
|
-
chunk = checkedOptionalBuiltinArm(lowerer, chunk, BYTES_U8) ?? chunk;
|
|
4191
|
-
if (!(chunk.type.kind === "bytes" && chunk.type.elem === "u8")) {
|
|
4192
|
-
lowerer.noLowering(`StringDecoder.write of '${lowerer.fmt(chunk.type)}' data`, call.arguments[0], "Buffer/Uint8Array chunks decode (narrow unions first)");
|
|
4193
|
-
}
|
|
4194
|
-
const helper = lowerer.strdecHelper("write", receiver.type.shapeId, loc);
|
|
4195
|
-
return { kind: "call", callee: helper, args: [receiver, chunk], type: STRING, loc };
|
|
4240
|
+
if ((name !== "write" && name !== "end") || call.arguments.length > 1 ||
|
|
4241
|
+
(name === "write" && call.arguments.length !== 1) || call.arguments.some(ts.isSpreadElement)) {
|
|
4242
|
+
lowerer.noLowering(`StringDecoder.${name}`, call, "use write(input) or end(input?)", lowerer.checker.getSymbolAtLocation(access.name));
|
|
4196
4243
|
}
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4244
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
4245
|
+
if (receiver.type.kind !== "record")
|
|
4246
|
+
lowerer.badType(access.expression, lowerer.typeOf(access.expression));
|
|
4247
|
+
if (call.arguments.length === 0) {
|
|
4248
|
+
return { kind: "call", callee: lowerer.strdecHelper("end", receiver.type.shapeId, loc), args: [receiver], type: STRING, loc };
|
|
4249
|
+
}
|
|
4250
|
+
const node = call.arguments[0];
|
|
4251
|
+
const undefinedArg = name === "end" ? lowerStaticallyUndefinedArgument(lowerer, node) : null;
|
|
4252
|
+
if (undefinedArg) {
|
|
4253
|
+
const saved = lowerer.declareHiddenLocal("%strdecRecv", receiver.type);
|
|
4254
|
+
const result = { kind: "call", callee: lowerer.strdecHelper("end", receiver.type.shapeId, loc), args: [varRef(saved.id, receiver.type, loc)], type: STRING, loc };
|
|
4255
|
+
return { kind: "seqExpr", stmts: [{ kind: "varDecl", localId: saved.id, init: receiver, loc }], result: defaultAfterUndefined(undefinedArg, result), type: STRING, loc };
|
|
4206
4256
|
}
|
|
4207
|
-
|
|
4257
|
+
let chunk = lowerBuiltinValuePreservingUndefined(lowerer, node);
|
|
4258
|
+
if (chunk.type.kind === "string") {
|
|
4259
|
+
const op = name === "end" ? "endString" : "writeString";
|
|
4260
|
+
return { kind: "call", callee: lowerer.strdecHelper(op, receiver.type.shapeId, loc), args: [receiver, chunk], type: STRING, loc };
|
|
4261
|
+
}
|
|
4262
|
+
chunk = checkedOptionalBuiltinArm(lowerer, chunk, BYTES_U8) ?? chunk;
|
|
4263
|
+
if (chunk.type.kind === "bytes" && chunk.type.elem !== "u8") {
|
|
4264
|
+
chunk = { kind: "libCall", fn: "bytes.bufferSource", args: [lowerer.coerceInto(node, chunk, DYN)], type: BYTES_U8, loc };
|
|
4265
|
+
}
|
|
4266
|
+
if (!(chunk.type.kind === "bytes" && chunk.type.elem === "u8")) {
|
|
4267
|
+
lowerer.noLowering(`StringDecoder.${name} of '${lowerer.fmt(chunk.type)}' data`, node, "pass a string or typed-array view (narrow unions first)");
|
|
4268
|
+
}
|
|
4269
|
+
const helper = lowerer.strdecHelper(name === "end" ? "endChunk" : "write", receiver.type.shapeId, loc);
|
|
4270
|
+
return { kind: "call", callee: helper, args: [receiver, chunk], type: STRING, loc };
|
|
4208
4271
|
}
|
|
4209
4272
|
/** The interned %strdec helpers: write(d, chunk) returns the decoded
|
|
4210
4273
|
* complete prefix and re-buffers the trailing partial into the pending
|
|
@@ -4242,7 +4305,7 @@ export function strdecHelper(lowerer, op, shapeId, loc) {
|
|
|
4242
4305
|
{ id: "s.0", name: "s", type: STRING, mutable: false },
|
|
4243
4306
|
];
|
|
4244
4307
|
let body;
|
|
4245
|
-
if (op === "write") {
|
|
4308
|
+
if (op === "write" || op === "endChunk") {
|
|
4246
4309
|
params.push({ localId: "chunk.0", name: "chunk", type: BYTES_U8 });
|
|
4247
4310
|
locals.splice(1, 0, { id: "chunk.0", name: "chunk", type: BYTES_U8, mutable: false });
|
|
4248
4311
|
body = [
|
|
@@ -4282,6 +4345,24 @@ export function strdecHelper(lowerer, op, shapeId, loc) {
|
|
|
4282
4345
|
{ kind: "return", value: varRef("s.0", STRING, loc), loc },
|
|
4283
4346
|
];
|
|
4284
4347
|
}
|
|
4348
|
+
if (op === "endString" || op === "writeString") {
|
|
4349
|
+
const inputT = STRING;
|
|
4350
|
+
params.push({ localId: "chunk.0", name: "chunk", type: inputT });
|
|
4351
|
+
locals.push({ id: "chunk.0", name: "chunk", type: inputT, mutable: false });
|
|
4352
|
+
if (op === "writeString")
|
|
4353
|
+
body = [{ kind: "return", value: varRef("chunk.0", STRING, loc), loc }];
|
|
4354
|
+
if (op === "endString")
|
|
4355
|
+
body[body.length - 1] = { kind: "return", value: {
|
|
4356
|
+
kind: "strConcat", left: varRef("chunk.0", STRING, loc), right: varRef("s.0", STRING, loc), type: STRING, loc,
|
|
4357
|
+
}, loc };
|
|
4358
|
+
}
|
|
4359
|
+
if (op === "endChunk") {
|
|
4360
|
+
locals.push({ id: "tail.0", name: "tail", type: STRING, mutable: false });
|
|
4361
|
+
body.splice(body.length - 1, 0, { kind: "varDecl", localId: "tail.0", init: { kind: "libCall", fn: "strdec.end", args: [encRead(), pendingRead()], type: STRING, loc }, loc }, { kind: "recordSet", obj: varRef("d.0", recT, loc), shapeId, field: "%pending", value: { kind: "numLit", value: 0, type: F64, loc }, loc });
|
|
4362
|
+
body[body.length - 1] = { kind: "return", value: {
|
|
4363
|
+
kind: "strConcat", left: varRef("s.0", STRING, loc), right: varRef("tail.0", STRING, loc), type: STRING, loc,
|
|
4364
|
+
}, loc };
|
|
4365
|
+
}
|
|
4285
4366
|
lowerer.liftedFns.push({ name, params, returnType: STRING, locals, body, loc });
|
|
4286
4367
|
return name;
|
|
4287
4368
|
}
|
|
@@ -4312,6 +4393,18 @@ export function lowerJsonMethodCall(lowerer, call, access) {
|
|
|
4312
4393
|
return { kind: "libCall", fn: "json.parseReviver", args: [text, callback], type: DYN, loc };
|
|
4313
4394
|
}
|
|
4314
4395
|
if (member === "stringify") {
|
|
4396
|
+
const replacerNode = call.arguments[1];
|
|
4397
|
+
const spaceNode = call.arguments[2];
|
|
4398
|
+
const runtimeOptions = replacerNode && !jsonNullishArgument(lowerer, replacerNode) &&
|
|
4399
|
+
lowerer.mapTypeOf(lowerer.typeOf(replacerNode))?.kind === "dyn" ||
|
|
4400
|
+
spaceNode && !jsonNullishArgument(lowerer, spaceNode) &&
|
|
4401
|
+
!ts.isNumericLiteral(spaceNode) && !ts.isStringLiteral(spaceNode) && !ts.isNoSubstitutionTemplateLiteral(spaceNode) &&
|
|
4402
|
+
!(ts.isPrefixUnaryExpression(spaceNode) && ts.isNumericLiteral(spaceNode.operand));
|
|
4403
|
+
if (runtimeOptions && call.arguments[0]) {
|
|
4404
|
+
const args = [0, 1, 2].map((index) => call.arguments[index]
|
|
4405
|
+
? lowerer.lowerExprExpecting(call.arguments[index], DYN) : dynUndefinedExpr(loc));
|
|
4406
|
+
return { kind: "libCall", fn: "json.stringifyValue", args, type: DYN, loc };
|
|
4407
|
+
}
|
|
4315
4408
|
const indent = stringifySpaceIndent(lowerer, call);
|
|
4316
4409
|
if (call.arguments.length === 0) {
|
|
4317
4410
|
return lowerer.wrappedUndefined(lowerer.withUndefinedArm(STRING), loc);
|
|
@@ -4366,11 +4459,11 @@ export function lowerJsonMethodCall(lowerer, call, access) {
|
|
|
4366
4459
|
const optionalString = lowerOptionalStringifyRoot(lowerer, value, indent, loc);
|
|
4367
4460
|
if (optionalString)
|
|
4368
4461
|
return optionalString;
|
|
4369
|
-
if (value.type.kind === "dyn" || isJsonStringifyDynamicType(value.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
4462
|
+
if (value.type.kind === "url" || value.type.kind === "dyn" || isJsonStringifyDynamicType(value.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
4370
4463
|
// Keep the original containers live while the runtime visits them:
|
|
4371
4464
|
// a toJSON callback can mutate a later field, and shared/cyclic
|
|
4372
4465
|
// references must retain their identities throughout traversal.
|
|
4373
|
-
const boxed = value.type.kind === "dyn" ? value : { kind: "dynFrom", value, liveRef: true, type: DYN, loc };
|
|
4466
|
+
const boxed = value.type.kind === "dyn" ? value : { kind: "dynFrom", value, ...(value.type.kind === "url" ? {} : { liveRef: true }), type: DYN, loc };
|
|
4374
4467
|
const raw = {
|
|
4375
4468
|
kind: "libCall", fn: "json.stringifyReplacer",
|
|
4376
4469
|
args: [boxed, dynUndefinedExpr(loc), { kind: "strLit", value: indent, type: STRING, loc }],
|
|
@@ -4516,6 +4609,12 @@ function jsonNullishArgument(lowerer, node) {
|
|
|
4516
4609
|
* refuse signatures that request one until that protocol is implemented. */
|
|
4517
4610
|
function lowerJsonCallback(lowerer, node, role) {
|
|
4518
4611
|
const callback = lowerer.lowerExpr(node);
|
|
4612
|
+
if (callback.type.kind === "dyn")
|
|
4613
|
+
return callback;
|
|
4614
|
+
if (callback.type.kind === "union" && lowerer.dynConvertible(callback.type) &&
|
|
4615
|
+
lowerer.unions.get(callback.type.unionId)?.arms.every((arm) => isUnitType(arm) || arm.kind === "func" &&
|
|
4616
|
+
arm.params.length <= 2 && (role !== "reviver" || (!arm.rest && !arm.argumentsAll))))
|
|
4617
|
+
return lowerer.coerceToExpected(callback, DYN);
|
|
4519
4618
|
if (callback.type.kind === "func" && callback.type.params.length <= 2 &&
|
|
4520
4619
|
(role !== "reviver" || (!callback.type.rest && !callback.type.argumentsAll)) &&
|
|
4521
4620
|
canBoxFuncIntoDyn(callback.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
@@ -4702,8 +4801,8 @@ function cryptoEncoding(lowerer, node, use) {
|
|
|
4702
4801
|
}
|
|
4703
4802
|
function cryptoAlgorithm(lowerer, node, use) {
|
|
4704
4803
|
const type = lowerer.typeOf(node);
|
|
4705
|
-
if (type.isStringLiteralType() && !["md5", "sha1", "sha256"].includes(type.value.toLowerCase())) {
|
|
4706
|
-
lowerer.noLowering(`${use} with algorithm '${type.value}'`, node, "md5, sha1,
|
|
4804
|
+
if (type.isStringLiteralType() && !["md5", "sha1", "sha224", "sha256", "sha384", "sha512"].includes(type.value.toLowerCase())) {
|
|
4805
|
+
lowerer.noLowering(`${use} with algorithm '${type.value}'`, node, "md5, sha1, sha224, sha256, sha384, and sha512 are the lowered digest algorithms");
|
|
4707
4806
|
}
|
|
4708
4807
|
return lowerer.lowerExprExpecting(node, STRING);
|
|
4709
4808
|
}
|
|
@@ -4722,7 +4821,19 @@ function cryptoInputBytes(lowerer, node, loc) {
|
|
|
4722
4821
|
}
|
|
4723
4822
|
lowerer.noLowering(`crypto byte input of '${lowerer.fmt(value.type)}' values`, node, "string and Buffer/Uint8Array values are supported");
|
|
4724
4823
|
}
|
|
4725
|
-
function
|
|
4824
|
+
function cryptoKdfInput(lowerer, node) {
|
|
4825
|
+
const loc = locOf(node);
|
|
4826
|
+
const type = lowerer.mapTypeOf(lowerer.typeOf(node));
|
|
4827
|
+
if (type?.kind === "string" || (type?.kind === "bytes" && type.elem === "u8"))
|
|
4828
|
+
return cryptoInputBytes(lowerer, node, loc);
|
|
4829
|
+
const symbol = lowerer.typeOf(node).getSymbol();
|
|
4830
|
+
if (type?.kind === "bytes" || (symbol?.name === "ArrayBuffer" && lowerer.isStdlibSymbol(symbol))) {
|
|
4831
|
+
const value = lowerer.coerceInto(node, lowerer.lowerExpr(node), DYN);
|
|
4832
|
+
return { kind: "libCall", fn: "bytes.bufferSource", args: [value], type: BYTES_U8, loc };
|
|
4833
|
+
}
|
|
4834
|
+
lowerer.noLowering("crypto key derivation with this input", node, "strings, Buffers, numeric typed arrays, DataViews, and fixed-length ArrayBuffers are supported; KeyObjects are not yet lowered");
|
|
4835
|
+
}
|
|
4836
|
+
function errorFirstBytesCallback(lowerer, node, api, arrayBuffer = false) {
|
|
4726
4837
|
let callback = lowerer.lowerExpr(node);
|
|
4727
4838
|
if (callback.type.kind === "dyn") {
|
|
4728
4839
|
callback = { kind: "dynCheck", value: callback, type: funcOf([DYN, DYN], VOID), loc: locOf(node) };
|
|
@@ -4744,8 +4855,8 @@ function errorFirstBytesCallback(lowerer, node, api) {
|
|
|
4744
4855
|
lowerer.unsupported("SC1090", node, `${api} callback error parameters must be Error | null`);
|
|
4745
4856
|
}
|
|
4746
4857
|
const value = callback.type.params[1];
|
|
4747
|
-
if (value !== undefined && value.kind !== "dyn" && !(value.kind === "bytes" && value.elem === "u8")) {
|
|
4748
|
-
lowerer.unsupported("SC1090", node, `${api} callback result parameters must be Buffer/Uint8Array values`);
|
|
4858
|
+
if (value !== undefined && value.kind !== "dyn" && (arrayBuffer || !(value.kind === "bytes" && value.elem === "u8"))) {
|
|
4859
|
+
lowerer.unsupported("SC1090", node, `${api} callback result parameters must be ${arrayBuffer ? "ArrayBuffer" : "Buffer/Uint8Array"} values`);
|
|
4749
4860
|
}
|
|
4750
4861
|
return voidizedCallback(lowerer, callback, locOf(node));
|
|
4751
4862
|
}
|
|
@@ -4793,6 +4904,31 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
|
|
|
4793
4904
|
loc,
|
|
4794
4905
|
};
|
|
4795
4906
|
}
|
|
4907
|
+
if (bi.member === "hkdf" || bi.member === "hkdfSync") {
|
|
4908
|
+
const async = bi.member === "hkdf";
|
|
4909
|
+
if (args.length !== (async ? 6 : 5))
|
|
4910
|
+
lowerer.noLowering(`crypto.${bi.member} with ${args.length} arguments`, expr);
|
|
4911
|
+
const values = [
|
|
4912
|
+
cryptoAlgorithm(lowerer, args[0], `crypto.${bi.member}`),
|
|
4913
|
+
cryptoKdfInput(lowerer, args[1]), cryptoKdfInput(lowerer, args[2]), cryptoKdfInput(lowerer, args[3]),
|
|
4914
|
+
lowerer.lowerExprExpecting(args[4], F64),
|
|
4915
|
+
];
|
|
4916
|
+
if (async)
|
|
4917
|
+
values.push(errorFirstBytesCallback(lowerer, args[5], "crypto.hkdf", true));
|
|
4918
|
+
return { kind: "libCall", fn: async ? "crypto.hkdfCb" : "crypto.hkdf", args: values, type: async ? VOID : DYN, loc };
|
|
4919
|
+
}
|
|
4920
|
+
if (bi.member === "scrypt" || bi.member === "scryptSync") {
|
|
4921
|
+
const async = bi.member === "scrypt";
|
|
4922
|
+
const minimum = async ? 4 : 3;
|
|
4923
|
+
if (args.length < minimum || args.length > minimum + 1)
|
|
4924
|
+
lowerer.noLowering(`crypto.${bi.member} with ${args.length} arguments`, expr);
|
|
4925
|
+
const values = [cryptoKdfInput(lowerer, args[0]), cryptoKdfInput(lowerer, args[1]), lowerer.lowerExprExpecting(args[2], F64)];
|
|
4926
|
+
const options = args.length > minimum ? args[3] : undefined;
|
|
4927
|
+
values.push(options ? lowerer.coerceInto(options, lowerer.lowerExpr(options), DYN) : dynUndefinedExpr(loc));
|
|
4928
|
+
if (async)
|
|
4929
|
+
values.push(errorFirstBytesCallback(lowerer, args[args.length - 1], "crypto.scrypt"));
|
|
4930
|
+
return { kind: "libCall", fn: async ? "crypto.scryptCb" : "crypto.scrypt", args: values, type: async ? VOID : BYTES_U8, loc };
|
|
4931
|
+
}
|
|
4796
4932
|
if (bi.member === "createHash") {
|
|
4797
4933
|
if (args.length !== 1) {
|
|
4798
4934
|
lowerer.noLowering(`crypto.createHash with ${args.length} arguments`, expr, "createHash(algorithm) is supported; options are not yet lowered");
|
|
@@ -4900,7 +5036,7 @@ export function lowerCryptoModuleCall(lowerer, expr, bi, loc) {
|
|
|
4900
5036
|
loc,
|
|
4901
5037
|
};
|
|
4902
5038
|
}
|
|
4903
|
-
/** Method calls on URL-typed receivers: `u.toString()`
|
|
5039
|
+
/** Method calls on URL-typed receivers: `u.toString()` and `u.toJSON()` are Node's href
|
|
4904
5040
|
* serialization (the href getter's libCall). Everything else the lib
|
|
4905
5041
|
* declares fences member-qualified. Null for non-URL receivers. */
|
|
4906
5042
|
export function lowerUrlMethodCall(lowerer, call, access) {
|
|
@@ -4911,11 +5047,11 @@ export function lowerUrlMethodCall(lowerer, call, access) {
|
|
|
4911
5047
|
if (!lowerer.isStdlibMember(access))
|
|
4912
5048
|
return null;
|
|
4913
5049
|
const name = access.name.text;
|
|
4914
|
-
if (name === "toString" && call.arguments.length === 0) {
|
|
5050
|
+
if ((name === "toString" || name === "toJSON") && call.arguments.length === 0) {
|
|
4915
5051
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
4916
5052
|
return { kind: "libCall", fn: "url.href", args: [receiver], type: STRING, loc: locOf(call) };
|
|
4917
5053
|
}
|
|
4918
|
-
lowerer.noLowering(`URL.${name}`, call, "protocol, origin, username, password, pathname, href, host, hostname, port, search, hash, searchParams, and
|
|
5054
|
+
lowerer.noLowering(`URL.${name}`, call, "protocol, origin, username, password, pathname, href, host, hostname, port, search, hash, searchParams, toString(), and toJSON() are the supported URL members", lowerer.checker.getSymbolAtLocation(access.name));
|
|
4919
5055
|
}
|
|
4920
5056
|
/** `new URLSearchParams(init?)` — the WHATWG constructor's lowered init
|
|
4921
5057
|
* shapes: omitted / literal `undefined` (empty list), a string (parsed,
|
|
@@ -4959,6 +5095,9 @@ export function lowerSearchParamsNew(lowerer, expr, loc) {
|
|
|
4959
5095
|
return acc;
|
|
4960
5096
|
}
|
|
4961
5097
|
const init = lowerer.lowerExpr(arg);
|
|
5098
|
+
if (init.type.kind === "dyn") {
|
|
5099
|
+
return { kind: "libCall", fn: "sp.newChecked", args: [init], type: SEARCH_PARAMS_T, loc };
|
|
5100
|
+
}
|
|
4962
5101
|
if (init.type.kind === "string") {
|
|
4963
5102
|
return { kind: "libCall", fn: "sp.parse", args: [init], type: SEARCH_PARAMS_T, loc };
|
|
4964
5103
|
}
|
|
@@ -5286,18 +5425,21 @@ export function lowerFileHandleMethodCall(lowerer, call, access) {
|
|
|
5286
5425
|
const loc = locOf(call);
|
|
5287
5426
|
const receiver = () => lowerer.lowerExprExpecting(access.expression, FILEHANDLE_T);
|
|
5288
5427
|
const promise = (inner) => ({ kind: "promise", inner });
|
|
5289
|
-
const num = (node, dflt) => {
|
|
5428
|
+
const num = (node, dflt, lowered) => {
|
|
5290
5429
|
const defaultValue = { kind: "numLit", value: dflt, type: F64, loc };
|
|
5291
|
-
if (!node)
|
|
5430
|
+
if (!node && !lowered)
|
|
5292
5431
|
return { value: defaultValue, defaulted: boolLit(true, loc) };
|
|
5293
|
-
|
|
5432
|
+
if (lowered && isUnitType(lowered.type)) {
|
|
5433
|
+
return { value: defaultAfterUndefined(lowered, defaultValue), defaulted: boolLit(true, loc) };
|
|
5434
|
+
}
|
|
5435
|
+
const undefinedArg = !lowered && node ? lowerStaticallyUndefinedArgument(lowerer, node) : null;
|
|
5294
5436
|
if (undefinedArg) {
|
|
5295
5437
|
return { value: defaultAfterUndefined(undefinedArg, defaultValue), defaulted: boolLit(true, loc) };
|
|
5296
5438
|
}
|
|
5297
|
-
if ((lowerer.typeOf(node).flags & ts.TypeFlags.Null) !== 0) {
|
|
5439
|
+
if (!lowered && node && (lowerer.typeOf(node).flags & ts.TypeFlags.Null) !== 0) {
|
|
5298
5440
|
return { value: defaultAfterUndefined(lowerer.lowerExpr(node), defaultValue), defaulted: boolLit(true, loc) };
|
|
5299
5441
|
}
|
|
5300
|
-
const value = lowerer.lowerExpr(node);
|
|
5442
|
+
const value = lowered ?? lowerer.lowerExpr(node);
|
|
5301
5443
|
if (value.type.kind === "union") {
|
|
5302
5444
|
const def = lowerer.unions.get(value.type.unionId);
|
|
5303
5445
|
const units = def?.arms.filter(isUnitType) ?? [];
|
|
@@ -5343,7 +5485,7 @@ export function lowerFileHandleMethodCall(lowerer, call, access) {
|
|
|
5343
5485
|
};
|
|
5344
5486
|
}
|
|
5345
5487
|
}
|
|
5346
|
-
return { value: lowerer.coerceInto(node, value, F64), defaulted: boolLit(false, loc) };
|
|
5488
|
+
return { value: lowerer.coerceInto(node ?? call, value, F64), defaulted: boolLit(false, loc) };
|
|
5347
5489
|
};
|
|
5348
5490
|
const utf8 = (node) => {
|
|
5349
5491
|
const dflt = { kind: "strLit", value: "utf8", type: STRING, loc };
|
|
@@ -5358,6 +5500,30 @@ export function lowerFileHandleMethodCall(lowerer, call, access) {
|
|
|
5358
5500
|
}
|
|
5359
5501
|
return lowerBuiltinOptionalDefault(lowerer, node, STRING, dflt, true);
|
|
5360
5502
|
};
|
|
5503
|
+
if (name === "sync" || name === "datasync") {
|
|
5504
|
+
if (call.arguments.length !== 0)
|
|
5505
|
+
lowerer.noLowering(`FileHandle.${name} with arguments`, call);
|
|
5506
|
+
return { kind: "libCall", fn: name === "sync" ? "fileHandle.sync" : "fileHandle.datasync", args: [receiver()], type: promise(VOID), loc };
|
|
5507
|
+
}
|
|
5508
|
+
if (name === "truncate" || name === "chmod") {
|
|
5509
|
+
if (call.arguments.length > 1 || (name === "chmod" && call.arguments.length !== 1))
|
|
5510
|
+
lowerer.noLowering(`FileHandle.${name} with ${call.arguments.length} arguments`, call);
|
|
5511
|
+
return {
|
|
5512
|
+
kind: "libCall", fn: name === "truncate" ? "fileHandle.truncate" : "fileHandle.chmod",
|
|
5513
|
+
args: [receiver(), num(call.arguments[0], 0).value], type: promise(VOID), loc,
|
|
5514
|
+
};
|
|
5515
|
+
}
|
|
5516
|
+
if (name === "readv" || name === "writev") {
|
|
5517
|
+
if (call.arguments.length < 1 || call.arguments.length > 2)
|
|
5518
|
+
lowerer.noLowering(`FileHandle.${name} with ${call.arguments.length} arguments`, call);
|
|
5519
|
+
const type = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
5520
|
+
if (type?.kind !== "promise" || type.inner.kind !== "record")
|
|
5521
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
5522
|
+
return {
|
|
5523
|
+
kind: "libCall", fn: name === "readv" ? "fileHandle.readv" : "fileHandle.writev",
|
|
5524
|
+
args: [receiver(), lowerer.lowerExprExpecting(call.arguments[0], arrayOf(BYTES_U8)), num(call.arguments[1], -1).value], type, loc,
|
|
5525
|
+
};
|
|
5526
|
+
}
|
|
5361
5527
|
if (name === "close" || name === "stat") {
|
|
5362
5528
|
if (call.arguments.length !== 0)
|
|
5363
5529
|
lowerer.noLowering(`FileHandle.${name} with arguments`, call);
|
|
@@ -5415,6 +5581,65 @@ export function lowerFileHandleMethodCall(lowerer, call, access) {
|
|
|
5415
5581
|
}
|
|
5416
5582
|
lowerer.noLowering(`FileHandle.${name} of '${dataT ? lowerer.fmt(dataT) : lowerer.checker.typeToString(lowerer.typeOf(dataNode))}' data`, dataNode, "string and Uint8Array data are supported");
|
|
5417
5583
|
}
|
|
5584
|
+
if (name === "read" || name === "write") {
|
|
5585
|
+
const firstNode = call.arguments[0];
|
|
5586
|
+
const firstT = firstNode ? lowerer.mapTypeOf(lowerer.typeOf(firstNode)) : undefined;
|
|
5587
|
+
const secondT = call.arguments[1] ? lowerer.mapTypeOf(lowerer.typeOf(call.arguments[1])) : undefined;
|
|
5588
|
+
const readOptions = name === "read" && (!firstNode || firstT?.kind === "record" || (firstT && isUnitType(firstT)));
|
|
5589
|
+
const bufferOptions = firstT?.kind === "bytes" && firstT.elem === "u8" && secondT?.kind === "record";
|
|
5590
|
+
if (readOptions || bufferOptions) {
|
|
5591
|
+
if (call.arguments.length > (bufferOptions ? 2 : 1))
|
|
5592
|
+
lowerer.noLowering(`FileHandle.${name} options with extra arguments`, call);
|
|
5593
|
+
const type = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
5594
|
+
if (type?.kind !== "promise" || type.inner.kind !== "record")
|
|
5595
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
5596
|
+
const stmts = [];
|
|
5597
|
+
const stage = (value, label) => {
|
|
5598
|
+
const local = lowerer.declareHiddenLocal(label, value.type);
|
|
5599
|
+
stmts.push({ kind: "varDecl", localId: local.id, init: value, loc: value.loc });
|
|
5600
|
+
return varRef(local.id, local.type, loc);
|
|
5601
|
+
};
|
|
5602
|
+
const handle = stage(receiver(), "%fhWindowReceiver");
|
|
5603
|
+
let buffer = bufferOptions ? stage(lowerer.lowerExprExpecting(firstNode, BYTES_U8), "%fhWindowBuffer") : undefined;
|
|
5604
|
+
const optionsNode = bufferOptions ? call.arguments[1] : firstNode;
|
|
5605
|
+
const options = optionsNode ? stage(lowerer.lowerExpr(optionsNode), "%fhWindowOptions") : undefined;
|
|
5606
|
+
const field = (key) => {
|
|
5607
|
+
if (options?.type.kind !== "record")
|
|
5608
|
+
return undefined;
|
|
5609
|
+
const fields = lowerer.shapes.get(options.type.shapeId)?.fields;
|
|
5610
|
+
const getter = fields?.find((f) => f.name === `%get:${key}`);
|
|
5611
|
+
if (getter?.type.kind === "func") {
|
|
5612
|
+
const callee = { kind: "recordGet", obj: options, shapeId: options.type.shapeId, field: getter.name, type: getter.type, loc };
|
|
5613
|
+
return { kind: "callValue", callee, args: [], type: getter.type.ret, loc };
|
|
5614
|
+
}
|
|
5615
|
+
const member = fields?.find((f) => f.name === key);
|
|
5616
|
+
return member ? { kind: "recordGet", obj: options, shapeId: options.type.shapeId, field: key, type: member.type, loc } : undefined;
|
|
5617
|
+
};
|
|
5618
|
+
if (!buffer) {
|
|
5619
|
+
const supplied = field("buffer");
|
|
5620
|
+
const fresh = { kind: "bytesNew", source: numLit(16384, loc), type: BYTES_U8, loc };
|
|
5621
|
+
if (!supplied || isUnitType(supplied.type))
|
|
5622
|
+
buffer = supplied ? defaultAfterUndefined(supplied, fresh) : fresh;
|
|
5623
|
+
else if (supplied.type.kind === "union") {
|
|
5624
|
+
const arms = lowerer.unions.get(supplied.type.unionId)?.arms;
|
|
5625
|
+
if (!arms?.every((arm) => typeEquals(arm, BYTES_U8) || isUnitType(arm)))
|
|
5626
|
+
lowerer.noLowering("FileHandle.read with this buffer type", call);
|
|
5627
|
+
buffer = { kind: "nullish", left: supplied, right: fresh, type: BYTES_U8, loc };
|
|
5628
|
+
}
|
|
5629
|
+
else
|
|
5630
|
+
buffer = lowerer.coerceInto(call, supplied, BYTES_U8);
|
|
5631
|
+
buffer = stage(buffer, "%fhWindowBuffer");
|
|
5632
|
+
}
|
|
5633
|
+
const offset = num(undefined, 0, field("offset"));
|
|
5634
|
+
const length = num(undefined, -1, field("length"));
|
|
5635
|
+
const position = num(undefined, -1, field("position"));
|
|
5636
|
+
const result = {
|
|
5637
|
+
kind: "libCall", fn: name === "read" ? "fileHandle.read" : "fileHandle.writeBytes",
|
|
5638
|
+
args: [handle, buffer, offset.value, length.value, position.value, length.defaulted], type, loc,
|
|
5639
|
+
};
|
|
5640
|
+
return { kind: "seqExpr", stmts, result, type, loc };
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5418
5643
|
if (name === "read") {
|
|
5419
5644
|
if (call.arguments.length < 1 || call.arguments.length > 4) {
|
|
5420
5645
|
lowerer.noLowering(`FileHandle.read with ${call.arguments.length} arguments`, call, "use read(buffer[, offset[, length[, position]]])");
|
|
@@ -5473,7 +5698,7 @@ export function lowerFileHandleMethodCall(lowerer, call, access) {
|
|
|
5473
5698
|
}
|
|
5474
5699
|
lowerer.noLowering(`FileHandle.write of '${dataT ? lowerer.fmt(dataT) : lowerer.checker.typeToString(lowerer.typeOf(dataNode))}' data`, dataNode, "string and Uint8Array data are supported");
|
|
5475
5700
|
}
|
|
5476
|
-
lowerer.noLowering(`FileHandle.${name}`, call, "fd, close(), read(), write(), readFile(), writeFile(), appendFile(), and
|
|
5701
|
+
lowerer.noLowering(`FileHandle.${name}`, call, "fd, close(), read(), write(), readv(), writev(), readFile(), writeFile(), appendFile(), stat(), sync(), datasync(), truncate(), and chmod() are the supported FileHandle members", lowerer.checker.getSymbolAtLocation(access.name));
|
|
5477
5702
|
}
|
|
5478
5703
|
/** Method calls on Stats-typed receivers: isFile()/isDirectory()/
|
|
5479
5704
|
* isSymbolicLink() are pure reads on the stat snapshot (a followed
|
|
@@ -5627,6 +5852,21 @@ export function lowerAtomicsCall(lowerer, call, access) {
|
|
|
5627
5852
|
export function lowerBuiltinExtraProperty(lowerer, expr) {
|
|
5628
5853
|
if (expr.questionDotToken && !lowerer.chainHandled.has(expr))
|
|
5629
5854
|
return null;
|
|
5855
|
+
const codec = storedTextCodecClassOf(lowerer, expr.expression);
|
|
5856
|
+
if (codec && lowerer.isStdlibMember(expr) && ["encoding", "fatal", "ignoreBOM"].includes(expr.name.text)) {
|
|
5857
|
+
const receiver = lowerer.lowerExpr(expr.expression);
|
|
5858
|
+
if (receiver.type.kind !== "record")
|
|
5859
|
+
lowerer.badType(expr.expression, lowerer.typeOf(expr.expression));
|
|
5860
|
+
const loc = locOf(expr);
|
|
5861
|
+
if (codec === "TextEncoder" && expr.name.text === "encoding") {
|
|
5862
|
+
return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: receiver, loc }], result: strLit("utf-8", loc), type: STRING, loc };
|
|
5863
|
+
}
|
|
5864
|
+
if (codec === "TextDecoder") {
|
|
5865
|
+
const field = expr.name.text === "encoding" ? "%TextDecoder" : `%${expr.name.text}`;
|
|
5866
|
+
const value = { kind: "recordGet", obj: receiver, shapeId: receiver.type.shapeId, field, type: expr.name.text === "encoding" ? F64 : BOOL, loc };
|
|
5867
|
+
return expr.name.text === "encoding" ? { kind: "libCall", fn: "text.decoderName", args: [value], type: STRING, loc } : value;
|
|
5868
|
+
}
|
|
5869
|
+
}
|
|
5630
5870
|
// decoder.encoding on a StringDecoder-typed receiver: the record's
|
|
5631
5871
|
// hidden canonical-name field (construction folded the aliases —
|
|
5632
5872
|
// exactly what Node's normalized `.encoding` answers).
|
|
@@ -5637,6 +5877,15 @@ export function lowerBuiltinExtraProperty(lowerer, expr) {
|
|
|
5637
5877
|
return { kind: "recordGet", obj: receiver, shapeId: receiver.type.shapeId, field: "%enc", type: STRING, loc: locOf(expr) };
|
|
5638
5878
|
}
|
|
5639
5879
|
const kind = lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind;
|
|
5880
|
+
if (kind === "record" && ["read", "written"].includes(expr.name.text) && lowerer.isStdlibMember(expr)) {
|
|
5881
|
+
const receiver = lowerer.lowerExpr(expr.expression);
|
|
5882
|
+
if (receiver.type.kind === "record") {
|
|
5883
|
+
const fields = lowerer.shapes.get(receiver.type.shapeId)?.fields;
|
|
5884
|
+
if (fields?.length === 2 && fields.every((field) => ["read", "written"].includes(field.name) && field.type.kind === "f64")) {
|
|
5885
|
+
return { kind: "recordGet", obj: receiver, shapeId: receiver.type.shapeId, field: expr.name.text, type: F64, loc: locOf(expr) };
|
|
5886
|
+
}
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5640
5889
|
if (kind !== "stats" && kind !== "fileHandle" && kind !== "spawnRes" && kind !== "child" && kind !== "childWriter")
|
|
5641
5890
|
return null;
|
|
5642
5891
|
if (kind === "child" ? !isChildSurfaceMember(lowerer, expr) : !lowerer.isStdlibMember(expr))
|
|
@@ -5817,7 +6066,7 @@ export function lowerChildMethodCall(lowerer, call, access) {
|
|
|
5817
6066
|
if ((name === "on" || name === "once") && call.arguments.length === 2) {
|
|
5818
6067
|
const evT = lowerer.typeOf(call.arguments[0]);
|
|
5819
6068
|
const event = evT.isStringLiteralType() ? evT.value : null;
|
|
5820
|
-
if (event !== "exit" && event !== "close" && event !== "error" && event !== "message" && event !== "disconnect") {
|
|
6069
|
+
if (event !== "spawn" && event !== "exit" && event !== "close" && event !== "error" && event !== "message" && event !== "disconnect") {
|
|
5821
6070
|
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
6071
|
}
|
|
5823
6072
|
if (!ts.isExpressionStatement(call.parent)) {
|
|
@@ -5843,7 +6092,34 @@ export function lowerChildMethodCall(lowerer, call, access) {
|
|
|
5843
6092
|
loc,
|
|
5844
6093
|
};
|
|
5845
6094
|
}
|
|
6095
|
+
const listenerNode = stripTypeCasts(call.arguments[1]);
|
|
6096
|
+
if (isJsSourceFile(listenerNode.getSourceFile()) &&
|
|
6097
|
+
(ts.isArrowFunction(listenerNode) || ts.isFunctionExpression(listenerNode)) &&
|
|
6098
|
+
listenerNode.parameters.some((param) => param.dotDotDotToken) &&
|
|
6099
|
+
listenerNode.parameters.every((param) => !param.type) &&
|
|
6100
|
+
!/@(?:param|type)\b/.test(listenerNode.getSourceFile().text.slice(listenerNode.pos, listenerNode.getStart()))) {
|
|
6101
|
+
for (const param of listenerNode.parameters)
|
|
6102
|
+
lowerer.checkedCallbackParams.add(param);
|
|
6103
|
+
}
|
|
5846
6104
|
const cb = lowerer.lowerExpr(call.arguments[1]);
|
|
6105
|
+
if (isJsSourceFile(listenerNode.getSourceFile()) && cb.type.kind === "dyn" ||
|
|
6106
|
+
cb.type.kind === "func" && (cb.type.rest || isJsSourceFile(listenerNode.getSourceFile()) && cb.type.params.some((param) => param.kind === "dyn"))) {
|
|
6107
|
+
if (cb.type.kind !== "dyn" && !canBoxFuncIntoDyn(cb.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
6108
|
+
lowerer.noLowering("child event listeners with non-representable parameters", call.arguments[1]);
|
|
6109
|
+
}
|
|
6110
|
+
return {
|
|
6111
|
+
kind: "libCall", fn: "child.onDyn",
|
|
6112
|
+
args: [receiver, { kind: "strLit", value: event, type: STRING, loc },
|
|
6113
|
+
cb.type.kind === "dyn" ? cb : { kind: "dynFrom", value: cb, type: DYN, loc }],
|
|
6114
|
+
type: VOID, loc,
|
|
6115
|
+
};
|
|
6116
|
+
}
|
|
6117
|
+
if (event === "spawn") {
|
|
6118
|
+
if (cb.type.kind !== "func" || cb.type.params.length !== 0 || cb.type.ret.kind !== "void") {
|
|
6119
|
+
lowerer.noLowering("spawn event listeners with parameters or a returned value", call.arguments[1]);
|
|
6120
|
+
}
|
|
6121
|
+
return { kind: "libCall", fn: "child.onSpawn", args: [receiver, cb], type: VOID, loc };
|
|
6122
|
+
}
|
|
5847
6123
|
if (cb.type.kind !== "func" || cb.type.params.length > (event === "error" ? 1 : 2)) {
|
|
5848
6124
|
lowerer.unsupported("SC1090", call.arguments[1], event !== "error"
|
|
5849
6125
|
? `${event} listeners with more than two parameters (use (code, signal), (code), or ())`
|
|
@@ -5918,9 +6194,9 @@ export function lowerChildMethodCall(lowerer, call, access) {
|
|
|
5918
6194
|
// child.unref(): drops the child from the event loop's keep-alive set
|
|
5919
6195
|
// (the process may exit while the child runs — Node's semantics; the
|
|
5920
6196
|
// child is still reaped while the loop runs for other reasons).
|
|
5921
|
-
if (name === "unref" && call.arguments.length === 0) {
|
|
6197
|
+
if ((name === "unref" || name === "ref") && call.arguments.length === 0) {
|
|
5922
6198
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
5923
|
-
return { kind: "libCall", fn: "child.unref", args: [receiver], type: VOID, loc };
|
|
6199
|
+
return { kind: "libCall", fn: name === "ref" ? "child.ref" : "child.unref", args: [receiver], type: VOID, loc };
|
|
5924
6200
|
}
|
|
5925
6201
|
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
6202
|
}
|
|
@@ -6217,7 +6493,8 @@ export function lowerErrorCodeProperty(lowerer, expr) {
|
|
|
6217
6493
|
return null;
|
|
6218
6494
|
if (!lowerer.isStdlibMember(expr))
|
|
6219
6495
|
return null;
|
|
6220
|
-
const
|
|
6496
|
+
const rawReceiver = lowerer.lowerExpr(expr.expression);
|
|
6497
|
+
const receiver = rawReceiver.type.kind === "dyn" ? lowerer.coerceInto(expr.expression, rawReceiver, recvT) : rawReceiver;
|
|
6221
6498
|
return {
|
|
6222
6499
|
kind: "libCall",
|
|
6223
6500
|
fn: expr.name.text === "stack" ? "error.stack" : expr.name.text === "cause" ? "error.cause" : "error.code",
|
|
@@ -6259,10 +6536,10 @@ export function lowerFsConstantsProperty(lowerer, expr) {
|
|
|
6259
6536
|
const bi = lowerer.builtinImportOf(expr.expression);
|
|
6260
6537
|
if (!bi || bi.module !== "fs" || bi.member !== "constants")
|
|
6261
6538
|
return null;
|
|
6262
|
-
const MODES = { F_OK: 0, X_OK: 1, W_OK: 2, R_OK: 4 };
|
|
6539
|
+
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
6540
|
const value = own(MODES, expr.name.text);
|
|
6264
6541
|
if (value === undefined) {
|
|
6265
|
-
lowerer.noLowering(`fs.constants.${expr.name.text}`, expr, "F_OK, R_OK, W_OK, and
|
|
6542
|
+
lowerer.noLowering(`fs.constants.${expr.name.text}`, expr, "F_OK, R_OK, W_OK, X_OK, and COPYFILE_* are the lowered constants");
|
|
6266
6543
|
}
|
|
6267
6544
|
return { kind: "numLit", value, type: F64, loc: locOf(expr) };
|
|
6268
6545
|
}
|
|
@@ -6917,6 +7194,19 @@ export function lowerProcessEnvGet(lowerer, expr) {
|
|
|
6917
7194
|
const key = { kind: "strLit", value: expr.name.text, type: STRING, loc: locOf(expr.name) };
|
|
6918
7195
|
return { kind: "libCall", fn: "process.envGet", args: [key], type: lowerer.envValueType(), loc };
|
|
6919
7196
|
}
|
|
7197
|
+
function lowerProcessLoadEnvFile(lowerer, call) {
|
|
7198
|
+
if (call.arguments.length > 1 || call.arguments.some(ts.isSpreadElement)) {
|
|
7199
|
+
lowerer.noLowering("process.loadEnvFile with spread or extra arguments", call);
|
|
7200
|
+
}
|
|
7201
|
+
const loc = locOf(call);
|
|
7202
|
+
const path = call.arguments[0] ? lowerer.lowerExprExpecting(call.arguments[0], DYN)
|
|
7203
|
+
: { kind: "dynFrom", value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc }, type: DYN, loc };
|
|
7204
|
+
const load = { kind: "libCall", fn: "process.loadEnvFile", args: [path], type: VOID, loc };
|
|
7205
|
+
if (ts.isExpressionStatement(call.parent))
|
|
7206
|
+
return load;
|
|
7207
|
+
return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: load, loc }],
|
|
7208
|
+
result: { kind: "dynFrom", value: { kind: "unitLit", unit: "undefined", type: UNDEFINED_T, loc }, type: DYN, loc }, type: DYN, loc };
|
|
7209
|
+
}
|
|
6920
7210
|
/** `process.exit(code)` / `process.cwd()` → libCall. The fallback
|
|
6921
7211
|
* declaration makes exit's code required; @types/node declares it
|
|
6922
7212
|
* optional. A bare `process.exit()` uses the current exitCode, or zero
|
|
@@ -6934,6 +7224,8 @@ export function lowerProcessMethodCall(lowerer, call, access) {
|
|
|
6934
7224
|
}
|
|
6935
7225
|
}
|
|
6936
7226
|
const directProcessMember = lowerer.stdlibGlobalMember(access, "process");
|
|
7227
|
+
if (directProcessMember === "loadEnvFile")
|
|
7228
|
+
return lowerProcessLoadEnvFile(lowerer, call);
|
|
6937
7229
|
if (directProcessMember === "hrtime") {
|
|
6938
7230
|
if (call.arguments.some(ts.isSpreadElement))
|
|
6939
7231
|
lowerer.noLowering("process.hrtime with spread arguments", call);
|
|
@@ -7777,7 +8069,7 @@ export function lowerDateCall(lowerer, call, access) {
|
|
|
7777
8069
|
export function lowerTextCodecNew(lowerer, ctor, cls) {
|
|
7778
8070
|
const args = ctor.arguments ?? [];
|
|
7779
8071
|
const loc = locOf(ctor);
|
|
7780
|
-
let encoding = -1;
|
|
8072
|
+
let encoding = { kind: "numLit", value: -1, type: F64, loc };
|
|
7781
8073
|
let label = null;
|
|
7782
8074
|
if (cls === "TextEncoder") {
|
|
7783
8075
|
if (args.length !== 0)
|
|
@@ -7786,17 +8078,39 @@ export function lowerTextCodecNew(lowerer, ctor, cls) {
|
|
|
7786
8078
|
else if (args.length !== 0) {
|
|
7787
8079
|
const labelT = lowerer.typeOf(args[0]);
|
|
7788
8080
|
const parsed = labelT.isStringLiteralType() ? staticTextDecoderEncoding(labelT.value) : null;
|
|
7789
|
-
if (args.length
|
|
7790
|
-
lowerer.noLowering("new TextDecoder with
|
|
8081
|
+
if (args.length > 2)
|
|
8082
|
+
lowerer.noLowering("new TextDecoder with extra arguments", ctor);
|
|
8083
|
+
if (parsed === null) {
|
|
8084
|
+
encoding = { kind: "libCall", fn: "text.decoderEncoding", args: [lowerer.lowerExprExpecting(args[0], DYN)], type: F64, loc };
|
|
8085
|
+
}
|
|
8086
|
+
else {
|
|
8087
|
+
encoding = { kind: "numLit", value: parsed.kind === "utf8" ? -1 : parsed.id, type: F64, loc };
|
|
8088
|
+
label = lowerer.lowerExprExpecting(args[0], STRING);
|
|
8089
|
+
}
|
|
8090
|
+
}
|
|
8091
|
+
const options = args[1] ? stripTypeCasts(args[1]) : null;
|
|
8092
|
+
const flags = new Map();
|
|
8093
|
+
for (const name of ["fatal", "ignoreBOM"])
|
|
8094
|
+
flags.set(name, { kind: "boolLit", value: false, type: BOOL, loc });
|
|
8095
|
+
if (options) {
|
|
8096
|
+
if (!ts.isObjectLiteralExpression(options))
|
|
8097
|
+
lowerer.noLowering("TextDecoder options outside an object literal", options);
|
|
8098
|
+
for (const property of options.properties) {
|
|
8099
|
+
if ((!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property)) ||
|
|
8100
|
+
!ts.isIdentifier(property.name) || !flags.has(property.name.text))
|
|
8101
|
+
lowerer.noLowering("unknown TextDecoder option", property);
|
|
8102
|
+
const value = ts.isPropertyAssignment(property) ? property.initializer : property.name;
|
|
8103
|
+
flags.set(property.name.text, lowerer.lowerExprExpecting(value, BOOL));
|
|
7791
8104
|
}
|
|
7792
|
-
encoding = parsed.kind === "utf8" ? -1 : parsed.id;
|
|
7793
|
-
label = lowerer.lowerExprExpecting(args[0], STRING);
|
|
7794
8105
|
}
|
|
7795
8106
|
const type = lowerer.mapTypeOf(lowerer.typeOf(ctor));
|
|
7796
8107
|
if (type?.kind !== "record")
|
|
7797
8108
|
lowerer.badType(ctor, lowerer.typeOf(ctor));
|
|
7798
8109
|
const result = {
|
|
7799
|
-
kind: "recordLit", fields: [{ name: `%${cls}`, value:
|
|
8110
|
+
kind: "recordLit", fields: [{ name: `%${cls}`, value: encoding }, ...(cls === "TextDecoder" ? [
|
|
8111
|
+
...[...flags].map(([name, value]) => ({ name: `%${name}`, value })),
|
|
8112
|
+
{ name: "%state", value: { kind: "dynObjLit", fields: [], type: DYN, loc } },
|
|
8113
|
+
] : [])], type, loc,
|
|
7800
8114
|
};
|
|
7801
8115
|
return label === null || label.kind === "strLit" ? result : {
|
|
7802
8116
|
kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: label, loc }], result, type, loc,
|
|
@@ -7814,17 +8128,32 @@ function lowerStoredTextCodecCall(lowerer, call, access) {
|
|
|
7814
8128
|
return null;
|
|
7815
8129
|
if (access.name.text !== (cls === "TextEncoder" ? "encode" : "decode"))
|
|
7816
8130
|
return null;
|
|
7817
|
-
if (call.arguments.length > 1) {
|
|
7818
|
-
lowerer.noLowering(cls
|
|
8131
|
+
if (call.arguments.length > (cls === "TextDecoder" ? 2 : 1)) {
|
|
8132
|
+
lowerer.noLowering(`${cls}.${access.name.text} with extra arguments`, call);
|
|
7819
8133
|
}
|
|
7820
8134
|
const loc = locOf(call);
|
|
8135
|
+
let stream = { kind: "boolLit", value: false, type: BOOL, loc };
|
|
8136
|
+
if (cls === "TextDecoder" && call.arguments[1]) {
|
|
8137
|
+
const options = stripTypeCasts(call.arguments[1]);
|
|
8138
|
+
if (!ts.isObjectLiteralExpression(options))
|
|
8139
|
+
lowerer.noLowering("TextDecoder.decode options outside an object literal", options);
|
|
8140
|
+
for (const property of options.properties) {
|
|
8141
|
+
if ((!ts.isPropertyAssignment(property) && !ts.isShorthandPropertyAssignment(property)) ||
|
|
8142
|
+
!ts.isIdentifier(property.name) || property.name.text !== "stream")
|
|
8143
|
+
lowerer.noLowering("unknown TextDecoder.decode option", property);
|
|
8144
|
+
stream = lowerer.lowerExprExpecting(ts.isPropertyAssignment(property) ? property.initializer : property.name, BOOL);
|
|
8145
|
+
}
|
|
8146
|
+
}
|
|
7821
8147
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
7822
8148
|
if (receiver.type.kind !== "record")
|
|
7823
8149
|
lowerer.badType(access.expression, lowerer.typeOf(access.expression));
|
|
7824
|
-
|
|
8150
|
+
let arg = call.arguments.length === 0
|
|
7825
8151
|
? cls === "TextEncoder" ? strLit("", loc)
|
|
7826
8152
|
: { kind: "bytesNew", source: null, type: BYTES_U8, loc }
|
|
7827
8153
|
: cls === "TextEncoder" ? lowerer.lowerExprExpecting(call.arguments[0], STRING) : lowerer.lowerExpr(call.arguments[0]);
|
|
8154
|
+
if (cls === "TextDecoder" && (arg.type.kind === "dyn" || arg.type.kind === "bytes" && arg.type.elem !== "u8")) {
|
|
8155
|
+
arg = { kind: "libCall", fn: "bytes.bufferSource", args: [lowerer.coerceInto(call.arguments[0], arg, DYN)], type: BYTES_U8, loc };
|
|
8156
|
+
}
|
|
7828
8157
|
if (cls === "TextDecoder" && !(arg.type.kind === "bytes" && arg.type.elem === "u8")) {
|
|
7829
8158
|
lowerer.noLowering(`TextDecoder.decode of '${lowerer.fmt(arg.type)}' values`, call, "Uint8Array/Buffer input decodes (ArrayBuffer values have no representation)");
|
|
7830
8159
|
}
|
|
@@ -7837,22 +8166,22 @@ function lowerStoredTextCodecCall(lowerer, call, access) {
|
|
|
7837
8166
|
const input = varRef("input.0", arg.type, loc);
|
|
7838
8167
|
const result = cls === "TextEncoder"
|
|
7839
8168
|
? { 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
|
-
|
|
8169
|
+
: { kind: "libCall", fn: "text.decodeStream", args: [
|
|
8170
|
+
{ kind: "recordGet", obj: varRef("codec.0", recT, loc), shapeId: recT.shapeId, field: "%state", type: DYN, loc },
|
|
8171
|
+
input,
|
|
8172
|
+
{ kind: "recordGet", obj: varRef("codec.0", recT, loc), shapeId: recT.shapeId, field: "%TextDecoder", type: F64, loc },
|
|
8173
|
+
...["%fatal", "%ignoreBOM"].map((field) => ({ kind: "recordGet", obj: varRef("codec.0", recT, loc), shapeId: recT.shapeId, field, type: BOOL, loc })),
|
|
8174
|
+
varRef("stream.0", BOOL, loc),
|
|
8175
|
+
], type: STRING, loc };
|
|
7847
8176
|
lowerer.liftedFns.push({
|
|
7848
8177
|
name,
|
|
7849
|
-
params: [{ localId: "codec.0", name: "codec", type: recT }, { localId: "input.0", name: "input", type: arg.type }],
|
|
8178
|
+
params: [{ localId: "codec.0", name: "codec", type: recT }, { localId: "input.0", name: "input", type: arg.type }, { localId: "stream.0", name: "stream", type: BOOL }],
|
|
7850
8179
|
returnType: result.type,
|
|
7851
|
-
locals: [{ id: "codec.0", name: "codec", type: recT, mutable: false }, { id: "input.0", name: "input", type: arg.type, mutable: false }],
|
|
8180
|
+
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
8181
|
body: [{ kind: "return", value: result, loc }], loc,
|
|
7853
8182
|
});
|
|
7854
8183
|
}
|
|
7855
|
-
return { kind: "call", callee: name, args: [receiver, arg], type: cls === "TextEncoder" ? BYTES_U8 : STRING, loc };
|
|
8184
|
+
return { kind: "call", callee: name, args: [receiver, arg, stream], type: cls === "TextEncoder" ? BYTES_U8 : STRING, loc };
|
|
7856
8185
|
}
|
|
7857
8186
|
/** A direct construction of THE stdlib TextEncoder/TextDecoder, through
|
|
7858
8187
|
* type-only wrappers. Name alone is never enough: a user class with the
|
|
@@ -7885,6 +8214,18 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7885
8214
|
if (call.questionDotToken || access.questionDotToken)
|
|
7886
8215
|
return null;
|
|
7887
8216
|
const member = access.name.text;
|
|
8217
|
+
if (member === "encodeInto" && storedTextCodecClassOf(lowerer, access.expression) === "TextEncoder" && lowerer.isStdlibMember(access)) {
|
|
8218
|
+
if (call.arguments.length !== 2 || call.arguments.some(ts.isSpreadElement))
|
|
8219
|
+
lowerer.noLowering("TextEncoder.encodeInto with this argument shape", call);
|
|
8220
|
+
const loc = locOf(call);
|
|
8221
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
8222
|
+
const result = { kind: "libCall", fn: "text.encodeInto", args: call.arguments.map((arg) => lowerer.lowerExprExpecting(stripTypeCasts(arg), DYN)), type: DYN, loc };
|
|
8223
|
+
const type = lowerer.mapTypeOf(lowerer.typeOf(call));
|
|
8224
|
+
if (!type)
|
|
8225
|
+
lowerer.badType(call, lowerer.typeOf(call));
|
|
8226
|
+
const checked = lowerer.coerceInto(call, result, type);
|
|
8227
|
+
return { kind: "seqExpr", stmts: [{ kind: "exprStmt", expr: receiver, loc }], result: checked, type, loc };
|
|
8228
|
+
}
|
|
7888
8229
|
if (member !== "decode" && member !== "encode")
|
|
7889
8230
|
return null;
|
|
7890
8231
|
const info = directTextCodecCtorOf(lowerer, access.expression);
|
|
@@ -7893,6 +8234,8 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7893
8234
|
if (!lowerer.isStdlibMember(access))
|
|
7894
8235
|
return null;
|
|
7895
8236
|
const { cls, ctor: recv } = info;
|
|
8237
|
+
if (cls === "TextDecoder" && ((recv.arguments?.length ?? 0) > 1 || call.arguments.length > 1))
|
|
8238
|
+
return lowerStoredTextCodecCall(lowerer, call, access);
|
|
7896
8239
|
if (!(cls === "TextDecoder" && member === "decode") && !(cls === "TextEncoder" && member === "encode")) {
|
|
7897
8240
|
return null;
|
|
7898
8241
|
}
|
|
@@ -7909,7 +8252,7 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7909
8252
|
? staticTextDecoderEncoding(labelT.value)
|
|
7910
8253
|
: null;
|
|
7911
8254
|
if (ctorArgs.length > 1 || encoding === null) {
|
|
7912
|
-
lowerer
|
|
8255
|
+
return lowerStoredTextCodecCall(lowerer, call, access);
|
|
7913
8256
|
}
|
|
7914
8257
|
const labelEffect = ctorArgs.length === 1
|
|
7915
8258
|
? lowerer.lowerExprExpecting(ctorArgs[0], STRING)
|
|
@@ -7931,7 +8274,10 @@ export function lowerTextCodecCall(lowerer, call, access) {
|
|
|
7931
8274
|
lowerer.noLowering("decode with a stream option", call, "streaming decode has no lowering — decode whole buffers");
|
|
7932
8275
|
}
|
|
7933
8276
|
const argNode = call.arguments[0];
|
|
7934
|
-
|
|
8277
|
+
let arg = lowerer.lowerExpr(argNode);
|
|
8278
|
+
if (arg.type.kind === "dyn" || arg.type.kind === "bytes" && arg.type.elem !== "u8") {
|
|
8279
|
+
arg = { kind: "libCall", fn: "bytes.bufferSource", args: [lowerer.coerceInto(argNode, arg, DYN)], type: BYTES_U8, loc };
|
|
8280
|
+
}
|
|
7935
8281
|
if (!(arg.type.kind === "bytes" && arg.type.elem === "u8")) {
|
|
7936
8282
|
lowerer.noLowering(`TextDecoder.decode of '${lowerer.fmt(arg.type)}' values`, argNode, "Uint8Array/Buffer input decodes (ArrayBuffer values have no representation)");
|
|
7937
8283
|
}
|
|
@@ -8159,7 +8505,7 @@ export function lowerPromiseStaticCall(lowerer, call, access) {
|
|
|
8159
8505
|
// reads are the routed keyed ops). All-static tuples keep the
|
|
8160
8506
|
// typed fence hint below. --dynamic only by construction: jsval
|
|
8161
8507
|
// entries exist only there.
|
|
8162
|
-
if (elems.some((e) => e.type.kind === "jsval")) {
|
|
8508
|
+
if (lowerer.dynamic && elems.some((e) => e.type.kind === "jsval" || e.type.kind === "dyn")) {
|
|
8163
8509
|
const diagsBefore = lowerer.diags.length;
|
|
8164
8510
|
try {
|
|
8165
8511
|
const marshaled = argNode.elements.map((el, i) => lowerer.jsvalIn(elems[i], el));
|
|
@@ -8183,16 +8529,21 @@ export function lowerPromiseStaticCall(lowerer, call, access) {
|
|
|
8183
8529
|
lowerer.diags.splice(diagsBefore);
|
|
8184
8530
|
}
|
|
8185
8531
|
}
|
|
8532
|
+
if (!lowerer.dynamic && isJsSourceFile(call.getSourceFile()) && elems.every((entry) => lowerer.dynConvertible(entry.type))) {
|
|
8533
|
+
return checkedPromiseAll(lowerer, { kind: "arrayLit", elems: elems.map((entry) => lowerer.coerceToExpected(entry, DYN)), type: arrayOf(DYN), loc }, loc);
|
|
8534
|
+
}
|
|
8186
8535
|
lowerer.noLowering("Promise.all over this argument shape", argNode, "the entries must share ONE promise type — Promise.all([p, q]) lowers when p and q are the same Promise<T>");
|
|
8187
8536
|
}
|
|
8188
8537
|
const entries = lowerer.lowerExpr(argNode);
|
|
8538
|
+
if (!lowerer.dynamic && isJsSourceFile(call.getSourceFile()) && entries.type.kind === "dyn")
|
|
8539
|
+
return checkedPromiseAll(lowerer, entries, loc);
|
|
8189
8540
|
// A NON-literal island argument (`Promise.all(plugins.map((p) =>
|
|
8190
8541
|
// loadPlugin(p)))` — the loadPlugins shape, where the checker
|
|
8191
8542
|
// spells `any[]`): the ENGINE's own Promise.all runs over the
|
|
8192
8543
|
// marshaled array (an 'any' value passes through; an `any[]` value
|
|
8193
8544
|
// lifts per element by reference), the result staying an island
|
|
8194
8545
|
// value the static side awaits through the island→static bridge.
|
|
8195
|
-
if (entries.type.kind === "jsval" ||
|
|
8546
|
+
if (entries.type.kind === "jsval" || lowerer.dynamic && entries.type.kind === "dyn" ||
|
|
8196
8547
|
(entries.type.kind === "array" && entries.type.elem.kind === "jsval")) {
|
|
8197
8548
|
const diagsBefore = lowerer.diags.length;
|
|
8198
8549
|
try {
|
|
@@ -8368,11 +8719,12 @@ export function lowerPromiseStaticCall(lowerer, call, access) {
|
|
|
8368
8719
|
return { kind: "intrinsic", name: "promise.resolve", args: [], type: { kind: "promise", inner: VOID }, loc };
|
|
8369
8720
|
}
|
|
8370
8721
|
if (resultT.inner.kind === "void") {
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8722
|
+
return {
|
|
8723
|
+
kind: "seqExpr",
|
|
8724
|
+
stmts: [lowerer.lowerExprStatement(argNode)],
|
|
8725
|
+
result: { kind: "intrinsic", name: "promise.resolve", args: [], type: resultT, loc },
|
|
8726
|
+
type: resultT, loc,
|
|
8727
|
+
};
|
|
8376
8728
|
}
|
|
8377
8729
|
if (isUnitType(resultT.inner)) {
|
|
8378
8730
|
// A unit payload (Promise<undefined>/Promise<null>) has no
|
|
@@ -8392,6 +8744,9 @@ export function lowerNumberStaticProperty(lowerer, expr) {
|
|
|
8392
8744
|
const member = lowerer.stdlibGlobalMember(expr, "Number");
|
|
8393
8745
|
if (member === null)
|
|
8394
8746
|
return null;
|
|
8747
|
+
const predicate = own(NUMBER_STATIC_PREDICATES, member);
|
|
8748
|
+
if (predicate)
|
|
8749
|
+
return lowerCheckedPredicateValue(lowerer, `Number.${member}`, "number", locOf(expr), predicate);
|
|
8395
8750
|
const value = own(NUMBER_CONSTANTS, member);
|
|
8396
8751
|
if (value === undefined)
|
|
8397
8752
|
return null;
|