nudojs 1.3.11 → 1.3.13
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/dist/index.js +1262 -728
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -21662,12 +21662,16 @@ function nullishGuardOf(test) {
|
|
|
21662
21662
|
if (t?.type === "UnaryExpression" && t.operator === "!") {
|
|
21663
21663
|
const m = memberGuardTarget(t.argument);
|
|
21664
21664
|
if (m) return { name: m.name, arm: "alt", grain: "nullish", memberKey: m.key };
|
|
21665
|
+
const a = assignGuardTarget(t.argument);
|
|
21666
|
+
if (a) return { name: a, arm: "alt", grain: "nullish" };
|
|
21665
21667
|
}
|
|
21666
21668
|
if (t?.type === "Identifier" && t.name) {
|
|
21667
21669
|
return { name: t.name, arm: "cons", grain: "nullish" };
|
|
21668
21670
|
}
|
|
21669
21671
|
const bare = memberGuardTarget(t);
|
|
21670
21672
|
if (bare) return { name: bare.name, arm: "cons", grain: "nullish", memberKey: bare.key };
|
|
21673
|
+
const bareAssign = assignGuardTarget(t);
|
|
21674
|
+
if (bareAssign) return { name: bareAssign, arm: "cons", grain: "nullish" };
|
|
21671
21675
|
if (t?.type !== "BinaryExpression") return void 0;
|
|
21672
21676
|
const op = t.operator;
|
|
21673
21677
|
if (op !== "===" && op !== "!==" && op !== "==" && op !== "!=") return void 0;
|
|
@@ -21699,6 +21703,20 @@ function nullishGuardOf(test) {
|
|
|
21699
21703
|
const grain = litGrain(l);
|
|
21700
21704
|
if (grain !== void 0) return { name: r.name, arm: truthyArm, grain };
|
|
21701
21705
|
}
|
|
21706
|
+
if (op === "==" || op === "!=") {
|
|
21707
|
+
const nullishLit = (n) => {
|
|
21708
|
+
const ln = n;
|
|
21709
|
+
return ln?.type === "NullLiteral" || ln?.name === "undefined";
|
|
21710
|
+
};
|
|
21711
|
+
const lm = memberGuardTarget(t.left);
|
|
21712
|
+
const rm = memberGuardTarget(t.right);
|
|
21713
|
+
if (lm && nullishLit(t.right)) {
|
|
21714
|
+
return { name: lm.name, arm: truthyArm, grain: "nullish", memberKey: lm.key };
|
|
21715
|
+
}
|
|
21716
|
+
if (rm && nullishLit(t.left)) {
|
|
21717
|
+
return { name: rm.name, arm: truthyArm, grain: "nullish", memberKey: rm.key };
|
|
21718
|
+
}
|
|
21719
|
+
}
|
|
21702
21720
|
return void 0;
|
|
21703
21721
|
}
|
|
21704
21722
|
function compositeNullishGuardOf(test) {
|
|
@@ -21719,6 +21737,31 @@ function compositeNullishGuardOf(test) {
|
|
|
21719
21737
|
}
|
|
21720
21738
|
return lg ?? rg;
|
|
21721
21739
|
}
|
|
21740
|
+
function mergeGuardInto(list, g) {
|
|
21741
|
+
const prev = list.find((x) => x.name === g.name);
|
|
21742
|
+
if (!prev) {
|
|
21743
|
+
list.push(g);
|
|
21744
|
+
return;
|
|
21745
|
+
}
|
|
21746
|
+
const grainA = prev.grain ?? "nullish";
|
|
21747
|
+
const grainB = g.grain ?? "nullish";
|
|
21748
|
+
if (grainA !== grainB) prev.grain = "nullish";
|
|
21749
|
+
if (prev.memberKey === void 0 && g.memberKey !== void 0) prev.memberKey = g.memberKey;
|
|
21750
|
+
}
|
|
21751
|
+
function nullishGuardsOf(test) {
|
|
21752
|
+
const t = test;
|
|
21753
|
+
if (t?.type === "LogicalExpression" && (t.operator === "||" || t.operator === "&&")) {
|
|
21754
|
+
const wantArm = t.operator === "||" ? "alt" : "cons";
|
|
21755
|
+
const out = [];
|
|
21756
|
+
for (const g2 of [...nullishGuardsOf(t.left), ...nullishGuardsOf(t.right)]) {
|
|
21757
|
+
if (g2.arm !== wantArm) continue;
|
|
21758
|
+
mergeGuardInto(out, g2);
|
|
21759
|
+
}
|
|
21760
|
+
return out;
|
|
21761
|
+
}
|
|
21762
|
+
const g = nullishGuardOf(test);
|
|
21763
|
+
return g ? [g] : [];
|
|
21764
|
+
}
|
|
21722
21765
|
function typeGuardOf(test) {
|
|
21723
21766
|
const t = test;
|
|
21724
21767
|
if (t?.type !== "BinaryExpression") return void 0;
|
|
@@ -21740,11 +21783,15 @@ function nullishRemoveCallOf(guard) {
|
|
|
21740
21783
|
if (guard.grain === "null") return `$removeNull(${guard.name})`;
|
|
21741
21784
|
return `$removeNullish(${guard.name})`;
|
|
21742
21785
|
}
|
|
21743
|
-
function
|
|
21744
|
-
if (!
|
|
21786
|
+
function narrowNullishArmThunks(thunk, guards, arm, forkBindingNames) {
|
|
21787
|
+
if (!guards || guards.length === 0) return thunk;
|
|
21788
|
+
const matching = guards.filter((g) => g.arm === arm);
|
|
21789
|
+
if (matching.length === 0) return thunk;
|
|
21745
21790
|
const names2 = forkBindingNames instanceof Set ? forkBindingNames : new Set(forkBindingNames);
|
|
21746
|
-
if (names2.has(
|
|
21747
|
-
|
|
21791
|
+
if (matching.some((g) => names2.has(g.name))) return thunk;
|
|
21792
|
+
const params = matching.map((g) => g.name).join(", ");
|
|
21793
|
+
const args = matching.map((g) => nullishRemoveCallOf(g)).join(", ");
|
|
21794
|
+
return `((${params}) => ${thunk})(${args})`;
|
|
21748
21795
|
}
|
|
21749
21796
|
function narrowTypeArmThunk(thunk, guard, arm, forkBindingNames) {
|
|
21750
21797
|
if (!guard) return thunk;
|
|
@@ -21753,7 +21800,58 @@ function narrowTypeArmThunk(thunk, guard, arm, forkBindingNames) {
|
|
|
21753
21800
|
const keep = arm === guard.arm;
|
|
21754
21801
|
return `((${guard.name}) => ${thunk})($narrowTypeOf(${guard.name}, ${JSON.stringify(guard.typeOf)}, ${keep}))`;
|
|
21755
21802
|
}
|
|
21756
|
-
|
|
21803
|
+
function discriminantGuardOf(test) {
|
|
21804
|
+
const t = test;
|
|
21805
|
+
if (t?.type !== "BinaryExpression") return void 0;
|
|
21806
|
+
if (t.operator !== "===" && t.operator !== "!==") return void 0;
|
|
21807
|
+
const lm = memberGuardTarget(t.left);
|
|
21808
|
+
const rm = memberGuardTarget(t.right);
|
|
21809
|
+
const m = lm !== void 0 && isPrimLitNode(t.right) ? { target: lm, lit: t.right } : rm !== void 0 && isPrimLitNode(t.left) ? { target: rm, lit: t.left } : void 0;
|
|
21810
|
+
if (!m) return void 0;
|
|
21811
|
+
return {
|
|
21812
|
+
name: m.target.name,
|
|
21813
|
+
key: m.target.key,
|
|
21814
|
+
value: m.lit.value,
|
|
21815
|
+
arm: t.operator === "===" ? "cons" : "alt"
|
|
21816
|
+
};
|
|
21817
|
+
}
|
|
21818
|
+
function discriminantGuardsOf(test) {
|
|
21819
|
+
const t = test;
|
|
21820
|
+
if (t?.type === "LogicalExpression" && (t.operator === "&&" || t.operator === "||")) {
|
|
21821
|
+
const wantArm = t.operator === "&&" ? "cons" : "alt";
|
|
21822
|
+
const out = [];
|
|
21823
|
+
for (const g2 of [...discriminantGuardsOf(t.left), ...discriminantGuardsOf(t.right)]) {
|
|
21824
|
+
if (g2.arm !== wantArm) continue;
|
|
21825
|
+
if (out.some((x) => x.name === g2.name && x.key === g2.key && x.value === g2.value)) continue;
|
|
21826
|
+
out.push(g2);
|
|
21827
|
+
}
|
|
21828
|
+
return out;
|
|
21829
|
+
}
|
|
21830
|
+
const g = discriminantGuardOf(test);
|
|
21831
|
+
return g ? [g] : [];
|
|
21832
|
+
}
|
|
21833
|
+
function narrowDiscriminantArmThunks(thunk, guards, arm, forkBindingNames) {
|
|
21834
|
+
if (!guards || guards.length === 0) return thunk;
|
|
21835
|
+
const matching = guards.filter((g) => g.arm === arm);
|
|
21836
|
+
if (matching.length === 0) return thunk;
|
|
21837
|
+
const names2 = forkBindingNames instanceof Set ? forkBindingNames : new Set(forkBindingNames);
|
|
21838
|
+
if (matching.some((g) => names2.has(g.name))) return thunk;
|
|
21839
|
+
const byName = /* @__PURE__ */ new Map();
|
|
21840
|
+
for (const g of matching) {
|
|
21841
|
+
const list = byName.get(g.name) ?? [];
|
|
21842
|
+
if (!list.some((x) => x.key === g.key && x.value === g.value)) list.push(g);
|
|
21843
|
+
byName.set(g.name, list);
|
|
21844
|
+
}
|
|
21845
|
+
const params = [...byName.keys()].join(", ");
|
|
21846
|
+
const args = [...byName.entries()].map(
|
|
21847
|
+
([name, gs]) => gs.reduce(
|
|
21848
|
+
(acc, g) => `$narrowMemberEq(${acc}, ${JSON.stringify(g.key)}, ${JSON.stringify(g.value)}, true)`,
|
|
21849
|
+
name
|
|
21850
|
+
)
|
|
21851
|
+
).join(", ");
|
|
21852
|
+
return `((${params}) => ${thunk})(${args})`;
|
|
21853
|
+
}
|
|
21854
|
+
var TYPEOF_NAMES2, isStrLitNode, typeofArgName, memberGuardTarget, assignGuardTarget, isPrimLitNode;
|
|
21757
21855
|
var init_stmt_predicates = __esm({
|
|
21758
21856
|
"../core/src/algebra/exec/transpile/stmt-predicates.ts"() {
|
|
21759
21857
|
"use strict";
|
|
@@ -21790,6 +21888,20 @@ var init_stmt_predicates = __esm({
|
|
|
21790
21888
|
if (key === void 0) return void 0;
|
|
21791
21889
|
return { name: m.object.name, key };
|
|
21792
21890
|
};
|
|
21891
|
+
assignGuardTarget = (n) => {
|
|
21892
|
+
const t = n;
|
|
21893
|
+
if (t?.type === "AssignmentExpression" && t.operator === "=" && t.left?.type === "Identifier" && t.left.name) {
|
|
21894
|
+
return t.left.name;
|
|
21895
|
+
}
|
|
21896
|
+
return void 0;
|
|
21897
|
+
};
|
|
21898
|
+
isPrimLitNode = (n) => {
|
|
21899
|
+
const t = n;
|
|
21900
|
+
if (t?.type === "StringLiteral") return typeof t.value === "string";
|
|
21901
|
+
if (t?.type === "NumericLiteral") return typeof t.value === "number";
|
|
21902
|
+
if (t?.type === "BooleanLiteral") return typeof t.value === "boolean";
|
|
21903
|
+
return false;
|
|
21904
|
+
};
|
|
21793
21905
|
}
|
|
21794
21906
|
});
|
|
21795
21907
|
|
|
@@ -21885,16 +21997,22 @@ function transpileFnBodyStmts(stmtsIn, depth, opts, varScope) {
|
|
|
21885
21997
|
};
|
|
21886
21998
|
const testRecvs = collectArrMutatorReceivers(stmt.test);
|
|
21887
21999
|
const testRebinds = testRecvs.size ? emitArrMutatorRebinds(stmt.test, scopedOpts, pad) : [];
|
|
21888
|
-
const
|
|
22000
|
+
const earlyGuards = nullishGuardsOf(stmt.test);
|
|
21889
22001
|
const earlyTGuard = typeGuardOf(stmt.test);
|
|
21890
|
-
const
|
|
21891
|
-
|
|
21892
|
-
|
|
21893
|
-
|
|
22002
|
+
const earlyDGuards = discriminantGuardsOf(stmt.test);
|
|
22003
|
+
const consNarrowed = narrowDiscriminantArmThunks(
|
|
22004
|
+
narrowTypeArmThunk(
|
|
22005
|
+
narrowNullishArmThunks(
|
|
22006
|
+
transpileBlockAsThunk(stmt.consequent, depth, scopedOpts),
|
|
22007
|
+
earlyGuards,
|
|
22008
|
+
"cons",
|
|
22009
|
+
recvSet
|
|
22010
|
+
),
|
|
22011
|
+
earlyTGuard,
|
|
21894
22012
|
"cons",
|
|
21895
22013
|
recvSet
|
|
21896
22014
|
),
|
|
21897
|
-
|
|
22015
|
+
earlyDGuards,
|
|
21898
22016
|
"cons",
|
|
21899
22017
|
recvSet
|
|
21900
22018
|
);
|
|
@@ -21903,9 +22021,14 @@ function transpileFnBodyStmts(stmtsIn, depth, opts, varScope) {
|
|
|
21903
22021
|
const altThunk = `() => {
|
|
21904
22022
|
${altBody}
|
|
21905
22023
|
${pad}}`;
|
|
21906
|
-
const altNarrowed =
|
|
21907
|
-
|
|
21908
|
-
|
|
22024
|
+
const altNarrowed = narrowDiscriminantArmThunks(
|
|
22025
|
+
narrowTypeArmThunk(
|
|
22026
|
+
narrowNullishArmThunks(altThunk, earlyGuards, "alt", recvSet),
|
|
22027
|
+
earlyTGuard,
|
|
22028
|
+
"alt",
|
|
22029
|
+
recvSet
|
|
22030
|
+
),
|
|
22031
|
+
earlyDGuards,
|
|
21909
22032
|
"alt",
|
|
21910
22033
|
recvSet
|
|
21911
22034
|
);
|
|
@@ -22234,17 +22357,28 @@ ${pad}export default ${name};`;
|
|
|
22234
22357
|
...opts,
|
|
22235
22358
|
conditionalFlow: (opts.conditionalFlow ?? 0) + 1
|
|
22236
22359
|
}) : null;
|
|
22237
|
-
const
|
|
22360
|
+
const guards = nullishGuardsOf(stmt.test);
|
|
22238
22361
|
const tguard = typeGuardOf(stmt.test);
|
|
22239
|
-
const
|
|
22240
|
-
|
|
22241
|
-
|
|
22362
|
+
const dguards = discriminantGuardsOf(stmt.test);
|
|
22363
|
+
const consNarrowed = narrowDiscriminantArmThunks(
|
|
22364
|
+
narrowTypeArmThunk(
|
|
22365
|
+
narrowNullishArmThunks(consRaw, guards, "cons", recvSet),
|
|
22366
|
+
tguard,
|
|
22367
|
+
"cons",
|
|
22368
|
+
recvSet
|
|
22369
|
+
),
|
|
22370
|
+
dguards,
|
|
22242
22371
|
"cons",
|
|
22243
22372
|
recvSet
|
|
22244
22373
|
);
|
|
22245
|
-
const altNarrowed = altRaw === null ? null :
|
|
22246
|
-
|
|
22247
|
-
|
|
22374
|
+
const altNarrowed = altRaw === null ? null : narrowDiscriminantArmThunks(
|
|
22375
|
+
narrowTypeArmThunk(
|
|
22376
|
+
narrowNullishArmThunks(altRaw, guards, "alt", recvSet),
|
|
22377
|
+
tguard,
|
|
22378
|
+
"alt",
|
|
22379
|
+
recvSet
|
|
22380
|
+
),
|
|
22381
|
+
dguards,
|
|
22248
22382
|
"alt",
|
|
22249
22383
|
recvSet
|
|
22250
22384
|
);
|
|
@@ -22691,13 +22825,24 @@ ${indent(depth + 1)}]${dflt})`;
|
|
|
22691
22825
|
collectAssignedIds(stmt.test, assigned);
|
|
22692
22826
|
const bodyLocalDecls = /* @__PURE__ */ new Set();
|
|
22693
22827
|
collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
|
|
22828
|
+
const bodyWrites = /* @__PURE__ */ new Set();
|
|
22829
|
+
collectAssignedIds(stmt.body, bodyWrites);
|
|
22830
|
+
collectArrMutatorReceivers(stmt.body, bodyWrites);
|
|
22831
|
+
const loopGuards = nullishGuardsOf(stmt.test).filter(
|
|
22832
|
+
(g) => g.arm === "cons" && !bodyWrites.has(g.name) && !bodyLocalDecls.has(g.name)
|
|
22833
|
+
);
|
|
22834
|
+
const bodyNarrowed = loopGuards.length === 0 ? body : [
|
|
22835
|
+
`${indent(depth + 1)}((${loopGuards.map((g) => g.name).join(", ")}) => {`,
|
|
22836
|
+
body,
|
|
22837
|
+
`${indent(depth + 1)}})(${loopGuards.map((g) => nullishRemoveCallOf(g)).join(", ")});`
|
|
22838
|
+
].join("\n");
|
|
22694
22839
|
const names2 = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
|
|
22695
22840
|
const loopOpts = opts.loopLabel ? `label: ${JSON.stringify(opts.loopLabel)}` : "";
|
|
22696
22841
|
if (names2.length === 0) {
|
|
22697
22842
|
return [
|
|
22698
22843
|
`${pad}// while \u2192 $whileSeq (bounded, max=${max})`,
|
|
22699
22844
|
`${pad}$whileSeq(() => ${test}, () => {`,
|
|
22700
|
-
|
|
22845
|
+
bodyNarrowed,
|
|
22701
22846
|
`${pad}}, ${max}${loopOpts ? `, { ${loopOpts} }` : ""});`
|
|
22702
22847
|
].join("\n");
|
|
22703
22848
|
}
|
|
@@ -22706,7 +22851,7 @@ ${indent(depth + 1)}]${dflt})`;
|
|
|
22706
22851
|
return [
|
|
22707
22852
|
`${pad}// while \u2192 $whileSeq (instrumented bindings: ${names2.join(", ")})`,
|
|
22708
22853
|
`${pad}$whileSeq(() => ${test}, () => {`,
|
|
22709
|
-
|
|
22854
|
+
bodyNarrowed,
|
|
22710
22855
|
`${pad}}, ${max}, { pack: () => ${packSrc}, unpack: ${unpackSrc}${loopOpts ? `, ${loopOpts}` : ""} });`
|
|
22711
22856
|
].join("\n");
|
|
22712
22857
|
}
|
|
@@ -22725,6 +22870,17 @@ ${indent(depth + 1)}]${dflt})`;
|
|
|
22725
22870
|
collectArrMutatorReceivers(stmt.body, assigned);
|
|
22726
22871
|
const bodyLocalDecls = /* @__PURE__ */ new Set();
|
|
22727
22872
|
collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
|
|
22873
|
+
const bodyWrites = /* @__PURE__ */ new Set();
|
|
22874
|
+
collectAssignedIds(stmt.body, bodyWrites);
|
|
22875
|
+
collectArrMutatorReceivers(stmt.body, bodyWrites);
|
|
22876
|
+
const loopGuards = nullishGuardsOf(stmt.test).filter(
|
|
22877
|
+
(g) => g.arm === "cons" && !bodyWrites.has(g.name) && !bodyLocalDecls.has(g.name)
|
|
22878
|
+
);
|
|
22879
|
+
const innerBody = loopGuards.length === 0 ? bodyStmts : [
|
|
22880
|
+
`${indent(depth + 1)}((${loopGuards.map((g) => g.name).join(", ")}) => {`,
|
|
22881
|
+
bodyStmts,
|
|
22882
|
+
`${indent(depth + 1)}})(${loopGuards.map((g) => nullishRemoveCallOf(g)).join(", ")});`
|
|
22883
|
+
].join("\n");
|
|
22728
22884
|
const names2 = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
|
|
22729
22885
|
const packSrc = names2.length === 0 ? null : `$obj({ ${names2.map((n) => `${JSON.stringify(n)}: $copy(${n})`).join(", ")} })`;
|
|
22730
22886
|
const unpackSrc = names2.length === 0 ? null : `(__lp) => { ${names2.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
|
|
@@ -22735,7 +22891,7 @@ ${indent(depth + 1)}]${dflt})`;
|
|
|
22735
22891
|
`{`,
|
|
22736
22892
|
bodyStmts,
|
|
22737
22893
|
`${indent(depth + 1)}$whileSeq(() => ${test}, () => {`,
|
|
22738
|
-
|
|
22894
|
+
innerBody,
|
|
22739
22895
|
`${indent(depth + 1)}}, ${max}${optsSrc});`,
|
|
22740
22896
|
`${pad}}`
|
|
22741
22897
|
].join("\n");
|
|
@@ -23156,27 +23312,42 @@ function transpileShortCircuitExpr(opts, parts) {
|
|
|
23156
23312
|
const forkTest2 = parts.testSrc ?? parts.alwaysSrc;
|
|
23157
23313
|
let consExpr = parts.consSrc === "__test" ? parts.alwaysSrc : parts.consSrc;
|
|
23158
23314
|
let altExpr = parts.altSrc === "__test" ? parts.alwaysSrc : parts.altSrc;
|
|
23159
|
-
|
|
23160
|
-
|
|
23161
|
-
|
|
23162
|
-
|
|
23163
|
-
|
|
23164
|
-
}
|
|
23165
|
-
}
|
|
23315
|
+
const applyGuards = (src, arm) => {
|
|
23316
|
+
const gs = (parts.narrowGuards ?? []).filter((g) => g.arm === arm);
|
|
23317
|
+
if (gs.length === 0) return src;
|
|
23318
|
+
const params = gs.map((g) => g.name).join(", ");
|
|
23319
|
+
const args = gs.map((g) => nullishRemoveCallOf(g)).join(", ");
|
|
23320
|
+
return `((${params}) => (${src}))(${args})`;
|
|
23321
|
+
};
|
|
23322
|
+
consExpr = applyGuards(consExpr, "cons");
|
|
23323
|
+
altExpr = applyGuards(altExpr, "alt");
|
|
23166
23324
|
if (parts.typeGuard) {
|
|
23167
23325
|
const g = parts.typeGuard;
|
|
23168
23326
|
const apply = (src, arm) => `((${g.name}) => (${src}))($narrowTypeOf(${g.name}, ${JSON.stringify(g.typeOf)}, ${arm === g.arm}))`;
|
|
23169
23327
|
consExpr = apply(consExpr, "cons");
|
|
23170
23328
|
altExpr = apply(altExpr, "alt");
|
|
23171
23329
|
}
|
|
23330
|
+
const applyDisc = (src, arm) => narrowDiscriminantArmThunks(src, parts.discGuards, arm, []);
|
|
23331
|
+
consExpr = applyDisc(consExpr, "cons");
|
|
23332
|
+
altExpr = applyDisc(altExpr, "alt");
|
|
23172
23333
|
return `$fork(${forkTest2}, () => ${consExpr}, () => ${altExpr})`;
|
|
23173
23334
|
}
|
|
23174
23335
|
const consLines = parts.consSrc === "__test" ? [`return __test;`] : consRebinds.length === 0 ? [`return (${parts.consSrc});`] : [`const __v = (${parts.consSrc});`, ...consRebinds, `return __v;`];
|
|
23175
23336
|
const altLines = parts.altSrc === "__test" ? [`return __test;`] : altRebinds.length === 0 ? [`return (${parts.altSrc});`] : [`const __v = (${parts.altSrc});`, ...altRebinds, `return __v;`];
|
|
23176
23337
|
const forkTest = parts.testSrc ?? "__test";
|
|
23177
|
-
const
|
|
23178
|
-
const consFinal =
|
|
23179
|
-
|
|
23338
|
+
const guards = parts.narrowGuards;
|
|
23339
|
+
const consFinal = narrowDiscriminantArmThunks(
|
|
23340
|
+
narrowNullishArmThunks(forkArmThunk(consLines, "fk1_", names2), guards, "cons", names2),
|
|
23341
|
+
parts.discGuards,
|
|
23342
|
+
"cons",
|
|
23343
|
+
names2
|
|
23344
|
+
);
|
|
23345
|
+
const altFinal = narrowDiscriminantArmThunks(
|
|
23346
|
+
narrowNullishArmThunks(forkArmThunk(altLines, "fk2_", names2), guards, "alt", names2),
|
|
23347
|
+
parts.discGuards,
|
|
23348
|
+
"alt",
|
|
23349
|
+
names2
|
|
23350
|
+
);
|
|
23180
23351
|
return [
|
|
23181
23352
|
`(() => {`,
|
|
23182
23353
|
` const __test = (${parts.alwaysSrc});`,
|
|
@@ -23398,8 +23569,9 @@ ${inner}
|
|
|
23398
23569
|
testSrc: `$nullishTest(${l})`
|
|
23399
23570
|
});
|
|
23400
23571
|
}
|
|
23401
|
-
const
|
|
23572
|
+
const leftGuards = nullishGuardsOf(expr.left);
|
|
23402
23573
|
const andTypeGuard = typeGuardOf(expr.left);
|
|
23574
|
+
const leftDiscGuards = discriminantGuardsOf(expr.left);
|
|
23403
23575
|
return op === "&&" ? transpileShortCircuitExpr(opts, {
|
|
23404
23576
|
alwaysNodes: [lNode],
|
|
23405
23577
|
alwaysSrc: l,
|
|
@@ -23407,8 +23579,9 @@ ${inner}
|
|
|
23407
23579
|
consNodes: [rNode],
|
|
23408
23580
|
altSrc: "__test",
|
|
23409
23581
|
altNodes: [],
|
|
23410
|
-
|
|
23411
|
-
typeGuard: andTypeGuard
|
|
23582
|
+
narrowGuards: leftGuards.filter((g) => g.arm === "cons"),
|
|
23583
|
+
typeGuard: andTypeGuard,
|
|
23584
|
+
discGuards: leftDiscGuards.filter((g) => g.arm === "cons")
|
|
23412
23585
|
}) : transpileShortCircuitExpr(opts, {
|
|
23413
23586
|
alwaysNodes: [lNode],
|
|
23414
23587
|
alwaysSrc: l,
|
|
@@ -23416,8 +23589,9 @@ ${inner}
|
|
|
23416
23589
|
consNodes: [],
|
|
23417
23590
|
altSrc: r,
|
|
23418
23591
|
altNodes: [rNode],
|
|
23419
|
-
|
|
23420
|
-
typeGuard: andTypeGuard
|
|
23592
|
+
narrowGuards: leftGuards.filter((g) => g.arm === "alt"),
|
|
23593
|
+
typeGuard: andTypeGuard,
|
|
23594
|
+
discGuards: leftDiscGuards.filter((g) => g.arm === "alt")
|
|
23421
23595
|
});
|
|
23422
23596
|
}
|
|
23423
23597
|
case "ConditionalExpression": {
|
|
@@ -23435,9 +23609,12 @@ ${inner}
|
|
|
23435
23609
|
altSrc: a,
|
|
23436
23610
|
altNodes: [altNode],
|
|
23437
23611
|
// 三元的 nullish/typeof 守卫臂收窄(issue #97:`p === null ? -1 : p.major`;
|
|
23438
|
-
// Bug 23:`typeof v === "string" ? v + "!" : 0
|
|
23439
|
-
|
|
23440
|
-
|
|
23612
|
+
// Bug 23:`typeof v === "string" ? v + "!" : 0`;#118 v3/#120:多名复合
|
|
23613
|
+
// `obj == null || node.p == null ? … : node.p.name` 一臂多事实);
|
|
23614
|
+
// 判别等值守卫(issue #126):`node.type === 'TL' ? node.quasis[0] : null`
|
|
23615
|
+
narrowGuards: nullishGuardsOf(expr.test),
|
|
23616
|
+
typeGuard: typeGuardOf(expr.test),
|
|
23617
|
+
discGuards: discriminantGuardsOf(expr.test)
|
|
23441
23618
|
});
|
|
23442
23619
|
}
|
|
23443
23620
|
case "RegExpLiteral": {
|
|
@@ -24194,7 +24371,7 @@ function transpileSource(source, opts = {}) {
|
|
|
24194
24371
|
return transpileFile(file, { ...opts, source: opts.source ?? source });
|
|
24195
24372
|
}
|
|
24196
24373
|
function runtimeImportOf(runtime) {
|
|
24197
|
-
return `import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`;
|
|
24374
|
+
return `import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowMemberEq, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`;
|
|
24198
24375
|
}
|
|
24199
24376
|
function transpileFile(file, opts = {}) {
|
|
24200
24377
|
const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
|
|
@@ -24215,7 +24392,7 @@ function transpileFile(file, opts = {}) {
|
|
|
24215
24392
|
};
|
|
24216
24393
|
const lines = [
|
|
24217
24394
|
`// nudo evaluator transpile \u2014 values are Abs; operators are overloaded calls`,
|
|
24218
|
-
`import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`,
|
|
24395
|
+
`import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowMemberEq, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`,
|
|
24219
24396
|
``
|
|
24220
24397
|
];
|
|
24221
24398
|
if (varHoistLine) lines.push(varHoistLine);
|
|
@@ -25685,6 +25862,8 @@ function $copy(a) {
|
|
|
25685
25862
|
open: s.open
|
|
25686
25863
|
});
|
|
25687
25864
|
next.conf = a.conf;
|
|
25865
|
+
next.term = a.term;
|
|
25866
|
+
next.pred = a.pred;
|
|
25688
25867
|
migrateAccessors(a, next);
|
|
25689
25868
|
migrateInvariants(a, next);
|
|
25690
25869
|
migrateNullProto(a, next);
|
|
@@ -28243,6 +28422,58 @@ function $narrowTypeOf(a, typeOf2, keep) {
|
|
|
28243
28422
|
if (kept.length === 0) return a;
|
|
28244
28423
|
return kept.length === 1 ? kept[0] : { ...a, shape: { k: "sum", members: kept } };
|
|
28245
28424
|
}
|
|
28425
|
+
function litRefutesEq(other, v2) {
|
|
28426
|
+
return other !== v2;
|
|
28427
|
+
}
|
|
28428
|
+
function memberEqClass(m, key, litAbs, value) {
|
|
28429
|
+
const sh = m.shape;
|
|
28430
|
+
if (sh.k === "obj") {
|
|
28431
|
+
const slots = sh.slots;
|
|
28432
|
+
if (!Object.prototype.hasOwnProperty.call(slots, key)) {
|
|
28433
|
+
return sh.open ? "may" : "never";
|
|
28434
|
+
}
|
|
28435
|
+
const slotValue = slots[key].value;
|
|
28436
|
+
if (slotValue.shape.k === "any" || slotValue.shape.k === "unknown") return "may";
|
|
28437
|
+
const shapeOnly = (s) => abs(s, void 0, void 0, "exact");
|
|
28438
|
+
if (!leqAbs(shapeOnly(litAbs.shape), shapeOnly(slotValue.shape)).ok) return "never";
|
|
28439
|
+
const t = slotValue.term;
|
|
28440
|
+
const p = slotValue.pred;
|
|
28441
|
+
if (!t || !p || p.op === "true") return "may";
|
|
28442
|
+
const litTerm = lit(value);
|
|
28443
|
+
if (implies(p, { op: "eq", a: t, b: litTerm })) return "only";
|
|
28444
|
+
if (implies(p, { op: "ne", a: t, b: litTerm })) return "never";
|
|
28445
|
+
const conjuncts = [];
|
|
28446
|
+
const visit2 = (c) => {
|
|
28447
|
+
if (c.op === "and") {
|
|
28448
|
+
c.args.forEach(visit2);
|
|
28449
|
+
return;
|
|
28450
|
+
}
|
|
28451
|
+
conjuncts.push(c);
|
|
28452
|
+
};
|
|
28453
|
+
visit2(p);
|
|
28454
|
+
for (const c of conjuncts) {
|
|
28455
|
+
if (c.op !== "eq") continue;
|
|
28456
|
+
const other = termEquals(c.a, t) && c.b.op === "lit" ? c.b.value : termEquals(c.b, t) && c.a.op === "lit" ? c.a.value : void 0;
|
|
28457
|
+
if (other !== void 0 && litRefutesEq(other, value)) return "never";
|
|
28458
|
+
}
|
|
28459
|
+
return "may";
|
|
28460
|
+
}
|
|
28461
|
+
if (m.term?.op === "lit") return "never";
|
|
28462
|
+
return "may";
|
|
28463
|
+
}
|
|
28464
|
+
function $narrowMemberEq(a, key, value, keep) {
|
|
28465
|
+
if (!a || typeof a !== "object" || !("shape" in a)) return a;
|
|
28466
|
+
if (a.shape.k !== "sum") return a;
|
|
28467
|
+
const litAbs = typeof value === "string" ? strLit(value) : typeof value === "number" ? numLit(value) : boolLit(value);
|
|
28468
|
+
const members = a.shape.members;
|
|
28469
|
+
const kept = members.filter((m) => {
|
|
28470
|
+
const c = memberEqClass(m, key, litAbs, value);
|
|
28471
|
+
return keep ? c !== "never" : c !== "only";
|
|
28472
|
+
});
|
|
28473
|
+
if (kept.length === members.length) return a;
|
|
28474
|
+
if (kept.length === 0) return a;
|
|
28475
|
+
return kept.length === 1 ? kept[0] : { ...a, shape: { k: "sum", members: kept } };
|
|
28476
|
+
}
|
|
28246
28477
|
function primShapeOfTypeOf(typeOf2) {
|
|
28247
28478
|
switch (typeOf2) {
|
|
28248
28479
|
case "string":
|
|
@@ -28267,7 +28498,10 @@ var init_async = __esm({
|
|
|
28267
28498
|
"../core/src/algebra/exec/runtime/async.ts"() {
|
|
28268
28499
|
"use strict";
|
|
28269
28500
|
init_abs();
|
|
28501
|
+
init_term();
|
|
28502
|
+
init_pred();
|
|
28270
28503
|
init_objects();
|
|
28504
|
+
init_leq();
|
|
28271
28505
|
init_abs_fn();
|
|
28272
28506
|
init_surface();
|
|
28273
28507
|
init_state();
|
|
@@ -28337,6 +28571,7 @@ __export(runtime_exports, {
|
|
|
28337
28571
|
$lt: () => $lt,
|
|
28338
28572
|
$mod: () => $mod,
|
|
28339
28573
|
$mul: () => $mul,
|
|
28574
|
+
$narrowMemberEq: () => $narrowMemberEq,
|
|
28340
28575
|
$narrowTypeOf: () => $narrowTypeOf,
|
|
28341
28576
|
$ne: () => $ne,
|
|
28342
28577
|
$neLoose: () => $neLoose,
|
|
@@ -28489,6 +28724,800 @@ var init_lru_map = __esm({
|
|
|
28489
28724
|
}
|
|
28490
28725
|
});
|
|
28491
28726
|
|
|
28727
|
+
// ../core/src/algebra/constraint.ts
|
|
28728
|
+
function selfTerm() {
|
|
28729
|
+
return v(SELF);
|
|
28730
|
+
}
|
|
28731
|
+
function getTerm(obj2, key) {
|
|
28732
|
+
return app("get", [obj2, lit(key)]);
|
|
28733
|
+
}
|
|
28734
|
+
function lenTerm(t) {
|
|
28735
|
+
return app("length", [t]);
|
|
28736
|
+
}
|
|
28737
|
+
function isConstraint(x) {
|
|
28738
|
+
return !!x && typeof x === "object" && x.__nudoConstraint === true;
|
|
28739
|
+
}
|
|
28740
|
+
function isNudoConstraint(x) {
|
|
28741
|
+
return isConstraint(x);
|
|
28742
|
+
}
|
|
28743
|
+
function isIntFlag(c) {
|
|
28744
|
+
return c.int === true || intFlaggedBuilders.has(c);
|
|
28745
|
+
}
|
|
28746
|
+
function makeBuilder(prim2, preds, extra) {
|
|
28747
|
+
const fields = extra?.fields;
|
|
28748
|
+
const element = extra?.element;
|
|
28749
|
+
const isInt = extra?.int;
|
|
28750
|
+
const optional = extra?.optional;
|
|
28751
|
+
const members = extra?.members;
|
|
28752
|
+
const fnSlot = extra?.fn;
|
|
28753
|
+
const lazySlot = extra?.lazy;
|
|
28754
|
+
const base = {
|
|
28755
|
+
__nudoConstraint: true,
|
|
28756
|
+
...prim2 ? { prim: prim2 } : {},
|
|
28757
|
+
preds: [...preds],
|
|
28758
|
+
...fields ? { fields } : {},
|
|
28759
|
+
...element ? { element } : {},
|
|
28760
|
+
...optional ? { isOptional: true } : {},
|
|
28761
|
+
...members ? { members } : {},
|
|
28762
|
+
...fnSlot ? { fn: fnSlot } : {},
|
|
28763
|
+
...lazySlot ? { lazy: lazySlot } : {}
|
|
28764
|
+
};
|
|
28765
|
+
const add2 = (p) => makeBuilder(prim2, [...preds, p], extra);
|
|
28766
|
+
const builder = Object.assign(
|
|
28767
|
+
/* @__PURE__ */ Object.create(null),
|
|
28768
|
+
base,
|
|
28769
|
+
{
|
|
28770
|
+
gt: (n) => add2(gt(selfTerm(), lit(n))),
|
|
28771
|
+
ge: (n) => add2(ge(selfTerm(), lit(n))),
|
|
28772
|
+
lt: (n) => add2(lt(selfTerm(), lit(n))),
|
|
28773
|
+
le: (n) => add2(le(selfTerm(), lit(n))),
|
|
28774
|
+
int: () => makeBuilder(prim2 ?? "number", preds, { ...extra, int: true }),
|
|
28775
|
+
min: (n) => add2(ge(lenTerm(selfTerm()), lit(n))),
|
|
28776
|
+
max: (n) => add2(le(lenTerm(selfTerm()), lit(n))),
|
|
28777
|
+
length: (n) => add2(and(ge(lenTerm(selfTerm()), lit(n)), le(lenTerm(selfTerm()), lit(n)))),
|
|
28778
|
+
shift: (n) => {
|
|
28779
|
+
if (!Number.isFinite(n))
|
|
28780
|
+
throw new Error("nudo shift(): offset must be a finite number");
|
|
28781
|
+
if (fields || element || members || fnSlot || lazySlot)
|
|
28782
|
+
throw new Error("nudo shift(): only numeric scalar constraint chains are allowed (shape/array/union/fn are not supported)");
|
|
28783
|
+
if (prim2 !== void 0 && prim2 !== "number")
|
|
28784
|
+
throw new Error(`nudo shift(): only numeric chains are allowed (prim=${prim2})`);
|
|
28785
|
+
return makeBuilder(prim2, shiftBoundPreds(preds, n), extra);
|
|
28786
|
+
},
|
|
28787
|
+
optional: () => makeBuilder(prim2, preds, { ...extra, optional: true })
|
|
28788
|
+
}
|
|
28789
|
+
);
|
|
28790
|
+
if (isInt) intFlaggedBuilders.add(builder);
|
|
28791
|
+
return builder;
|
|
28792
|
+
}
|
|
28793
|
+
function shiftBoundPreds(preds, n) {
|
|
28794
|
+
return preds.map((p) => {
|
|
28795
|
+
if (p.op !== "gt" && p.op !== "ge" && p.op !== "lt" && p.op !== "le")
|
|
28796
|
+
throw new Error(`nudo shift(): predicate ${p.op} is not supported (only gt/ge/lt/le constant bounds)`);
|
|
28797
|
+
const { a, b } = p;
|
|
28798
|
+
if (b.op !== "lit" || typeof b.value !== "number")
|
|
28799
|
+
throw new Error("nudo shift(): the right-hand side of a constant bound must be a numeric literal");
|
|
28800
|
+
if (termHasApp(a, "length") || termHasApp(b, "length"))
|
|
28801
|
+
throw new Error("nudo shift(): length(...) bounds are not supported");
|
|
28802
|
+
return { op: p.op, a, b: lit(b.value + n) };
|
|
28803
|
+
});
|
|
28804
|
+
}
|
|
28805
|
+
function termHasApp(t, fn2) {
|
|
28806
|
+
if (t.op !== "app") return false;
|
|
28807
|
+
if (t.fn === fn2) return true;
|
|
28808
|
+
return t.args.some((x) => termHasApp(x, fn2));
|
|
28809
|
+
}
|
|
28810
|
+
function number() {
|
|
28811
|
+
return makeBuilder("number", []);
|
|
28812
|
+
}
|
|
28813
|
+
function string() {
|
|
28814
|
+
return makeBuilder("string", []);
|
|
28815
|
+
}
|
|
28816
|
+
function boolean() {
|
|
28817
|
+
return makeBuilder("boolean", []);
|
|
28818
|
+
}
|
|
28819
|
+
function any() {
|
|
28820
|
+
return makeBuilder(void 0, []);
|
|
28821
|
+
}
|
|
28822
|
+
function array(item) {
|
|
28823
|
+
return makeBuilder(void 0, [], {
|
|
28824
|
+
element: asNestedConstraint(item, "array(item)")
|
|
28825
|
+
});
|
|
28826
|
+
}
|
|
28827
|
+
function shape(fields) {
|
|
28828
|
+
const mapped = {};
|
|
28829
|
+
for (const [k, v2] of Object.entries(fields)) {
|
|
28830
|
+
const constraint = asNestedConstraint(v2, `shape \u5B57\u6BB5 '${k}'`);
|
|
28831
|
+
mapped[k] = {
|
|
28832
|
+
constraint,
|
|
28833
|
+
...constraint.isOptional ? { optional: true } : {}
|
|
28834
|
+
};
|
|
28835
|
+
}
|
|
28836
|
+
return makeBuilder(void 0, [], { fields: mapped });
|
|
28837
|
+
}
|
|
28838
|
+
function toPlainConstraint(c) {
|
|
28839
|
+
if (!isConstraint(c))
|
|
28840
|
+
throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
|
|
28841
|
+
return {
|
|
28842
|
+
__nudoConstraint: true,
|
|
28843
|
+
...c.prim ? { prim: c.prim } : {},
|
|
28844
|
+
preds: [...c.preds],
|
|
28845
|
+
...c.fields ? { fields: c.fields } : {},
|
|
28846
|
+
...c.element ? { element: c.element } : {},
|
|
28847
|
+
// isIntFlag 统一读取:builder(int 是方法)查 WeakSet,纯数据看 === true
|
|
28848
|
+
...isIntFlag(c) ? { int: true } : {},
|
|
28849
|
+
...c.isOptional ? { isOptional: true } : {},
|
|
28850
|
+
...c.members ? { members: c.members } : {},
|
|
28851
|
+
...c.fn ? { fn: c.fn } : {},
|
|
28852
|
+
...c.lazy ? { lazy: c.lazy } : {}
|
|
28853
|
+
};
|
|
28854
|
+
}
|
|
28855
|
+
function litC(v2) {
|
|
28856
|
+
const prim2 = typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : typeof v2 === "boolean" ? "boolean" : void 0;
|
|
28857
|
+
return makeBuilder(prim2, [eq(selfTerm(), lit(v2))]);
|
|
28858
|
+
}
|
|
28859
|
+
function asNestedConstraint(x, ctx2) {
|
|
28860
|
+
if (isConstraint(x)) return toPlainConstraint(x);
|
|
28861
|
+
if (x === null || x === void 0 || typeof x === "number" || typeof x === "string" || typeof x === "boolean") {
|
|
28862
|
+
return toPlainConstraint(litC(x));
|
|
28863
|
+
}
|
|
28864
|
+
throw new Error(
|
|
28865
|
+
`nudo: ${ctx2} expects a constraint value (number()/string()/\u2026) or a concrete literal; received a non-constraint`
|
|
28866
|
+
);
|
|
28867
|
+
}
|
|
28868
|
+
function union(...cs) {
|
|
28869
|
+
if (cs.length === 0)
|
|
28870
|
+
throw new Error("nudo union(): at least one member constraint is required");
|
|
28871
|
+
return makeBuilder(void 0, [], {
|
|
28872
|
+
members: cs.map((c) => asNestedConstraint(c, "union member"))
|
|
28873
|
+
});
|
|
28874
|
+
}
|
|
28875
|
+
function nullable(c) {
|
|
28876
|
+
return makeBuilder(void 0, [], {
|
|
28877
|
+
members: [
|
|
28878
|
+
asNestedConstraint(c, "nullable()"),
|
|
28879
|
+
toPlainConstraint(litC(null)),
|
|
28880
|
+
toPlainConstraint(litC(void 0))
|
|
28881
|
+
]
|
|
28882
|
+
});
|
|
28883
|
+
}
|
|
28884
|
+
function lazy(thunk) {
|
|
28885
|
+
if (typeof thunk !== "function")
|
|
28886
|
+
throw new Error("nudo lazy(): expects a thunk function () => constraint");
|
|
28887
|
+
return makeBuilder(void 0, [], { lazy: thunk });
|
|
28888
|
+
}
|
|
28889
|
+
function derefConstraint(c) {
|
|
28890
|
+
const thunk = c.lazy;
|
|
28891
|
+
if (!thunk) return c;
|
|
28892
|
+
const memoized = lazyDerefMemo.get(thunk);
|
|
28893
|
+
if (memoized) return memoized;
|
|
28894
|
+
const out = thunk();
|
|
28895
|
+
if (!isConstraint(out))
|
|
28896
|
+
throw new Error(
|
|
28897
|
+
"nudo lazy(): the thunk must return a constraint (number()/string()/shape()/\u2026)"
|
|
28898
|
+
);
|
|
28899
|
+
const normalized = toPlainConstraint(out);
|
|
28900
|
+
lazyDerefMemo.set(thunk, normalized);
|
|
28901
|
+
return normalized;
|
|
28902
|
+
}
|
|
28903
|
+
function constraintAdmitsNullish(c, seen) {
|
|
28904
|
+
if (c.lazy) {
|
|
28905
|
+
const s = seen ?? /* @__PURE__ */ new Set();
|
|
28906
|
+
if (s.has(c.lazy)) return false;
|
|
28907
|
+
s.add(c.lazy);
|
|
28908
|
+
return constraintAdmitsNullish(derefConstraint(c), s);
|
|
28909
|
+
}
|
|
28910
|
+
if (c.members)
|
|
28911
|
+
return c.members.some((m) => constraintAdmitsNullish(m, seen));
|
|
28912
|
+
if (!c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.fn) return true;
|
|
28913
|
+
for (const p of c.preds) {
|
|
28914
|
+
for (const flat of p.op === "and" ? p.args : [p]) {
|
|
28915
|
+
if (flat.op !== "eq") continue;
|
|
28916
|
+
for (const side of [flat.a, flat.b]) {
|
|
28917
|
+
if (side.op === "lit" && (side.value === null || side.value === void 0)) return true;
|
|
28918
|
+
}
|
|
28919
|
+
}
|
|
28920
|
+
}
|
|
28921
|
+
return false;
|
|
28922
|
+
}
|
|
28923
|
+
function fn(params, returns, opts) {
|
|
28924
|
+
const normalized = {};
|
|
28925
|
+
for (const [k, v2] of Object.entries(params)) {
|
|
28926
|
+
normalized[k] = asNestedConstraint(v2, `fn param '${k}'`);
|
|
28927
|
+
}
|
|
28928
|
+
return makeBuilder(void 0, [], {
|
|
28929
|
+
fn: {
|
|
28930
|
+
params: normalized,
|
|
28931
|
+
...returns !== void 0 ? { returns: asNestedConstraint(returns, "fn return value") } : {},
|
|
28932
|
+
...opts?.throws !== void 0 ? { throws: asNestedConstraint(opts.throws, "fn throws") } : {}
|
|
28933
|
+
}
|
|
28934
|
+
});
|
|
28935
|
+
}
|
|
28936
|
+
function andC(...cs) {
|
|
28937
|
+
if (cs.length === 0)
|
|
28938
|
+
throw new Error("nudo and(): at least one constraint is required");
|
|
28939
|
+
let prim2;
|
|
28940
|
+
let isInt = false;
|
|
28941
|
+
let allOptional = true;
|
|
28942
|
+
const preds = [];
|
|
28943
|
+
for (const c0 of cs) {
|
|
28944
|
+
if (!isConstraint(c0))
|
|
28945
|
+
throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
|
|
28946
|
+
const c = derefConstraint(c0);
|
|
28947
|
+
if (c.fields || c.element || c.members || c.fn)
|
|
28948
|
+
throw new Error("nudo and(): Phase 1 supports scalar constraint conjunction only (shape/array/union/fn are not supported)");
|
|
28949
|
+
if (c.prim) {
|
|
28950
|
+
if (prim2 !== void 0 && prim2 !== c.prim)
|
|
28951
|
+
throw new Error(`nudo and(): inconsistent prim (${prim2} vs ${c.prim})`);
|
|
28952
|
+
prim2 = c.prim;
|
|
28953
|
+
}
|
|
28954
|
+
preds.push(...c.preds);
|
|
28955
|
+
if (isIntFlag(c)) isInt = true;
|
|
28956
|
+
if (!c.isOptional) allOptional = false;
|
|
28957
|
+
}
|
|
28958
|
+
return makeBuilder(prim2, preds, {
|
|
28959
|
+
...isInt ? { int: true } : {},
|
|
28960
|
+
...allOptional ? { optional: true } : {}
|
|
28961
|
+
});
|
|
28962
|
+
}
|
|
28963
|
+
function partial(c) {
|
|
28964
|
+
if (!isConstraint(c))
|
|
28965
|
+
throw new Error("nudo partial(): only shape(...) constraints are accepted");
|
|
28966
|
+
const d = derefConstraint(c);
|
|
28967
|
+
if (!d.fields)
|
|
28968
|
+
throw new Error("nudo partial(): only shape(...) constraints are accepted");
|
|
28969
|
+
const fields = {};
|
|
28970
|
+
for (const [k, f] of Object.entries(d.fields)) {
|
|
28971
|
+
fields[k] = {
|
|
28972
|
+
constraint: { ...toPlainConstraint(f.constraint), isOptional: true },
|
|
28973
|
+
optional: true
|
|
28974
|
+
};
|
|
28975
|
+
}
|
|
28976
|
+
return makeBuilder(d.prim, d.preds, { fields });
|
|
28977
|
+
}
|
|
28978
|
+
function pick(c, keys) {
|
|
28979
|
+
if (!isConstraint(c))
|
|
28980
|
+
throw new Error("nudo pick(): only shape(...) constraints are accepted");
|
|
28981
|
+
const d = derefConstraint(c);
|
|
28982
|
+
if (!d.fields)
|
|
28983
|
+
throw new Error("nudo pick(): only shape(...) constraints are accepted");
|
|
28984
|
+
const fields = {};
|
|
28985
|
+
for (const k of keys) {
|
|
28986
|
+
const f = d.fields[k];
|
|
28987
|
+
if (f) fields[k] = f;
|
|
28988
|
+
}
|
|
28989
|
+
return makeBuilder(d.prim, d.preds, { fields });
|
|
28990
|
+
}
|
|
28991
|
+
function omit(c, keys) {
|
|
28992
|
+
if (!isConstraint(c))
|
|
28993
|
+
throw new Error("nudo omit(): only shape(...) constraints are accepted");
|
|
28994
|
+
const d = derefConstraint(c);
|
|
28995
|
+
if (!d.fields)
|
|
28996
|
+
throw new Error("nudo omit(): only shape(...) constraints are accepted");
|
|
28997
|
+
const drop = new Set(keys);
|
|
28998
|
+
const fields = {};
|
|
28999
|
+
for (const [k, f] of Object.entries(d.fields)) {
|
|
29000
|
+
if (!drop.has(k)) fields[k] = f;
|
|
29001
|
+
}
|
|
29002
|
+
return makeBuilder(d.prim, d.preds, { fields });
|
|
29003
|
+
}
|
|
29004
|
+
function substTerm(t, paramName2) {
|
|
29005
|
+
if (t.op === "var" && t.id === SELF) return v(paramName2);
|
|
29006
|
+
if (t.op === "app" && t.fn === "get" && t.args.length === 2) {
|
|
29007
|
+
return getTerm(substTerm(t.args[0], paramName2), String(
|
|
29008
|
+
t.args[1].op === "lit" ? t.args[1].value : ""
|
|
29009
|
+
));
|
|
29010
|
+
}
|
|
29011
|
+
return t;
|
|
29012
|
+
}
|
|
29013
|
+
function substPred2(p, paramName2) {
|
|
29014
|
+
switch (p.op) {
|
|
29015
|
+
case "gt":
|
|
29016
|
+
case "ge":
|
|
29017
|
+
case "lt":
|
|
29018
|
+
case "le":
|
|
29019
|
+
case "eq":
|
|
29020
|
+
case "ne": {
|
|
29021
|
+
return { op: p.op, a: substTerm(p.a, paramName2), b: substTerm(p.b, paramName2) };
|
|
29022
|
+
}
|
|
29023
|
+
case "typeof": {
|
|
29024
|
+
return { op: "typeof", t: substTerm(p.t, paramName2), type: p.type };
|
|
29025
|
+
}
|
|
29026
|
+
case "and":
|
|
29027
|
+
return and(...p.args.map((x) => substPred2(x, paramName2)));
|
|
29028
|
+
default:
|
|
29029
|
+
return p;
|
|
29030
|
+
}
|
|
29031
|
+
}
|
|
29032
|
+
function instantiateConstraint(c, paramName2, depth = LAZY_TEMPLATE_DEPTH) {
|
|
29033
|
+
if (c.lazy) {
|
|
29034
|
+
if (depth <= 0) return pTrue;
|
|
29035
|
+
return instantiateConstraint(derefConstraint(c), paramName2, depth - 1);
|
|
29036
|
+
}
|
|
29037
|
+
if (c.fields) {
|
|
29038
|
+
const parts = [];
|
|
29039
|
+
for (const [key, field] of Object.entries(c.fields)) {
|
|
29040
|
+
if (field.optional || field.constraint.isOptional) continue;
|
|
29041
|
+
const fieldTerm = getTerm(v(paramName2), key);
|
|
29042
|
+
parts.push(instantiateOnTerm(field.constraint, fieldTerm, depth));
|
|
29043
|
+
}
|
|
29044
|
+
if (c.prim) parts.push(ptypeof(v(paramName2), primToTypeof(c.prim)));
|
|
29045
|
+
if (parts.length === 0) return { op: "true" };
|
|
29046
|
+
return parts.length === 1 ? parts[0] : and(...parts);
|
|
29047
|
+
}
|
|
29048
|
+
if (c.members) {
|
|
29049
|
+
const disj = or(
|
|
29050
|
+
...c.members.map((m) => instantiateOnTerm(m, v(paramName2), depth))
|
|
29051
|
+
);
|
|
29052
|
+
const own = c.preds.map((p) => substPred2(p, paramName2));
|
|
29053
|
+
return own.length === 0 ? disj : and(...own, disj);
|
|
29054
|
+
}
|
|
29055
|
+
if (c.fn) {
|
|
29056
|
+
const own = c.preds.map((p) => substPred2(p, paramName2));
|
|
29057
|
+
return own.length === 0 ? pTrue : and(...own);
|
|
29058
|
+
}
|
|
29059
|
+
const preds = c.preds.map((p) => substPred2(p, paramName2));
|
|
29060
|
+
if (c.prim && c.preds.length === 0) {
|
|
29061
|
+
return ptypeof(v(paramName2), primToTypeof(c.prim));
|
|
29062
|
+
}
|
|
29063
|
+
return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
|
|
29064
|
+
}
|
|
29065
|
+
function instantiateOnTerm(c, t, depth = LAZY_TEMPLATE_DEPTH) {
|
|
29066
|
+
if (c.lazy) {
|
|
29067
|
+
if (depth <= 0) return pTrue;
|
|
29068
|
+
return instantiateOnTerm(derefConstraint(c), t, depth - 1);
|
|
29069
|
+
}
|
|
29070
|
+
const subst = (p) => {
|
|
29071
|
+
switch (p.op) {
|
|
29072
|
+
case "gt":
|
|
29073
|
+
case "ge":
|
|
29074
|
+
case "lt":
|
|
29075
|
+
case "le":
|
|
29076
|
+
case "eq":
|
|
29077
|
+
case "ne": {
|
|
29078
|
+
const a = p.a.op === "var" && p.a.id === SELF ? t : p.a;
|
|
29079
|
+
const b = p.b.op === "var" && p.b.id === SELF ? t : p.b;
|
|
29080
|
+
return { op: p.op, a, b };
|
|
29081
|
+
}
|
|
29082
|
+
case "typeof": {
|
|
29083
|
+
const tt2 = p.t.op === "var" && p.t.id === SELF ? t : p.t;
|
|
29084
|
+
return { op: "typeof", t: tt2, type: p.type };
|
|
29085
|
+
}
|
|
29086
|
+
case "and":
|
|
29087
|
+
return and(...p.args.map(subst));
|
|
29088
|
+
default:
|
|
29089
|
+
return p;
|
|
29090
|
+
}
|
|
29091
|
+
};
|
|
29092
|
+
if (c.fields) {
|
|
29093
|
+
const parts = [];
|
|
29094
|
+
for (const [key, field] of Object.entries(c.fields)) {
|
|
29095
|
+
if (field.optional || field.constraint.isOptional) continue;
|
|
29096
|
+
parts.push(instantiateOnTerm(field.constraint, getTerm(t, key), depth));
|
|
29097
|
+
}
|
|
29098
|
+
if (parts.length === 0) return { op: "true" };
|
|
29099
|
+
return parts.length === 1 ? parts[0] : and(...parts);
|
|
29100
|
+
}
|
|
29101
|
+
if (c.members) {
|
|
29102
|
+
const disj = or(...c.members.map((m) => instantiateOnTerm(m, t, depth)));
|
|
29103
|
+
const own = c.preds.map(subst);
|
|
29104
|
+
return own.length === 0 ? disj : and(...own, disj);
|
|
29105
|
+
}
|
|
29106
|
+
if (c.fn) {
|
|
29107
|
+
const own = c.preds.map(subst);
|
|
29108
|
+
return own.length === 0 ? pTrue : and(...own);
|
|
29109
|
+
}
|
|
29110
|
+
const preds = c.preds.map(subst);
|
|
29111
|
+
if (c.prim && c.preds.length === 0) return ptypeof(t, primToTypeof(c.prim));
|
|
29112
|
+
return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
|
|
29113
|
+
}
|
|
29114
|
+
function constraintToEntryAbs(c, paramName2, depth = LAZY_TEMPLATE_DEPTH) {
|
|
29115
|
+
const t = v(paramName2);
|
|
29116
|
+
if (c.fields) {
|
|
29117
|
+
const slots = {};
|
|
29118
|
+
for (const [key, field] of Object.entries(c.fields)) {
|
|
29119
|
+
if (field.constraint.lazy && depth <= 0) continue;
|
|
29120
|
+
const fieldTerm = getTerm(t, key);
|
|
29121
|
+
slots[key] = {
|
|
29122
|
+
value: constraintOnTermAbs(field.constraint, fieldTerm, depth),
|
|
29123
|
+
...field.optional || field.constraint.isOptional ? { optional: true } : {}
|
|
29124
|
+
};
|
|
29125
|
+
}
|
|
29126
|
+
return abs({ k: "obj", slots }, t, void 0, "path");
|
|
29127
|
+
}
|
|
29128
|
+
return constraintOnTermAbs(c, t, depth);
|
|
29129
|
+
}
|
|
29130
|
+
function memberLitValue(m) {
|
|
29131
|
+
const leaves = [];
|
|
29132
|
+
const visit2 = (p2) => {
|
|
29133
|
+
if (p2.op === "and") {
|
|
29134
|
+
p2.args.forEach(visit2);
|
|
29135
|
+
return;
|
|
29136
|
+
}
|
|
29137
|
+
leaves.push(p2);
|
|
29138
|
+
};
|
|
29139
|
+
m.preds.forEach(visit2);
|
|
29140
|
+
if (leaves.length !== 1) return { ok: false };
|
|
29141
|
+
const p = leaves[0];
|
|
29142
|
+
if (p.op !== "eq") return { ok: false };
|
|
29143
|
+
if (p.a.op === "var" && p.b.op === "lit") {
|
|
29144
|
+
return { ok: true, v: p.b.value };
|
|
29145
|
+
}
|
|
29146
|
+
if (p.b.op === "var" && p.a.op === "lit") {
|
|
29147
|
+
return { ok: true, v: p.a.value };
|
|
29148
|
+
}
|
|
29149
|
+
return { ok: false };
|
|
29150
|
+
}
|
|
29151
|
+
function samePrimLiteralUnionAbs(members, t) {
|
|
29152
|
+
if (members.length === 0) return void 0;
|
|
29153
|
+
const values = [];
|
|
29154
|
+
let prim2;
|
|
29155
|
+
for (const m of members) {
|
|
29156
|
+
const mk = memberLitValue(m);
|
|
29157
|
+
if (!mk.ok) return void 0;
|
|
29158
|
+
const v2 = mk.v;
|
|
29159
|
+
if (v2 === void 0 || v2 === null) return void 0;
|
|
29160
|
+
const mp = m.prim ?? (typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : "boolean");
|
|
29161
|
+
if (prim2 === void 0) prim2 = mp;
|
|
29162
|
+
else if (prim2 !== mp) return void 0;
|
|
29163
|
+
values.push(v2);
|
|
29164
|
+
}
|
|
29165
|
+
if (prim2 === void 0) return void 0;
|
|
29166
|
+
const uniq = [];
|
|
29167
|
+
for (const v2 of values) {
|
|
29168
|
+
if (!uniq.some((u) => Object.is(u, v2))) uniq.push(v2);
|
|
29169
|
+
}
|
|
29170
|
+
const disj = or(
|
|
29171
|
+
...uniq.map((v2) => eq(t, lit(v2)))
|
|
29172
|
+
);
|
|
29173
|
+
return abs({ k: "prim", type: prim2 }, t, disj, "path");
|
|
29174
|
+
}
|
|
29175
|
+
function constraintOnTermAbs(c, t, depth) {
|
|
29176
|
+
if (c.lazy) {
|
|
29177
|
+
if (depth <= 0) return abs({ k: "any" }, t, void 0, "path");
|
|
29178
|
+
return constraintOnTermAbs(derefConstraint(c), t, depth - 1);
|
|
29179
|
+
}
|
|
29180
|
+
if (c.fields) {
|
|
29181
|
+
const slots = {};
|
|
29182
|
+
for (const [key, field] of Object.entries(c.fields)) {
|
|
29183
|
+
if (field.constraint.lazy && depth <= 0) continue;
|
|
29184
|
+
slots[key] = {
|
|
29185
|
+
value: constraintOnTermAbs(field.constraint, getTerm(t, key), depth),
|
|
29186
|
+
...field.optional || field.constraint.isOptional ? { optional: true } : {}
|
|
29187
|
+
};
|
|
29188
|
+
}
|
|
29189
|
+
return abs({ k: "obj", slots }, t, void 0, "path");
|
|
29190
|
+
}
|
|
29191
|
+
if (c.members) {
|
|
29192
|
+
const litUnion = samePrimLiteralUnionAbs(c.members, t);
|
|
29193
|
+
if (litUnion) return litUnion;
|
|
29194
|
+
const joined = c.members.map((m) => constraintOnTermAbs(m, t, depth)).reduce((a, b) => joinAbs(a, b));
|
|
29195
|
+
if (joined.shape.k === "prim" && joined.pred === void 0 && c.members.every((m) => m.prim === joined.shape.type)) {
|
|
29196
|
+
const type = joined.shape.type;
|
|
29197
|
+
return abs({ k: "prim", type }, t, ptypeof(t, primToTypeof(type)), "path");
|
|
29198
|
+
}
|
|
29199
|
+
return joined;
|
|
29200
|
+
}
|
|
29201
|
+
if (c.fn) {
|
|
29202
|
+
const paramNames = Object.keys(c.fn.params);
|
|
29203
|
+
const paramTypes = paramNames.map(
|
|
29204
|
+
(p, i) => constraintOnTermAbs(c.fn.params[p], v(`x${i}`), depth)
|
|
29205
|
+
);
|
|
29206
|
+
const returnType = c.fn.returns ? constraintOnTermAbs(c.fn.returns, v("ret"), depth) : unknown;
|
|
29207
|
+
return abs(
|
|
29208
|
+
{ k: "fn", params: paramNames, paramTypes, returnType },
|
|
29209
|
+
t,
|
|
29210
|
+
void 0,
|
|
29211
|
+
"path"
|
|
29212
|
+
);
|
|
29213
|
+
}
|
|
29214
|
+
if (c.element) {
|
|
29215
|
+
const elem = constraintOnTermAbs(c.element, v("x[]"), depth);
|
|
29216
|
+
return abs({ k: "arr", element: elem }, t, void 0, "path");
|
|
29217
|
+
}
|
|
29218
|
+
const pred = instantiateOnTerm(c, t, depth);
|
|
29219
|
+
const predOut = pred.op === "true" ? void 0 : pred;
|
|
29220
|
+
if (c.prim) {
|
|
29221
|
+
return abs({ k: "prim", type: c.prim }, t, predOut, "path");
|
|
29222
|
+
}
|
|
29223
|
+
const allEqNullish = c.preds.length > 0 && c.preds.every(
|
|
29224
|
+
(p) => p.op === "eq" && (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0) || p.a.op === "lit" && (p.a.value === null || p.a.value === void 0))
|
|
29225
|
+
);
|
|
29226
|
+
if (allEqNullish) {
|
|
29227
|
+
let nullish = null;
|
|
29228
|
+
for (const p of c.preds) {
|
|
29229
|
+
if (p.op !== "eq") continue;
|
|
29230
|
+
if (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0)) {
|
|
29231
|
+
nullish = p.b.value;
|
|
29232
|
+
break;
|
|
29233
|
+
}
|
|
29234
|
+
if (p.a.op === "lit" && (p.a.value === null || p.a.value === void 0)) {
|
|
29235
|
+
nullish = p.a.value;
|
|
29236
|
+
break;
|
|
29237
|
+
}
|
|
29238
|
+
}
|
|
29239
|
+
return abs({ k: "unknown" }, lit(nullish), void 0, "path");
|
|
29240
|
+
}
|
|
29241
|
+
if (c.preds.length > 0) {
|
|
29242
|
+
return abs({ k: "prim", type: "number" }, t, predOut, "path");
|
|
29243
|
+
}
|
|
29244
|
+
return abs({ k: "any" }, t, void 0, "path");
|
|
29245
|
+
}
|
|
29246
|
+
function fnConstraintToEntryReqs(c) {
|
|
29247
|
+
if (!c.fn) throw new Error("nudo fnConstraintToEntryReqs(): constraint is not in fn() form");
|
|
29248
|
+
return Object.entries(c.fn.params).map(([param, constraint]) => ({
|
|
29249
|
+
param,
|
|
29250
|
+
constraint
|
|
29251
|
+
}));
|
|
29252
|
+
}
|
|
29253
|
+
function throwConstraintToKinds(c) {
|
|
29254
|
+
if (!c) return void 0;
|
|
29255
|
+
const out = /* @__PURE__ */ new Set();
|
|
29256
|
+
let any2 = false;
|
|
29257
|
+
const seen = /* @__PURE__ */ new Set();
|
|
29258
|
+
const note2 = (s) => {
|
|
29259
|
+
if (s === "*" || s === "any") any2 = true;
|
|
29260
|
+
else if (s) out.add(s);
|
|
29261
|
+
};
|
|
29262
|
+
const walk = (x) => {
|
|
29263
|
+
if (x.lazy) {
|
|
29264
|
+
if (seen.has(x.lazy)) return;
|
|
29265
|
+
seen.add(x.lazy);
|
|
29266
|
+
walk(derefConstraint(x));
|
|
29267
|
+
return;
|
|
29268
|
+
}
|
|
29269
|
+
if (x.members) {
|
|
29270
|
+
for (const m of x.members) walk(m);
|
|
29271
|
+
return;
|
|
29272
|
+
}
|
|
29273
|
+
for (const p of x.preds) {
|
|
29274
|
+
if (p.op !== "eq" && p.op !== "ne") continue;
|
|
29275
|
+
for (const side of [p.a, p.b]) {
|
|
29276
|
+
if (side.op === "lit" && typeof side.value === "string") note2(side.value);
|
|
29277
|
+
}
|
|
29278
|
+
}
|
|
29279
|
+
};
|
|
29280
|
+
walk(c);
|
|
29281
|
+
if (any2) return "*";
|
|
29282
|
+
if (out.size > 0) return [...out];
|
|
29283
|
+
return void 0;
|
|
29284
|
+
}
|
|
29285
|
+
var SELF, intFlaggedBuilders, LAZY_TEMPLATE_DEPTH, lazyDerefMemo, CONSTRAINT_BUILDERS, CONSTRAINT_BUILDER_NAMES, CONSTRAINT_EXPR_RE;
|
|
29286
|
+
var init_constraint = __esm({
|
|
29287
|
+
"../core/src/algebra/constraint.ts"() {
|
|
29288
|
+
"use strict";
|
|
29289
|
+
init_pred();
|
|
29290
|
+
init_term();
|
|
29291
|
+
init_abs();
|
|
29292
|
+
init_objects();
|
|
29293
|
+
SELF = "__nudo_self__";
|
|
29294
|
+
intFlaggedBuilders = /* @__PURE__ */ new WeakSet();
|
|
29295
|
+
LAZY_TEMPLATE_DEPTH = 3;
|
|
29296
|
+
lazyDerefMemo = /* @__PURE__ */ new WeakMap();
|
|
29297
|
+
CONSTRAINT_BUILDERS = {
|
|
29298
|
+
number,
|
|
29299
|
+
string,
|
|
29300
|
+
boolean,
|
|
29301
|
+
any,
|
|
29302
|
+
array,
|
|
29303
|
+
shape,
|
|
29304
|
+
lit: litC,
|
|
29305
|
+
union,
|
|
29306
|
+
nullable,
|
|
29307
|
+
lazy,
|
|
29308
|
+
fn,
|
|
29309
|
+
and: andC,
|
|
29310
|
+
partial,
|
|
29311
|
+
pick,
|
|
29312
|
+
omit
|
|
29313
|
+
};
|
|
29314
|
+
CONSTRAINT_BUILDER_NAMES = Object.keys(
|
|
29315
|
+
CONSTRAINT_BUILDERS
|
|
29316
|
+
);
|
|
29317
|
+
CONSTRAINT_EXPR_RE = new RegExp(
|
|
29318
|
+
`^(${CONSTRAINT_BUILDER_NAMES.join("|")})\\s*\\(`
|
|
29319
|
+
);
|
|
29320
|
+
}
|
|
29321
|
+
});
|
|
29322
|
+
|
|
29323
|
+
// ../core/src/algebra/domain-membership.ts
|
|
29324
|
+
function literalMeetsConstraint(lv, c, seen) {
|
|
29325
|
+
if (c.lazy) {
|
|
29326
|
+
const s = seen ?? /* @__PURE__ */ new Set();
|
|
29327
|
+
if (s.has(c.lazy)) return false;
|
|
29328
|
+
s.add(c.lazy);
|
|
29329
|
+
return literalMeetsConstraint(lv, derefConstraint(c), s);
|
|
29330
|
+
}
|
|
29331
|
+
const ext = c;
|
|
29332
|
+
if (c.fields || c.element) return false;
|
|
29333
|
+
if (ext.fn) return false;
|
|
29334
|
+
if (Array.isArray(ext.members) && ext.members.length > 0) {
|
|
29335
|
+
return ext.members.some((m) => literalMeetsConstraint(lv, m, seen));
|
|
29336
|
+
}
|
|
29337
|
+
if (c.prim === void 0) {
|
|
29338
|
+
return c.preds.every((p) => predHolds(lv, p));
|
|
29339
|
+
}
|
|
29340
|
+
if (!primMatches(c.prim, lv)) return false;
|
|
29341
|
+
if (isIntFlag(c) && c.prim === "number" && !(typeof lv === "number" && Number.isInteger(lv))) {
|
|
29342
|
+
return false;
|
|
29343
|
+
}
|
|
29344
|
+
return c.preds.every((p) => predHolds(lv, p));
|
|
29345
|
+
}
|
|
29346
|
+
function primMatches(prim2, lv) {
|
|
29347
|
+
switch (prim2) {
|
|
29348
|
+
case "number":
|
|
29349
|
+
return typeof lv === "number";
|
|
29350
|
+
case "string":
|
|
29351
|
+
return typeof lv === "string";
|
|
29352
|
+
case "boolean":
|
|
29353
|
+
return typeof lv === "boolean";
|
|
29354
|
+
case "object":
|
|
29355
|
+
return lv === null;
|
|
29356
|
+
case "undefined":
|
|
29357
|
+
return lv === void 0;
|
|
29358
|
+
default:
|
|
29359
|
+
return false;
|
|
29360
|
+
}
|
|
29361
|
+
}
|
|
29362
|
+
function predHolds(lv, p) {
|
|
29363
|
+
switch (p.op) {
|
|
29364
|
+
case "eq": {
|
|
29365
|
+
const litT = isSelfVar(p.a) && p.b.op === "lit" ? p.b : isSelfVar(p.b) && p.a.op === "lit" ? p.a : void 0;
|
|
29366
|
+
if (!litT) return false;
|
|
29367
|
+
return Object.is(lv, litT.value);
|
|
29368
|
+
}
|
|
29369
|
+
case "gt":
|
|
29370
|
+
case "ge":
|
|
29371
|
+
case "lt":
|
|
29372
|
+
case "le":
|
|
29373
|
+
return boundHolds(lv, p);
|
|
29374
|
+
case "typeof":
|
|
29375
|
+
return p.t.op === "var" && p.t.id === SELF && primMatches(p.type, lv);
|
|
29376
|
+
// and 是合取:逐参数按同一规则判定(string().length(n) 的 preds 是
|
|
29377
|
+
// and 包裹的两个长度界,叶子仍是 gt/ge/lt/le,无假阳性风险)
|
|
29378
|
+
case "and":
|
|
29379
|
+
return p.args.every((x) => predHolds(lv, x));
|
|
29380
|
+
// ne / or / not / true / false 等其余形态:保守不满足
|
|
29381
|
+
default:
|
|
29382
|
+
return false;
|
|
29383
|
+
}
|
|
29384
|
+
}
|
|
29385
|
+
function cmpHolds(x, op, n) {
|
|
29386
|
+
switch (op) {
|
|
29387
|
+
case "gt":
|
|
29388
|
+
return x > n;
|
|
29389
|
+
case "ge":
|
|
29390
|
+
return x >= n;
|
|
29391
|
+
case "lt":
|
|
29392
|
+
return x < n;
|
|
29393
|
+
case "le":
|
|
29394
|
+
return x <= n;
|
|
29395
|
+
}
|
|
29396
|
+
}
|
|
29397
|
+
function boundHolds(lv, p) {
|
|
29398
|
+
if (p.b.op !== "lit" || typeof p.b.value !== "number") return false;
|
|
29399
|
+
const n = p.b.value;
|
|
29400
|
+
if (isLengthSelf(p.a)) {
|
|
29401
|
+
return typeof lv === "string" && cmpHolds(lv.length, p.op, n);
|
|
29402
|
+
}
|
|
29403
|
+
if (isSelfVar(p.a)) {
|
|
29404
|
+
return typeof lv === "number" && cmpHolds(lv, p.op, n);
|
|
29405
|
+
}
|
|
29406
|
+
return false;
|
|
29407
|
+
}
|
|
29408
|
+
function isSelfVar(t) {
|
|
29409
|
+
return t.op === "var" && t.id === SELF;
|
|
29410
|
+
}
|
|
29411
|
+
function isLengthSelf(t) {
|
|
29412
|
+
return t.op === "app" && t.fn === "length" && t.args.length === 1 && isSelfVar(t.args[0]);
|
|
29413
|
+
}
|
|
29414
|
+
var init_domain_membership = __esm({
|
|
29415
|
+
"../core/src/algebra/domain-membership.ts"() {
|
|
29416
|
+
"use strict";
|
|
29417
|
+
init_constraint();
|
|
29418
|
+
}
|
|
29419
|
+
});
|
|
29420
|
+
|
|
29421
|
+
// ../core/src/algebra/contract-face.ts
|
|
29422
|
+
function attachContractFaces(fnObj, faces) {
|
|
29423
|
+
facesByFn.set(fnObj, faces);
|
|
29424
|
+
}
|
|
29425
|
+
function contractFacesOf(fnObj) {
|
|
29426
|
+
if (!fnObj || typeof fnObj !== "object" && typeof fnObj !== "function") {
|
|
29427
|
+
return void 0;
|
|
29428
|
+
}
|
|
29429
|
+
return facesByFn.get(fnObj);
|
|
29430
|
+
}
|
|
29431
|
+
function setContractFaceResolver(resolver) {
|
|
29432
|
+
const prev = contractFaceResolverSlot.get();
|
|
29433
|
+
contractFaceResolverSlot.set(resolver);
|
|
29434
|
+
return prev;
|
|
29435
|
+
}
|
|
29436
|
+
function resolveContractFacesByName(fnName) {
|
|
29437
|
+
const resolver = contractFaceResolverSlot.get();
|
|
29438
|
+
return resolver ? resolver(fnName) : void 0;
|
|
29439
|
+
}
|
|
29440
|
+
function argLacksInformation(a) {
|
|
29441
|
+
if (!a || typeof a !== "object" || !("shape" in a)) return false;
|
|
29442
|
+
const k = a.shape?.k;
|
|
29443
|
+
if (k === "any") return true;
|
|
29444
|
+
if (k === "unknown") return a.term?.op !== "lit";
|
|
29445
|
+
return false;
|
|
29446
|
+
}
|
|
29447
|
+
function adoptCallArgsToFaces(args, faces) {
|
|
29448
|
+
const n = Math.min(args.length, faces.paramFaces.length);
|
|
29449
|
+
let changed = false;
|
|
29450
|
+
const out = args.slice();
|
|
29451
|
+
for (let i = 0; i < n; i++) {
|
|
29452
|
+
const face = faces.paramFaces[i];
|
|
29453
|
+
if (!face || !argLacksInformation(args[i])) continue;
|
|
29454
|
+
out[i] = face;
|
|
29455
|
+
changed = true;
|
|
29456
|
+
}
|
|
29457
|
+
return changed ? out : args;
|
|
29458
|
+
}
|
|
29459
|
+
function litMeetsReturnConstraint(r, c) {
|
|
29460
|
+
if (!c) return false;
|
|
29461
|
+
const lv = litValue(r);
|
|
29462
|
+
if (!lv.ok) return false;
|
|
29463
|
+
const v2 = lv.value;
|
|
29464
|
+
if (typeof v2 !== "number" && typeof v2 !== "string" && typeof v2 !== "boolean" && v2 !== null && v2 !== void 0) {
|
|
29465
|
+
return false;
|
|
29466
|
+
}
|
|
29467
|
+
return literalMeetsConstraint(v2, c);
|
|
29468
|
+
}
|
|
29469
|
+
function presentCallResultFace(r, faces) {
|
|
29470
|
+
const face = faces.returns;
|
|
29471
|
+
if (!face || !r || typeof r !== "object" || !r.shape) return r;
|
|
29472
|
+
if (r.shape.k === "never") return r;
|
|
29473
|
+
if (r.conf === "opaque") return r;
|
|
29474
|
+
if (litMeetsReturnConstraint(r, faces.returnsConstraint)) return r;
|
|
29475
|
+
if (leqAbs(r, face).ok) return r;
|
|
29476
|
+
return face;
|
|
29477
|
+
}
|
|
29478
|
+
function contractFacesFromEffectiveInterface(eff, paramNames) {
|
|
29479
|
+
if (eff.source !== "handwritten") return void 0;
|
|
29480
|
+
const conflictParams = eff.conflict?.params ?? [];
|
|
29481
|
+
const paramFaces = [];
|
|
29482
|
+
let hasFace = false;
|
|
29483
|
+
for (const e of eff.params) {
|
|
29484
|
+
const idx = paramNames.indexOf(e.param);
|
|
29485
|
+
if (idx < 0 || conflictParams.includes(e.param)) continue;
|
|
29486
|
+
paramFaces[idx] = constraintToEntryAbs(e.constraint, e.param);
|
|
29487
|
+
hasFace = true;
|
|
29488
|
+
}
|
|
29489
|
+
let returns;
|
|
29490
|
+
let returnsConstraint;
|
|
29491
|
+
if (eff.returns && !eff.conflict?.returns) {
|
|
29492
|
+
returns = constraintToEntryAbs(eff.returns.constraint, "return");
|
|
29493
|
+
returnsConstraint = eff.returns.constraint;
|
|
29494
|
+
hasFace = true;
|
|
29495
|
+
}
|
|
29496
|
+
return hasFace ? {
|
|
29497
|
+
paramFaces,
|
|
29498
|
+
...returns !== void 0 ? { returns } : {},
|
|
29499
|
+
...returnsConstraint !== void 0 ? { returnsConstraint } : {}
|
|
29500
|
+
} : void 0;
|
|
29501
|
+
}
|
|
29502
|
+
var facesByFn, contractFaceResolverSlot;
|
|
29503
|
+
var init_contract_face = __esm({
|
|
29504
|
+
"../core/src/algebra/contract-face.ts"() {
|
|
29505
|
+
"use strict";
|
|
29506
|
+
init_abs();
|
|
29507
|
+
init_leq();
|
|
29508
|
+
init_constraint();
|
|
29509
|
+
init_domain_membership();
|
|
29510
|
+
init_collector_scope();
|
|
29511
|
+
facesByFn = /* @__PURE__ */ new WeakMap();
|
|
29512
|
+
contractFaceResolverSlot = createScopedSlot(
|
|
29513
|
+
() => null
|
|
29514
|
+
);
|
|
29515
|
+
registerCollectorScopeParticipant(
|
|
29516
|
+
(body) => contractFaceResolverSlot.runScoped(body)
|
|
29517
|
+
);
|
|
29518
|
+
}
|
|
29519
|
+
});
|
|
29520
|
+
|
|
28492
29521
|
// ../core/src/algebra/exec/calls.ts
|
|
28493
29522
|
var calls_exports = {};
|
|
28494
29523
|
__export(calls_exports, {
|
|
@@ -28697,12 +29726,18 @@ function evalExitCall() {
|
|
|
28697
29726
|
if (evalActiveCallKeys.length > 0) evalActiveCallKeys.pop();
|
|
28698
29727
|
}
|
|
28699
29728
|
function $callNamed(name, fn2, args, loc, argLocs) {
|
|
28700
|
-
const
|
|
29729
|
+
const faces = resolveContractFacesByName(name) ?? contractFacesOf(fn2);
|
|
28701
29730
|
const fnObj = fn2 && (typeof fn2 === "object" || typeof fn2 === "function") ? fn2 : void 0;
|
|
28702
|
-
|
|
29731
|
+
if (faces && fnObj) attachContractFaces(fnObj, faces);
|
|
29732
|
+
const execArgs = faces ? adoptCallArgsToFaces(args, faces) : args;
|
|
29733
|
+
const pureName = pureFnNameOf(fn2);
|
|
29734
|
+
const pk = pureName && fnObj ? callBudgetKey("pure", "", execArgs) : void 0;
|
|
28703
29735
|
if (fnObj && pk !== void 0) {
|
|
28704
29736
|
const hit = pureCallMemo.get(fnObj)?.get(pk);
|
|
28705
|
-
if (hit !== void 0)
|
|
29737
|
+
if (hit !== void 0) {
|
|
29738
|
+
const routed = routeApplyThrows(hit.abs, hit.throws);
|
|
29739
|
+
return faces ? presentCallResultFace(routed, faces) : routed;
|
|
29740
|
+
}
|
|
28706
29741
|
}
|
|
28707
29742
|
let result = unknown;
|
|
28708
29743
|
let threw = false;
|
|
@@ -28736,24 +29771,24 @@ function $callNamed(name, fn2, args, loc, argLocs) {
|
|
|
28736
29771
|
} else if (isHostGlobalFn(fn2)) {
|
|
28737
29772
|
result = callHostGlobalLiteralOnly(name, fn2, args);
|
|
28738
29773
|
} else {
|
|
28739
|
-
const entered = evalEnterCall(name, fn2,
|
|
29774
|
+
const entered = evalEnterCall(name, fn2, execArgs);
|
|
28740
29775
|
if (!entered.ok) {
|
|
28741
29776
|
result = evalTruncatedAbs();
|
|
28742
29777
|
} else {
|
|
28743
29778
|
try {
|
|
28744
|
-
result = callAtFunctionBoundary(() => fn2(...
|
|
29779
|
+
result = callAtFunctionBoundary(() => fn2(...execArgs));
|
|
28745
29780
|
} finally {
|
|
28746
29781
|
evalExitCall();
|
|
28747
29782
|
}
|
|
28748
29783
|
}
|
|
28749
29784
|
}
|
|
28750
29785
|
} else if (fn2 && typeof fn2 === "object" && "shape" in fn2) {
|
|
28751
|
-
const entered = evalEnterCall(name, fn2,
|
|
29786
|
+
const entered = evalEnterCall(name, fn2, execArgs);
|
|
28752
29787
|
if (!entered.ok) {
|
|
28753
29788
|
result = evalTruncatedAbs();
|
|
28754
29789
|
} else {
|
|
28755
29790
|
try {
|
|
28756
|
-
result = $call(fn2,
|
|
29791
|
+
result = $call(fn2, execArgs);
|
|
28757
29792
|
} finally {
|
|
28758
29793
|
evalExitCall();
|
|
28759
29794
|
}
|
|
@@ -28787,7 +29822,7 @@ function $callNamed(name, fn2, args, loc, argLocs) {
|
|
|
28787
29822
|
}
|
|
28788
29823
|
}
|
|
28789
29824
|
}
|
|
28790
|
-
return result;
|
|
29825
|
+
return faces ? presentCallResultFace(result, faces) : result;
|
|
28791
29826
|
}
|
|
28792
29827
|
var PURE_CALL_MEMO_MAX, pureCallMemo, evalCallCollectorSlot, evalAssignCollectorSlot, bindingSinkSlot, GLOBAL_FNS, NEVER_EXEC_HOST_FN_NAMES, hostGlobalFnIds, MAX_EVAL_CALL_DEPTH, MAX_EVAL_TOTAL_CALLS, evalCallDepth, evalTotalCalls, evalActiveCallKeys, evalBudgetSessionDepth, evalCallDepthLimit, evalTotalCallsLimit, evalFnCallIds, evalFnCallIdSeq;
|
|
28793
29828
|
var init_calls = __esm({
|
|
@@ -28808,6 +29843,7 @@ var init_calls = __esm({
|
|
|
28808
29843
|
init_objects();
|
|
28809
29844
|
init_lru_map();
|
|
28810
29845
|
init_collector_scope();
|
|
29846
|
+
init_contract_face();
|
|
28811
29847
|
PURE_CALL_MEMO_MAX = 256;
|
|
28812
29848
|
pureCallMemo = /* @__PURE__ */ new WeakMap();
|
|
28813
29849
|
evalCallCollectorSlot = createScopedSlot(() => null);
|
|
@@ -32953,9 +33989,14 @@ function $call(fn2, args, thisVal) {
|
|
|
32953
33989
|
function $callInner(fn2, args, thisVal) {
|
|
32954
33990
|
if (fn2?.shape?.k === "sum") {
|
|
32955
33991
|
const results = fn2.shape.members.map((m) => $call(m, args, thisVal));
|
|
32956
|
-
if (results.every((
|
|
33992
|
+
if (results.every((r2) => r2.shape.k === "unknown")) return unknown;
|
|
32957
33993
|
return results.reduce((a, b) => joinAbs(a, b));
|
|
32958
33994
|
}
|
|
33995
|
+
const faces = contractFacesOf(fn2);
|
|
33996
|
+
const r = $callDispatch(fn2, faces ? adoptCallArgsToFaces(args, faces) : args, thisVal);
|
|
33997
|
+
return faces ? presentCallResultFace(r, faces) : r;
|
|
33998
|
+
}
|
|
33999
|
+
function $callDispatch(fn2, args, thisVal) {
|
|
32959
34000
|
const pureName = pureFnNameOf(fn2);
|
|
32960
34001
|
const fnObj = fn2 && typeof fn2 === "object" ? fn2 : void 0;
|
|
32961
34002
|
const pk = pureName && fnObj ? pureMemoKey(args) : void 0;
|
|
@@ -33040,6 +34081,7 @@ var init_call = __esm({
|
|
|
33040
34081
|
init_nudo_throw2();
|
|
33041
34082
|
init_may_throw2();
|
|
33042
34083
|
init_surface();
|
|
34084
|
+
init_contract_face();
|
|
33043
34085
|
init_state();
|
|
33044
34086
|
init_call_budget();
|
|
33045
34087
|
init_lru_map();
|
|
@@ -37036,539 +38078,6 @@ var init_diag_channel = __esm({
|
|
|
37036
38078
|
}
|
|
37037
38079
|
});
|
|
37038
38080
|
|
|
37039
|
-
// ../core/src/algebra/constraint.ts
|
|
37040
|
-
function selfTerm() {
|
|
37041
|
-
return v(SELF);
|
|
37042
|
-
}
|
|
37043
|
-
function getTerm(obj2, key) {
|
|
37044
|
-
return app("get", [obj2, lit(key)]);
|
|
37045
|
-
}
|
|
37046
|
-
function lenTerm(t) {
|
|
37047
|
-
return app("length", [t]);
|
|
37048
|
-
}
|
|
37049
|
-
function isConstraint(x) {
|
|
37050
|
-
return !!x && typeof x === "object" && x.__nudoConstraint === true;
|
|
37051
|
-
}
|
|
37052
|
-
function isNudoConstraint(x) {
|
|
37053
|
-
return isConstraint(x);
|
|
37054
|
-
}
|
|
37055
|
-
function isIntFlag(c) {
|
|
37056
|
-
return c.int === true || intFlaggedBuilders.has(c);
|
|
37057
|
-
}
|
|
37058
|
-
function makeBuilder(prim2, preds, extra) {
|
|
37059
|
-
const fields = extra?.fields;
|
|
37060
|
-
const element = extra?.element;
|
|
37061
|
-
const isInt = extra?.int;
|
|
37062
|
-
const optional = extra?.optional;
|
|
37063
|
-
const members = extra?.members;
|
|
37064
|
-
const fnSlot = extra?.fn;
|
|
37065
|
-
const base = {
|
|
37066
|
-
__nudoConstraint: true,
|
|
37067
|
-
...prim2 ? { prim: prim2 } : {},
|
|
37068
|
-
preds: [...preds],
|
|
37069
|
-
...fields ? { fields } : {},
|
|
37070
|
-
...element ? { element } : {},
|
|
37071
|
-
...optional ? { isOptional: true } : {},
|
|
37072
|
-
...members ? { members } : {},
|
|
37073
|
-
...fnSlot ? { fn: fnSlot } : {}
|
|
37074
|
-
};
|
|
37075
|
-
const add2 = (p) => makeBuilder(prim2, [...preds, p], extra);
|
|
37076
|
-
const builder = Object.assign(
|
|
37077
|
-
/* @__PURE__ */ Object.create(null),
|
|
37078
|
-
base,
|
|
37079
|
-
{
|
|
37080
|
-
gt: (n) => add2(gt(selfTerm(), lit(n))),
|
|
37081
|
-
ge: (n) => add2(ge(selfTerm(), lit(n))),
|
|
37082
|
-
lt: (n) => add2(lt(selfTerm(), lit(n))),
|
|
37083
|
-
le: (n) => add2(le(selfTerm(), lit(n))),
|
|
37084
|
-
int: () => makeBuilder(prim2 ?? "number", preds, { ...extra, int: true }),
|
|
37085
|
-
min: (n) => add2(ge(lenTerm(selfTerm()), lit(n))),
|
|
37086
|
-
max: (n) => add2(le(lenTerm(selfTerm()), lit(n))),
|
|
37087
|
-
length: (n) => add2(and(ge(lenTerm(selfTerm()), lit(n)), le(lenTerm(selfTerm()), lit(n)))),
|
|
37088
|
-
shift: (n) => {
|
|
37089
|
-
if (!Number.isFinite(n))
|
|
37090
|
-
throw new Error("nudo shift(): offset must be a finite number");
|
|
37091
|
-
if (fields || element || members || fnSlot)
|
|
37092
|
-
throw new Error("nudo shift(): only numeric scalar constraint chains are allowed (shape/array/union/fn are not supported)");
|
|
37093
|
-
if (prim2 !== void 0 && prim2 !== "number")
|
|
37094
|
-
throw new Error(`nudo shift(): only numeric chains are allowed (prim=${prim2})`);
|
|
37095
|
-
return makeBuilder(prim2, shiftBoundPreds(preds, n), extra);
|
|
37096
|
-
},
|
|
37097
|
-
optional: () => makeBuilder(prim2, preds, { ...extra, optional: true })
|
|
37098
|
-
}
|
|
37099
|
-
);
|
|
37100
|
-
if (isInt) intFlaggedBuilders.add(builder);
|
|
37101
|
-
return builder;
|
|
37102
|
-
}
|
|
37103
|
-
function shiftBoundPreds(preds, n) {
|
|
37104
|
-
return preds.map((p) => {
|
|
37105
|
-
if (p.op !== "gt" && p.op !== "ge" && p.op !== "lt" && p.op !== "le")
|
|
37106
|
-
throw new Error(`nudo shift(): predicate ${p.op} is not supported (only gt/ge/lt/le constant bounds)`);
|
|
37107
|
-
const { a, b } = p;
|
|
37108
|
-
if (b.op !== "lit" || typeof b.value !== "number")
|
|
37109
|
-
throw new Error("nudo shift(): the right-hand side of a constant bound must be a numeric literal");
|
|
37110
|
-
if (termHasApp(a, "length") || termHasApp(b, "length"))
|
|
37111
|
-
throw new Error("nudo shift(): length(...) bounds are not supported");
|
|
37112
|
-
return { op: p.op, a, b: lit(b.value + n) };
|
|
37113
|
-
});
|
|
37114
|
-
}
|
|
37115
|
-
function termHasApp(t, fn2) {
|
|
37116
|
-
if (t.op !== "app") return false;
|
|
37117
|
-
if (t.fn === fn2) return true;
|
|
37118
|
-
return t.args.some((x) => termHasApp(x, fn2));
|
|
37119
|
-
}
|
|
37120
|
-
function number() {
|
|
37121
|
-
return makeBuilder("number", []);
|
|
37122
|
-
}
|
|
37123
|
-
function string() {
|
|
37124
|
-
return makeBuilder("string", []);
|
|
37125
|
-
}
|
|
37126
|
-
function boolean() {
|
|
37127
|
-
return makeBuilder("boolean", []);
|
|
37128
|
-
}
|
|
37129
|
-
function any() {
|
|
37130
|
-
return makeBuilder(void 0, []);
|
|
37131
|
-
}
|
|
37132
|
-
function array(item) {
|
|
37133
|
-
return makeBuilder(void 0, [], {
|
|
37134
|
-
element: asNestedConstraint(item, "array(item)")
|
|
37135
|
-
});
|
|
37136
|
-
}
|
|
37137
|
-
function shape(fields) {
|
|
37138
|
-
const mapped = {};
|
|
37139
|
-
for (const [k, v2] of Object.entries(fields)) {
|
|
37140
|
-
const constraint = asNestedConstraint(v2, `shape \u5B57\u6BB5 '${k}'`);
|
|
37141
|
-
mapped[k] = {
|
|
37142
|
-
constraint,
|
|
37143
|
-
...constraint.isOptional ? { optional: true } : {}
|
|
37144
|
-
};
|
|
37145
|
-
}
|
|
37146
|
-
return makeBuilder(void 0, [], { fields: mapped });
|
|
37147
|
-
}
|
|
37148
|
-
function toPlainConstraint(c) {
|
|
37149
|
-
if (!isConstraint(c))
|
|
37150
|
-
throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
|
|
37151
|
-
return {
|
|
37152
|
-
__nudoConstraint: true,
|
|
37153
|
-
...c.prim ? { prim: c.prim } : {},
|
|
37154
|
-
preds: [...c.preds],
|
|
37155
|
-
...c.fields ? { fields: c.fields } : {},
|
|
37156
|
-
...c.element ? { element: c.element } : {},
|
|
37157
|
-
// isIntFlag 统一读取:builder(int 是方法)查 WeakSet,纯数据看 === true
|
|
37158
|
-
...isIntFlag(c) ? { int: true } : {},
|
|
37159
|
-
...c.isOptional ? { isOptional: true } : {},
|
|
37160
|
-
...c.members ? { members: c.members } : {},
|
|
37161
|
-
...c.fn ? { fn: c.fn } : {}
|
|
37162
|
-
};
|
|
37163
|
-
}
|
|
37164
|
-
function litC(v2) {
|
|
37165
|
-
const prim2 = typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : typeof v2 === "boolean" ? "boolean" : void 0;
|
|
37166
|
-
return makeBuilder(prim2, [eq(selfTerm(), lit(v2))]);
|
|
37167
|
-
}
|
|
37168
|
-
function asNestedConstraint(x, ctx2) {
|
|
37169
|
-
if (isConstraint(x)) return toPlainConstraint(x);
|
|
37170
|
-
if (x === null || x === void 0 || typeof x === "number" || typeof x === "string" || typeof x === "boolean") {
|
|
37171
|
-
return toPlainConstraint(litC(x));
|
|
37172
|
-
}
|
|
37173
|
-
throw new Error(
|
|
37174
|
-
`nudo: ${ctx2} expects a constraint value (number()/string()/\u2026) or a concrete literal; received a non-constraint`
|
|
37175
|
-
);
|
|
37176
|
-
}
|
|
37177
|
-
function union(...cs) {
|
|
37178
|
-
if (cs.length === 0)
|
|
37179
|
-
throw new Error("nudo union(): at least one member constraint is required");
|
|
37180
|
-
return makeBuilder(void 0, [], {
|
|
37181
|
-
members: cs.map((c) => asNestedConstraint(c, "union member"))
|
|
37182
|
-
});
|
|
37183
|
-
}
|
|
37184
|
-
function nullable(c) {
|
|
37185
|
-
return makeBuilder(void 0, [], {
|
|
37186
|
-
members: [
|
|
37187
|
-
asNestedConstraint(c, "nullable()"),
|
|
37188
|
-
toPlainConstraint(litC(null)),
|
|
37189
|
-
toPlainConstraint(litC(void 0))
|
|
37190
|
-
]
|
|
37191
|
-
});
|
|
37192
|
-
}
|
|
37193
|
-
function constraintAdmitsNullish(c) {
|
|
37194
|
-
if (c.members) return c.members.some((m) => constraintAdmitsNullish(m));
|
|
37195
|
-
if (!c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.fn) return true;
|
|
37196
|
-
for (const p of c.preds) {
|
|
37197
|
-
for (const flat of p.op === "and" ? p.args : [p]) {
|
|
37198
|
-
if (flat.op !== "eq") continue;
|
|
37199
|
-
for (const side of [flat.a, flat.b]) {
|
|
37200
|
-
if (side.op === "lit" && (side.value === null || side.value === void 0)) return true;
|
|
37201
|
-
}
|
|
37202
|
-
}
|
|
37203
|
-
}
|
|
37204
|
-
return false;
|
|
37205
|
-
}
|
|
37206
|
-
function fn(params, returns, opts) {
|
|
37207
|
-
const normalized = {};
|
|
37208
|
-
for (const [k, v2] of Object.entries(params)) {
|
|
37209
|
-
normalized[k] = asNestedConstraint(v2, `fn param '${k}'`);
|
|
37210
|
-
}
|
|
37211
|
-
return makeBuilder(void 0, [], {
|
|
37212
|
-
fn: {
|
|
37213
|
-
params: normalized,
|
|
37214
|
-
...returns !== void 0 ? { returns: asNestedConstraint(returns, "fn return value") } : {},
|
|
37215
|
-
...opts?.throws !== void 0 ? { throws: asNestedConstraint(opts.throws, "fn throws") } : {}
|
|
37216
|
-
}
|
|
37217
|
-
});
|
|
37218
|
-
}
|
|
37219
|
-
function andC(...cs) {
|
|
37220
|
-
if (cs.length === 0)
|
|
37221
|
-
throw new Error("nudo and(): at least one constraint is required");
|
|
37222
|
-
let prim2;
|
|
37223
|
-
let isInt = false;
|
|
37224
|
-
let allOptional = true;
|
|
37225
|
-
const preds = [];
|
|
37226
|
-
for (const c of cs) {
|
|
37227
|
-
if (!isConstraint(c))
|
|
37228
|
-
throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
|
|
37229
|
-
if (c.fields || c.element || c.members || c.fn)
|
|
37230
|
-
throw new Error("nudo and(): Phase 1 supports scalar constraint conjunction only (shape/array/union/fn are not supported)");
|
|
37231
|
-
if (c.prim) {
|
|
37232
|
-
if (prim2 !== void 0 && prim2 !== c.prim)
|
|
37233
|
-
throw new Error(`nudo and(): inconsistent prim (${prim2} vs ${c.prim})`);
|
|
37234
|
-
prim2 = c.prim;
|
|
37235
|
-
}
|
|
37236
|
-
preds.push(...c.preds);
|
|
37237
|
-
if (isIntFlag(c)) isInt = true;
|
|
37238
|
-
if (!c.isOptional) allOptional = false;
|
|
37239
|
-
}
|
|
37240
|
-
return makeBuilder(prim2, preds, {
|
|
37241
|
-
...isInt ? { int: true } : {},
|
|
37242
|
-
...allOptional ? { optional: true } : {}
|
|
37243
|
-
});
|
|
37244
|
-
}
|
|
37245
|
-
function partial(c) {
|
|
37246
|
-
if (!isConstraint(c) || !c.fields)
|
|
37247
|
-
throw new Error("nudo partial(): only shape(...) constraints are accepted");
|
|
37248
|
-
const fields = {};
|
|
37249
|
-
for (const [k, f] of Object.entries(c.fields)) {
|
|
37250
|
-
fields[k] = {
|
|
37251
|
-
constraint: { ...toPlainConstraint(f.constraint), isOptional: true },
|
|
37252
|
-
optional: true
|
|
37253
|
-
};
|
|
37254
|
-
}
|
|
37255
|
-
return makeBuilder(c.prim, c.preds, { fields });
|
|
37256
|
-
}
|
|
37257
|
-
function pick(c, keys) {
|
|
37258
|
-
if (!isConstraint(c) || !c.fields)
|
|
37259
|
-
throw new Error("nudo pick(): only shape(...) constraints are accepted");
|
|
37260
|
-
const fields = {};
|
|
37261
|
-
for (const k of keys) {
|
|
37262
|
-
const f = c.fields[k];
|
|
37263
|
-
if (f) fields[k] = f;
|
|
37264
|
-
}
|
|
37265
|
-
return makeBuilder(c.prim, c.preds, { fields });
|
|
37266
|
-
}
|
|
37267
|
-
function omit(c, keys) {
|
|
37268
|
-
if (!isConstraint(c) || !c.fields)
|
|
37269
|
-
throw new Error("nudo omit(): only shape(...) constraints are accepted");
|
|
37270
|
-
const drop = new Set(keys);
|
|
37271
|
-
const fields = {};
|
|
37272
|
-
for (const [k, f] of Object.entries(c.fields)) {
|
|
37273
|
-
if (!drop.has(k)) fields[k] = f;
|
|
37274
|
-
}
|
|
37275
|
-
return makeBuilder(c.prim, c.preds, { fields });
|
|
37276
|
-
}
|
|
37277
|
-
function substTerm(t, paramName2) {
|
|
37278
|
-
if (t.op === "var" && t.id === SELF) return v(paramName2);
|
|
37279
|
-
if (t.op === "app" && t.fn === "get" && t.args.length === 2) {
|
|
37280
|
-
return getTerm(substTerm(t.args[0], paramName2), String(
|
|
37281
|
-
t.args[1].op === "lit" ? t.args[1].value : ""
|
|
37282
|
-
));
|
|
37283
|
-
}
|
|
37284
|
-
return t;
|
|
37285
|
-
}
|
|
37286
|
-
function substPred2(p, paramName2) {
|
|
37287
|
-
switch (p.op) {
|
|
37288
|
-
case "gt":
|
|
37289
|
-
case "ge":
|
|
37290
|
-
case "lt":
|
|
37291
|
-
case "le":
|
|
37292
|
-
case "eq":
|
|
37293
|
-
case "ne": {
|
|
37294
|
-
return { op: p.op, a: substTerm(p.a, paramName2), b: substTerm(p.b, paramName2) };
|
|
37295
|
-
}
|
|
37296
|
-
case "typeof": {
|
|
37297
|
-
return { op: "typeof", t: substTerm(p.t, paramName2), type: p.type };
|
|
37298
|
-
}
|
|
37299
|
-
case "and":
|
|
37300
|
-
return and(...p.args.map((x) => substPred2(x, paramName2)));
|
|
37301
|
-
default:
|
|
37302
|
-
return p;
|
|
37303
|
-
}
|
|
37304
|
-
}
|
|
37305
|
-
function instantiateConstraint(c, paramName2) {
|
|
37306
|
-
if (c.fields) {
|
|
37307
|
-
const parts = [];
|
|
37308
|
-
for (const [key, field] of Object.entries(c.fields)) {
|
|
37309
|
-
if (field.optional || field.constraint.isOptional) continue;
|
|
37310
|
-
const fieldTerm = getTerm(v(paramName2), key);
|
|
37311
|
-
parts.push(instantiateOnTerm(field.constraint, fieldTerm));
|
|
37312
|
-
}
|
|
37313
|
-
if (c.prim) parts.push(ptypeof(v(paramName2), primToTypeof(c.prim)));
|
|
37314
|
-
if (parts.length === 0) return { op: "true" };
|
|
37315
|
-
return parts.length === 1 ? parts[0] : and(...parts);
|
|
37316
|
-
}
|
|
37317
|
-
if (c.members) {
|
|
37318
|
-
const disj = or(
|
|
37319
|
-
...c.members.map((m) => instantiateOnTerm(m, v(paramName2)))
|
|
37320
|
-
);
|
|
37321
|
-
const own = c.preds.map((p) => substPred2(p, paramName2));
|
|
37322
|
-
return own.length === 0 ? disj : and(...own, disj);
|
|
37323
|
-
}
|
|
37324
|
-
if (c.fn) {
|
|
37325
|
-
const own = c.preds.map((p) => substPred2(p, paramName2));
|
|
37326
|
-
return own.length === 0 ? pTrue : and(...own);
|
|
37327
|
-
}
|
|
37328
|
-
const preds = c.preds.map((p) => substPred2(p, paramName2));
|
|
37329
|
-
if (c.prim && c.preds.length === 0) {
|
|
37330
|
-
return ptypeof(v(paramName2), primToTypeof(c.prim));
|
|
37331
|
-
}
|
|
37332
|
-
return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
|
|
37333
|
-
}
|
|
37334
|
-
function instantiateOnTerm(c, t) {
|
|
37335
|
-
const subst = (p) => {
|
|
37336
|
-
switch (p.op) {
|
|
37337
|
-
case "gt":
|
|
37338
|
-
case "ge":
|
|
37339
|
-
case "lt":
|
|
37340
|
-
case "le":
|
|
37341
|
-
case "eq":
|
|
37342
|
-
case "ne": {
|
|
37343
|
-
const a = p.a.op === "var" && p.a.id === SELF ? t : p.a;
|
|
37344
|
-
const b = p.b.op === "var" && p.b.id === SELF ? t : p.b;
|
|
37345
|
-
return { op: p.op, a, b };
|
|
37346
|
-
}
|
|
37347
|
-
case "typeof": {
|
|
37348
|
-
const tt2 = p.t.op === "var" && p.t.id === SELF ? t : p.t;
|
|
37349
|
-
return { op: "typeof", t: tt2, type: p.type };
|
|
37350
|
-
}
|
|
37351
|
-
case "and":
|
|
37352
|
-
return and(...p.args.map(subst));
|
|
37353
|
-
default:
|
|
37354
|
-
return p;
|
|
37355
|
-
}
|
|
37356
|
-
};
|
|
37357
|
-
if (c.fields) {
|
|
37358
|
-
const parts = [];
|
|
37359
|
-
for (const [key, field] of Object.entries(c.fields)) {
|
|
37360
|
-
if (field.optional || field.constraint.isOptional) continue;
|
|
37361
|
-
parts.push(instantiateOnTerm(field.constraint, getTerm(t, key)));
|
|
37362
|
-
}
|
|
37363
|
-
if (parts.length === 0) return { op: "true" };
|
|
37364
|
-
return parts.length === 1 ? parts[0] : and(...parts);
|
|
37365
|
-
}
|
|
37366
|
-
if (c.members) {
|
|
37367
|
-
const disj = or(...c.members.map((m) => instantiateOnTerm(m, t)));
|
|
37368
|
-
const own = c.preds.map(subst);
|
|
37369
|
-
return own.length === 0 ? disj : and(...own, disj);
|
|
37370
|
-
}
|
|
37371
|
-
if (c.fn) {
|
|
37372
|
-
const own = c.preds.map(subst);
|
|
37373
|
-
return own.length === 0 ? pTrue : and(...own);
|
|
37374
|
-
}
|
|
37375
|
-
const preds = c.preds.map(subst);
|
|
37376
|
-
if (c.prim && c.preds.length === 0) return ptypeof(t, primToTypeof(c.prim));
|
|
37377
|
-
return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
|
|
37378
|
-
}
|
|
37379
|
-
function constraintToEntryAbs(c, paramName2) {
|
|
37380
|
-
const t = v(paramName2);
|
|
37381
|
-
if (c.fields) {
|
|
37382
|
-
const slots = {};
|
|
37383
|
-
for (const [key, field] of Object.entries(c.fields)) {
|
|
37384
|
-
const fieldTerm = getTerm(t, key);
|
|
37385
|
-
slots[key] = {
|
|
37386
|
-
value: constraintOnTermAbs(field.constraint, fieldTerm),
|
|
37387
|
-
...field.optional || field.constraint.isOptional ? { optional: true } : {}
|
|
37388
|
-
};
|
|
37389
|
-
}
|
|
37390
|
-
return abs({ k: "obj", slots }, t, void 0, "path");
|
|
37391
|
-
}
|
|
37392
|
-
return constraintOnTermAbs(c, t);
|
|
37393
|
-
}
|
|
37394
|
-
function memberLitValue(m) {
|
|
37395
|
-
const leaves = [];
|
|
37396
|
-
const visit2 = (p2) => {
|
|
37397
|
-
if (p2.op === "and") {
|
|
37398
|
-
p2.args.forEach(visit2);
|
|
37399
|
-
return;
|
|
37400
|
-
}
|
|
37401
|
-
leaves.push(p2);
|
|
37402
|
-
};
|
|
37403
|
-
m.preds.forEach(visit2);
|
|
37404
|
-
if (leaves.length !== 1) return { ok: false };
|
|
37405
|
-
const p = leaves[0];
|
|
37406
|
-
if (p.op !== "eq") return { ok: false };
|
|
37407
|
-
if (p.a.op === "var" && p.b.op === "lit") {
|
|
37408
|
-
return { ok: true, v: p.b.value };
|
|
37409
|
-
}
|
|
37410
|
-
if (p.b.op === "var" && p.a.op === "lit") {
|
|
37411
|
-
return { ok: true, v: p.a.value };
|
|
37412
|
-
}
|
|
37413
|
-
return { ok: false };
|
|
37414
|
-
}
|
|
37415
|
-
function samePrimLiteralUnionAbs(members, t) {
|
|
37416
|
-
if (members.length === 0) return void 0;
|
|
37417
|
-
const values = [];
|
|
37418
|
-
let prim2;
|
|
37419
|
-
for (const m of members) {
|
|
37420
|
-
const mk = memberLitValue(m);
|
|
37421
|
-
if (!mk.ok) return void 0;
|
|
37422
|
-
const v2 = mk.v;
|
|
37423
|
-
if (v2 === void 0 || v2 === null) return void 0;
|
|
37424
|
-
const mp = m.prim ?? (typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : "boolean");
|
|
37425
|
-
if (prim2 === void 0) prim2 = mp;
|
|
37426
|
-
else if (prim2 !== mp) return void 0;
|
|
37427
|
-
values.push(v2);
|
|
37428
|
-
}
|
|
37429
|
-
if (prim2 === void 0) return void 0;
|
|
37430
|
-
const uniq = [];
|
|
37431
|
-
for (const v2 of values) {
|
|
37432
|
-
if (!uniq.some((u) => Object.is(u, v2))) uniq.push(v2);
|
|
37433
|
-
}
|
|
37434
|
-
const disj = or(
|
|
37435
|
-
...uniq.map((v2) => eq(t, lit(v2)))
|
|
37436
|
-
);
|
|
37437
|
-
return abs({ k: "prim", type: prim2 }, t, disj, "path");
|
|
37438
|
-
}
|
|
37439
|
-
function constraintOnTermAbs(c, t) {
|
|
37440
|
-
if (c.fields) {
|
|
37441
|
-
const slots = {};
|
|
37442
|
-
for (const [key, field] of Object.entries(c.fields)) {
|
|
37443
|
-
slots[key] = {
|
|
37444
|
-
value: constraintOnTermAbs(field.constraint, getTerm(t, key)),
|
|
37445
|
-
...field.optional || field.constraint.isOptional ? { optional: true } : {}
|
|
37446
|
-
};
|
|
37447
|
-
}
|
|
37448
|
-
return abs({ k: "obj", slots }, t, void 0, "path");
|
|
37449
|
-
}
|
|
37450
|
-
if (c.members) {
|
|
37451
|
-
const litUnion = samePrimLiteralUnionAbs(c.members, t);
|
|
37452
|
-
if (litUnion) return litUnion;
|
|
37453
|
-
const joined = c.members.map((m) => constraintOnTermAbs(m, t)).reduce((a, b) => joinAbs(a, b));
|
|
37454
|
-
if (joined.shape.k === "prim" && joined.pred === void 0 && c.members.every((m) => m.prim === joined.shape.type)) {
|
|
37455
|
-
const type = joined.shape.type;
|
|
37456
|
-
return abs({ k: "prim", type }, t, ptypeof(t, primToTypeof(type)), "path");
|
|
37457
|
-
}
|
|
37458
|
-
return joined;
|
|
37459
|
-
}
|
|
37460
|
-
if (c.fn) {
|
|
37461
|
-
const paramNames = Object.keys(c.fn.params);
|
|
37462
|
-
const paramTypes = paramNames.map(
|
|
37463
|
-
(p, i) => constraintOnTermAbs(c.fn.params[p], v(`x${i}`))
|
|
37464
|
-
);
|
|
37465
|
-
const returnType = c.fn.returns ? constraintOnTermAbs(c.fn.returns, v("ret")) : unknown;
|
|
37466
|
-
return abs(
|
|
37467
|
-
{ k: "fn", params: paramNames, paramTypes, returnType },
|
|
37468
|
-
t,
|
|
37469
|
-
void 0,
|
|
37470
|
-
"path"
|
|
37471
|
-
);
|
|
37472
|
-
}
|
|
37473
|
-
if (c.element) {
|
|
37474
|
-
const elem = constraintOnTermAbs(c.element, v("x[]"));
|
|
37475
|
-
return abs({ k: "arr", element: elem }, t, void 0, "path");
|
|
37476
|
-
}
|
|
37477
|
-
const pred = instantiateOnTerm(c, t);
|
|
37478
|
-
const predOut = pred.op === "true" ? void 0 : pred;
|
|
37479
|
-
if (c.prim) {
|
|
37480
|
-
return abs({ k: "prim", type: c.prim }, t, predOut, "path");
|
|
37481
|
-
}
|
|
37482
|
-
const allEqNullish = c.preds.length > 0 && c.preds.every(
|
|
37483
|
-
(p) => p.op === "eq" && (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0) || p.a.op === "lit" && (p.a.value === null || p.a.value === void 0))
|
|
37484
|
-
);
|
|
37485
|
-
if (allEqNullish) {
|
|
37486
|
-
let nullish = null;
|
|
37487
|
-
for (const p of c.preds) {
|
|
37488
|
-
if (p.op !== "eq") continue;
|
|
37489
|
-
if (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0)) {
|
|
37490
|
-
nullish = p.b.value;
|
|
37491
|
-
break;
|
|
37492
|
-
}
|
|
37493
|
-
if (p.a.op === "lit" && (p.a.value === null || p.a.value === void 0)) {
|
|
37494
|
-
nullish = p.a.value;
|
|
37495
|
-
break;
|
|
37496
|
-
}
|
|
37497
|
-
}
|
|
37498
|
-
return abs({ k: "unknown" }, lit(nullish), void 0, "path");
|
|
37499
|
-
}
|
|
37500
|
-
if (c.preds.length > 0) {
|
|
37501
|
-
return abs({ k: "prim", type: "number" }, t, predOut, "path");
|
|
37502
|
-
}
|
|
37503
|
-
return abs({ k: "any" }, t, void 0, "path");
|
|
37504
|
-
}
|
|
37505
|
-
function fnConstraintToEntryReqs(c) {
|
|
37506
|
-
if (!c.fn) throw new Error("nudo fnConstraintToEntryReqs(): constraint is not in fn() form");
|
|
37507
|
-
return Object.entries(c.fn.params).map(([param, constraint]) => ({
|
|
37508
|
-
param,
|
|
37509
|
-
constraint
|
|
37510
|
-
}));
|
|
37511
|
-
}
|
|
37512
|
-
function throwConstraintToKinds(c) {
|
|
37513
|
-
if (!c) return void 0;
|
|
37514
|
-
const out = /* @__PURE__ */ new Set();
|
|
37515
|
-
let any2 = false;
|
|
37516
|
-
const note2 = (s) => {
|
|
37517
|
-
if (s === "*" || s === "any") any2 = true;
|
|
37518
|
-
else if (s) out.add(s);
|
|
37519
|
-
};
|
|
37520
|
-
const walk = (x) => {
|
|
37521
|
-
if (x.members) {
|
|
37522
|
-
for (const m of x.members) walk(m);
|
|
37523
|
-
return;
|
|
37524
|
-
}
|
|
37525
|
-
for (const p of x.preds) {
|
|
37526
|
-
if (p.op !== "eq" && p.op !== "ne") continue;
|
|
37527
|
-
for (const side of [p.a, p.b]) {
|
|
37528
|
-
if (side.op === "lit" && typeof side.value === "string") note2(side.value);
|
|
37529
|
-
}
|
|
37530
|
-
}
|
|
37531
|
-
};
|
|
37532
|
-
walk(c);
|
|
37533
|
-
if (any2) return "*";
|
|
37534
|
-
if (out.size > 0) return [...out];
|
|
37535
|
-
return void 0;
|
|
37536
|
-
}
|
|
37537
|
-
var SELF, intFlaggedBuilders, CONSTRAINT_BUILDERS, CONSTRAINT_BUILDER_NAMES, CONSTRAINT_EXPR_RE;
|
|
37538
|
-
var init_constraint = __esm({
|
|
37539
|
-
"../core/src/algebra/constraint.ts"() {
|
|
37540
|
-
"use strict";
|
|
37541
|
-
init_pred();
|
|
37542
|
-
init_term();
|
|
37543
|
-
init_abs();
|
|
37544
|
-
init_objects();
|
|
37545
|
-
SELF = "__nudo_self__";
|
|
37546
|
-
intFlaggedBuilders = /* @__PURE__ */ new WeakSet();
|
|
37547
|
-
CONSTRAINT_BUILDERS = {
|
|
37548
|
-
number,
|
|
37549
|
-
string,
|
|
37550
|
-
boolean,
|
|
37551
|
-
any,
|
|
37552
|
-
array,
|
|
37553
|
-
shape,
|
|
37554
|
-
lit: litC,
|
|
37555
|
-
union,
|
|
37556
|
-
nullable,
|
|
37557
|
-
fn,
|
|
37558
|
-
and: andC,
|
|
37559
|
-
partial,
|
|
37560
|
-
pick,
|
|
37561
|
-
omit
|
|
37562
|
-
};
|
|
37563
|
-
CONSTRAINT_BUILDER_NAMES = Object.keys(
|
|
37564
|
-
CONSTRAINT_BUILDERS
|
|
37565
|
-
);
|
|
37566
|
-
CONSTRAINT_EXPR_RE = new RegExp(
|
|
37567
|
-
`^(${CONSTRAINT_BUILDER_NAMES.join("|")})\\s*\\(`
|
|
37568
|
-
);
|
|
37569
|
-
}
|
|
37570
|
-
});
|
|
37571
|
-
|
|
37572
38081
|
// ../core/src/algebra/refine.ts
|
|
37573
38082
|
function diagnoseMalformedNudoImports(source) {
|
|
37574
38083
|
for (const bad of scanMalformedNudoImports(source)) {
|
|
@@ -38979,24 +39488,28 @@ function predToChain(p) {
|
|
|
38979
39488
|
}
|
|
38980
39489
|
return `{${predToString(p)}}`;
|
|
38981
39490
|
}
|
|
38982
|
-
function fmtConstraint(c) {
|
|
39491
|
+
function fmtConstraint(c, depth = LAZY_DISPLAY_DEPTH) {
|
|
39492
|
+
if (c.lazy) {
|
|
39493
|
+
if (depth <= 0) return "\u2026";
|
|
39494
|
+
return fmtConstraint(derefConstraint(c), depth - 1);
|
|
39495
|
+
}
|
|
38983
39496
|
if (c.fn) {
|
|
38984
39497
|
const args = [
|
|
38985
|
-
`{ ${Object.entries(c.fn.params).map(([k, v2]) => `${k}: ${fmtConstraint(v2)}`).join(", ")} }`
|
|
39498
|
+
`{ ${Object.entries(c.fn.params).map(([k, v2]) => `${k}: ${fmtConstraint(v2, depth)}`).join(", ")} }`
|
|
38986
39499
|
];
|
|
38987
|
-
if (c.fn.returns !== void 0) args.push(fmtConstraint(c.fn.returns));
|
|
38988
|
-
if (c.fn.throws !== void 0) args.push(`{ throws: ${fmtConstraint(c.fn.throws)} }`);
|
|
39500
|
+
if (c.fn.returns !== void 0) args.push(fmtConstraint(c.fn.returns, depth));
|
|
39501
|
+
if (c.fn.throws !== void 0) args.push(`{ throws: ${fmtConstraint(c.fn.throws, depth)} }`);
|
|
38989
39502
|
return `fn(${args.join(", ")})`;
|
|
38990
39503
|
}
|
|
38991
|
-
if (c.members) return `union(${c.members.map(fmtConstraint).join(", ")})`;
|
|
39504
|
+
if (c.members) return `union(${c.members.map((m) => fmtConstraint(m, depth)).join(", ")})`;
|
|
38992
39505
|
if (c.fields) {
|
|
38993
39506
|
const fs = Object.entries(c.fields).map(([k, f]) => {
|
|
38994
39507
|
const opt = f.optional || f.constraint.isOptional ? "?" : "";
|
|
38995
|
-
return `${k}${opt}: ${fmtConstraint(f.constraint)}`;
|
|
39508
|
+
return `${k}${opt}: ${fmtConstraint(f.constraint, depth)}`;
|
|
38996
39509
|
});
|
|
38997
39510
|
return `shape({ ${fs.join(", ")} })`;
|
|
38998
39511
|
}
|
|
38999
|
-
if (c.element) return `array(${fmtConstraint(c.element)})`;
|
|
39512
|
+
if (c.element) return `array(${fmtConstraint(c.element, depth)})`;
|
|
39000
39513
|
if (c.preds.length === 1 && c.preds[0].op === "eq" && c.preds[0].a.op === "var" && c.preds[0].b.op === "lit" && !isIntFlag(c)) {
|
|
39001
39514
|
return `lit(${litToString(c.preds[0].b.value)})`;
|
|
39002
39515
|
}
|
|
@@ -39030,7 +39543,7 @@ function interfaceTierOf(source, fnName, fromFile, opts = {}) {
|
|
|
39030
39543
|
function interfaceSourceOf(source, fnName, fromFile, opts = {}) {
|
|
39031
39544
|
return interfaceTierOf(source, fnName, fromFile, opts)?.source;
|
|
39032
39545
|
}
|
|
39033
|
-
var MAX_INTERFACE_DIAGS, interfaceDiagChannel, sidecarLoadFailureSlot, MAX_SIDECAR_FP_NODES;
|
|
39546
|
+
var MAX_INTERFACE_DIAGS, interfaceDiagChannel, sidecarLoadFailureSlot, MAX_SIDECAR_FP_NODES, LAZY_DISPLAY_DEPTH;
|
|
39034
39547
|
var init_interface = __esm({
|
|
39035
39548
|
"../core/src/algebra/interface.ts"() {
|
|
39036
39549
|
"use strict";
|
|
@@ -39054,6 +39567,7 @@ var init_interface = __esm({
|
|
|
39054
39567
|
);
|
|
39055
39568
|
registerCollectorScopeParticipant((body) => sidecarLoadFailureSlot.runScoped(body));
|
|
39056
39569
|
MAX_SIDECAR_FP_NODES = 64;
|
|
39570
|
+
LAZY_DISPLAY_DEPTH = 2;
|
|
39057
39571
|
}
|
|
39058
39572
|
});
|
|
39059
39573
|
|
|
@@ -40758,98 +41272,6 @@ var init_diagnostics = __esm({
|
|
|
40758
41272
|
}
|
|
40759
41273
|
});
|
|
40760
41274
|
|
|
40761
|
-
// ../core/src/algebra/domain-membership.ts
|
|
40762
|
-
function literalMeetsConstraint(lv, c) {
|
|
40763
|
-
const ext = c;
|
|
40764
|
-
if (c.fields || c.element) return false;
|
|
40765
|
-
if (ext.fn) return false;
|
|
40766
|
-
if (Array.isArray(ext.members) && ext.members.length > 0) {
|
|
40767
|
-
return ext.members.some((m) => literalMeetsConstraint(lv, m));
|
|
40768
|
-
}
|
|
40769
|
-
if (c.prim === void 0) {
|
|
40770
|
-
return c.preds.every((p) => predHolds(lv, p));
|
|
40771
|
-
}
|
|
40772
|
-
if (!primMatches(c.prim, lv)) return false;
|
|
40773
|
-
if (isIntFlag(c) && c.prim === "number" && !(typeof lv === "number" && Number.isInteger(lv))) {
|
|
40774
|
-
return false;
|
|
40775
|
-
}
|
|
40776
|
-
return c.preds.every((p) => predHolds(lv, p));
|
|
40777
|
-
}
|
|
40778
|
-
function primMatches(prim2, lv) {
|
|
40779
|
-
switch (prim2) {
|
|
40780
|
-
case "number":
|
|
40781
|
-
return typeof lv === "number";
|
|
40782
|
-
case "string":
|
|
40783
|
-
return typeof lv === "string";
|
|
40784
|
-
case "boolean":
|
|
40785
|
-
return typeof lv === "boolean";
|
|
40786
|
-
case "object":
|
|
40787
|
-
return lv === null;
|
|
40788
|
-
case "undefined":
|
|
40789
|
-
return lv === void 0;
|
|
40790
|
-
default:
|
|
40791
|
-
return false;
|
|
40792
|
-
}
|
|
40793
|
-
}
|
|
40794
|
-
function predHolds(lv, p) {
|
|
40795
|
-
switch (p.op) {
|
|
40796
|
-
case "eq": {
|
|
40797
|
-
const litT = isSelfVar(p.a) && p.b.op === "lit" ? p.b : isSelfVar(p.b) && p.a.op === "lit" ? p.a : void 0;
|
|
40798
|
-
if (!litT) return false;
|
|
40799
|
-
return Object.is(lv, litT.value);
|
|
40800
|
-
}
|
|
40801
|
-
case "gt":
|
|
40802
|
-
case "ge":
|
|
40803
|
-
case "lt":
|
|
40804
|
-
case "le":
|
|
40805
|
-
return boundHolds(lv, p);
|
|
40806
|
-
case "typeof":
|
|
40807
|
-
return p.t.op === "var" && p.t.id === SELF && primMatches(p.type, lv);
|
|
40808
|
-
// and 是合取:逐参数按同一规则判定(string().length(n) 的 preds 是
|
|
40809
|
-
// and 包裹的两个长度界,叶子仍是 gt/ge/lt/le,无假阳性风险)
|
|
40810
|
-
case "and":
|
|
40811
|
-
return p.args.every((x) => predHolds(lv, x));
|
|
40812
|
-
// ne / or / not / true / false 等其余形态:保守不满足
|
|
40813
|
-
default:
|
|
40814
|
-
return false;
|
|
40815
|
-
}
|
|
40816
|
-
}
|
|
40817
|
-
function cmpHolds(x, op, n) {
|
|
40818
|
-
switch (op) {
|
|
40819
|
-
case "gt":
|
|
40820
|
-
return x > n;
|
|
40821
|
-
case "ge":
|
|
40822
|
-
return x >= n;
|
|
40823
|
-
case "lt":
|
|
40824
|
-
return x < n;
|
|
40825
|
-
case "le":
|
|
40826
|
-
return x <= n;
|
|
40827
|
-
}
|
|
40828
|
-
}
|
|
40829
|
-
function boundHolds(lv, p) {
|
|
40830
|
-
if (p.b.op !== "lit" || typeof p.b.value !== "number") return false;
|
|
40831
|
-
const n = p.b.value;
|
|
40832
|
-
if (isLengthSelf(p.a)) {
|
|
40833
|
-
return typeof lv === "string" && cmpHolds(lv.length, p.op, n);
|
|
40834
|
-
}
|
|
40835
|
-
if (isSelfVar(p.a)) {
|
|
40836
|
-
return typeof lv === "number" && cmpHolds(lv, p.op, n);
|
|
40837
|
-
}
|
|
40838
|
-
return false;
|
|
40839
|
-
}
|
|
40840
|
-
function isSelfVar(t) {
|
|
40841
|
-
return t.op === "var" && t.id === SELF;
|
|
40842
|
-
}
|
|
40843
|
-
function isLengthSelf(t) {
|
|
40844
|
-
return t.op === "app" && t.fn === "length" && t.args.length === 1 && isSelfVar(t.args[0]);
|
|
40845
|
-
}
|
|
40846
|
-
var init_domain_membership = __esm({
|
|
40847
|
-
"../core/src/algebra/domain-membership.ts"() {
|
|
40848
|
-
"use strict";
|
|
40849
|
-
init_constraint();
|
|
40850
|
-
}
|
|
40851
|
-
});
|
|
40852
|
-
|
|
40853
41275
|
// ../core/src/algebra/postcondition.ts
|
|
40854
41276
|
function proved() {
|
|
40855
41277
|
return { status: "proved" };
|
|
@@ -40899,6 +41321,15 @@ function provesBarePrimDomain(arm, constraint) {
|
|
|
40899
41321
|
return arm.shape.k === "prim" && arm.shape.type === constraint.prim;
|
|
40900
41322
|
}
|
|
40901
41323
|
function assertImplies(ret, constraint, opts) {
|
|
41324
|
+
if (constraint.lazy) {
|
|
41325
|
+
const seen = opts?.seen;
|
|
41326
|
+
if (seen?.has(constraint.lazy)) {
|
|
41327
|
+
return unprovable("lazy constraint cycle");
|
|
41328
|
+
}
|
|
41329
|
+
const next = seen ? new Set(seen) : /* @__PURE__ */ new Set();
|
|
41330
|
+
next.add(constraint.lazy);
|
|
41331
|
+
return assertImplies(ret, derefConstraint(constraint), { ...opts, seen: next });
|
|
41332
|
+
}
|
|
40902
41333
|
const phi2 = opts?.phi ?? pTrue;
|
|
40903
41334
|
if (ret.shape.k === "never") return proved();
|
|
40904
41335
|
if (isAnyConstraint(constraint)) return proved();
|
|
@@ -40984,7 +41415,7 @@ function assertImpliesSingle(arm, constraint, opts, phi2) {
|
|
|
40984
41415
|
return assertScalar(arm, constraint, phi2);
|
|
40985
41416
|
}
|
|
40986
41417
|
function isAnyConstraint(c) {
|
|
40987
|
-
return !c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.members && !c.fn && !isIntFlag(c);
|
|
41418
|
+
return !c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.members && !c.fn && !c.lazy && !isIntFlag(c);
|
|
40988
41419
|
}
|
|
40989
41420
|
function assertShapeFields(ret, constraint, opts) {
|
|
40990
41421
|
let slots;
|
|
@@ -43901,43 +44332,142 @@ function checkSourceInScope(filePath, source, phi2, opts) {
|
|
|
43901
44332
|
resetAbsCallBudget();
|
|
43902
44333
|
const prevTrunc = setAbsTruncationCollector((label) => truncated.add(label));
|
|
43903
44334
|
try {
|
|
43904
|
-
const
|
|
43905
|
-
filePath,
|
|
43906
|
-
source,
|
|
43907
|
-
file,
|
|
43908
|
-
phi2,
|
|
43909
|
-
callOpts,
|
|
43910
|
-
issues,
|
|
43911
|
-
signatures,
|
|
43912
|
-
names2,
|
|
43913
|
-
truncated,
|
|
43914
|
-
opts,
|
|
43915
|
-
depsFp,
|
|
43916
|
-
sidecarFp
|
|
44335
|
+
const prevFaceResolver = setContractFaceResolver(
|
|
44336
|
+
makeSameFileFaceResolver(callOpts, filePath, source, file)
|
|
43917
44337
|
);
|
|
43918
|
-
|
|
43919
|
-
|
|
43920
|
-
|
|
43921
|
-
|
|
43922
|
-
|
|
43923
|
-
|
|
43924
|
-
|
|
43925
|
-
|
|
43926
|
-
|
|
43927
|
-
|
|
43928
|
-
|
|
43929
|
-
|
|
43930
|
-
|
|
43931
|
-
|
|
43932
|
-
|
|
43933
|
-
|
|
44338
|
+
try {
|
|
44339
|
+
attachCrossModuleContractFaces(callOpts, filePath);
|
|
44340
|
+
const report = checkSourceInner(
|
|
44341
|
+
filePath,
|
|
44342
|
+
source,
|
|
44343
|
+
file,
|
|
44344
|
+
phi2,
|
|
44345
|
+
callOpts,
|
|
44346
|
+
issues,
|
|
44347
|
+
signatures,
|
|
44348
|
+
names2,
|
|
44349
|
+
truncated,
|
|
44350
|
+
opts,
|
|
44351
|
+
depsFp,
|
|
44352
|
+
sidecarFp
|
|
44353
|
+
);
|
|
44354
|
+
const diagIssues = sidecarDiagIssues([
|
|
44355
|
+
...takeRefineDiagsSince(refineSince),
|
|
44356
|
+
...takeInterfaceDiagsSince(ifaceSince)
|
|
44357
|
+
]);
|
|
44358
|
+
if (diagIssues.length > 0) {
|
|
44359
|
+
report.issues.push(...diagIssues);
|
|
44360
|
+
const errors = report.issues.filter((i) => i.severity === "error").length;
|
|
44361
|
+
const warnings = report.issues.filter((i) => i.severity === "warning").length;
|
|
44362
|
+
const infos = report.issues.filter((i) => i.severity === "info").length;
|
|
44363
|
+
report.ok = errors === 0;
|
|
44364
|
+
report.summary = {
|
|
44365
|
+
errors,
|
|
44366
|
+
warnings,
|
|
44367
|
+
infos,
|
|
44368
|
+
functions: report.summary.functions
|
|
44369
|
+
};
|
|
44370
|
+
}
|
|
44371
|
+
if (memoKey) checkMemoSet(memoKey, report, memoPaths);
|
|
44372
|
+
return cloneCheckReport(report);
|
|
44373
|
+
} finally {
|
|
44374
|
+
setContractFaceResolver(prevFaceResolver);
|
|
43934
44375
|
}
|
|
43935
|
-
if (memoKey) checkMemoSet(memoKey, report, memoPaths);
|
|
43936
|
-
return cloneCheckReport(report);
|
|
43937
44376
|
} finally {
|
|
43938
44377
|
setAbsTruncationCollector(prevTrunc);
|
|
43939
44378
|
}
|
|
43940
44379
|
}
|
|
44380
|
+
function makeSameFileFaceResolver(opts, filePath, source, file) {
|
|
44381
|
+
const loadModule = opts.loadModule;
|
|
44382
|
+
const fromFile = opts.fromFile ?? filePath;
|
|
44383
|
+
const autoBind = opts.autoBind;
|
|
44384
|
+
const projectDir = opts.projectDir;
|
|
44385
|
+
const memo = /* @__PURE__ */ new Map();
|
|
44386
|
+
return (fnName) => {
|
|
44387
|
+
if (memo.has(fnName)) return memo.get(fnName);
|
|
44388
|
+
let faces;
|
|
44389
|
+
try {
|
|
44390
|
+
const eff = effectiveInterface(source, fnName, {
|
|
44391
|
+
...loadModule ? { loadModule } : {},
|
|
44392
|
+
fromFile,
|
|
44393
|
+
...autoBind !== void 0 ? { autoBind } : {},
|
|
44394
|
+
...projectDir !== void 0 ? { projectDir } : {}
|
|
44395
|
+
});
|
|
44396
|
+
if (eff) {
|
|
44397
|
+
const params = extractFn(source, fnName, file)?.params ?? [];
|
|
44398
|
+
faces = contractFacesFromEffectiveInterface(eff, params);
|
|
44399
|
+
}
|
|
44400
|
+
} catch {
|
|
44401
|
+
faces = void 0;
|
|
44402
|
+
}
|
|
44403
|
+
memo.set(fnName, faces);
|
|
44404
|
+
return faces;
|
|
44405
|
+
};
|
|
44406
|
+
}
|
|
44407
|
+
function attachCrossModuleContractFaces(opts, filePath) {
|
|
44408
|
+
const loadModule = opts.loadModule;
|
|
44409
|
+
const fromFile = opts.fromFile ?? filePath;
|
|
44410
|
+
if (!loadModule) return;
|
|
44411
|
+
const tables2 = [];
|
|
44412
|
+
for (const t of [opts.modules, opts.inject?.modules]) {
|
|
44413
|
+
if (t && typeof t === "object" && !tables2.includes(t)) tables2.push(t);
|
|
44414
|
+
}
|
|
44415
|
+
if (tables2.length === 0) return;
|
|
44416
|
+
const autoBind = opts.autoBind;
|
|
44417
|
+
const projectDir = opts.projectDir;
|
|
44418
|
+
const facesCache = /* @__PURE__ */ new Map();
|
|
44419
|
+
const facesFor = (depSource, depPath, name, paramNames) => {
|
|
44420
|
+
const key = `${depPath}\0${name}`;
|
|
44421
|
+
if (facesCache.has(key)) return facesCache.get(key);
|
|
44422
|
+
let faces;
|
|
44423
|
+
try {
|
|
44424
|
+
const eff = effectiveInterface(depSource, name, {
|
|
44425
|
+
loadModule,
|
|
44426
|
+
fromFile: depPath,
|
|
44427
|
+
...autoBind !== void 0 ? { autoBind } : {},
|
|
44428
|
+
...projectDir !== void 0 ? { projectDir } : {}
|
|
44429
|
+
});
|
|
44430
|
+
if (eff) faces = contractFacesFromEffectiveInterface(eff, paramNames);
|
|
44431
|
+
} catch {
|
|
44432
|
+
faces = void 0;
|
|
44433
|
+
}
|
|
44434
|
+
facesCache.set(key, faces);
|
|
44435
|
+
return faces;
|
|
44436
|
+
};
|
|
44437
|
+
const attachFnAbs = (v2, depSource, depPath, name) => {
|
|
44438
|
+
if (!v2 || typeof v2 !== "object" || !("shape" in v2)) return;
|
|
44439
|
+
const shape2 = v2.shape;
|
|
44440
|
+
if (shape2.k !== "fn") return;
|
|
44441
|
+
let paramNames;
|
|
44442
|
+
try {
|
|
44443
|
+
paramNames = extractFn(depSource, name)?.params ?? [];
|
|
44444
|
+
} catch {
|
|
44445
|
+
paramNames = [];
|
|
44446
|
+
}
|
|
44447
|
+
const faces = facesFor(depSource, depPath, name, paramNames);
|
|
44448
|
+
if (faces) attachContractFaces(v2, faces);
|
|
44449
|
+
};
|
|
44450
|
+
for (const table of tables2) {
|
|
44451
|
+
for (const [spec, mod2] of Object.entries(table)) {
|
|
44452
|
+
if (!mod2 || typeof mod2 !== "object") continue;
|
|
44453
|
+
const named = mod2.named;
|
|
44454
|
+
if (!named) continue;
|
|
44455
|
+
let depSource;
|
|
44456
|
+
try {
|
|
44457
|
+
depSource = loadModule(spec, fromFile);
|
|
44458
|
+
} catch {
|
|
44459
|
+
depSource = void 0;
|
|
44460
|
+
}
|
|
44461
|
+
if (!depSource) continue;
|
|
44462
|
+
const depPath = resolveDepPath(fromFile, spec);
|
|
44463
|
+
for (const [name, v2] of Object.entries(named)) {
|
|
44464
|
+
attachFnAbs(v2, depSource, depPath, name);
|
|
44465
|
+
}
|
|
44466
|
+
const def = mod2.default;
|
|
44467
|
+
if (def !== void 0) attachFnAbs(def, depSource, depPath, "default");
|
|
44468
|
+
}
|
|
44469
|
+
}
|
|
44470
|
+
}
|
|
43941
44471
|
function sidecarDiagIssues(diags) {
|
|
43942
44472
|
const seen = /* @__PURE__ */ new Set();
|
|
43943
44473
|
const out = [];
|
|
@@ -44445,6 +44975,8 @@ var init_check = __esm({
|
|
|
44445
44975
|
init_constraint();
|
|
44446
44976
|
init_postcondition();
|
|
44447
44977
|
init_generalize();
|
|
44978
|
+
init_contract_face();
|
|
44979
|
+
init_sidecar_path();
|
|
44448
44980
|
init_param_surface();
|
|
44449
44981
|
init_fn_fp();
|
|
44450
44982
|
init_stable_source_key();
|
|
@@ -45026,6 +45558,7 @@ __export(src_exports, {
|
|
|
45026
45558
|
currentExecPhi: () => currentExecPhi,
|
|
45027
45559
|
currentPhi: () => currentPhi,
|
|
45028
45560
|
definitelyNotNullishShape: () => definitelyNotNullishShape,
|
|
45561
|
+
derefConstraint: () => derefConstraint,
|
|
45029
45562
|
describePhi: () => describePhi,
|
|
45030
45563
|
div: () => div,
|
|
45031
45564
|
drainPromiseMicros: () => drainPromiseMicros,
|
|
@@ -45149,6 +45682,7 @@ __export(src_exports, {
|
|
|
45149
45682
|
joinObjects: () => joinObjects,
|
|
45150
45683
|
joinThenProject: () => joinThenProject,
|
|
45151
45684
|
joinValues: () => joinValues,
|
|
45685
|
+
lazy: () => lazy,
|
|
45152
45686
|
le: () => le,
|
|
45153
45687
|
leNum: () => leNum,
|
|
45154
45688
|
leavePromiseExecutorScope: () => leavePromiseExecutorScope,
|
|
@@ -60210,7 +60744,7 @@ var require_typescript = __commonJS({
|
|
|
60210
60744
|
affectsEmitOptionDeclarations: () => affectsEmitOptionDeclarations,
|
|
60211
60745
|
allKeysStartWithDot: () => allKeysStartWithDot,
|
|
60212
60746
|
altDirectorySeparator: () => altDirectorySeparator,
|
|
60213
|
-
and: () =>
|
|
60747
|
+
and: () => and8,
|
|
60214
60748
|
append: () => append,
|
|
60215
60749
|
appendIfUnique: () => appendIfUnique,
|
|
60216
60750
|
arrayFrom: () => arrayFrom,
|
|
@@ -63665,7 +64199,7 @@ var require_typescript = __commonJS({
|
|
|
63665
64199
|
function isPatternMatch({ prefix: prefix2, suffix }, candidate) {
|
|
63666
64200
|
return candidate.length >= prefix2.length + suffix.length && startsWith(candidate, prefix2) && endsWith(candidate, suffix);
|
|
63667
64201
|
}
|
|
63668
|
-
function
|
|
64202
|
+
function and8(f, g) {
|
|
63669
64203
|
return (arg) => f(arg) && g(arg);
|
|
63670
64204
|
}
|
|
63671
64205
|
function or2(...fs) {
|
|
@@ -114751,7 +115285,7 @@ ${lanes.join("\n")}
|
|
|
114751
115285
|
SignatureCheckMode3[SignatureCheckMode3["Callback"] = 3] = "Callback";
|
|
114752
115286
|
return SignatureCheckMode3;
|
|
114753
115287
|
})(SignatureCheckMode || {});
|
|
114754
|
-
var isNotOverloadAndNotAccessor =
|
|
115288
|
+
var isNotOverloadAndNotAccessor = and8(isNotOverload, isNotAccessor);
|
|
114755
115289
|
var intrinsicTypeKinds = new Map(Object.entries({
|
|
114756
115290
|
Uppercase: 0,
|
|
114757
115291
|
Lowercase: 1,
|
|
@@ -157737,7 +158271,7 @@ ${lanes.join("\n")}
|
|
|
157737
158271
|
if (flags & (1920 | 384)) {
|
|
157738
158272
|
return;
|
|
157739
158273
|
}
|
|
157740
|
-
const exportedDeclarationsCount = countWhere(declarations,
|
|
158274
|
+
const exportedDeclarationsCount = countWhere(declarations, and8(isNotOverloadAndNotAccessor, not2(isInterfaceDeclaration)));
|
|
157741
158275
|
if (flags & 524288 && exportedDeclarationsCount <= 2) {
|
|
157742
158276
|
return;
|
|
157743
158277
|
}
|
|
@@ -229094,7 +229628,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
229094
229628
|
const maybeHeritageClauseSymbol = getHeritageClauseSymbolTable(classDeclaration, checker);
|
|
229095
229629
|
const implementedType = checker.getTypeAtLocation(implementedTypeNode);
|
|
229096
229630
|
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
|
|
229097
|
-
const nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(
|
|
229631
|
+
const nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(and8(symbolPointsToNonPrivateMember, (symbol) => !maybeHeritageClauseSymbol.has(symbol.escapedName)));
|
|
229098
229632
|
const classType = checker.getTypeAtLocation(classDeclaration);
|
|
229099
229633
|
const constructor = find2(classDeclaration.members, (m) => isConstructorDeclaration(m));
|
|
229100
229634
|
if (!classType.getNumberIndexType()) {
|
|
@@ -256467,7 +257001,7 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
256467
257001
|
affectsEmitOptionDeclarations: () => affectsEmitOptionDeclarations,
|
|
256468
257002
|
allKeysStartWithDot: () => allKeysStartWithDot,
|
|
256469
257003
|
altDirectorySeparator: () => altDirectorySeparator,
|
|
256470
|
-
and: () =>
|
|
257004
|
+
and: () => and8,
|
|
256471
257005
|
append: () => append,
|
|
256472
257006
|
appendIfUnique: () => appendIfUnique,
|
|
256473
257007
|
arrayFrom: () => arrayFrom,
|
|
@@ -288176,7 +288710,7 @@ function runTscBaseline(root, files) {
|
|
|
288176
288710
|
}
|
|
288177
288711
|
}
|
|
288178
288712
|
async function migrateVerify(paths, opts = {}) {
|
|
288179
|
-
const { checkSource: checkSource2, formatCheckReport: formatCheckReport2, pTrue:
|
|
288713
|
+
const { checkSource: checkSource2, formatCheckReport: formatCheckReport2, pTrue: pTrue4 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
288180
288714
|
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
|
|
288181
288715
|
const files = [];
|
|
288182
288716
|
for (const p of paths) {
|
|
@@ -288201,7 +288735,7 @@ async function migrateVerify(paths, opts = {}) {
|
|
|
288201
288735
|
const proj = findProjectConfig3(dirname29(file));
|
|
288202
288736
|
const cCfg = checkConfig2(proj?.config);
|
|
288203
288737
|
const autoBind = interfaceConfig3(proj?.config).autoBind;
|
|
288204
|
-
const report = checkSource2(file, source,
|
|
288738
|
+
const report = checkSource2(file, source, pTrue4, {
|
|
288205
288739
|
loadModule: defaultLoadModule3,
|
|
288206
288740
|
fromFile: file,
|
|
288207
288741
|
...autoBind === false ? { autoBind: false } : {},
|
|
@@ -290630,7 +291164,7 @@ async function healthFile(filePath, records) {
|
|
|
290630
291164
|
return report;
|
|
290631
291165
|
}
|
|
290632
291166
|
async function countInterfaceDrift(filePath) {
|
|
290633
|
-
const { sidecarPathOf: sidecarPathOf2, checkSource: checkSource2, pTrue:
|
|
291167
|
+
const { sidecarPathOf: sidecarPathOf2, checkSource: checkSource2, pTrue: pTrue4 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
290634
291168
|
const { defaultLoadModule: defaultLoadModule3 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
|
|
290635
291169
|
const { existsSync: ex, readFileSync: rf } = await import("fs");
|
|
290636
291170
|
const abs2 = resolve18(filePath);
|
|
@@ -290648,7 +291182,7 @@ async function countInterfaceDrift(filePath) {
|
|
|
290648
291182
|
const proj = findProjectConfig3(dirname28(abs2));
|
|
290649
291183
|
const autoBind = interfaceConfig3(proj?.config).autoBind;
|
|
290650
291184
|
const source = rf(abs2, "utf-8");
|
|
290651
|
-
const r = checkSource2(abs2, source,
|
|
291185
|
+
const r = checkSource2(abs2, source, pTrue4, {
|
|
290652
291186
|
loadModule: defaultLoadModule3,
|
|
290653
291187
|
fromFile: abs2,
|
|
290654
291188
|
...autoBind === false ? { autoBind: false } : {},
|