@scriptc/compiler 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +158 -31
- package/dist/backend/cycle-analysis.js +63 -50
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +51 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/llvm/borrowed-receivers.d.ts +9 -0
- package/dist/backend/llvm/borrowed-receivers.js +58 -0
- package/dist/backend/llvm/borrowed-receivers.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.d.ts +20 -0
- package/dist/backend/llvm/call-lifetimes.js +179 -0
- package/dist/backend/llvm/call-lifetimes.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.test.d.ts +1 -0
- package/dist/backend/llvm/call-lifetimes.test.js +205 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +5 -2
- package/dist/backend/llvm/dyn.js +163 -47
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +37 -1
- package/dist/backend/llvm/emitter.js +209 -21
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +29 -2
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +1 -1
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +42 -5
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +75 -13
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +31 -6
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +6 -5
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +1 -1
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +75 -19
- 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-shared.js +70 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +44 -0
- package/dist/backend/llvm/local-array-reads.js +313 -0
- package/dist/backend/llvm/local-array-reads.js.map +1 -0
- package/dist/backend/llvm/local-array-reads.test.d.ts +1 -0
- package/dist/backend/llvm/local-array-reads.test.js +446 -0
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +36 -0
- package/dist/backend/llvm/map-read-lifetimes.js +128 -0
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.test.d.ts +1 -0
- package/dist/backend/llvm/map-read-lifetimes.test.js +123 -0
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -0
- package/dist/backend/llvm/shapes.js +1 -0
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/split.js +15 -5
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +17 -0
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.d.ts +20 -0
- package/dist/backend/llvm/stack-unions.js +61 -0
- package/dist/backend/llvm/stack-unions.js.map +1 -0
- package/dist/backend/llvm/stack-unions.test.d.ts +1 -0
- package/dist/backend/llvm/stack-unions.test.js +241 -0
- package/dist/backend/llvm/stack-unions.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.d.ts +12 -0
- package/dist/backend/llvm/string-lifetimes.js +70 -0
- package/dist/backend/llvm/string-lifetimes.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.test.d.ts +1 -0
- package/dist/backend/llvm/string-lifetimes.test.js +230 -0
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -0
- package/dist/backend/mangle.d.ts +2 -0
- package/dist/backend/mangle.js +4 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +71 -29
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +104 -1
- package/dist/backend/may-throw.test.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 +2 -2
- package/dist/backend/native-toolchain.js +2 -0
- package/dist/backend/native-toolchain.js.map +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/coverage/surface-manifest.js +5 -3
- package/dist/coverage/surface-manifest.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/input-tracker.js +3 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +38 -2
- package/dist/frontend/input-tracker.test.js.map +1 -1
- 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 +1 -1
- package/dist/frontend/lowering/class-callbacks.js +7 -6
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +2 -0
- package/dist/frontend/lowering/class-construction.js +34 -5
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +1 -1
- package/dist/frontend/lowering/class-descriptors.js +12 -5
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +25 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +597 -78
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +64 -2
- 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 +11 -41
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.d.ts +16 -0
- package/dist/frontend/lowering/class-method-values.js +60 -29
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +5 -1
- package/dist/frontend/lowering/class-prototypes.js +69 -10
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +4 -4
- package/dist/frontend/lowering/class-runtime-statics.js +26 -8
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.d.ts +1 -0
- package/dist/frontend/lowering/class-static-data.js +4 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.d.ts +31 -0
- package/dist/frontend/lowering/collection-ingestion.js +215 -0
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.js +19 -4
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +6 -1
- 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/expressions/object-literals.js +31 -1
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +3 -3
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/import-meta.d.ts +10 -0
- package/dist/frontend/lowering/import-meta.js +52 -0
- package/dist/frontend/lowering/import-meta.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.js +105 -41
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +2 -0
- package/dist/frontend/lowering/lower-builtin-values.js +22 -1
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +7 -22
- package/dist/frontend/lowering/lower-builtins.js +439 -95
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +289 -76
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +5 -0
- package/dist/frontend/lowering/lower-classes.js +443 -29
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +6 -2
- package/dist/frontend/lowering/lower-containers.js +79 -20
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +10 -6
- package/dist/frontend/lowering/lower-exprs.js +329 -170
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +5 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +58 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +4 -0
- 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 +186 -82
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +69 -1
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +172 -103
- 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 +2 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-system-errors.d.ts +6 -0
- package/dist/frontend/lowering/lower-system-errors.js +29 -0
- package/dist/frontend/lowering/lower-system-errors.js.map +1 -0
- 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 +30 -12
- package/dist/frontend/lowering/lowerer.js +268 -49
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +38 -0
- 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 -2
- package/dist/frontend/lowering/surfaces.js +93 -33
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.js +3 -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/module-syntax.d.ts +1 -1
- package/dist/frontend/module-syntax.js +8 -1
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/module-syntax.test.js +10 -0
- package/dist/frontend/module-syntax.test.js.map +1 -1
- package/dist/frontend/npm.d.ts +4 -0
- package/dist/frontend/npm.js +86 -33
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +103 -0
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.js +2 -1
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/program.js +4 -2
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/services-node.js +3 -2
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services.d.ts +5 -1
- package/dist/frontend/services.js +9 -1
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +21 -0
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +2 -0
- package/dist/frontend/ts7/ast-node.js +30 -4
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +60 -1
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/type-mapper.js +89 -14
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/union-discriminants.js +22 -7
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/index.js +19 -12
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +1 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +7 -0
- package/dist/ir/integer-loops.js +23 -0
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.d.ts +1 -0
- package/dist/ir/integer-loops.test.js +41 -0
- package/dist/ir/integer-loops.test.js.map +1 -0
- package/dist/ir/ir.d.ts +44 -26
- package/dist/ir/ir.js +69 -11
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +18 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/serialize.js +21 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +21 -0
- 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 +216 -80
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +244 -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/fence-eval.js +9 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/fence-eval.test.d.ts +1 -0
- package/dist/library/fence-eval.test.js +21 -0
- package/dist/library/fence-eval.test.js.map +1 -0
- 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/runtime-typescript.d.ts +4 -0
- package/dist/native/runtime-typescript.js +61 -0
- package/dist/native/runtime-typescript.js.map +1 -0
- package/dist/native/runtime-typescript.test.d.ts +1 -0
- package/dist/native/runtime-typescript.test.js +41 -0
- package/dist/native/runtime-typescript.test.js.map +1 -0
- package/package.json +20 -20
- package/surface-manifest.json +385 -29
package/dist/ir/validate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { arrayOf, BYTES_ELEMENT_NAME, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canDynCheckTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, CHILDWRITER_T, CRYPTOHASH_T, CRYPTOHMAC_T, DATE_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, ffiClassType, ffiSourceParamTypes, FILEHANDLE_T, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isDynTypedRefType, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isJsonSafeType, isJsonStringifySafeType, isRefCounted, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, shapeHasAccessorSlots, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionContainerArmsOk, URL_T, VOID } from "./ir.js";
|
|
2
|
-
import { BIGINT_T } from "./ir.js";
|
|
2
|
+
import { BIGINT_T, DYN_CLASS_PROPERTIES } from "./ir.js";
|
|
3
3
|
import { unionWideningTags } from "./analysis.js";
|
|
4
4
|
import { alwaysReturns } from "./control-flow.js";
|
|
5
5
|
/** Per-method signature for strIntrinsic: `argTypes` lists every argument
|
|
@@ -26,6 +26,7 @@ export const STR_INTRINSIC_SIGS = {
|
|
|
26
26
|
padEnd: { argTypes: [F64, STRING], minArgs: 2, result: STRING },
|
|
27
27
|
toLowerCase: { argTypes: [], minArgs: 0, result: STRING },
|
|
28
28
|
toUpperCase: { argTypes: [], minArgs: 0, result: STRING },
|
|
29
|
+
normalize: { argTypes: [STRING], minArgs: 1, result: STRING },
|
|
29
30
|
isWellFormed: { argTypes: [], minArgs: 0, result: BOOL },
|
|
30
31
|
toWellFormed: { argTypes: [], minArgs: 0, result: STRING },
|
|
31
32
|
cpAt: { argTypes: [F64], minArgs: 1, result: STRING },
|
|
@@ -63,6 +64,10 @@ export const LIB_FN_SIGS = {
|
|
|
63
64
|
"fetch.start": { argTypes: [STRING, DYN], result: { kind: "promise", inner: DYN } },
|
|
64
65
|
"fetch.responseNew": { argTypes: [DYN, DYN], result: DYN },
|
|
65
66
|
"fetch.input": { argTypes: [DYN, DYN], result: { kind: "promise", inner: DYN } },
|
|
67
|
+
"abort.controllerNew": { argTypes: [], result: DYN },
|
|
68
|
+
"abort.timeout": { argTypes: [DYN], result: DYN },
|
|
69
|
+
"abort.now": { argTypes: [DYN], result: DYN },
|
|
70
|
+
"abort.any": { argTypes: [DYN], result: DYN },
|
|
66
71
|
"fetch.function": { argTypes: [], result: DYN },
|
|
67
72
|
"fetch.requestNew": { argTypes: [DYN, DYN], result: DYN },
|
|
68
73
|
"fetch.headersNew": { argTypes: [DYN], result: DYN },
|
|
@@ -130,6 +135,7 @@ export const LIB_FN_SIGS = {
|
|
|
130
135
|
"dyn.defineProperty": { argTypes: [DYN, DYN, DYN], result: DYN },
|
|
131
136
|
"dyn.getOwnPropertyDescriptor": { argTypes: [DYN, DYN], result: DYN },
|
|
132
137
|
"dyn.arrayProtoCall": { argTypes: [DYN, STRING, DYN], result: DYN },
|
|
138
|
+
"dyn.promiseAll": { argTypes: [DYN], result: { kind: "promise", inner: DYN } },
|
|
133
139
|
"dyn.typeof": { argTypes: [DYN], result: STRING },
|
|
134
140
|
"dyn.objectTag": { argTypes: [DYN], result: STRING },
|
|
135
141
|
"module.registryInit": { argTypes: [F64], result: VOID },
|
|
@@ -229,6 +235,7 @@ export const LIB_FN_SIGS = {
|
|
|
229
235
|
"os.totalmem": { argTypes: [], result: F64 },
|
|
230
236
|
"process.umask": { argTypes: [F64], result: F64 },
|
|
231
237
|
"process.chdir": { argTypes: [STRING], result: VOID },
|
|
238
|
+
"process.loadEnvFile": { argTypes: [DYN], result: VOID },
|
|
232
239
|
"process.exiting": { argTypes: [], result: BOOL },
|
|
233
240
|
"net.getAutoSelTimeout": { argTypes: [], result: F64 },
|
|
234
241
|
"net.setAutoSelTimeout": { argTypes: [F64], result: VOID },
|
|
@@ -338,6 +345,10 @@ export const LIB_FN_SIGS = {
|
|
|
338
345
|
"bigint.dataViewSet": { argTypes: [BYTES_U8, F64, BIGINT_T, BOOL], result: VOID },
|
|
339
346
|
"url.new": { argTypes: [STRING], result: URL_T },
|
|
340
347
|
"url.newBase": { argTypes: [STRING, STRING], result: URL_T },
|
|
348
|
+
"url.canParse": { argTypes: [STRING], result: BOOL },
|
|
349
|
+
"url.canParseBase": { argTypes: [STRING, STRING], result: BOOL },
|
|
350
|
+
"url.parse": { argTypes: [STRING], result: DYN },
|
|
351
|
+
"url.parseBase": { argTypes: [STRING, STRING], result: DYN },
|
|
341
352
|
"url.protocol": { argTypes: [URL_T], result: STRING },
|
|
342
353
|
"url.origin": { argTypes: [URL_T], result: STRING },
|
|
343
354
|
"url.username": { argTypes: [URL_T], result: STRING },
|
|
@@ -347,8 +358,13 @@ export const LIB_FN_SIGS = {
|
|
|
347
358
|
"url.port": { argTypes: [URL_T], result: STRING },
|
|
348
359
|
"url.pathname": { argTypes: [URL_T], result: STRING },
|
|
349
360
|
"url.href": { argTypes: [URL_T], result: STRING },
|
|
361
|
+
"url.set": { argTypes: [URL_T, STRING, STRING], result: VOID },
|
|
362
|
+
"url.setChecked": { argTypes: [URL_T, STRING, DYN], result: VOID },
|
|
350
363
|
"url.fileURLToPathUrl": { argTypes: [URL_T], result: STRING },
|
|
351
364
|
"url.fileURLToPathChecked": { argTypes: [DYN], result: STRING },
|
|
365
|
+
"url.fileURLToPathOptions": { argTypes: [DYN, DYN], result: STRING },
|
|
366
|
+
"url.fileURLToPathBuffer": { argTypes: [DYN, DYN], result: BYTES_U8 },
|
|
367
|
+
"url.pathToFileURLChecked": { argTypes: [DYN, DYN], result: URL_T },
|
|
352
368
|
"url.fileURLToPathStr": { argTypes: [STRING], result: STRING },
|
|
353
369
|
"url.pathToFileURL": { argTypes: [STRING], result: URL_T },
|
|
354
370
|
"url.pathToFileURLPlatform": { argTypes: [STRING, BOOL], result: URL_T },
|
|
@@ -388,12 +404,34 @@ export const LIB_FN_SIGS = {
|
|
|
388
404
|
"qs.escape": { argTypes: [STRING], result: STRING },
|
|
389
405
|
"qs.unescape": { argTypes: [STRING], result: STRING },
|
|
390
406
|
"util.parseArgs": { argTypes: [DYN], result: DYN },
|
|
407
|
+
"util.parseEnv": { argTypes: [DYN], result: DYN },
|
|
408
|
+
"util.getSystemErrorName": { argTypes: [DYN], result: STRING },
|
|
409
|
+
"util.getSystemErrorMessage": { argTypes: [DYN], result: STRING },
|
|
410
|
+
"util.systemErrorEntries": { argTypes: [], result: DYN },
|
|
411
|
+
"util.stripVTControlCharacters": { argTypes: [DYN], result: STRING },
|
|
412
|
+
"util.toUSVString": { argTypes: [DYN], result: STRING },
|
|
413
|
+
"util.isDeepStrictEqual": { argTypes: [DYN, DYN, DYN], result: BOOL },
|
|
414
|
+
"util.styleText": { argTypes: [DYN, DYN, DYN], result: STRING },
|
|
415
|
+
"util.typeIs": { argTypes: [DYN, STRING], result: BOOL },
|
|
416
|
+
"util.typeValue": { argTypes: [DYN, STRING], result: DYN },
|
|
391
417
|
"fs.statSync": { argTypes: [STRING], result: STATS_T },
|
|
392
418
|
"fs.lstatSync": { argTypes: [STRING], result: STATS_T },
|
|
393
419
|
"fs.fstatSync": { argTypes: [F64], result: STATS_T },
|
|
394
420
|
"fs.fchmodSync": { argTypes: [F64, F64], result: VOID },
|
|
395
421
|
"fs.fsyncSync": { argTypes: [F64], result: VOID },
|
|
396
|
-
"fs.
|
|
422
|
+
"fs.fdatasyncSync": { argTypes: [F64], result: VOID },
|
|
423
|
+
"fs.ftruncateSync": { argTypes: [F64, F64], result: VOID },
|
|
424
|
+
"fs.utimesSync": { argTypes: [DYN, DYN, DYN], result: VOID },
|
|
425
|
+
"fs.futimesSync": { argTypes: [DYN, DYN, DYN], result: VOID },
|
|
426
|
+
"fs.lutimesSync": { argTypes: [DYN, DYN, DYN], result: VOID },
|
|
427
|
+
"fs.readvSync": { argTypes: [F64, arrayOf(BYTES_U8), F64], result: F64 },
|
|
428
|
+
"fs.writevSync": { argTypes: [F64, arrayOf(BYTES_U8), F64], result: F64 },
|
|
429
|
+
"fs.linkSync": { argTypes: [DYN, DYN], result: VOID },
|
|
430
|
+
"fs.symlinkSync": { argTypes: [DYN, DYN, DYN], result: VOID },
|
|
431
|
+
"fs.readlinkSync": { argTypes: [DYN, DYN], result: DYN },
|
|
432
|
+
"fs.statfsSync": { argTypes: [DYN, DYN], result: DYN },
|
|
433
|
+
"fs.readlinkSyncStr": { argTypes: [DYN, DYN], result: STRING },
|
|
434
|
+
"fs.readlinkSyncBuffer": { argTypes: [DYN, DYN], result: BYTES_U8 },
|
|
397
435
|
"fs.openSync": { argTypes: [STRING, STRING], result: F64 },
|
|
398
436
|
"fs.openNumericSync": { argTypes: [STRING, F64, F64], result: F64 },
|
|
399
437
|
"fs.readSync": { argTypes: [F64, BYTES_U8, F64, F64, F64], result: F64 },
|
|
@@ -964,6 +1002,10 @@ export const LIB_FN_SIGS = {
|
|
|
964
1002
|
"crypto.pbkdf2": { argTypes: [BYTES_U8, BYTES_U8, F64, F64, STRING], result: BYTES_U8 },
|
|
965
1003
|
"crypto.randomBytesCb": { argTypes: [F64, null], result: VOID },
|
|
966
1004
|
"crypto.pbkdf2Cb": { argTypes: [BYTES_U8, BYTES_U8, F64, F64, STRING, null], result: VOID },
|
|
1005
|
+
"crypto.hkdf": { argTypes: [STRING, BYTES_U8, BYTES_U8, BYTES_U8, F64], result: DYN },
|
|
1006
|
+
"crypto.hkdfCb": { argTypes: [STRING, BYTES_U8, BYTES_U8, BYTES_U8, F64, null], result: VOID },
|
|
1007
|
+
"crypto.scrypt": { argTypes: [BYTES_U8, BYTES_U8, F64, DYN], result: BYTES_U8 },
|
|
1008
|
+
"crypto.scryptCb": { argTypes: [BYTES_U8, BYTES_U8, F64, DYN, null], result: VOID },
|
|
967
1009
|
// The Buffer statics and the fs/zlib Buffer forms: fixed always-u8
|
|
968
1010
|
// signatures (Buffer IS a Uint8Array — one bytes kind).
|
|
969
1011
|
"buffer.fromStr": { argTypes: [STRING, STRING], result: BYTES_U8 },
|
|
@@ -1031,6 +1073,14 @@ export const LIB_FN_SIGS = {
|
|
|
1031
1073
|
"fsp.mkdirRecursiveMode": { argTypes: [STRING, F64], result: { kind: "promise", inner: VOID } },
|
|
1032
1074
|
"fsp.unlink": { argTypes: [STRING], result: { kind: "promise", inner: VOID } },
|
|
1033
1075
|
"fsp.chmod": { argTypes: [STRING, F64], result: { kind: "promise", inner: VOID } },
|
|
1076
|
+
"fsp.link": { argTypes: [DYN, DYN], result: { kind: "promise", inner: VOID } },
|
|
1077
|
+
"fsp.symlink": { argTypes: [DYN, DYN, DYN], result: { kind: "promise", inner: VOID } },
|
|
1078
|
+
"fsp.readlink": { argTypes: [DYN, DYN], result: { kind: "promise", inner: DYN } },
|
|
1079
|
+
"fsp.statfs": { argTypes: [DYN, DYN], result: { kind: "promise", inner: DYN } },
|
|
1080
|
+
"fsp.readlinkStr": { argTypes: [DYN, DYN], result: { kind: "promise", inner: STRING } },
|
|
1081
|
+
"fsp.readlinkBuffer": { argTypes: [DYN, DYN], result: { kind: "promise", inner: BYTES_U8 } },
|
|
1082
|
+
"fsp.utimes": { argTypes: [DYN, DYN, DYN], result: { kind: "promise", inner: VOID } },
|
|
1083
|
+
"fsp.lutimes": { argTypes: [DYN, DYN, DYN], result: { kind: "promise", inner: VOID } },
|
|
1034
1084
|
"fsp.rename": { argTypes: [STRING, STRING], result: { kind: "promise", inner: VOID } },
|
|
1035
1085
|
"fsp.readdir": { argTypes: [STRING], result: { kind: "promise", inner: arrayOf(STRING) } },
|
|
1036
1086
|
// Result is promise<call-site Dirent record array>; the libCall case
|
|
@@ -1043,6 +1093,13 @@ export const LIB_FN_SIGS = {
|
|
|
1043
1093
|
"fsp.open": { argTypes: [STRING, STRING, F64], result: { kind: "promise", inner: FILEHANDLE_T } },
|
|
1044
1094
|
"fileHandle.fd": { argTypes: [FILEHANDLE_T], result: F64 },
|
|
1045
1095
|
"fileHandle.close": { argTypes: [FILEHANDLE_T], result: { kind: "promise", inner: VOID } },
|
|
1096
|
+
"fileHandle.sync": { argTypes: [FILEHANDLE_T], result: { kind: "promise", inner: VOID } },
|
|
1097
|
+
"fileHandle.datasync": { argTypes: [FILEHANDLE_T], result: { kind: "promise", inner: VOID } },
|
|
1098
|
+
"fileHandle.truncate": { argTypes: [FILEHANDLE_T, F64], result: { kind: "promise", inner: VOID } },
|
|
1099
|
+
"fileHandle.chmod": { argTypes: [FILEHANDLE_T, F64], result: { kind: "promise", inner: VOID } },
|
|
1100
|
+
"fileHandle.utimes": { argTypes: [FILEHANDLE_T, DYN, DYN], result: { kind: "promise", inner: VOID } },
|
|
1101
|
+
"fileHandle.readv": { argTypes: [FILEHANDLE_T, arrayOf(BYTES_U8), F64], result: { kind: "promise", inner: VOID } },
|
|
1102
|
+
"fileHandle.writev": { argTypes: [FILEHANDLE_T, arrayOf(BYTES_U8), F64], result: { kind: "promise", inner: VOID } },
|
|
1046
1103
|
// read/write carry call-site result record shapes; the validator checks
|
|
1047
1104
|
// those below, so promise<void> is only a table sentinel.
|
|
1048
1105
|
"fileHandle.read": { argTypes: [FILEHANDLE_T, BYTES_U8, F64, F64, F64, BOOL], result: { kind: "promise", inner: VOID } },
|
|
@@ -1180,9 +1237,14 @@ export const LIB_FN_SIGS = {
|
|
|
1180
1237
|
"dyn.packPushSpread": { argTypes: [DYN, DYN, STRING], result: VOID },
|
|
1181
1238
|
"dyn.packPushSpreadIter": { argTypes: [DYN, DYN], result: VOID },
|
|
1182
1239
|
"dyn.reflectApply": { argTypes: [DYN, DYN, DYN], result: DYN },
|
|
1240
|
+
"dyn.reflectGet": { argTypes: [DYN, DYN, DYN], result: DYN },
|
|
1241
|
+
"dyn.reflectSet": { argTypes: [DYN, DYN, DYN, DYN], result: BOOL },
|
|
1242
|
+
"dyn.reflectDefine": { argTypes: [DYN, DYN, DYN], result: BOOL },
|
|
1243
|
+
"dyn.abstractEq": { argTypes: [DYN, DYN], result: BOOL },
|
|
1183
1244
|
"dyn.assignAll": { argTypes: [DYN, DYN], result: DYN },
|
|
1184
1245
|
"dyn.objCreateNullProto": { argTypes: [], result: DYN },
|
|
1185
1246
|
"dyn.arrayPrototype": { argTypes: [], result: DYN },
|
|
1247
|
+
"dyn.arrayConstructor": { argTypes: [], result: DYN },
|
|
1186
1248
|
"dyn.objectPrototype": { argTypes: [], result: DYN },
|
|
1187
1249
|
"dyn.functionApply": { argTypes: [], result: DYN },
|
|
1188
1250
|
"dyn.builtinMethod": { argTypes: [STRING, STRING], result: DYN },
|
|
@@ -1191,6 +1253,9 @@ export const LIB_FN_SIGS = {
|
|
|
1191
1253
|
"dyn.classInherit": { argTypes: [DYN, DYN], result: DYN },
|
|
1192
1254
|
"dyn.classSuper": { argTypes: [DYN, DYN, DYN], result: VOID },
|
|
1193
1255
|
"dyn.assignPrototype": { argTypes: [DYN, DYN, DYN], result: DYN },
|
|
1256
|
+
"dyn.definePrototypeProps": { argTypes: [DYN, DYN, DYN], result: DYN },
|
|
1257
|
+
"dyn.bagGet": { argTypes: [DYN, STRING, DYN], result: DYN },
|
|
1258
|
+
"dyn.bagSet": { argTypes: [DYN, STRING, DYN, DYN], result: VOID },
|
|
1194
1259
|
"dyn.objCreate": { argTypes: [DYN], result: DYN },
|
|
1195
1260
|
"dyn.objCreateWithProperties": { argTypes: [DYN, DYN], result: DYN },
|
|
1196
1261
|
"dyn.getPrototype": { argTypes: [DYN], result: DYN },
|
|
@@ -1356,6 +1421,9 @@ export const LIB_FN_SIGS = {
|
|
|
1356
1421
|
"assert.shapeEnd": { argTypes: [STRING, BOOL], result: VOID },
|
|
1357
1422
|
"assert.regexErrTest": { argTypes: [REGEX, { kind: "object", className: "%Error" }], result: BOOL },
|
|
1358
1423
|
"assert.unwantedRejection": { argTypes: [{ kind: "object", className: "%Error" }, STRING, BOOL], result: VOID },
|
|
1424
|
+
"assert.unwantedError": { argTypes: [STRING, BOOL, STRING, BOOL], result: VOID },
|
|
1425
|
+
"assert.noErrorPredicate": { argTypes: [DYN, DYN], result: BOOL },
|
|
1426
|
+
"assert.regexDynTest": { argTypes: [REGEX, DYN], result: BOOL },
|
|
1359
1427
|
"assert.expectsErrDyn": { argTypes: [DYN, DYN, STRING, BOOL], result: VOID },
|
|
1360
1428
|
// assert.ifError's typed entries (always throw; unit args never
|
|
1361
1429
|
// lower). The error slot is program-dependent — any %Error-hierarchy
|
|
@@ -1485,6 +1553,11 @@ export const LIB_FN_SIGS = {
|
|
|
1485
1553
|
"text.decodeLegacyOptions": { argTypes: [BYTES_U8, F64, BOOL, BOOL], result: STRING },
|
|
1486
1554
|
"text.decodeLegacy": { argTypes: [BYTES_U8, F64], result: STRING },
|
|
1487
1555
|
"text.decoderEncoding": { argTypes: [DYN], result: F64 },
|
|
1556
|
+
"text.decoderName": { argTypes: [F64], result: STRING },
|
|
1557
|
+
"text.encodeInto": { argTypes: [DYN, DYN], result: DYN },
|
|
1558
|
+
"buffer.isAscii": { argTypes: [DYN], result: BOOL },
|
|
1559
|
+
"buffer.isUtf8": { argTypes: [DYN], result: BOOL },
|
|
1560
|
+
"buffer.transcode": { argTypes: [DYN, DYN, DYN], result: BYTES_U8 },
|
|
1488
1561
|
"fs.mkdirRecursiveSync": { argTypes: [STRING], result: VOID },
|
|
1489
1562
|
"fs.rmOptsSync": { argTypes: [STRING, BOOL, BOOL], result: VOID },
|
|
1490
1563
|
"fs.rmRetrySync": { argTypes: [STRING, BOOL, BOOL, F64, F64], result: VOID },
|
|
@@ -1722,6 +1795,7 @@ export function validateModule(mod) {
|
|
|
1722
1795
|
});
|
|
1723
1796
|
}
|
|
1724
1797
|
const classesByName = new Map();
|
|
1798
|
+
const classFields = new Map();
|
|
1725
1799
|
for (const cls of mod.classes ?? []) {
|
|
1726
1800
|
if (classesByName.has(cls.name)) {
|
|
1727
1801
|
errors.push({ message: `duplicate class "${cls.name}"`, loc: cls.loc });
|
|
@@ -1751,6 +1825,9 @@ export function validateModule(mod) {
|
|
|
1751
1825
|
if (cls.jsLength !== undefined && (!Number.isSafeInteger(cls.jsLength) || cls.jsLength < 0)) {
|
|
1752
1826
|
errors.push({ message: `class ${cls.name}: invalid constructor length`, loc: cls.loc });
|
|
1753
1827
|
}
|
|
1828
|
+
if (cls.tracksOwnFields && (cls.runtime || cls.fields.find((field) => field.name === DYN_CLASS_PROPERTIES)?.type.kind !== "dyn")) {
|
|
1829
|
+
errors.push({ message: `class ${cls.name}: field presence tracking requires a native dyn property bag`, loc: cls.loc });
|
|
1830
|
+
}
|
|
1754
1831
|
if (cls.prototypeDataHelper !== undefined) {
|
|
1755
1832
|
const helper = functionsByName.get(cls.prototypeDataHelper);
|
|
1756
1833
|
if (!helper || helper.params.length !== 0 || helper.returnType.kind !== "dyn" || helper.captures !== undefined || helper.classCaptures !== undefined) {
|
|
@@ -1771,16 +1848,24 @@ export function validateModule(mod) {
|
|
|
1771
1848
|
errors.push({ message: `class ${cls.name}: invalid symbol field metadata`, loc: cls.loc });
|
|
1772
1849
|
}
|
|
1773
1850
|
}
|
|
1774
|
-
|
|
1851
|
+
// Reuse duplicate detection as the field index for function validation.
|
|
1852
|
+
// Array.find selected the first field, even in an invalid duplicate layout.
|
|
1853
|
+
const seen = new Map();
|
|
1775
1854
|
for (const f of cls.fields) {
|
|
1776
1855
|
if (seen.has(f.name)) {
|
|
1777
1856
|
errors.push({ message: `class ${cls.name}: duplicate field "${f.name}"`, loc: cls.loc });
|
|
1778
1857
|
}
|
|
1779
|
-
|
|
1858
|
+
else
|
|
1859
|
+
seen.set(f.name, f.type);
|
|
1780
1860
|
if (isUnitType(f.type)) {
|
|
1781
1861
|
errors.push({ message: `class ${cls.name}: field "${f.name}" is ${f.type.kind}`, loc: cls.loc });
|
|
1782
1862
|
}
|
|
1783
1863
|
}
|
|
1864
|
+
// Duplicate class names, like classesByName, select the last declaration.
|
|
1865
|
+
if (seen.size > 0)
|
|
1866
|
+
classFields.set(cls.name, seen);
|
|
1867
|
+
else
|
|
1868
|
+
classFields.delete(cls.name);
|
|
1784
1869
|
// Constructor presence is checked at `new` sites (below): a class kept
|
|
1785
1870
|
// only for its layout/type (reachability never constructs it) carries
|
|
1786
1871
|
// no constructor function, and that is fine — nothing calls it.
|
|
@@ -1857,30 +1942,41 @@ export function validateModule(mod) {
|
|
|
1857
1942
|
}
|
|
1858
1943
|
const noLoc = { file: mod.sourceFile, start: 0, end: 0 };
|
|
1859
1944
|
const recordsById = new Map();
|
|
1945
|
+
const recordIds = new Set((mod.records ?? []).map((record) => record.id));
|
|
1946
|
+
const recordValidation = new Map();
|
|
1860
1947
|
for (const rec of mod.records ?? []) {
|
|
1861
1948
|
if (recordsById.has(rec.id)) {
|
|
1862
1949
|
errors.push({ message: `duplicate record shape "${rec.id}"`, loc: noLoc });
|
|
1863
1950
|
}
|
|
1864
1951
|
recordsById.set(rec.id, rec);
|
|
1865
|
-
const
|
|
1952
|
+
const fields = new Map();
|
|
1866
1953
|
for (const f of rec.fields) {
|
|
1867
|
-
if (
|
|
1954
|
+
if (fields.has(f.name)) {
|
|
1868
1955
|
errors.push({ message: `record ${rec.id}: duplicate field "${f.name}"`, loc: noLoc });
|
|
1869
1956
|
}
|
|
1870
|
-
|
|
1957
|
+
else
|
|
1958
|
+
fields.set(f.name, f.type);
|
|
1871
1959
|
// Unit kinds (undefinedT/nullT) exist only as union arms — a BARE
|
|
1872
1960
|
// unit field is as malformed as a void one. dyn and jsval slots
|
|
1873
1961
|
// are valid; both are refcounted values held by the record shape.
|
|
1874
1962
|
if (f.type.kind === "void" || isUnitType(f.type)) {
|
|
1875
1963
|
errors.push({ message: `record ${rec.id}: field "${f.name}" is ${f.type.kind}`, loc: noLoc });
|
|
1876
1964
|
}
|
|
1877
|
-
if (f.type.kind === "record" && !
|
|
1965
|
+
if (f.type.kind === "record" && !recordIds.has(f.type.shapeId)) {
|
|
1878
1966
|
errors.push({
|
|
1879
1967
|
message: `record ${rec.id}: field "${f.name}" references undeclared shape "${f.type.shapeId}"`,
|
|
1880
1968
|
loc: noLoc,
|
|
1881
1969
|
});
|
|
1882
1970
|
}
|
|
1883
1971
|
}
|
|
1972
|
+
// Reads historically use the first duplicate field, while literal and
|
|
1973
|
+
// clone checks use the last. Preserve both on malformed shapes; valid
|
|
1974
|
+
// shapes share one index. All indexes belong to this validation call.
|
|
1975
|
+
recordValidation.set(rec.id, {
|
|
1976
|
+
fields,
|
|
1977
|
+
initializationFields: fields.size === rec.fields.length ? fields : new Map(rec.fields.map((field) => [field.name, field.type])),
|
|
1978
|
+
hasAccessorSlots: shapeHasAccessorSlots(rec),
|
|
1979
|
+
});
|
|
1884
1980
|
// Canonical order is the shape's identity — enforce it.
|
|
1885
1981
|
const sorted = [...rec.fields].map((f) => f.name).sort();
|
|
1886
1982
|
if (rec.fields.some((f, i) => f.name !== sorted[i])) {
|
|
@@ -1933,7 +2029,7 @@ export function validateModule(mod) {
|
|
|
1933
2029
|
for (const candidate of cases) {
|
|
1934
2030
|
const arm = u.arms[candidate.tag];
|
|
1935
2031
|
const record = arm?.kind === "record" ? recordsById.get(arm.shapeId) : undefined;
|
|
1936
|
-
const member = record?.fields.
|
|
2032
|
+
const member = record ? recordValidation.get(record.id)?.fields.get(field) : undefined;
|
|
1937
2033
|
if (!Number.isInteger(candidate.tag) || candidate.tag < 0 || !member || tags.has(candidate.tag)) {
|
|
1938
2034
|
errors.push({ message: `union ${u.id}: invalid discriminant tag ${candidate.tag}`, loc: noLoc });
|
|
1939
2035
|
}
|
|
@@ -1946,8 +2042,8 @@ export function validateModule(mod) {
|
|
|
1946
2042
|
errors.push({ message: `union ${u.id}: undefined discriminant value`, loc: noLoc });
|
|
1947
2043
|
continue;
|
|
1948
2044
|
}
|
|
1949
|
-
const fieldTypes = member?.
|
|
1950
|
-
? unionsById.get(member.
|
|
2045
|
+
const fieldTypes = member?.kind === "union"
|
|
2046
|
+
? unionsById.get(member.unionId)?.arms ?? [] : member ? [member] : [];
|
|
1951
2047
|
const valid = fieldTypes.some((type) => typeof value === "string" ? type.kind === "string"
|
|
1952
2048
|
: typeof value === "boolean" ? type.kind === "bool"
|
|
1953
2049
|
: typeof value === "number" && Number.isFinite(value) && type.kind === "f64");
|
|
@@ -2110,12 +2206,34 @@ export function validateModule(mod) {
|
|
|
2110
2206
|
}
|
|
2111
2207
|
}
|
|
2112
2208
|
}
|
|
2209
|
+
// Class metadata is invariant across functions. Keep field lookup, hierarchy
|
|
2210
|
+
// membership, and virtual-call resolution local to this validation invocation.
|
|
2211
|
+
const classValidation = {
|
|
2212
|
+
fields: classFields,
|
|
2213
|
+
hierarchy: new Set(), implementations: new Map(), virtualCalls: new Map(),
|
|
2214
|
+
};
|
|
2215
|
+
for (const cls of classesByName.values()) {
|
|
2216
|
+
if (cls.base !== undefined) {
|
|
2217
|
+
classValidation.hierarchy.add(cls.name);
|
|
2218
|
+
classValidation.hierarchy.add(cls.base);
|
|
2219
|
+
}
|
|
2220
|
+
if (cls.name === RUNTIME_EMITTER_CLASS)
|
|
2221
|
+
classValidation.hierarchy.add(cls.name);
|
|
2222
|
+
for (const method of new Set(cls.methods ?? [])) {
|
|
2223
|
+
if (cls.abstractMethods?.includes(method))
|
|
2224
|
+
continue;
|
|
2225
|
+
let implementations = classValidation.implementations.get(method);
|
|
2226
|
+
if (!implementations)
|
|
2227
|
+
classValidation.implementations.set(method, (implementations = []));
|
|
2228
|
+
implementations.push(cls);
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2113
2231
|
for (const fn of mod.functions) {
|
|
2114
|
-
validateFunction(fn, functionsByName, ffiByName, classesByName, recordsById, unionsById, globalsById, errors);
|
|
2232
|
+
validateFunction(fn, functionsByName, ffiByName, classesByName, recordsById, recordValidation, unionsById, globalsById, classValidation, errors);
|
|
2115
2233
|
}
|
|
2116
2234
|
return errors;
|
|
2117
2235
|
}
|
|
2118
|
-
function validateFunction(fn, functions, ffiByName, classes, records, unions, globals, errors) {
|
|
2236
|
+
function validateFunction(fn, functions, ffiByName, classes, records, recordValidation, unions, globals, classValidation, errors) {
|
|
2119
2237
|
const locals = new Map(fn.locals.map((l) => [l.id, l]));
|
|
2120
2238
|
const err = (message, loc) => errors.push({ message: `in ${fn.name}: ${message}`, loc });
|
|
2121
2239
|
const asyncCaches = [
|
|
@@ -2158,17 +2276,41 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
2158
2276
|
}
|
|
2159
2277
|
return false;
|
|
2160
2278
|
};
|
|
2161
|
-
const hierarchy =
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2279
|
+
const hierarchy = classValidation.hierarchy;
|
|
2280
|
+
const virtualCallInfo = (className, method) => {
|
|
2281
|
+
let methods = classValidation.virtualCalls.get(className);
|
|
2282
|
+
const cached = methods?.get(method);
|
|
2283
|
+
if (cached)
|
|
2284
|
+
return cached;
|
|
2285
|
+
if (!methods)
|
|
2286
|
+
classValidation.virtualCalls.set(className, (methods = new Map()));
|
|
2287
|
+
let declared = false;
|
|
2288
|
+
let implementation;
|
|
2289
|
+
for (let c = classes.get(className); c; c = c.base !== undefined ? classes.get(c.base) : undefined) {
|
|
2290
|
+
if (c.methods?.includes(method)) {
|
|
2291
|
+
declared = true;
|
|
2292
|
+
if (!c.abstractMethods?.includes(method)) {
|
|
2293
|
+
implementation = functions.get(`%${c.name}.${method}`);
|
|
2294
|
+
break;
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
let hasOverride = false;
|
|
2299
|
+
if (declared) {
|
|
2300
|
+
// Preserve class-table order when choosing an abstract slot's ABI.
|
|
2301
|
+
for (const c of classValidation.implementations.get(method) ?? []) {
|
|
2302
|
+
if (!isStrictSubclass(c.name, className))
|
|
2303
|
+
continue;
|
|
2304
|
+
hasOverride = true;
|
|
2305
|
+
implementation ??= functions.get(`%${c.name}.${method}`);
|
|
2306
|
+
if (implementation)
|
|
2307
|
+
break;
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2310
|
+
const result = { declared, hasOverride, implementation };
|
|
2311
|
+
methods.set(method, result);
|
|
2312
|
+
return result;
|
|
2313
|
+
};
|
|
2172
2314
|
// Unit kinds live only inside unions: a bare-unit local, param, or
|
|
2173
2315
|
// return type is frontend breakage (mapType never produces them).
|
|
2174
2316
|
for (const l of fn.locals) {
|
|
@@ -2594,15 +2736,15 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
2594
2736
|
// dyn field with fieldDyn set (validated numeric read-modify-write).
|
|
2595
2737
|
checkExpr(e.obj);
|
|
2596
2738
|
const cls = classes.get(e.className);
|
|
2597
|
-
const
|
|
2739
|
+
const fieldType = classValidation.fields.get(e.className)?.get(e.field);
|
|
2598
2740
|
if (!cls)
|
|
2599
2741
|
err(`fieldIncDec on undeclared class "${e.className}"`, e.loc);
|
|
2600
|
-
else if (!
|
|
2742
|
+
else if (!fieldType)
|
|
2601
2743
|
err(`class ${e.className} has no field "${e.field}"`, e.loc);
|
|
2602
2744
|
else {
|
|
2603
2745
|
expectType(e.obj, { kind: "object", className: e.className }, "fieldIncDec receiver");
|
|
2604
|
-
if (e.fieldDyn ?
|
|
2605
|
-
err(`fieldIncDec ${e.className}.${e.field} field/flag mismatch (${
|
|
2746
|
+
if (e.fieldDyn ? fieldType.kind !== "dyn" : fieldType.kind !== "f64") {
|
|
2747
|
+
err(`fieldIncDec ${e.className}.${e.field} field/flag mismatch (${fieldType.kind})`, e.loc);
|
|
2606
2748
|
}
|
|
2607
2749
|
}
|
|
2608
2750
|
if (e.type.kind !== "f64")
|
|
@@ -3626,14 +3768,14 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
3626
3768
|
case "fieldGet": {
|
|
3627
3769
|
checkExpr(e.obj);
|
|
3628
3770
|
const cls = classes.get(e.className);
|
|
3629
|
-
const
|
|
3771
|
+
const fieldType = classValidation.fields.get(e.className)?.get(e.field);
|
|
3630
3772
|
if (!cls)
|
|
3631
3773
|
err(`fieldGet on undeclared class "${e.className}"`, e.loc);
|
|
3632
|
-
else if (!
|
|
3774
|
+
else if (!fieldType)
|
|
3633
3775
|
err(`class ${e.className} has no field "${e.field}"`, e.loc);
|
|
3634
3776
|
else {
|
|
3635
3777
|
expectType(e.obj, { kind: "object", className: e.className }, "fieldGet receiver");
|
|
3636
|
-
if (!typeEquals(e.type,
|
|
3778
|
+
if (!typeEquals(e.type, fieldType)) {
|
|
3637
3779
|
err(`fieldGet ${e.className}.${e.field} type mismatch`, e.loc);
|
|
3638
3780
|
}
|
|
3639
3781
|
}
|
|
@@ -3807,30 +3949,15 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
3807
3949
|
// is then well-formed against any concrete override below — the
|
|
3808
3950
|
// frontend's override-exactness rule makes every implementation
|
|
3809
3951
|
// ABI-identical, so any one of them carries the slot's signature.
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
for (let c = classes.get(e.className); c; c = c.base !== undefined ? classes.get(c.base) : undefined) {
|
|
3813
|
-
if (c.methods?.includes(e.method)) {
|
|
3814
|
-
declared = true;
|
|
3815
|
-
if (!c.abstractMethods?.includes(e.method)) {
|
|
3816
|
-
impl = functions.get(`%${c.name}.${e.method}`);
|
|
3817
|
-
break;
|
|
3818
|
-
}
|
|
3819
|
-
}
|
|
3820
|
-
}
|
|
3821
|
-
if (!declared) {
|
|
3952
|
+
const info = virtualCallInfo(e.className, e.method);
|
|
3953
|
+
if (!info.declared) {
|
|
3822
3954
|
err(`virtualCall ${e.className}.${e.method}: no declaration on the base chain`, e.loc);
|
|
3823
3955
|
break;
|
|
3824
3956
|
}
|
|
3825
|
-
|
|
3826
|
-
!c.abstractMethods?.includes(e.method) &&
|
|
3827
|
-
isStrictSubclass(c.name, e.className));
|
|
3828
|
-
if (concreteBelow.length === 0) {
|
|
3957
|
+
if (!info.hasOverride) {
|
|
3829
3958
|
err(`virtualCall ${e.className}.${e.method}: no concrete override below the static class`, e.loc);
|
|
3830
3959
|
}
|
|
3831
|
-
impl
|
|
3832
|
-
.map((c) => functions.get(`%${c.name}.${e.method}`))
|
|
3833
|
-
.find((f) => f !== undefined);
|
|
3960
|
+
const impl = info.implementation;
|
|
3834
3961
|
if (!impl) {
|
|
3835
3962
|
err(`virtualCall ${e.className}.${e.method}: no implementation function exists`, e.loc);
|
|
3836
3963
|
break;
|
|
@@ -3866,7 +3993,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
3866
3993
|
err(`recordLit of undeclared shape "${e.type.shapeId}"`, e.loc);
|
|
3867
3994
|
break;
|
|
3868
3995
|
}
|
|
3869
|
-
const want =
|
|
3996
|
+
const want = recordValidation.get(shape.id).initializationFields;
|
|
3870
3997
|
const seen = new Set();
|
|
3871
3998
|
for (const f of e.fields) {
|
|
3872
3999
|
checkExpr(f.value);
|
|
@@ -3922,11 +4049,11 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
3922
4049
|
err(`recordClone of undeclared shape "${e.type.shapeId}"`, e.loc);
|
|
3923
4050
|
break;
|
|
3924
4051
|
}
|
|
3925
|
-
if (shape.tuple || shape.indexValue ||
|
|
4052
|
+
if (shape.tuple || shape.indexValue || recordValidation.get(shape.id).hasAccessorSlots) {
|
|
3926
4053
|
err(`recordClone requires a plain declared-field shape, got ${shape.id}`, e.loc);
|
|
3927
4054
|
}
|
|
3928
4055
|
expectType(e.source, e.type, "recordClone source");
|
|
3929
|
-
const want =
|
|
4056
|
+
const want = recordValidation.get(shape.id).initializationFields;
|
|
3930
4057
|
const seen = new Set();
|
|
3931
4058
|
for (const f of e.overrides) {
|
|
3932
4059
|
checkExpr(f.value);
|
|
@@ -3944,14 +4071,14 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
3944
4071
|
case "recordGet": {
|
|
3945
4072
|
checkExpr(e.obj);
|
|
3946
4073
|
const shape = records.get(e.shapeId);
|
|
3947
|
-
const field =
|
|
4074
|
+
const field = recordValidation.get(e.shapeId)?.fields.get(e.field);
|
|
3948
4075
|
if (!shape)
|
|
3949
4076
|
err(`recordGet on undeclared shape "${e.shapeId}"`, e.loc);
|
|
3950
4077
|
else if (!field)
|
|
3951
4078
|
err(`shape ${e.shapeId} has no field "${e.field}"`, e.loc);
|
|
3952
4079
|
else {
|
|
3953
4080
|
expectType(e.obj, { kind: "record", shapeId: e.shapeId }, "recordGet receiver");
|
|
3954
|
-
if (!typeEquals(e.type, field
|
|
4081
|
+
if (!typeEquals(e.type, field)) {
|
|
3955
4082
|
err(`recordGet ${e.shapeId}.${e.field} type mismatch`, e.loc);
|
|
3956
4083
|
}
|
|
3957
4084
|
}
|
|
@@ -4074,6 +4201,10 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4074
4201
|
}
|
|
4075
4202
|
case "dynCall": {
|
|
4076
4203
|
checkExpr(e.callee);
|
|
4204
|
+
if (e.calleeNameValue !== undefined) {
|
|
4205
|
+
checkExpr(e.calleeNameValue);
|
|
4206
|
+
expectType(e.calleeNameValue, STRING, "dynCall callee name");
|
|
4207
|
+
}
|
|
4077
4208
|
if (e.receiver !== undefined) {
|
|
4078
4209
|
checkExpr(e.receiver);
|
|
4079
4210
|
expectType(e.receiver, DYN, "dynCall receiver");
|
|
@@ -4105,6 +4236,10 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4105
4236
|
}
|
|
4106
4237
|
case "dynInvoke": {
|
|
4107
4238
|
checkExpr(e.recv);
|
|
4239
|
+
if (e.calleeNameValue !== undefined) {
|
|
4240
|
+
checkExpr(e.calleeNameValue);
|
|
4241
|
+
expectType(e.calleeNameValue, STRING, "dynInvoke callee name");
|
|
4242
|
+
}
|
|
4108
4243
|
expectType(e.recv, DYN, "dynInvoke receiver");
|
|
4109
4244
|
if (e.type.kind !== "dyn")
|
|
4110
4245
|
err(`dynInvoke must be dyn-typed, got ${e.type.kind}`, e.loc);
|
|
@@ -4315,9 +4450,9 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4315
4450
|
}
|
|
4316
4451
|
def.arms.forEach((arm, i) => {
|
|
4317
4452
|
const fieldType = arm.kind === "record"
|
|
4318
|
-
?
|
|
4453
|
+
? recordValidation.get(arm.shapeId)?.fields.get(e.field)
|
|
4319
4454
|
: arm.kind === "object"
|
|
4320
|
-
?
|
|
4455
|
+
? classValidation.fields.get(arm.className)?.get(e.field)
|
|
4321
4456
|
: undefined;
|
|
4322
4457
|
if (!fieldType) {
|
|
4323
4458
|
err(`unionDisc: arm ${i} of ${e.unionId} has no field "${e.field}"`, e.loc);
|
|
@@ -4380,7 +4515,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4380
4515
|
return;
|
|
4381
4516
|
}
|
|
4382
4517
|
const literal = e.key.kind === "strLit" ? e.key.value : null;
|
|
4383
|
-
const declared = literal !== null ? shape.fields.
|
|
4518
|
+
const declared = literal !== null ? recordValidation.get(shape.id)?.fields.get(literal) : undefined;
|
|
4384
4519
|
if (declared) {
|
|
4385
4520
|
if (!surfaces(declared)) {
|
|
4386
4521
|
err(`unionKeyGet: arm ${i} field "${literal}" of type ${declared.kind} cannot surface as the result`, e.loc);
|
|
@@ -4595,18 +4730,19 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
4595
4730
|
}
|
|
4596
4731
|
}
|
|
4597
4732
|
function checkLibValueCall(e) {
|
|
4598
|
-
if (e.fn === "fileHandle.read" || e.fn === "fileHandle.writeBytes" || e.fn === "fileHandle.writeStr") {
|
|
4733
|
+
if (e.fn === "fileHandle.read" || e.fn === "fileHandle.writeBytes" || e.fn === "fileHandle.writeStr" || e.fn === "fileHandle.readv" || e.fn === "fileHandle.writev") {
|
|
4599
4734
|
const inner = e.type.kind === "promise" ? e.type.inner : undefined;
|
|
4600
4735
|
const shape = inner?.kind === "record" ? records.get(inner.shapeId) : undefined;
|
|
4601
|
-
const countName = e.fn === "fileHandle.read" ? "bytesRead" : "bytesWritten";
|
|
4736
|
+
const countName = e.fn === "fileHandle.read" || e.fn === "fileHandle.readv" ? "bytesRead" : "bytesWritten";
|
|
4737
|
+
const payloadName = e.fn === "fileHandle.readv" || e.fn === "fileHandle.writev" ? "buffers" : "buffer";
|
|
4602
4738
|
const payload = e.args[1]?.type;
|
|
4603
|
-
const count = shape?.fields.
|
|
4604
|
-
const buffer = shape?.fields.
|
|
4739
|
+
const count = shape ? recordValidation.get(shape.id)?.fields.get(countName) : undefined;
|
|
4740
|
+
const buffer = shape ? recordValidation.get(shape.id)?.fields.get(payloadName) : undefined;
|
|
4605
4741
|
const ok = shape !== undefined && !shape.tuple && shape.indexValue === undefined && shape.fields.length === 2 &&
|
|
4606
|
-
count?.
|
|
4607
|
-
typeEquals(buffer
|
|
4742
|
+
count?.kind === "f64" && payload !== undefined && buffer !== undefined &&
|
|
4743
|
+
typeEquals(buffer, payload);
|
|
4608
4744
|
if (!ok) {
|
|
4609
|
-
err(`libCall ${e.fn} must return a promise of { ${countName}: number,
|
|
4745
|
+
err(`libCall ${e.fn} must return a promise of { ${countName}: number, ${payloadName} }`, e.loc);
|
|
4610
4746
|
}
|
|
4611
4747
|
return true;
|
|
4612
4748
|
}
|
|
@@ -5897,17 +6033,17 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
5897
6033
|
break;
|
|
5898
6034
|
}
|
|
5899
6035
|
const rec = records.get(resultT.shapeId);
|
|
5900
|
-
const doneF = rec?.fields.
|
|
5901
|
-
const valueF = rec?.fields.
|
|
5902
|
-
if (!rec || rec.fields.length !== 2 || doneF?.
|
|
6036
|
+
const doneF = rec ? recordValidation.get(rec.id)?.fields.get("done") : undefined;
|
|
6037
|
+
const valueF = rec ? recordValidation.get(rec.id)?.fields.get("value") : undefined;
|
|
6038
|
+
if (!rec || rec.fields.length !== 2 || doneF?.kind !== "bool" || valueF === undefined) {
|
|
5903
6039
|
err(`genResume result record ${resultT.shapeId} is not { done: bool, value: V }`, e.loc);
|
|
5904
6040
|
break;
|
|
5905
6041
|
}
|
|
5906
|
-
if (valueF.
|
|
6042
|
+
if (valueF.kind === "dyn")
|
|
5907
6043
|
break;
|
|
5908
|
-
const vdef = valueF.
|
|
6044
|
+
const vdef = valueF.kind === "union" ? unions.get(valueF.unionId) : undefined;
|
|
5909
6045
|
if (!vdef || !vdef.arms.some((a) => a.kind === "undefinedT")) {
|
|
5910
|
-
err(`genResume value slot ${typeKey(valueF
|
|
6046
|
+
err(`genResume value slot ${typeKey(valueF)} is neither dyn nor an undefined-armed union`, e.loc);
|
|
5911
6047
|
}
|
|
5912
6048
|
break;
|
|
5913
6049
|
}
|
|
@@ -5991,10 +6127,10 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
5991
6127
|
break;
|
|
5992
6128
|
}
|
|
5993
6129
|
const shape = records.get(e.type.shapeId);
|
|
5994
|
-
const fields =
|
|
5995
|
-
const prom = fields
|
|
5996
|
-
const resolve = fields
|
|
5997
|
-
const reject = fields
|
|
6130
|
+
const fields = recordValidation.get(e.type.shapeId)?.initializationFields;
|
|
6131
|
+
const prom = fields?.get("promise");
|
|
6132
|
+
const resolve = fields?.get("resolve");
|
|
6133
|
+
const reject = fields?.get("reject");
|
|
5998
6134
|
if (!shape || shape.fields.length !== 3 || !prom || !resolve || !reject) {
|
|
5999
6135
|
err("promiseWithResolvers record must be { promise, resolve, reject }", e.loc);
|
|
6000
6136
|
break;
|
|
@@ -6306,14 +6442,14 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
6306
6442
|
checkExpr(s.obj);
|
|
6307
6443
|
checkExpr(s.value);
|
|
6308
6444
|
const cls = classes.get(s.className);
|
|
6309
|
-
const
|
|
6445
|
+
const fieldType = classValidation.fields.get(s.className)?.get(s.field);
|
|
6310
6446
|
if (!cls)
|
|
6311
6447
|
err(`fieldSet on undeclared class "${s.className}"`, s.loc);
|
|
6312
|
-
else if (!
|
|
6448
|
+
else if (!fieldType)
|
|
6313
6449
|
err(`class ${s.className} has no field "${s.field}"`, s.loc);
|
|
6314
6450
|
else {
|
|
6315
6451
|
expectType(s.obj, { kind: "object", className: s.className }, "fieldSet receiver");
|
|
6316
|
-
expectType(s.value,
|
|
6452
|
+
expectType(s.value, fieldType, `fieldSet ${s.className}.${s.field}`);
|
|
6317
6453
|
}
|
|
6318
6454
|
break;
|
|
6319
6455
|
}
|
|
@@ -6321,14 +6457,14 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
|
|
|
6321
6457
|
checkExpr(s.obj);
|
|
6322
6458
|
checkExpr(s.value);
|
|
6323
6459
|
const shape = records.get(s.shapeId);
|
|
6324
|
-
const field =
|
|
6460
|
+
const field = recordValidation.get(s.shapeId)?.fields.get(s.field);
|
|
6325
6461
|
if (!shape)
|
|
6326
6462
|
err(`recordSet on undeclared shape "${s.shapeId}"`, s.loc);
|
|
6327
6463
|
else if (!field)
|
|
6328
6464
|
err(`shape ${s.shapeId} has no field "${s.field}"`, s.loc);
|
|
6329
6465
|
else {
|
|
6330
6466
|
expectType(s.obj, { kind: "record", shapeId: s.shapeId }, "recordSet receiver");
|
|
6331
|
-
expectType(s.value, field
|
|
6467
|
+
expectType(s.value, field, `recordSet ${s.shapeId}.${s.field}`);
|
|
6332
6468
|
}
|
|
6333
6469
|
break;
|
|
6334
6470
|
}
|