@nudojs/core 0.3.1 → 1.0.0

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.
@@ -39,6 +39,7 @@ __export(runtime_exports, {
39
39
  $neg: () => $neg,
40
40
  $not: () => $not,
41
41
  $obj: () => $obj,
42
+ $regex: () => $regex,
42
43
  $set: () => $set,
43
44
  $spread: () => $spread,
44
45
  $sub: () => $sub,
@@ -55,6 +56,8 @@ __export(runtime_exports, {
55
56
  isDefinitelyFalse: () => isDefinitelyFalse,
56
57
  isDefinitelyTrue: () => isDefinitelyTrue,
57
58
  isNudoThrow: () => isNudoThrow,
59
+ litTruth: () => litTruth,
60
+ namespaceNameOf: () => namespaceNameOf,
58
61
  withExecPhi: () => withExecPhi
59
62
  });
60
63
 
@@ -700,6 +703,86 @@ function shapeOnlyFn(paramTypes, returnType, opts) {
700
703
  }
701
704
 
702
705
  // src/algebra/template.ts
706
+ function viewTemplateParts(parts, describe) {
707
+ return parts.map((p) => {
708
+ const d = describe(p);
709
+ return "fixed" in d ? { fixed: d.fixed, render: d.fixed, part: p } : { fixed: void 0, render: d.render, part: p };
710
+ });
711
+ }
712
+ function knownPrefixOfViews(views) {
713
+ let s = "";
714
+ for (const v2 of views) {
715
+ if (v2.fixed !== void 0) s += v2.fixed;
716
+ else break;
717
+ }
718
+ return s;
719
+ }
720
+ function knownSuffixOfViews(views) {
721
+ let s = "";
722
+ for (let i = views.length - 1; i >= 0; i--) {
723
+ const v2 = views[i];
724
+ if (v2.fixed !== void 0) s = v2.fixed + s;
725
+ else break;
726
+ }
727
+ return s;
728
+ }
729
+ function allFixedTextOfViews(views) {
730
+ return views.filter((v2) => v2.fixed !== void 0).map((v2) => v2.fixed).join("");
731
+ }
732
+ function fixedLengthOfViews(views) {
733
+ if (views.some((v2) => v2.fixed === void 0)) return void 0;
734
+ return allFixedTextOfViews(views).length;
735
+ }
736
+ function formatTemplateNameViews(views) {
737
+ const inner = views.map((v2) => v2.fixed !== void 0 ? v2.fixed : `\${${v2.render}}`).join("");
738
+ return `\`${inner}\``;
739
+ }
740
+ function mergeAdjacentFixedViews(views, rebuildFixed) {
741
+ const out = [];
742
+ for (const v2 of views) {
743
+ const last = out[out.length - 1];
744
+ if (last && last.fixed !== void 0 && v2.fixed !== void 0) {
745
+ out[out.length - 1] = rebuildFixed(last.fixed + v2.fixed);
746
+ } else {
747
+ out.push(v2);
748
+ }
749
+ }
750
+ return out;
751
+ }
752
+ function templateMatchesValue(value, views) {
753
+ let pos = 0;
754
+ for (let i = 0; i < views.length; i++) {
755
+ const v2 = views[i];
756
+ if (v2.fixed !== void 0) {
757
+ if (!value.startsWith(v2.fixed, pos)) return false;
758
+ pos += v2.fixed.length;
759
+ } else {
760
+ if (i === views.length - 1) return true;
761
+ const next = views[i + 1];
762
+ if (next?.fixed !== void 0) {
763
+ const idx = value.indexOf(next.fixed, pos);
764
+ if (idx === -1) return false;
765
+ pos = idx;
766
+ } else {
767
+ return true;
768
+ }
769
+ }
770
+ }
771
+ return pos === value.length;
772
+ }
773
+ function decideStartsWith(prefix, search) {
774
+ if (prefix.length >= search.length) return prefix.startsWith(search);
775
+ if (search.startsWith(prefix)) return "unknown";
776
+ return false;
777
+ }
778
+ function decideEndsWith(suffix, search) {
779
+ if (suffix.length >= search.length) return suffix.endsWith(search);
780
+ if (search.endsWith(suffix)) return "unknown";
781
+ return false;
782
+ }
783
+ function decideIncludes(fixedText, search) {
784
+ return fixedText.includes(search) ? true : "unknown";
785
+ }
703
786
  function isStrLit(a) {
704
787
  return a.shape.k === "prim" && a.shape.type === "string" && a.term?.op === "lit" && typeof a.term.value === "string";
705
788
  }
@@ -709,6 +792,13 @@ function isStrPrim2(a) {
709
792
  function isTemplateAbs(a) {
710
793
  return a.shape.k === "prim" && a.shape.type === "string" && !!a.pred && a.pred.name?.startsWith("`") === true && Array.isArray(a.pred.meta?.templateParts);
711
794
  }
795
+ function describeAbsPart(p) {
796
+ if (isStrLit(p)) return { fixed: String(litValue(p)) };
797
+ return { render: p.term ? termToString(p.term) : "string" };
798
+ }
799
+ function absTemplateViews(parts) {
800
+ return viewTemplateParts(parts, describeAbsPart);
801
+ }
712
802
  function templatePartsOf(a) {
713
803
  if (isTemplateAbs(a)) {
714
804
  const meta = a.pred.meta;
@@ -716,29 +806,18 @@ function templatePartsOf(a) {
716
806
  }
717
807
  return [a];
718
808
  }
809
+ function rebuildAbsFixedView(text) {
810
+ return {
811
+ fixed: text,
812
+ render: text,
813
+ part: abs({ k: "prim", type: "string" }, lit(text), void 0, "exact")
814
+ };
815
+ }
719
816
  function normalizeParts(parts) {
720
- const out = [];
721
- for (const p of parts) {
722
- const last = out[out.length - 1];
723
- if (last && isStrLit(last) && isStrLit(p)) {
724
- out[out.length - 1] = abs(
725
- { k: "prim", type: "string" },
726
- lit(String(litValue(last)) + String(litValue(p))),
727
- void 0,
728
- "exact"
729
- );
730
- } else {
731
- out.push(p);
732
- }
733
- }
734
- return out;
817
+ return mergeAdjacentFixedViews(absTemplateViews(parts), rebuildAbsFixedView).map((v2) => v2.part);
735
818
  }
736
819
  function formatTemplateName(parts) {
737
- const inner = parts.map((p) => {
738
- if (isStrLit(p)) return String(litValue(p));
739
- return `\${${p.term ? termToString(p.term) : "string"}}`;
740
- }).join("");
741
- return `\`${inner}\``;
820
+ return formatTemplateNameViews(absTemplateViews(parts));
742
821
  }
743
822
  function createTemplateAbs(parts) {
744
823
  const normalized = normalizeParts(parts);
@@ -790,6 +869,157 @@ function coerceToStringParts(a) {
790
869
  return void 0;
791
870
  }
792
871
 
872
+ // src/algebra/objects.ts
873
+ function objOf(slots, opts) {
874
+ const shape = { k: "obj", slots };
875
+ if (opts?.index) shape.index = opts.index;
876
+ if (opts?.open) shape.open = true;
877
+ return { shape, conf: "exact" };
878
+ }
879
+ function isObj(a) {
880
+ return a.shape.k === "obj";
881
+ }
882
+ function getSlot(slots, key) {
883
+ return Object.prototype.hasOwnProperty.call(slots, key) ? slots[key] : void 0;
884
+ }
885
+ function spread(base, over) {
886
+ if (!isObj(base) && !isObj(over)) {
887
+ if (isObj(over)) return { shape: { ...over.shape, open: true }, conf: confJoin(base.conf, over.conf) };
888
+ if (isObj(base)) return { shape: { ...base.shape, open: true }, conf: confJoin(base.conf, over.conf) };
889
+ return unknown;
890
+ }
891
+ if (!isObj(over)) {
892
+ if (!isObj(base)) return unknown;
893
+ return {
894
+ shape: { ...base.shape, open: true },
895
+ conf: confJoin(base.conf, "partial")
896
+ };
897
+ }
898
+ if (!isObj(base)) {
899
+ return { shape: { ...over.shape, open: true }, conf: confJoin(base.conf, over.conf) };
900
+ }
901
+ const slots = { ...base.shape.slots };
902
+ for (const [k, s] of Object.entries(over.shape.slots)) {
903
+ slots[k] = s;
904
+ }
905
+ const open = base.shape.open || over.shape.open || false;
906
+ const shape = { k: "obj", slots };
907
+ if (open) shape.open = true;
908
+ if (base.shape.index || over.shape.index) {
909
+ shape.index = over.shape.index ?? base.shape.index;
910
+ }
911
+ return { shape, conf: confJoin(base.conf, over.conf) };
912
+ }
913
+ function joinObjects(a, b) {
914
+ if (a.shape.k === "never") return b;
915
+ if (b.shape.k === "never") return a;
916
+ if (!isObj(a) || !isObj(b)) {
917
+ return makeSum(a, b);
918
+ }
919
+ const ka = Object.keys(a.shape.slots).sort();
920
+ const kb = Object.keys(b.shape.slots).sort();
921
+ const sameKeys = ka.length === kb.length && ka.every((k, i) => k === kb[i]);
922
+ if (!sameKeys) {
923
+ return makeSum(a, b);
924
+ }
925
+ const slots = {};
926
+ let conf = confJoin(a.conf, b.conf);
927
+ for (const k of ka) {
928
+ const sa = a.shape.slots[k];
929
+ const sb = b.shape.slots[k];
930
+ const optional = sa.optional || sb.optional;
931
+ const jv = joinValues(sa.value, sb.value);
932
+ conf = confJoin(conf, jv.conf);
933
+ slots[k] = { value: jv, optional };
934
+ }
935
+ return { shape: { k: "obj", slots }, conf };
936
+ }
937
+ function joinValues(a, b) {
938
+ if (a.shape.k === "never") return b;
939
+ if (b.shape.k === "never") return a;
940
+ const va = litValue(a);
941
+ const vb = litValue(b);
942
+ if (va !== void 0 && Object.is(va, vb)) return a;
943
+ if (a.shape.k === "prim" && b.shape.k === "prim" && a.shape.type === b.shape.type) {
944
+ if (va !== void 0 && vb !== void 0) {
945
+ return abs(
946
+ a.shape,
947
+ void 0,
948
+ void 0,
949
+ confJoin(a.conf, "path")
950
+ );
951
+ }
952
+ return abs(a.shape, void 0, void 0, confJoin(confJoin(a.conf, b.conf), "path"));
953
+ }
954
+ return makeSum(a, b);
955
+ }
956
+ function makeSum(a, b) {
957
+ const members = flattenSum([a, b]);
958
+ if (members.length === 1) return members[0];
959
+ return {
960
+ shape: { k: "sum", members },
961
+ conf: confJoin(a.conf, b.conf)
962
+ };
963
+ }
964
+ function flattenSum(xs) {
965
+ const out = [];
966
+ for (const x of xs) {
967
+ if (x.shape.k === "sum") out.push(...x.shape.members);
968
+ else out.push(x);
969
+ }
970
+ const seen = /* @__PURE__ */ new Set();
971
+ const deduped = [];
972
+ for (const x of out) {
973
+ const key = shapeKey(x);
974
+ if (seen.has(key)) continue;
975
+ seen.add(key);
976
+ deduped.push(x);
977
+ }
978
+ return deduped;
979
+ }
980
+ function shapeKey(a) {
981
+ const s = a.shape;
982
+ if (s.k === "prim") {
983
+ const lv = litValue(a);
984
+ if (lv !== void 0) return `prim:${s.type}:${String(lv)}`;
985
+ const t = a.term ? termToString(a.term) : "";
986
+ const p = a.pred && a.pred.op !== "true" ? predToString(a.pred) : "";
987
+ return `prim:${s.type}:${t}:${p}`;
988
+ }
989
+ if (s.k === "never") return "never";
990
+ if (s.k === "any") return "any";
991
+ if (s.k === "unknown") return "unknown";
992
+ if (s.k === "obj") return `obj:${Object.keys(s.slots).sort().join(",")}`;
993
+ if (s.k === "fn") return `fn:${s.params.length}`;
994
+ if (s.k === "sum") return `sum:${s.members.length}`;
995
+ return "other";
996
+ }
997
+ function fnOf(params, name) {
998
+ const shape = { k: "fn", params };
999
+ if (name) shape.name = name;
1000
+ return { shape, conf: "exact" };
1001
+ }
1002
+ function joinFunctions(a, b) {
1003
+ const sa = a.shape;
1004
+ const sb = b.shape;
1005
+ if (sa.k !== "fn" || sb.k !== "fn") return makeSum(a, b);
1006
+ const an = sa.name;
1007
+ const bn = sb.name;
1008
+ if (an && an === bn) {
1009
+ if (sa.params.length === sb.params.length && sa.params.every((p, i) => p === sb.params[i])) {
1010
+ return a;
1011
+ }
1012
+ }
1013
+ return makeSum(a, b);
1014
+ }
1015
+ function joinAbs(a, b) {
1016
+ if (a.shape.k === "never") return b;
1017
+ if (b.shape.k === "never") return a;
1018
+ if (isObj(a) && isObj(b)) return joinObjects(a, b);
1019
+ if (a.shape.k === "fn" && b.shape.k === "fn") return joinFunctions(a, b);
1020
+ return joinValues(a, b);
1021
+ }
1022
+
793
1023
  // src/algebra/arithmetic.ts
794
1024
  function add(a, b, phi2 = pTrue) {
795
1025
  const va = litValue(a);
@@ -873,6 +1103,9 @@ function isAnyLike(a) {
873
1103
  if (a.shape.k === "unknown") return true;
874
1104
  return false;
875
1105
  }
1106
+ function coercibleLit(v2) {
1107
+ return v2 !== void 0 && (typeof v2 === "number" || typeof v2 === "string" || typeof v2 === "boolean" || v2 === null);
1108
+ }
876
1109
  function toNumberResult(a, b, op) {
877
1110
  const term = a.term && b.term ? simplifyTerm(app(op, [a.term, b.term])) : void 0;
878
1111
  return abs(
@@ -991,6 +1224,9 @@ function sub(a, b, phi2 = pTrue) {
991
1224
  if (typeof va === "number" && typeof vb === "number") {
992
1225
  return numLit(va - vb);
993
1226
  }
1227
+ if (coercibleLit(va) && coercibleLit(vb)) {
1228
+ return numLit(Number(va) - Number(vb));
1229
+ }
994
1230
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
995
1231
  const term = simplifyTerm(app("-", [a.term, b.term]));
996
1232
  const ab = numericBounds(a, phi2);
@@ -1023,6 +1259,9 @@ function mul(a, b, phi2 = pTrue) {
1023
1259
  if (typeof va === "number" && typeof vb === "number") {
1024
1260
  return numLit(va * vb);
1025
1261
  }
1262
+ if (coercibleLit(va) && coercibleLit(vb)) {
1263
+ return numLit(Number(va) * Number(vb));
1264
+ }
1026
1265
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
1027
1266
  const term = simplifyTerm(app("*", [a.term, b.term]));
1028
1267
  if (b.term.op === "lit" && b.term.value === 0 || a.term.op === "lit" && a.term.value === 0) {
@@ -1089,6 +1328,9 @@ function div(a, b, phi2 = pTrue) {
1089
1328
  }
1090
1329
  return numLit(va / vb);
1091
1330
  }
1331
+ if (coercibleLit(va) && coercibleLit(vb)) {
1332
+ return numLit(Number(va) / Number(vb));
1333
+ }
1092
1334
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
1093
1335
  const term = simplifyTerm(app("/", [a.term, b.term]));
1094
1336
  if (b.term.op === "lit" && typeof b.term.value === "number" && b.term.value !== 0) {
@@ -1131,6 +1373,9 @@ function mod(a, b, phi2 = pTrue) {
1131
1373
  }
1132
1374
  return numLit(va % vb);
1133
1375
  }
1376
+ if (coercibleLit(va) && coercibleLit(vb)) {
1377
+ return numLit(Number(va) % Number(vb));
1378
+ }
1134
1379
  if (isNumericLike(a) && isNumericLike(b) && a.term && b.term) {
1135
1380
  const term = simplifyTerm(app("%", [a.term, b.term]));
1136
1381
  if (b.term.op === "lit" && typeof b.term.value === "number" && b.term.value !== 0) {
@@ -1202,6 +1447,20 @@ function compareLits(op, a, b) {
1202
1447
  return a >= b;
1203
1448
  }
1204
1449
  }
1450
+ if (op === "lt" || op === "le" || op === "gt" || op === "ge") {
1451
+ const x = a;
1452
+ const y = b;
1453
+ switch (op) {
1454
+ case "lt":
1455
+ return x < y;
1456
+ case "le":
1457
+ return x <= y;
1458
+ case "gt":
1459
+ return x > y;
1460
+ case "ge":
1461
+ return x >= y;
1462
+ }
1463
+ }
1205
1464
  return void 0;
1206
1465
  }
1207
1466
  function decideByBounds(op, a, b, phi2) {
@@ -1240,6 +1499,34 @@ function trueConstraint(c) {
1240
1499
  if (c.term?.op === "lit" && c.term.value === false) return void 0;
1241
1500
  return c.pred;
1242
1501
  }
1502
+ function refineAbsForRelTrue(a, op, k) {
1503
+ const bound = (t) => op === "gt" ? gt(t, lit(k)) : op === "ge" ? ge(t, lit(k)) : op === "lt" ? lt(t, lit(k)) : le(t, lit(k));
1504
+ if (isNumPrim(a) && a.term) {
1505
+ const pred = a.pred && a.pred.op !== "true" ? and(a.pred, bound(a.term)) : bound(a.term);
1506
+ return abs(a.shape, a.term, pred, a.conf);
1507
+ }
1508
+ if (isStrPrim(a)) return a;
1509
+ if ((a.shape.k === "any" || a.shape.k === "unknown") && a.term) {
1510
+ const numArm = abs({ k: "prim", type: "number" }, a.term, bound(a.term), "path");
1511
+ const strArm = abs({ k: "prim", type: "string" }, a.term, void 0, "path");
1512
+ return makeSum(numArm, strArm);
1513
+ }
1514
+ return a;
1515
+ }
1516
+ function matchRelIdentLit(test) {
1517
+ const t = test;
1518
+ if (t?.type !== "BinaryExpression") return void 0;
1519
+ const rel = t.operator === ">" ? "gt" : t.operator === ">=" ? "ge" : t.operator === "<" ? "lt" : t.operator === "<=" ? "le" : void 0;
1520
+ if (!rel) return void 0;
1521
+ if (t.left?.type === "Identifier" && t.left.name && t.right?.type === "NumericLiteral" && typeof t.right.value === "number") {
1522
+ return { name: t.left.name, op: rel, k: t.right.value };
1523
+ }
1524
+ if (t.right?.type === "Identifier" && t.right.name && t.left?.type === "NumericLiteral" && typeof t.left.value === "number") {
1525
+ const flipped = rel === "gt" ? "lt" : rel === "ge" ? "le" : rel === "lt" ? "gt" : "ge";
1526
+ return { name: t.right.name, op: flipped, k: t.left.value };
1527
+ }
1528
+ return void 0;
1529
+ }
1243
1530
  function falseConstraint(c) {
1244
1531
  if (c.term?.op === "lit" && c.term.value === true) return void 0;
1245
1532
  if (c.term?.op === "lit" && c.term.value === false) return pTrue;
@@ -1432,176 +1719,20 @@ function strictEqAbs(a, b) {
1432
1719
  return void 0;
1433
1720
  }
1434
1721
 
1435
- // src/algebra/objects.ts
1436
- function objOf(slots, opts) {
1437
- const shape = { k: "obj", slots };
1438
- if (opts?.index) shape.index = opts.index;
1439
- if (opts?.open) shape.open = true;
1440
- return { shape, conf: "exact" };
1722
+ // src/algebra/containers.ts
1723
+ var TUPLE_LITERAL_CAP = 8;
1724
+ function shouldWidenArrayLiteral(n) {
1725
+ return n > TUPLE_LITERAL_CAP;
1441
1726
  }
1442
- function isObj(a) {
1443
- return a.shape.k === "obj";
1727
+ function widenedArrayConf() {
1728
+ return "path";
1444
1729
  }
1445
- function spread(base, over) {
1446
- if (!isObj(base) && !isObj(over)) {
1447
- if (isObj(over)) return { shape: { ...over.shape, open: true }, conf: confJoin(base.conf, over.conf) };
1448
- if (isObj(base)) return { shape: { ...base.shape, open: true }, conf: confJoin(base.conf, over.conf) };
1449
- return unknown;
1450
- }
1451
- if (!isObj(over)) {
1452
- if (!isObj(base)) return unknown;
1453
- return {
1454
- shape: { ...base.shape, open: true },
1455
- conf: confJoin(base.conf, "partial")
1456
- };
1457
- }
1458
- if (!isObj(base)) {
1459
- return { shape: { ...over.shape, open: true }, conf: confJoin(base.conf, over.conf) };
1460
- }
1461
- const slots = { ...base.shape.slots };
1462
- for (const [k, s] of Object.entries(over.shape.slots)) {
1463
- slots[k] = s;
1464
- }
1465
- const open = base.shape.open || over.shape.open || false;
1466
- const shape = { k: "obj", slots };
1467
- if (open) shape.open = true;
1468
- if (base.shape.index || over.shape.index) {
1469
- shape.index = over.shape.index ?? base.shape.index;
1470
- }
1471
- return { shape, conf: confJoin(base.conf, over.conf) };
1472
- }
1473
- function joinObjects(a, b) {
1474
- if (a.shape.k === "never") return b;
1475
- if (b.shape.k === "never") return a;
1476
- if (!isObj(a) || !isObj(b)) {
1477
- return makeSum(a, b);
1478
- }
1479
- const ka = Object.keys(a.shape.slots).sort();
1480
- const kb = Object.keys(b.shape.slots).sort();
1481
- const sameKeys = ka.length === kb.length && ka.every((k, i) => k === kb[i]);
1482
- if (!sameKeys) {
1483
- return makeSum(a, b);
1484
- }
1485
- const slots = {};
1486
- let conf = confJoin(a.conf, b.conf);
1487
- for (const k of ka) {
1488
- const sa = a.shape.slots[k];
1489
- const sb = b.shape.slots[k];
1490
- const optional = sa.optional || sb.optional;
1491
- const jv = joinValues(sa.value, sb.value);
1492
- conf = confJoin(conf, jv.conf);
1493
- slots[k] = { value: jv, optional };
1494
- }
1495
- return { shape: { k: "obj", slots }, conf };
1496
- }
1497
- function joinValues(a, b) {
1498
- if (a.shape.k === "never") return b;
1499
- if (b.shape.k === "never") return a;
1500
- const va = litValue(a);
1501
- const vb = litValue(b);
1502
- if (va !== void 0 && va === vb) return a;
1503
- if (a.shape.k === "prim" && b.shape.k === "prim" && a.shape.type === b.shape.type) {
1504
- if (va !== void 0 && vb !== void 0) {
1505
- return abs(
1506
- a.shape,
1507
- void 0,
1508
- void 0,
1509
- confJoin(a.conf, "path")
1510
- );
1511
- }
1512
- return abs(a.shape, void 0, void 0, confJoin(confJoin(a.conf, b.conf), "path"));
1513
- }
1514
- return makeSum(a, b);
1515
- }
1516
- function makeSum(a, b) {
1517
- const members = flattenSum([a, b]);
1518
- if (members.length === 1) return members[0];
1519
- return {
1520
- shape: { k: "sum", members },
1521
- conf: confJoin(a.conf, b.conf)
1522
- };
1523
- }
1524
- function flattenSum(xs) {
1525
- const out = [];
1526
- for (const x of xs) {
1527
- if (x.shape.k === "sum") out.push(...x.shape.members);
1528
- else out.push(x);
1529
- }
1530
- const seen = /* @__PURE__ */ new Set();
1531
- const deduped = [];
1532
- for (const x of out) {
1533
- const key = shapeKey(x);
1534
- if (seen.has(key)) continue;
1535
- seen.add(key);
1536
- deduped.push(x);
1537
- }
1538
- return deduped;
1539
- }
1540
- function shapeKey(a) {
1541
- const s = a.shape;
1542
- if (s.k === "prim") return `prim:${s.type}`;
1543
- if (s.k === "never") return "never";
1544
- if (s.k === "any") return "any";
1545
- if (s.k === "unknown") return "unknown";
1546
- if (s.k === "obj") return `obj:${Object.keys(s.slots).sort().join(",")}`;
1547
- if (s.k === "fn") return `fn:${s.params.length}`;
1548
- if (s.k === "sum") return `sum:${s.members.length}`;
1549
- return "other";
1550
- }
1551
- function collapseToOptional(sum) {
1552
- if (sum.shape.k !== "sum") {
1553
- if (isObj(sum)) return { ...sum, conf: confJoin(sum.conf, "widened") };
1554
- return sum;
1555
- }
1556
- const objs = sum.shape.members.filter(isObj);
1557
- if (objs.length === 0) {
1558
- return abs({ k: "unknown" }, void 0, void 0, "widened");
1559
- }
1560
- const allKeys = /* @__PURE__ */ new Set();
1561
- for (const o of objs) {
1562
- for (const k of Object.keys(o.shape.slots)) allKeys.add(k);
1563
- }
1564
- const slots = {};
1565
- for (const k of allKeys) {
1566
- const present = objs.filter((o) => k in o.shape.slots);
1567
- const values = present.map((o) => o.shape.slots[k].value);
1568
- const joined = values.reduce((acc, v2) => joinValues(acc, v2));
1569
- const optional = present.length < objs.length;
1570
- slots[k] = { value: joined, optional };
1571
- }
1572
- return { shape: { k: "obj", slots }, conf: "widened" };
1573
- }
1574
- function fnOf(params, name) {
1575
- const shape = { k: "fn", params };
1576
- if (name) shape.name = name;
1577
- return { shape, conf: "exact" };
1578
- }
1579
- function joinFunctions(a, b) {
1580
- const sa = a.shape;
1581
- const sb = b.shape;
1582
- if (sa.k !== "fn" || sb.k !== "fn") return makeSum(a, b);
1583
- const an = sa.name;
1584
- const bn = sb.name;
1585
- if (an && an === bn) {
1586
- if (sa.params.length === sb.params.length && sa.params.every((p, i) => p === sb.params[i])) {
1587
- return a;
1588
- }
1589
- }
1590
- return makeSum(a, b);
1591
- }
1592
- function joinAbs(a, b) {
1593
- if (a.shape.k === "never") return b;
1594
- if (b.shape.k === "never") return a;
1595
- if (isObj(a) && isObj(b)) return joinObjects(a, b);
1596
- if (a.shape.k === "fn" && b.shape.k === "fn") return joinFunctions(a, b);
1597
- return joinValues(a, b);
1598
- }
1599
-
1600
- // src/algebra/language.ts
1601
- function classesOf(env) {
1602
- const e = env;
1603
- if (!e.classes) e.classes = /* @__PURE__ */ new Map();
1604
- return e.classes;
1730
+
1731
+ // src/algebra/language.ts
1732
+ function classesOf(env) {
1733
+ const e = env;
1734
+ if (!e.classes) e.classes = /* @__PURE__ */ new Map();
1735
+ return e.classes;
1605
1736
  }
1606
1737
  function defineClass(env, def) {
1607
1738
  classesOf(env).set(def.name, def);
@@ -1710,8 +1841,8 @@ function litFalse() {
1710
1841
  function projectBrand(self, key) {
1711
1842
  if (self.shape.k !== "brand") return unknown;
1712
1843
  const inner = self.shape.shape;
1713
- if (inner.shape.k === "obj") {
1714
- const slot = inner.shape.slots[key];
1844
+ if (inner && inner.shape.k === "obj") {
1845
+ const slot = getSlot(inner.shape.slots, key);
1715
1846
  if (slot) return slot.value;
1716
1847
  }
1717
1848
  return unknown;
@@ -1900,7 +2031,7 @@ function leqShape(src, tgt, phi2, env, depth) {
1900
2031
  const srcObj = s.k === "obj" ? s : s.k === "brand" ? s.shape.shape.k === "obj" ? s.shape.shape : null : null;
1901
2032
  if (!srcObj || srcObj.k !== "obj") return fail(`shape ${s.k} \u22AD obj`);
1902
2033
  for (const [key, slot] of Object.entries(t.slots)) {
1903
- const srcSlot = srcObj.slots[key];
2034
+ const srcSlot = getSlot(srcObj.slots, key);
1904
2035
  if (!srcSlot) {
1905
2036
  if (slot.optional) continue;
1906
2037
  return fail(`missing slot ${key}`);
@@ -1981,1118 +2112,1138 @@ function primOf(a) {
1981
2112
  return void 0;
1982
2113
  }
1983
2114
 
1984
- // src/algebra/exec/calls.ts
1985
- var calls_exports = {};
1986
- __export(calls_exports, {
1987
- $callNamed: () => $callNamed,
1988
- getAbsOrigin: () => getAbsOrigin,
1989
- getBCallCollector: () => getBCallCollector,
1990
- noteMemberDispatchMiss: () => noteMemberDispatchMiss,
1991
- notePrimMemberMissing: () => notePrimMemberMissing,
1992
- noteUnknownMemberMissing: () => noteUnknownMemberMissing,
1993
- recordMemberDiag: () => recordMemberDiag,
1994
- setBCallCollector: () => setBCallCollector,
1995
- setMemberDiagCollector: () => setMemberDiagCollector,
1996
- tagAbsOrigin: () => tagAbsOrigin
1997
- });
1998
-
1999
- // src/algebra/parse-source.ts
2000
- import { parse as babelParse } from "@babel/parser";
2001
-
2002
- // src/strip-types.ts
2003
- var REMOVE = Symbol("nudo.strip.remove");
2004
- var SKIP_KEYS = /* @__PURE__ */ new Set([
2005
- "loc",
2006
- "start",
2007
- "end",
2008
- "range",
2009
- "leadingComments",
2010
- "trailingComments",
2011
- "innerComments",
2012
- "comments",
2013
- "tokens",
2014
- "extra"
2015
- ]);
2016
- function transformValue(value) {
2017
- if (Array.isArray(value)) {
2018
- let changed = false;
2019
- const out = [];
2020
- for (const el of value) {
2021
- if (el === null || el === void 0) {
2022
- out.push(el);
2023
- continue;
2115
+ // src/algebra/builtins.ts
2116
+ function numPrim(conf = "path") {
2117
+ return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
2118
+ }
2119
+ function strPrim(conf = "path") {
2120
+ return abs({ k: "prim", type: "string" }, void 0, void 0, conf);
2121
+ }
2122
+ function boolPrim(conf = "partial") {
2123
+ return abs({ k: "prim", type: "boolean" }, void 0, void 0, conf);
2124
+ }
2125
+ function evalMathMethod(name, args) {
2126
+ const a0 = args[0] ? litValue(args[0]) : void 0;
2127
+ const a1 = args[1] ? litValue(args[1]) : void 0;
2128
+ switch (name) {
2129
+ case "abs":
2130
+ if (typeof a0 === "number") return numLit(Math.abs(a0));
2131
+ return numPrim();
2132
+ case "floor":
2133
+ if (typeof a0 === "number") return numLit(Math.floor(a0));
2134
+ return numPrim();
2135
+ case "ceil":
2136
+ if (typeof a0 === "number") return numLit(Math.ceil(a0));
2137
+ return numPrim();
2138
+ case "round":
2139
+ if (typeof a0 === "number") return numLit(Math.round(a0));
2140
+ return numPrim();
2141
+ case "sqrt":
2142
+ if (typeof a0 === "number") return numLit(Math.sqrt(a0));
2143
+ return numPrim();
2144
+ case "min": {
2145
+ const lits = args.map(litValue);
2146
+ if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2147
+ return numLit(Math.min(...lits));
2024
2148
  }
2025
- const r = transformValue(el);
2026
- if (r === REMOVE) {
2027
- changed = true;
2028
- } else {
2029
- if (r !== el) changed = true;
2030
- out.push(r);
2149
+ return numPrim();
2150
+ }
2151
+ case "max": {
2152
+ const lits = args.map(litValue);
2153
+ if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2154
+ return numLit(Math.max(...lits));
2031
2155
  }
2156
+ return numPrim();
2032
2157
  }
2033
- return changed ? out : value;
2034
- }
2035
- if (typeof value !== "object" || value === null) return value;
2036
- if (typeof value.type !== "string") return value;
2037
- return transformNode(value);
2038
- }
2039
- function isTsDeclareLike(node) {
2040
- return node.declare === true;
2041
- }
2042
- function isTypeOnlyDeclaration(decl) {
2043
- switch (decl.type) {
2044
- case "TSInterfaceDeclaration":
2045
- case "TSTypeAliasDeclaration":
2046
- case "TSEnumDeclaration":
2047
- case "TSDeclareFunction":
2048
- return true;
2049
- case "VariableDeclaration":
2050
- case "ClassDeclaration":
2051
- return isTsDeclareLike(decl);
2158
+ case "pow":
2159
+ if (typeof a0 === "number" && typeof a1 === "number") return numLit(Math.pow(a0, a1));
2160
+ return numPrim();
2161
+ case "sign":
2162
+ if (typeof a0 === "number") return numLit(Math.sign(a0));
2163
+ return numPrim();
2052
2164
  default:
2053
- return false;
2165
+ return void 0;
2054
2166
  }
2055
2167
  }
2056
- function isTypeOnlyStatement(node) {
2057
- const anyNode = node;
2058
- switch (node.type) {
2059
- case "TSInterfaceDeclaration":
2060
- case "TSTypeAliasDeclaration":
2061
- case "TSEnumDeclaration":
2062
- case "TSDeclareFunction":
2063
- return true;
2064
- case "TSModuleDeclaration":
2065
- return isTsDeclareLike(node);
2066
- case "VariableDeclaration":
2067
- case "ClassDeclaration":
2068
- return isTsDeclareLike(node);
2069
- case "ImportDeclaration":
2070
- if (anyNode.importKind === "type") return true;
2071
- {
2072
- const specs = anyNode.specifiers;
2073
- if (specs && specs.length > 0 && specs.every((s) => s.importKind === "type" || s.importKind === "typeof")) {
2074
- return true;
2075
- }
2168
+ function evalObjectMethod(name, args) {
2169
+ const a0 = args[0];
2170
+ switch (name) {
2171
+ case "keys": {
2172
+ if (a0?.shape.k === "obj") {
2173
+ const keys = Object.keys(a0.shape.slots).map(
2174
+ (k) => strLit(k)
2175
+ );
2176
+ return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
2076
2177
  }
2077
- return false;
2078
- case "ExportNamedDeclaration": {
2079
- if (anyNode.exportKind === "type") return true;
2080
- const decl = node.declaration;
2081
- if (decl && isTypeOnlyDeclaration(decl)) return true;
2082
- {
2083
- const specs = anyNode.specifiers;
2084
- if (!decl && specs && specs.length > 0 && specs.every((s) => s.exportKind === "type")) return true;
2178
+ return abs({ k: "arr", element: strPrim("path") }, void 0, void 0, "partial");
2179
+ }
2180
+ case "values": {
2181
+ if (a0?.shape.k === "obj") {
2182
+ const slots = a0.shape.slots;
2183
+ const vals = Object.values(slots).map((s) => s.value);
2184
+ return abs({ k: "tuple", elements: vals }, void 0, void 0, "exact");
2085
2185
  }
2086
- return false;
2186
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2187
+ }
2188
+ case "entries": {
2189
+ if (a0?.shape.k === "obj") {
2190
+ const slots = a0.shape.slots;
2191
+ const entries = Object.entries(slots).map(
2192
+ ([, s]) => abs({ k: "tuple", elements: [strPrim("exact"), s.value] }, void 0, void 0, "exact")
2193
+ );
2194
+ return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
2195
+ }
2196
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2197
+ }
2198
+ case "assign": {
2199
+ if (!args.length) return unknown;
2200
+ let acc = args[0];
2201
+ for (let i = 1; i < args.length; i++) {
2202
+ acc = { ...acc };
2203
+ if (acc.shape.k === "obj" && args[i].shape.k === "obj") {
2204
+ const base = acc.shape.slots;
2205
+ const over = args[i].shape.slots;
2206
+ acc = abs({ k: "obj", slots: { ...base, ...over } }, void 0, void 0, confJoin(acc.conf, args[i].conf));
2207
+ }
2208
+ }
2209
+ return acc;
2087
2210
  }
2088
- case "ExportAllDeclaration":
2089
- return anyNode.exportKind === "type";
2090
- case "ExportDefaultDeclaration":
2091
- return isTypeOnlyDeclaration(node.declaration);
2092
- // ---- 类成员 ----
2093
- case "TSIndexSignature":
2094
- case "TSDeclareMethod":
2095
- return true;
2096
- case "ClassProperty":
2097
- case "ClassPrivateProperty":
2098
- return isTsDeclareLike(node) || node.abstract === true;
2099
2211
  default:
2100
- return false;
2212
+ return void 0;
2101
2213
  }
2102
2214
  }
2103
- function deleteTypeSyntaxFields(node) {
2104
- const tp = node.typeParameters;
2105
- if (tp && typeof tp.type === "string" && tp.type.startsWith("TSTypeParameter")) {
2106
- delete node.typeParameters;
2107
- }
2108
- const ta = node.typeAnnotation;
2109
- if (ta && ta.type === "TSTypeAnnotation") delete node.typeAnnotation;
2110
- const rt = node.returnType;
2111
- if (rt && (rt.type === "TSTypeAnnotation" || rt.type === "TSTypePredicate")) delete node.returnType;
2112
- if (node.optional === true && (node.type === "Identifier" || node.type === "ObjectPattern" || node.type === "ArrayPattern" || node.type === "RestElement")) {
2113
- delete node.optional;
2215
+ function evalJsonMethod(name, args) {
2216
+ if (name === "stringify") return strPrim("partial");
2217
+ if (name === "parse") return unknown;
2218
+ return void 0;
2219
+ }
2220
+ function evalNumberStatic(name, args) {
2221
+ const a0 = args[0] ? litValue(args[0]) : void 0;
2222
+ switch (name) {
2223
+ case "isInteger":
2224
+ if (typeof a0 === "number") return boolLit(Number.isInteger(a0));
2225
+ return boolPrim();
2226
+ case "isNaN":
2227
+ if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2228
+ return boolPrim();
2229
+ case "isFinite":
2230
+ if (typeof a0 === "number") return boolLit(Number.isFinite(a0));
2231
+ return boolPrim();
2232
+ case "parseInt":
2233
+ case "parseFloat":
2234
+ if (typeof a0 === "string" || typeof a0 === "number") {
2235
+ const n = name === "parseInt" ? parseInt(String(a0), 10) : parseFloat(String(a0));
2236
+ return numLit(n);
2237
+ }
2238
+ return numPrim();
2239
+ case "MAX_SAFE_INTEGER":
2240
+ return numLit(Number.MAX_SAFE_INTEGER);
2241
+ default:
2242
+ return void 0;
2114
2243
  }
2115
- if ("implements" in node) delete node.implements;
2116
- if ("superTypeParameters" in node) delete node.superTypeParameters;
2117
2244
  }
2118
- function unwrapExpression(node) {
2119
- switch (node.type) {
2120
- case "TSAsExpression":
2121
- // 含 as const
2122
- case "TSSatisfiesExpression":
2123
- case "TSTypeAssertion":
2124
- case "TSNonNullExpression":
2125
- case "TSInstantiationExpression":
2126
- return node.expression;
2245
+ function evalGlobalFn(name, args) {
2246
+ const a0 = args[0] ? litValue(args[0]) : void 0;
2247
+ switch (name) {
2248
+ case "parseInt":
2249
+ if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseInt(String(a0), 10));
2250
+ return numPrim();
2251
+ case "parseFloat":
2252
+ if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseFloat(String(a0)));
2253
+ return numPrim();
2254
+ case "isNaN":
2255
+ if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2256
+ return boolPrim();
2257
+ case "Number":
2258
+ if (typeof a0 === "number") return numLit(a0);
2259
+ if (typeof a0 === "string") return numLit(Number(a0));
2260
+ if (typeof a0 === "boolean") return numLit(a0 ? 1 : 0);
2261
+ return numPrim();
2262
+ case "String":
2263
+ if (a0 !== void 0) return strLit(String(a0));
2264
+ return strPrim();
2265
+ case "Boolean":
2266
+ if (a0 !== void 0) return boolLit(Boolean(a0));
2267
+ return boolPrim();
2127
2268
  default:
2128
- return null;
2269
+ return void 0;
2129
2270
  }
2130
2271
  }
2131
- function transformNode(node) {
2132
- if (isTypeOnlyStatement(node)) return REMOVE;
2133
- deleteTypeSyntaxFields(node);
2134
- if (node.type === "ImportDeclaration") {
2135
- node.specifiers = node.specifiers.filter(
2136
- (s) => !(s.importKind === "type" || s.importKind === "typeof")
2137
- );
2138
- } else if (node.type === "ExportNamedDeclaration") {
2139
- if (node.specifiers) {
2140
- node.specifiers = node.specifiers.filter((s) => s.exportKind !== "type");
2272
+ function evalArrayStatic(name, args) {
2273
+ const a0 = args[0];
2274
+ switch (name) {
2275
+ case "isArray": {
2276
+ if (!a0) return boolLit(false);
2277
+ const k = a0.shape.k;
2278
+ return boolLit(k === "arr" || k === "tuple");
2141
2279
  }
2142
- }
2143
- for (const key of Object.keys(node)) {
2144
- if (SKIP_KEYS.has(key)) continue;
2145
- const child = node[key];
2146
- if (child === null || typeof child !== "object") continue;
2147
- const r = transformValue(child);
2148
- if (r === REMOVE) {
2149
- delete node[key];
2150
- } else {
2151
- node[key] = r;
2280
+ case "of":
2281
+ return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
2282
+ case "from": {
2283
+ if (!a0) return unknown;
2284
+ const k = a0.shape.k;
2285
+ if (k === "arr") return a0;
2286
+ if (k === "tuple") {
2287
+ const els = a0.shape.elements;
2288
+ if (els.length === 0) return abs({ k: "arr", element: unknown }, void 0, void 0, "path");
2289
+ let el = els[0];
2290
+ for (let i = 1; i < els.length; i++) el = joinAbs(el, els[i]);
2291
+ return abs({ k: "arr", element: el }, void 0, void 0, "path");
2292
+ }
2293
+ if (k === "prim" && a0.shape.type === "string") {
2294
+ return abs(
2295
+ { k: "arr", element: abs({ k: "prim", type: "string" }, void 0, void 0, "path") },
2296
+ void 0,
2297
+ void 0,
2298
+ "path"
2299
+ );
2300
+ }
2301
+ return unknown;
2152
2302
  }
2303
+ default:
2304
+ return void 0;
2153
2305
  }
2154
- return unwrapExpression(node) ?? node;
2155
2306
  }
2156
- function stripTypes(ast) {
2157
- transformValue(ast);
2158
- return ast;
2307
+ function evalDateCtor(args) {
2308
+ return abs(
2309
+ { k: "brand", name: "Date", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2310
+ void 0,
2311
+ void 0,
2312
+ "path"
2313
+ );
2159
2314
  }
2160
-
2161
- // src/algebra/parse-source.ts
2162
- var MAX_AST_CACHE = 16;
2163
- var MAX_AST_SOURCE_CHARS = 1e6;
2164
- var astCache = /* @__PURE__ */ new Map();
2165
- function resetParseSourceCache() {
2166
- astCache.clear();
2315
+ function evalDateStatic(name, _args) {
2316
+ if (name === "now") return numLit(Date.now());
2317
+ return void 0;
2167
2318
  }
2168
- function getParseSourceCacheSize() {
2169
- return astCache.size;
2319
+ function evalDateMethod(name, _recv, _args) {
2320
+ switch (name) {
2321
+ case "getTime":
2322
+ case "valueOf":
2323
+ return numPrim("path");
2324
+ case "toISOString":
2325
+ case "toString":
2326
+ return strPrim("path");
2327
+ default:
2328
+ return void 0;
2329
+ }
2170
2330
  }
2171
- function parseUncached(source, opts) {
2172
- const ast = babelParse(source, {
2173
- sourceType: "module",
2174
- plugins: ["typescript", "jsx"],
2175
- attachComment: true,
2176
- errorRecovery: opts?.errorRecovery === true
2177
- });
2178
- return stripTypes(ast);
2331
+ function evalRegExpCtor(_args) {
2332
+ return abs(
2333
+ { k: "brand", name: "RegExp", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2334
+ void 0,
2335
+ void 0,
2336
+ "path"
2337
+ );
2179
2338
  }
2180
- function parseSource(source, opts) {
2181
- if (opts?.errorRecovery === true) {
2182
- return parseUncached(source, opts);
2183
- }
2184
- if (source.length > MAX_AST_SOURCE_CHARS) {
2185
- return parseUncached(source, opts);
2186
- }
2187
- const hit = astCache.get(source);
2188
- if (hit !== void 0) {
2189
- astCache.delete(source);
2190
- astCache.set(source, hit);
2191
- return hit;
2192
- }
2193
- const ast = parseUncached(source, opts);
2194
- if (astCache.size >= MAX_AST_CACHE) {
2195
- const oldest = astCache.keys().next().value;
2196
- if (oldest !== void 0) astCache.delete(oldest);
2339
+ function evalRegExpMethod(name, _recv, _args) {
2340
+ switch (name) {
2341
+ case "test":
2342
+ return boolPrim();
2343
+ case "exec":
2344
+ return unknown;
2345
+ default:
2346
+ return void 0;
2197
2347
  }
2198
- astCache.set(source, ast);
2199
- return ast;
2200
2348
  }
2201
-
2202
- // src/algebra/leak.ts
2203
- var defaultLeakBudget = {
2204
- maxDepth: 6,
2205
- maxNodes: 32
2206
- };
2207
- function termDepth(t) {
2208
- if (t.op !== "app") return 1;
2209
- return 1 + Math.max(0, ...t.args.map(termDepth));
2349
+ function evalPromiseCtor(_args) {
2350
+ return abs(
2351
+ { k: "eff", eff: "promise", inner: unknown },
2352
+ void 0,
2353
+ void 0,
2354
+ "partial"
2355
+ );
2210
2356
  }
2211
- function termNodes(t) {
2212
- if (t.op !== "app") return 1;
2213
- return 1 + t.args.reduce((s, x) => s + termNodes(x), 0);
2214
- }
2215
- function exceedsBudget(t, budget = defaultLeakBudget) {
2216
- return termDepth(t) > budget.maxDepth || termNodes(t) > budget.maxNodes;
2357
+ function evalPromiseStatic(name, args) {
2358
+ switch (name) {
2359
+ case "resolve": {
2360
+ const inner = args[0] ?? unknown;
2361
+ if (inner.shape.k === "eff" && inner.shape.eff === "promise") return inner;
2362
+ return abs({ k: "eff", eff: "promise", inner }, void 0, void 0, "path");
2363
+ }
2364
+ case "reject":
2365
+ return abs({ k: "eff", eff: "promise", inner: unknown }, void 0, void 0, "partial");
2366
+ case "all": {
2367
+ const a0 = args[0];
2368
+ if (a0?.shape.k === "arr" && a0.shape.element.shape.k === "eff") {
2369
+ return abs(
2370
+ { k: "eff", eff: "promise", inner: abs({ k: "arr", element: a0.shape.element.shape.inner }, void 0, void 0, "path") },
2371
+ void 0,
2372
+ void 0,
2373
+ "path"
2374
+ );
2375
+ }
2376
+ return abs({ k: "eff", eff: "promise", inner: abs({ k: "arr", element: unknown }, void 0, void 0, "partial") }, void 0, void 0, "partial");
2377
+ }
2378
+ default:
2379
+ return void 0;
2380
+ }
2217
2381
  }
2218
- var leakCounter = 0;
2219
- function resetLeakCounter() {
2220
- leakCounter = 0;
2382
+ function evalNamespaceCall(ns, method, args) {
2383
+ switch (ns) {
2384
+ case "Math":
2385
+ return evalMathMethod(method, args);
2386
+ case "Object":
2387
+ return evalObjectMethod(method, args);
2388
+ case "JSON":
2389
+ return evalJsonMethod(method, args);
2390
+ case "Number":
2391
+ return evalNumberStatic(method, args);
2392
+ case "Array":
2393
+ return evalArrayStatic(method, args);
2394
+ case "Date":
2395
+ return evalDateStatic(method, args);
2396
+ case "Promise":
2397
+ return evalPromiseStatic(method, args);
2398
+ default:
2399
+ return void 0;
2400
+ }
2221
2401
  }
2222
- function maybeLeak(a, budget = defaultLeakBudget, label = "t") {
2223
- if (!a.term || a.term.op !== "app") return a;
2224
- if (!exceedsBudget(a.term, budget)) return a;
2225
- leakCounter += 1;
2226
- const id = `${label}$${leakCounter}`;
2227
- const fresh = v(id);
2228
- const linkage = eq(fresh, a.term);
2229
- return abs(a.shape, fresh, linkage, confJoin(a.conf, "path"));
2402
+ function evalBuiltinNew(className, args) {
2403
+ switch (className) {
2404
+ case "Date":
2405
+ return evalDateCtor(args);
2406
+ case "RegExp":
2407
+ return evalRegExpCtor(args);
2408
+ case "Promise":
2409
+ return evalPromiseCtor(args);
2410
+ case "Map":
2411
+ return abs(
2412
+ { k: "brand", name: "Map", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2413
+ void 0,
2414
+ void 0,
2415
+ "path"
2416
+ );
2417
+ case "Set":
2418
+ return abs(
2419
+ { k: "brand", name: "Set", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2420
+ void 0,
2421
+ void 0,
2422
+ "path"
2423
+ );
2424
+ default:
2425
+ return void 0;
2426
+ }
2230
2427
  }
2231
- function leakIfNeeded(a, budget, label) {
2232
- return maybeLeak(a, budget, label);
2428
+ function evalBuiltinInstanceMethod(brandName, method, recv, args) {
2429
+ if (brandName === "Date") return evalDateMethod(method, recv, args);
2430
+ if (brandName === "RegExp") return evalRegExpMethod(method, recv, args);
2431
+ if (brandName === "Map") {
2432
+ switch (method) {
2433
+ case "get":
2434
+ return unknown;
2435
+ case "has":
2436
+ return boolPrim();
2437
+ case "set":
2438
+ return recv;
2439
+ case "size":
2440
+ return numPrim("path");
2441
+ default:
2442
+ return void 0;
2443
+ }
2444
+ }
2445
+ if (brandName === "Set") {
2446
+ switch (method) {
2447
+ case "has":
2448
+ return boolPrim();
2449
+ case "add":
2450
+ return recv;
2451
+ case "size":
2452
+ return numPrim("path");
2453
+ default:
2454
+ return void 0;
2455
+ }
2456
+ }
2457
+ return void 0;
2233
2458
  }
2234
2459
 
2235
- // src/algebra/hof.ts
2236
- function createHofCollectCtx(paramNames, alphaIds) {
2237
- return {
2238
- paramNames,
2239
- alphaIds: new Set(alphaIds),
2240
- freshSeq: { n: 0 },
2241
- sites: [],
2242
- fnRels: /* @__PURE__ */ new Map(),
2243
- entryShapes: /* @__PURE__ */ new Map()
2244
- };
2245
- }
2246
- function alphaOf(absOrTerm, ctx) {
2247
- const t = absOrTerm && typeof absOrTerm === "object" && "shape" in absOrTerm ? absOrTerm.term : absOrTerm;
2248
- if (t?.op === "var" && ctx.alphaIds.has(t.id)) return t;
2249
- ctx.freshSeq.n += 1;
2250
- const id = `T${ctx.freshSeq.n}`;
2251
- ctx.alphaIds.add(id);
2252
- return v(id);
2253
- }
2254
- function betaOf(param) {
2255
- return v(`B:${param}`);
2256
- }
2257
- function promoteParamShape(env, param, promotedShape, opts) {
2258
- const prev = env.vars.get(param);
2259
- if (!prev) return false;
2260
- if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return false;
2261
- const next = {
2262
- shape: promotedShape,
2263
- term: prev.term,
2264
- pred: prev.pred,
2265
- conf: "path"
2266
- };
2267
- env.vars.set(param, next);
2268
- const hc = env.hofCollect;
2269
- if (hc && hc.paramNames.has(param)) {
2270
- if (promotedShape.k === "fn") {
2271
- if (!hc.fnRels.has(param) && !hc.entryShapes.has(param)) {
2272
- hc.fnRels.set(param, { abs: { ...next }, source: "promote" });
2460
+ // src/algebra/exec/calls.ts
2461
+ var calls_exports = {};
2462
+ __export(calls_exports, {
2463
+ $callNamed: () => $callNamed,
2464
+ getAbsOrigin: () => getAbsOrigin,
2465
+ getBCallCollector: () => getBCallCollector,
2466
+ noteMemberDispatchMiss: () => noteMemberDispatchMiss,
2467
+ notePrimMemberMissing: () => notePrimMemberMissing,
2468
+ noteUnknownMemberMissing: () => noteUnknownMemberMissing,
2469
+ recordMemberDiag: () => recordMemberDiag,
2470
+ setBCallCollector: () => setBCallCollector,
2471
+ setMemberDiagCollector: () => setMemberDiagCollector,
2472
+ tagAbsOrigin: () => tagAbsOrigin
2473
+ });
2474
+
2475
+ // src/algebra/parse-source.ts
2476
+ import { parse as babelParse } from "@babel/parser";
2477
+
2478
+ // src/strip-types.ts
2479
+ var REMOVE = Symbol("nudo.strip.remove");
2480
+ var SKIP_KEYS = /* @__PURE__ */ new Set([
2481
+ "loc",
2482
+ "start",
2483
+ "end",
2484
+ "range",
2485
+ "leadingComments",
2486
+ "trailingComments",
2487
+ "innerComments",
2488
+ "comments",
2489
+ "tokens",
2490
+ "extra"
2491
+ ]);
2492
+ function transformValue(value) {
2493
+ if (Array.isArray(value)) {
2494
+ let changed = false;
2495
+ const out = [];
2496
+ for (const el of value) {
2497
+ if (el === null || el === void 0) {
2498
+ out.push(el);
2499
+ continue;
2273
2500
  }
2274
- } else {
2275
- if (!hc.fnRels.has(param) && !hc.entryShapes.has(param)) {
2276
- hc.entryShapes.set(param, { abs: { ...next }, source: "promote" });
2501
+ const r = transformValue(el);
2502
+ if (r === REMOVE) {
2503
+ changed = true;
2504
+ } else {
2505
+ if (r !== el) changed = true;
2506
+ out.push(r);
2277
2507
  }
2278
2508
  }
2279
- if (opts?.recordSite !== false && promotedShape.k === "fn") {
2280
- const result = promotedShape.returnType ?? next;
2281
- hc.sites.push({
2282
- param,
2283
- argTerms: [],
2284
- result,
2285
- loc: opts?.loc
2286
- });
2287
- }
2509
+ return changed ? out : value;
2288
2510
  }
2289
- return true;
2290
- }
2291
- var HOF_ARR_METHODS = /* @__PURE__ */ new Set(["map", "filter", "reduce", "flatMap"]);
2292
- function promoteParamAsArr(env, name, loc) {
2293
- const hc = env.hofCollect;
2294
- if (!hc || !hc.paramNames.has(name)) return void 0;
2295
- const prev = env.vars.get(name);
2296
- if (!prev) return void 0;
2297
- if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return void 0;
2298
- const element = prev.term ? abs(prev.shape, prev.term, prev.pred, "path") : abs({ k: "any" }, void 0, void 0, "path");
2299
- const arrShape = { k: "arr", element };
2300
- promoteParamShape(env, name, arrShape, { loc });
2301
- return env.vars.get(name);
2511
+ if (typeof value !== "object" || value === null) return value;
2512
+ if (typeof value.type !== "string") return value;
2513
+ return transformNode(value);
2302
2514
  }
2303
- function tryPromoteReceiverAsArr(env, receiverName, method, loc) {
2304
- if (!HOF_ARR_METHODS.has(method)) return void 0;
2305
- return promoteParamAsArr(env, receiverName, loc);
2515
+ function isTsDeclareLike(node) {
2516
+ return node.declare === true;
2306
2517
  }
2307
- function tryPromoteForOfIteratee(env, iterateeName, loc) {
2308
- return promoteParamAsArr(env, iterateeName, loc);
2518
+ function isTypeOnlyDeclaration(decl) {
2519
+ switch (decl.type) {
2520
+ case "TSInterfaceDeclaration":
2521
+ case "TSTypeAliasDeclaration":
2522
+ case "TSEnumDeclaration":
2523
+ case "TSDeclareFunction":
2524
+ return true;
2525
+ case "VariableDeclaration":
2526
+ case "ClassDeclaration":
2527
+ return isTsDeclareLike(decl);
2528
+ default:
2529
+ return false;
2530
+ }
2309
2531
  }
2310
- function tryPromoteDirectCall(env, calleeName, args, loc) {
2311
- const hc = env.hofCollect;
2312
- if (!hc || !hc.paramNames.has(calleeName)) return void 0;
2313
- const prev = env.vars.get(calleeName);
2314
- if (!prev) return void 0;
2315
- if (prev.shape.k !== "any" && prev.shape.k !== "unknown") {
2316
- if (prev.shape.k === "fn") {
2317
- hc.sites.push({
2318
- param: calleeName,
2319
- argTerms: args.map((a) => a.term ?? { op: "var", id: "_" }),
2320
- result: prev.shape.returnType ?? prev,
2321
- loc
2322
- });
2323
- }
2324
- return void 0;
2325
- }
2326
- const paramTypes = args.map(
2327
- (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2328
- );
2329
- const ret = abs({ k: "any" }, betaOf(calleeName), void 0, "path");
2330
- const fnShape = {
2331
- k: "fn",
2332
- params: args.map((_, i) => `x${i}`),
2333
- paramTypes,
2334
- returnType: ret
2335
- };
2336
- promoteParamShape(env, calleeName, fnShape, { loc, recordSite: false });
2337
- hc.sites.push({
2338
- param: calleeName,
2339
- argTerms: args.map((a) => a.term ?? { op: "var", id: "_" }),
2340
- result: ret,
2341
- loc
2342
- });
2343
- return env.vars.get(calleeName);
2344
- }
2345
- function tryPromoteHofCallback(env, cbName, method, argAbses, loc) {
2346
- const hc = env.hofCollect;
2347
- if (!hc || !hc.paramNames.has(cbName)) return void 0;
2348
- const prev = env.vars.get(cbName);
2349
- if (!prev) return void 0;
2350
- if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return void 0;
2351
- let paramTypes;
2352
- let returnType;
2353
- if (method === "filter") {
2354
- paramTypes = argAbses.map(
2355
- (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2356
- );
2357
- returnType = abs({ k: "prim", type: "boolean" }, void 0, void 0, "path");
2358
- } else if (method === "reduce") {
2359
- paramTypes = argAbses.map(
2360
- (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2361
- );
2362
- returnType = abs({ k: "any" }, betaOf(cbName), void 0, "path");
2363
- } else {
2364
- paramTypes = argAbses.map(
2365
- (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2366
- );
2367
- returnType = abs({ k: "any" }, betaOf(cbName), void 0, "path");
2368
- }
2369
- const fnShape = {
2370
- k: "fn",
2371
- params: argAbses.map((_, i) => `x${i}`),
2372
- paramTypes,
2373
- returnType
2374
- };
2375
- promoteParamShape(env, cbName, fnShape, { loc, recordSite: false });
2376
- hc.sites.push({
2377
- param: cbName,
2378
- argTerms: argAbses.map((a) => a.term ?? { op: "var", id: "_" }),
2379
- result: returnType,
2380
- loc
2381
- });
2382
- return env.vars.get(cbName);
2383
- }
2384
- function snapshotAbs(a) {
2385
- const shape = a.shape;
2386
- const copyShape = (s) => {
2387
- switch (s.k) {
2388
- case "arr":
2389
- return { ...s, element: snapshotAbs(s.element) };
2390
- case "tuple": {
2391
- const next = {
2392
- k: "tuple",
2393
- elements: s.elements.map(snapshotAbs)
2394
- };
2395
- if (s.rest) next.rest = snapshotAbs(s.rest);
2396
- return next;
2397
- }
2398
- case "fn": {
2399
- const next = { k: "fn", params: [...s.params] };
2400
- if (s.name !== void 0) next.name = s.name;
2401
- if (s.paramTypes) next.paramTypes = s.paramTypes.map(snapshotAbs);
2402
- if (s.returnType) next.returnType = snapshotAbs(s.returnType);
2403
- return next;
2404
- }
2405
- case "sum":
2406
- return { ...s, members: s.members.map(snapshotAbs) };
2407
- case "obj": {
2408
- const slots = {};
2409
- for (const [k, slot] of Object.entries(s.slots)) {
2410
- const nextSlot = { value: snapshotAbs(slot.value) };
2411
- if (slot.optional) nextSlot.optional = true;
2412
- if (slot.readonly) nextSlot.readonly = true;
2413
- slots[k] = nextSlot;
2414
- }
2415
- const next = { k: "obj", slots };
2416
- if (s.index) {
2417
- next.index = {
2418
- key: snapshotAbs(s.index.key),
2419
- value: snapshotAbs(s.index.value)
2420
- };
2421
- }
2422
- if (s.open) next.open = true;
2423
- return next;
2424
- }
2425
- case "brand":
2426
- return { ...s, shape: snapshotAbs(s.shape) };
2427
- case "eff":
2428
- return { ...s, inner: snapshotAbs(s.inner) };
2429
- default:
2430
- return s;
2431
- }
2432
- };
2433
- return {
2434
- shape: copyShape(shape),
2435
- term: a.term,
2436
- pred: a.pred,
2437
- conf: a.conf
2438
- };
2439
- }
2440
- function isRelFn(a) {
2441
- if (!a || typeof a !== "object") return false;
2442
- if (getFnImpl(a)) return false;
2443
- const s = a.shape;
2444
- if (!s || s.k !== "fn") return false;
2445
- if (s.returnType === void 0) return false;
2446
- if (s.paramTypes === void 0) return s.params.length === 0;
2447
- return s.paramTypes.length === s.params.length;
2448
- }
2449
- function litOfTerm(t) {
2450
- return t.op === "lit" ? t.value : void 0;
2451
- }
2452
- function foldCompare(op, a, b) {
2453
- if (a === void 0 || b === void 0) return void 0;
2454
- if (typeof a !== typeof b) {
2455
- if (op === "eq") return pFalse;
2456
- if (op === "ne") return pTrue;
2457
- return void 0;
2458
- }
2459
- switch (op) {
2460
- case "eq":
2461
- return a === b ? pTrue : pFalse;
2462
- case "ne":
2463
- return a !== b ? pTrue : pFalse;
2464
- case "lt":
2465
- return a < b ? pTrue : pFalse;
2466
- case "le":
2467
- return a <= b ? pTrue : pFalse;
2468
- case "gt":
2469
- return a > b ? pTrue : pFalse;
2470
- case "ge":
2471
- return a >= b ? pTrue : pFalse;
2472
- default:
2473
- return void 0;
2474
- }
2475
- }
2476
- function predUsesMappedVars(p, map) {
2477
- const walkTerm = (t) => {
2478
- if (t.op === "var") return map.has(t.id);
2479
- if (t.op === "app") return t.args.some(walkTerm);
2480
- return false;
2481
- };
2482
- const walk = (q) => {
2483
- switch (q.op) {
2484
- case "true":
2485
- case "false":
2486
- return false;
2487
- case "eq":
2488
- case "ne":
2489
- case "lt":
2490
- case "le":
2491
- case "gt":
2492
- case "ge":
2493
- return walkTerm(q.a) || walkTerm(q.b);
2494
- case "and":
2495
- case "or":
2496
- return q.args.some(walk);
2497
- case "not":
2498
- return walk(q.arg);
2499
- case "typeof":
2500
- return walkTerm(q.t);
2501
- }
2502
- };
2503
- return walk(p);
2504
- }
2505
- function mapHasShapeOnlyVar(p, map) {
2506
- const walkTerm = (t) => {
2507
- if (t.op === "var") {
2508
- const arg = map.get(t.id);
2509
- return !!arg && arg.term === void 0;
2510
- }
2511
- if (t.op === "app") return t.args.some(walkTerm);
2512
- return false;
2513
- };
2514
- const walk = (q) => {
2515
- switch (q.op) {
2516
- case "true":
2517
- case "false":
2518
- return false;
2519
- case "eq":
2520
- case "ne":
2521
- case "lt":
2522
- case "le":
2523
- case "gt":
2524
- case "ge":
2525
- return walkTerm(q.a) || walkTerm(q.b);
2526
- case "and":
2527
- case "or":
2528
- return q.args.some(walk);
2529
- case "not":
2530
- return walk(q.arg);
2531
- case "typeof":
2532
- return walkTerm(q.t);
2533
- }
2534
- };
2535
- return walk(p);
2536
- }
2537
- function substPredAbs(p, map) {
2538
- if (!predUsesMappedVars(p, map)) return { pred: p, dropped: false };
2539
- if (mapHasShapeOnlyVar(p, map)) return { pred: pTrue, dropped: true };
2540
- const substTerm = (t) => {
2541
- if (t.op === "var") {
2542
- const arg = map.get(t.id);
2543
- return arg?.term ?? t;
2544
- }
2545
- if (t.op === "app") {
2546
- return { op: "app", fn: t.fn, args: t.args.map(substTerm) };
2547
- }
2548
- return t;
2549
- };
2550
- const replaced = substPred(p, substTerm);
2551
- const fold = (q) => {
2552
- switch (q.op) {
2553
- case "true":
2554
- case "false":
2555
- return q;
2556
- case "eq":
2557
- case "ne":
2558
- case "lt":
2559
- case "le":
2560
- case "gt":
2561
- case "ge": {
2562
- const a = litOfTerm(q.a);
2563
- const b = litOfTerm(q.b);
2564
- const folded = foldCompare(q.op, a, b);
2565
- return folded ?? q;
2566
- }
2567
- case "and": {
2568
- const args = q.args.map(fold);
2569
- if (args.some((x) => x.op === "false")) return pFalse;
2570
- const rest = args.filter((x) => x.op !== "true");
2571
- if (rest.length === 0) return pTrue;
2572
- if (rest.length === 1) return rest[0];
2573
- return and(...rest);
2574
- }
2575
- case "or": {
2576
- const args = q.args.map(fold);
2577
- if (args.some((x) => x.op === "true")) return pTrue;
2578
- const rest = args.filter((x) => x.op !== "false");
2579
- if (rest.length === 0) return pFalse;
2580
- if (rest.length === 1) return rest[0];
2581
- return { op: "or", args: rest };
2532
+ function isTypeOnlyStatement(node) {
2533
+ const anyNode = node;
2534
+ switch (node.type) {
2535
+ case "TSInterfaceDeclaration":
2536
+ case "TSTypeAliasDeclaration":
2537
+ case "TSEnumDeclaration":
2538
+ case "TSDeclareFunction":
2539
+ return true;
2540
+ case "TSModuleDeclaration":
2541
+ return isTsDeclareLike(node);
2542
+ case "VariableDeclaration":
2543
+ case "ClassDeclaration":
2544
+ return isTsDeclareLike(node);
2545
+ case "ImportDeclaration":
2546
+ if (anyNode.importKind === "type") return true;
2547
+ {
2548
+ const specs = anyNode.specifiers;
2549
+ if (specs && specs.length > 0 && specs.every((s) => s.importKind === "type" || s.importKind === "typeof")) {
2550
+ return true;
2551
+ }
2582
2552
  }
2583
- case "not": {
2584
- const inner = fold(q.arg);
2585
- if (inner.op === "true") return pFalse;
2586
- if (inner.op === "false") return pTrue;
2587
- return { op: "not", arg: inner };
2553
+ return false;
2554
+ case "ExportNamedDeclaration": {
2555
+ if (anyNode.exportKind === "type") return true;
2556
+ const decl = node.declaration;
2557
+ if (decl && isTypeOnlyDeclaration(decl)) return true;
2558
+ {
2559
+ const specs = anyNode.specifiers;
2560
+ if (!decl && specs && specs.length > 0 && specs.every((s) => s.exportKind === "type")) return true;
2588
2561
  }
2589
- case "typeof":
2590
- return q;
2562
+ return false;
2591
2563
  }
2592
- };
2593
- return { pred: fold(replaced), dropped: false };
2564
+ case "ExportAllDeclaration":
2565
+ return anyNode.exportKind === "type";
2566
+ case "ExportDefaultDeclaration":
2567
+ return isTypeOnlyDeclaration(node.declaration);
2568
+ // ---- 类成员 ----
2569
+ case "TSIndexSignature":
2570
+ case "TSDeclareMethod":
2571
+ return true;
2572
+ case "ClassProperty":
2573
+ case "ClassPrivateProperty":
2574
+ return isTsDeclareLike(node) || node.abstract === true;
2575
+ default:
2576
+ return false;
2577
+ }
2594
2578
  }
2595
- function substTermAbs(t, map) {
2596
- if (t.op === "var") {
2597
- const arg = map.get(t.id);
2598
- return arg?.term ?? t;
2579
+ function deleteTypeSyntaxFields(node) {
2580
+ const tp = node.typeParameters;
2581
+ if (tp && typeof tp.type === "string" && tp.type.startsWith("TSTypeParameter")) {
2582
+ delete node.typeParameters;
2599
2583
  }
2600
- if (t.op === "app") {
2601
- return simplifyTerm({
2602
- op: "app",
2603
- fn: t.fn,
2604
- args: t.args.map((x) => substTermAbs(x, map))
2605
- });
2584
+ const ta = node.typeAnnotation;
2585
+ if (ta && ta.type === "TSTypeAnnotation") delete node.typeAnnotation;
2586
+ const rt = node.returnType;
2587
+ if (rt && (rt.type === "TSTypeAnnotation" || rt.type === "TSTypePredicate")) delete node.returnType;
2588
+ if (node.optional === true && (node.type === "Identifier" || node.type === "ObjectPattern" || node.type === "ArrayPattern" || node.type === "RestElement")) {
2589
+ delete node.optional;
2606
2590
  }
2607
- return t;
2591
+ if ("implements" in node) delete node.implements;
2592
+ if ("superTypeParameters" in node) delete node.superTypeParameters;
2608
2593
  }
2609
- function substShape(s, map, cache, visiting) {
2610
- switch (s.k) {
2611
- case "never":
2612
- case "any":
2613
- case "unknown":
2614
- case "prim":
2615
- return s;
2616
- case "brand":
2617
- return { ...s, shape: substAbsInner(s.shape, map, cache, visiting) };
2618
- case "eff":
2619
- return { ...s, inner: substAbsInner(s.inner, map, cache, visiting) };
2620
- case "arr":
2621
- return { ...s, element: substAbsInner(s.element, map, cache, visiting) };
2622
- case "tuple": {
2623
- const elements = s.elements.map(
2624
- (e) => substAbsInner(e, map, cache, visiting)
2625
- );
2626
- const next = { k: "tuple", elements };
2627
- if (s.rest) next.rest = substAbsInner(s.rest, map, cache, visiting);
2628
- return next;
2629
- }
2630
- case "fn": {
2631
- const next = { k: "fn", params: s.params };
2632
- if (s.name !== void 0) next.name = s.name;
2633
- if (s.paramTypes) {
2634
- next.paramTypes = s.paramTypes.map(
2635
- (p) => substAbsInner(p, map, cache, visiting)
2636
- );
2637
- }
2638
- if (s.returnType !== void 0) {
2639
- next.returnType = substAbsInner(s.returnType, map, cache, visiting);
2640
- }
2641
- return next;
2642
- }
2643
- case "sum":
2644
- return {
2645
- ...s,
2646
- members: s.members.map((m) => substAbsInner(m, map, cache, visiting))
2647
- };
2648
- case "obj": {
2649
- const slots = {};
2650
- for (const [k, slot] of Object.entries(s.slots)) {
2651
- const nextSlot = { value: substAbsInner(slot.value, map, cache, visiting) };
2652
- if (slot.optional) nextSlot.optional = true;
2653
- if (slot.readonly) nextSlot.readonly = true;
2654
- slots[k] = nextSlot;
2655
- }
2656
- const next = { k: "obj", slots };
2657
- if (s.index) {
2658
- next.index = {
2659
- key: substAbsInner(s.index.key, map, cache, visiting),
2660
- value: substAbsInner(s.index.value, map, cache, visiting)
2661
- };
2662
- }
2663
- if (s.open) next.open = true;
2664
- return next;
2665
- }
2594
+ function unwrapExpression(node) {
2595
+ switch (node.type) {
2596
+ case "TSAsExpression":
2597
+ // 含 as const
2598
+ case "TSSatisfiesExpression":
2599
+ case "TSTypeAssertion":
2600
+ case "TSNonNullExpression":
2601
+ case "TSInstantiationExpression":
2602
+ return node.expression;
2603
+ default:
2604
+ return null;
2666
2605
  }
2667
2606
  }
2668
- function substAbsInner(a, map, cache, visiting) {
2669
- if (a.term?.op === "var" && map.has(a.term.id)) {
2670
- const repl = map.get(a.term.id);
2671
- return {
2672
- shape: repl.shape,
2673
- term: repl.term,
2674
- pred: repl.pred,
2675
- conf: confJoin(a.conf, repl.conf)
2676
- };
2607
+ function transformNode(node) {
2608
+ if (isTypeOnlyStatement(node)) return REMOVE;
2609
+ deleteTypeSyntaxFields(node);
2610
+ if (node.type === "ImportDeclaration") {
2611
+ node.specifiers = node.specifiers.filter(
2612
+ (s) => !(s.importKind === "type" || s.importKind === "typeof")
2613
+ );
2614
+ } else if (node.type === "ExportNamedDeclaration") {
2615
+ if (node.specifiers) {
2616
+ node.specifiers = node.specifiers.filter((s) => s.exportKind !== "type");
2617
+ }
2677
2618
  }
2678
- const hit = cache.get(a);
2679
- if (hit !== void 0) return hit;
2680
- if (visiting.has(a)) return a;
2681
- visiting.add(a);
2682
- const shape = substShape(a.shape, map, cache, visiting);
2683
- const term = a.term ? substTermAbs(a.term, map) : void 0;
2684
- let pred = a.pred;
2685
- let conf = a.conf;
2686
- if (a.pred) {
2687
- const r = substPredAbs(a.pred, map);
2688
- pred = r.pred;
2689
- if (r.dropped) conf = confJoin(conf, "partial");
2619
+ for (const key of Object.keys(node)) {
2620
+ if (SKIP_KEYS.has(key)) continue;
2621
+ const child = node[key];
2622
+ if (child === null || typeof child !== "object") continue;
2623
+ const r = transformValue(child);
2624
+ if (r === REMOVE) {
2625
+ delete node[key];
2626
+ } else {
2627
+ node[key] = r;
2628
+ }
2690
2629
  }
2691
- visiting.delete(a);
2692
- const result = abs(shape, term, pred, conf);
2693
- cache.set(a, result);
2694
- return result;
2630
+ return unwrapExpression(node) ?? node;
2695
2631
  }
2696
- function substAbs(a, map) {
2697
- if (map.size === 0) return a;
2698
- return substAbsInner(a, map, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
2632
+ function stripTypes(ast) {
2633
+ transformValue(ast);
2634
+ return ast;
2699
2635
  }
2700
- function instantiateReturn(fn, args) {
2701
- const shape = fn.shape;
2702
- if (!shape || shape.k !== "fn") return unknown;
2703
- const src = getFnImpl(fn)?.relation ?? {
2704
- paramTypes: shape.paramTypes ?? [],
2705
- returnType: shape.returnType ?? unknown
2706
- };
2707
- const map = /* @__PURE__ */ new Map();
2708
- src.paramTypes.forEach((p, i) => {
2709
- if (p.term?.op !== "var") return;
2710
- const id = p.term.id;
2711
- if (map.has(id)) return;
2712
- map.set(id, args[i] ?? unknown);
2713
- });
2714
- return substAbs(src.returnType, map);
2636
+
2637
+ // src/algebra/parse-source.ts
2638
+ var MAX_AST_CACHE = 16;
2639
+ var MAX_AST_SOURCE_CHARS = 1e6;
2640
+ var astCache = /* @__PURE__ */ new Map();
2641
+ function resetParseSourceCache() {
2642
+ astCache.clear();
2715
2643
  }
2716
- var applyCallbackHost;
2717
- function setApplyCallbackHost(fn) {
2718
- applyCallbackHost = fn;
2644
+ function getParseSourceCacheSize() {
2645
+ return astCache.size;
2719
2646
  }
2720
- function applyCallbackAbs(cb, args, env, phi2, budget) {
2721
- if (!applyCallbackHost) {
2722
- if (cb && typeof cb === "object" && "shape" in cb) {
2723
- const a = cb;
2724
- const impl = getFnImpl(a);
2725
- if (impl?.relation) return instantiateReturn(a, args);
2726
- if (isRelFn(a)) return instantiateReturn(a, args);
2727
- }
2728
- return unknown;
2647
+ function parseUncached(source, opts) {
2648
+ const ast = babelParse(source, {
2649
+ sourceType: "module",
2650
+ plugins: ["typescript", "jsx"],
2651
+ attachComment: true,
2652
+ errorRecovery: opts?.errorRecovery === true
2653
+ });
2654
+ return opts?.keepTs === true ? ast : stripTypes(ast);
2655
+ }
2656
+ function parseSource(source, opts) {
2657
+ if (opts?.keepTs === true || opts?.errorRecovery === true) {
2658
+ return parseUncached(source, opts);
2729
2659
  }
2730
- return applyCallbackHost(cb, args, env, phi2, budget);
2660
+ if (source.length > MAX_AST_SOURCE_CHARS) {
2661
+ return parseUncached(source, opts);
2662
+ }
2663
+ const hit = astCache.get(source);
2664
+ if (hit !== void 0) {
2665
+ astCache.delete(source);
2666
+ astCache.set(source, hit);
2667
+ return hit;
2668
+ }
2669
+ const ast = parseUncached(source, opts);
2670
+ if (astCache.size >= MAX_AST_CACHE) {
2671
+ const oldest = astCache.keys().next().value;
2672
+ if (oldest !== void 0) astCache.delete(oldest);
2673
+ }
2674
+ astCache.set(source, ast);
2675
+ return ast;
2676
+ }
2677
+
2678
+ // src/algebra/leak.ts
2679
+ var defaultLeakBudget = {
2680
+ maxDepth: 6,
2681
+ maxNodes: 32
2682
+ };
2683
+ function termDepth(t) {
2684
+ if (t.op !== "app") return 1;
2685
+ return 1 + Math.max(0, ...t.args.map(termDepth));
2686
+ }
2687
+ function termNodes(t) {
2688
+ if (t.op !== "app") return 1;
2689
+ return 1 + t.args.reduce((s, x) => s + termNodes(x), 0);
2731
2690
  }
2732
- function undefAbs() {
2733
- return abs(
2734
- { k: "unknown" },
2735
- { op: "lit", value: void 0 },
2736
- pTrue,
2737
- "exact"
2738
- );
2691
+ function exceedsBudget(t, budget = defaultLeakBudget) {
2692
+ return termDepth(t) > budget.maxDepth || termNodes(t) > budget.maxNodes;
2739
2693
  }
2740
- function mapElementFallback(cbAbs, elem, out) {
2741
- if (out.shape.k !== "unknown" || elem.term?.op !== "var") return out;
2742
- const slot = cbAbs?.shape.k === "fn" ? cbAbs.shape.returnType : void 0;
2743
- return slot ?? out;
2694
+ var leakCounter = 0;
2695
+ function resetLeakCounter() {
2696
+ leakCounter = 0;
2744
2697
  }
2745
- function projectFlatMapResult(arrConf, mapped) {
2746
- const flatEls = [];
2747
- let anyUnknown = false;
2748
- for (const m of mapped) {
2749
- if (m.shape.k === "arr") flatEls.push(m.shape.element);
2750
- else if (m.shape.k === "tuple") flatEls.push(...m.shape.elements);
2751
- else anyUnknown = true;
2752
- }
2753
- if (anyUnknown || flatEls.length === 0) return unknown;
2754
- const first = flatEls[0];
2755
- const sameIdentity = flatEls.every((e) => {
2756
- if (e.shape.k !== first.shape.k) return false;
2757
- if (!e.term && !first.term) return true;
2758
- if (!e.term || !first.term) return false;
2759
- return termToString(e.term) === termToString(first.term);
2760
- });
2761
- const el = sameIdentity ? first : flatEls.reduce((a, b) => joinAbs(a, b));
2762
- return abs(
2763
- { k: "arr", element: el },
2764
- void 0,
2765
- void 0,
2766
- confJoin(arrConf, "path")
2767
- );
2698
+ function maybeLeak(a, budget = defaultLeakBudget, label = "t") {
2699
+ if (!a.term || a.term.op !== "app") return a;
2700
+ if (!exceedsBudget(a.term, budget)) return a;
2701
+ leakCounter += 1;
2702
+ const id = `${label}$${leakCounter}`;
2703
+ const fresh = v(id);
2704
+ const linkage = eq(fresh, a.term);
2705
+ return abs(a.shape, fresh, linkage, confJoin(a.conf, "path"));
2768
2706
  }
2769
- function asAbs(v2) {
2770
- if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
2771
- return void 0;
2707
+ function leakIfNeeded(a, budget, label) {
2708
+ return maybeLeak(a, budget, label);
2772
2709
  }
2773
2710
 
2774
- // src/algebra/builtins.ts
2775
- function numPrim(conf = "path") {
2776
- return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
2711
+ // src/algebra/hof.ts
2712
+ function createHofCollectCtx(paramNames, alphaIds) {
2713
+ return {
2714
+ paramNames,
2715
+ alphaIds: new Set(alphaIds),
2716
+ freshSeq: { n: 0 },
2717
+ sites: [],
2718
+ fnRels: /* @__PURE__ */ new Map(),
2719
+ entryShapes: /* @__PURE__ */ new Map()
2720
+ };
2777
2721
  }
2778
- function strPrim(conf = "path") {
2779
- return abs({ k: "prim", type: "string" }, void 0, void 0, conf);
2722
+ function alphaOf(absOrTerm, ctx) {
2723
+ const t = absOrTerm && typeof absOrTerm === "object" && "shape" in absOrTerm ? absOrTerm.term : absOrTerm;
2724
+ if (t?.op === "var" && ctx.alphaIds.has(t.id)) return t;
2725
+ ctx.freshSeq.n += 1;
2726
+ const id = `T${ctx.freshSeq.n}`;
2727
+ ctx.alphaIds.add(id);
2728
+ return v(id);
2780
2729
  }
2781
- function boolPrim(conf = "partial") {
2782
- return abs({ k: "prim", type: "boolean" }, void 0, void 0, conf);
2730
+ function betaOf(param) {
2731
+ return v(`B:${param}`);
2783
2732
  }
2784
- function evalMathMethod(name, args) {
2785
- const a0 = args[0] ? litValue(args[0]) : void 0;
2786
- const a1 = args[1] ? litValue(args[1]) : void 0;
2787
- switch (name) {
2788
- case "abs":
2789
- if (typeof a0 === "number") return numLit(Math.abs(a0));
2790
- return numPrim();
2791
- case "floor":
2792
- if (typeof a0 === "number") return numLit(Math.floor(a0));
2793
- return numPrim();
2794
- case "ceil":
2795
- if (typeof a0 === "number") return numLit(Math.ceil(a0));
2796
- return numPrim();
2797
- case "round":
2798
- if (typeof a0 === "number") return numLit(Math.round(a0));
2799
- return numPrim();
2800
- case "sqrt":
2801
- if (typeof a0 === "number") return numLit(Math.sqrt(a0));
2802
- return numPrim();
2803
- case "min": {
2804
- const lits = args.map(litValue);
2805
- if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2806
- return numLit(Math.min(...lits));
2733
+ function promoteParamShape(env, param, promotedShape, opts) {
2734
+ const prev = env.vars.get(param);
2735
+ if (!prev) return false;
2736
+ if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return false;
2737
+ const next = {
2738
+ shape: promotedShape,
2739
+ term: prev.term,
2740
+ pred: prev.pred,
2741
+ conf: "path"
2742
+ };
2743
+ env.vars.set(param, next);
2744
+ const hc = env.hofCollect;
2745
+ if (hc && hc.paramNames.has(param)) {
2746
+ if (promotedShape.k === "fn") {
2747
+ if (!hc.fnRels.has(param) && !hc.entryShapes.has(param)) {
2748
+ hc.fnRels.set(param, { abs: { ...next }, source: "promote" });
2807
2749
  }
2808
- return numPrim();
2809
- }
2810
- case "max": {
2811
- const lits = args.map(litValue);
2812
- if (lits.length > 0 && lits.every((x) => typeof x === "number")) {
2813
- return numLit(Math.max(...lits));
2750
+ } else {
2751
+ if (!hc.fnRels.has(param) && !hc.entryShapes.has(param)) {
2752
+ hc.entryShapes.set(param, { abs: { ...next }, source: "promote" });
2814
2753
  }
2815
- return numPrim();
2816
2754
  }
2817
- case "pow":
2818
- if (typeof a0 === "number" && typeof a1 === "number") return numLit(Math.pow(a0, a1));
2819
- return numPrim();
2820
- case "sign":
2821
- if (typeof a0 === "number") return numLit(Math.sign(a0));
2822
- return numPrim();
2823
- default:
2824
- return void 0;
2755
+ if (opts?.recordSite !== false && promotedShape.k === "fn") {
2756
+ const result = promotedShape.returnType ?? next;
2757
+ hc.sites.push({
2758
+ param,
2759
+ argTerms: [],
2760
+ result,
2761
+ loc: opts?.loc
2762
+ });
2763
+ }
2825
2764
  }
2765
+ return true;
2826
2766
  }
2827
- function evalObjectMethod(name, args) {
2828
- const a0 = args[0];
2829
- switch (name) {
2830
- case "keys": {
2831
- if (a0?.shape.k === "obj") {
2832
- const keys = Object.keys(a0.shape.slots).map(
2833
- (k) => strLit(k)
2834
- );
2835
- return abs({ k: "tuple", elements: keys }, void 0, void 0, "exact");
2836
- }
2837
- return abs({ k: "arr", element: strPrim("path") }, void 0, void 0, "partial");
2767
+ var HOF_ARR_METHODS = /* @__PURE__ */ new Set(["map", "filter", "reduce", "flatMap"]);
2768
+ function promoteParamAsArr(env, name, loc) {
2769
+ const hc = env.hofCollect;
2770
+ if (!hc || !hc.paramNames.has(name)) return void 0;
2771
+ const prev = env.vars.get(name);
2772
+ if (!prev) return void 0;
2773
+ if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return void 0;
2774
+ const element = prev.term ? abs(prev.shape, prev.term, prev.pred, "path") : abs({ k: "any" }, void 0, void 0, "path");
2775
+ const arrShape = { k: "arr", element };
2776
+ promoteParamShape(env, name, arrShape, { loc });
2777
+ return env.vars.get(name);
2778
+ }
2779
+ function tryPromoteReceiverAsArr(env, receiverName, method, loc) {
2780
+ if (!HOF_ARR_METHODS.has(method)) return void 0;
2781
+ return promoteParamAsArr(env, receiverName, loc);
2782
+ }
2783
+ function tryPromoteForOfIteratee(env, iterateeName, loc) {
2784
+ return promoteParamAsArr(env, iterateeName, loc);
2785
+ }
2786
+ function tryPromoteDirectCall(env, calleeName, args, loc) {
2787
+ const hc = env.hofCollect;
2788
+ if (!hc || !hc.paramNames.has(calleeName)) return void 0;
2789
+ const prev = env.vars.get(calleeName);
2790
+ if (!prev) return void 0;
2791
+ if (prev.shape.k !== "any" && prev.shape.k !== "unknown") {
2792
+ if (prev.shape.k === "fn") {
2793
+ hc.sites.push({
2794
+ param: calleeName,
2795
+ argTerms: args.map((a) => a.term ?? { op: "var", id: "_" }),
2796
+ result: prev.shape.returnType ?? prev,
2797
+ loc
2798
+ });
2838
2799
  }
2839
- case "values": {
2840
- if (a0?.shape.k === "obj") {
2841
- const slots = a0.shape.slots;
2842
- const vals = Object.values(slots).map((s) => s.value);
2843
- return abs({ k: "tuple", elements: vals }, void 0, void 0, "exact");
2800
+ return void 0;
2801
+ }
2802
+ const paramTypes = args.map(
2803
+ (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2804
+ );
2805
+ const ret = abs({ k: "any" }, betaOf(calleeName), void 0, "path");
2806
+ const fnShape = {
2807
+ k: "fn",
2808
+ params: args.map((_, i) => `x${i}`),
2809
+ paramTypes,
2810
+ returnType: ret
2811
+ };
2812
+ promoteParamShape(env, calleeName, fnShape, { loc, recordSite: false });
2813
+ hc.sites.push({
2814
+ param: calleeName,
2815
+ argTerms: args.map((a) => a.term ?? { op: "var", id: "_" }),
2816
+ result: ret,
2817
+ loc
2818
+ });
2819
+ return env.vars.get(calleeName);
2820
+ }
2821
+ function tryPromoteHofCallback(env, cbName, method, argAbses, loc) {
2822
+ const hc = env.hofCollect;
2823
+ if (!hc || !hc.paramNames.has(cbName)) return void 0;
2824
+ const prev = env.vars.get(cbName);
2825
+ if (!prev) return void 0;
2826
+ if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return void 0;
2827
+ let paramTypes;
2828
+ let returnType;
2829
+ if (method === "filter") {
2830
+ paramTypes = argAbses.map(
2831
+ (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2832
+ );
2833
+ returnType = abs({ k: "prim", type: "boolean" }, void 0, void 0, "path");
2834
+ } else if (method === "reduce") {
2835
+ paramTypes = argAbses.map(
2836
+ (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2837
+ );
2838
+ returnType = abs({ k: "any" }, betaOf(cbName), void 0, "path");
2839
+ } else {
2840
+ paramTypes = argAbses.map(
2841
+ (a) => abs({ k: "any" }, alphaOf(a, hc), void 0, "path")
2842
+ );
2843
+ returnType = abs({ k: "any" }, betaOf(cbName), void 0, "path");
2844
+ }
2845
+ const fnShape = {
2846
+ k: "fn",
2847
+ params: argAbses.map((_, i) => `x${i}`),
2848
+ paramTypes,
2849
+ returnType
2850
+ };
2851
+ promoteParamShape(env, cbName, fnShape, { loc, recordSite: false });
2852
+ hc.sites.push({
2853
+ param: cbName,
2854
+ argTerms: argAbses.map((a) => a.term ?? { op: "var", id: "_" }),
2855
+ result: returnType,
2856
+ loc
2857
+ });
2858
+ return env.vars.get(cbName);
2859
+ }
2860
+ function snapshotAbs(a) {
2861
+ const shape = a.shape;
2862
+ const copyShape = (s) => {
2863
+ switch (s.k) {
2864
+ case "arr":
2865
+ return { ...s, element: snapshotAbs(s.element) };
2866
+ case "tuple": {
2867
+ const next = {
2868
+ k: "tuple",
2869
+ elements: s.elements.map(snapshotAbs)
2870
+ };
2871
+ if (s.rest) next.rest = snapshotAbs(s.rest);
2872
+ return next;
2844
2873
  }
2845
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2846
- }
2847
- case "entries": {
2848
- if (a0?.shape.k === "obj") {
2849
- const slots = a0.shape.slots;
2850
- const entries = Object.entries(slots).map(
2851
- ([, s]) => abs({ k: "tuple", elements: [strPrim("exact"), s.value] }, void 0, void 0, "exact")
2852
- );
2853
- return abs({ k: "tuple", elements: entries }, void 0, void 0, "exact");
2874
+ case "fn": {
2875
+ const next = { k: "fn", params: [...s.params] };
2876
+ if (s.name !== void 0) next.name = s.name;
2877
+ if (s.paramTypes) next.paramTypes = s.paramTypes.map(snapshotAbs);
2878
+ if (s.returnType) next.returnType = snapshotAbs(s.returnType);
2879
+ return next;
2854
2880
  }
2855
- return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
2856
- }
2857
- case "assign": {
2858
- if (!args.length) return unknown;
2859
- let acc = args[0];
2860
- for (let i = 1; i < args.length; i++) {
2861
- acc = { ...acc };
2862
- if (acc.shape.k === "obj" && args[i].shape.k === "obj") {
2863
- const base = acc.shape.slots;
2864
- const over = args[i].shape.slots;
2865
- acc = abs({ k: "obj", slots: { ...base, ...over } }, void 0, void 0, confJoin(acc.conf, args[i].conf));
2881
+ case "sum":
2882
+ return { ...s, members: s.members.map(snapshotAbs) };
2883
+ case "obj": {
2884
+ const slots = {};
2885
+ for (const [k, slot] of Object.entries(s.slots)) {
2886
+ const nextSlot = { value: snapshotAbs(slot.value) };
2887
+ if (slot.optional) nextSlot.optional = true;
2888
+ if (slot.readonly) nextSlot.readonly = true;
2889
+ slots[k] = nextSlot;
2890
+ }
2891
+ const next = { k: "obj", slots };
2892
+ if (s.index) {
2893
+ next.index = {
2894
+ key: snapshotAbs(s.index.key),
2895
+ value: snapshotAbs(s.index.value)
2896
+ };
2866
2897
  }
2898
+ if (s.open) next.open = true;
2899
+ return next;
2867
2900
  }
2868
- return acc;
2901
+ case "brand":
2902
+ return { ...s, shape: snapshotAbs(s.shape) };
2903
+ case "eff":
2904
+ return { ...s, inner: snapshotAbs(s.inner) };
2905
+ default:
2906
+ return s;
2869
2907
  }
2870
- default:
2871
- return void 0;
2872
- }
2908
+ };
2909
+ return {
2910
+ shape: copyShape(shape),
2911
+ term: a.term,
2912
+ pred: a.pred,
2913
+ conf: a.conf
2914
+ };
2873
2915
  }
2874
- function evalJsonMethod(name, args) {
2875
- if (name === "stringify") return strPrim("partial");
2876
- if (name === "parse") return unknown;
2877
- return void 0;
2916
+ function isRelFn(a) {
2917
+ if (!a || typeof a !== "object") return false;
2918
+ if (getFnImpl(a)) return false;
2919
+ const s = a.shape;
2920
+ if (!s || s.k !== "fn") return false;
2921
+ if (s.returnType === void 0) return false;
2922
+ if (s.paramTypes === void 0) return s.params.length === 0;
2923
+ return s.paramTypes.length === s.params.length;
2878
2924
  }
2879
- function evalNumberStatic(name, args) {
2880
- const a0 = args[0] ? litValue(args[0]) : void 0;
2881
- switch (name) {
2882
- case "isInteger":
2883
- if (typeof a0 === "number") return boolLit(Number.isInteger(a0));
2884
- return boolPrim();
2885
- case "isNaN":
2886
- if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2887
- return boolPrim();
2888
- case "isFinite":
2889
- if (typeof a0 === "number") return boolLit(Number.isFinite(a0));
2890
- return boolPrim();
2891
- case "parseInt":
2892
- case "parseFloat":
2893
- if (typeof a0 === "string" || typeof a0 === "number") {
2894
- const n = name === "parseInt" ? parseInt(String(a0), 10) : parseFloat(String(a0));
2895
- return numLit(n);
2896
- }
2897
- return numPrim();
2898
- case "MAX_SAFE_INTEGER":
2899
- return numLit(Number.MAX_SAFE_INTEGER);
2900
- default:
2901
- return void 0;
2902
- }
2925
+ function litOfTerm(t) {
2926
+ return t.op === "lit" ? t.value : void 0;
2903
2927
  }
2904
- function evalGlobalFn(name, args) {
2905
- const a0 = args[0] ? litValue(args[0]) : void 0;
2906
- switch (name) {
2907
- case "parseInt":
2908
- if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseInt(String(a0), 10));
2909
- return numPrim();
2910
- case "parseFloat":
2911
- if (typeof a0 === "string" || typeof a0 === "number") return numLit(parseFloat(String(a0)));
2912
- return numPrim();
2913
- case "isNaN":
2914
- if (typeof a0 === "number") return boolLit(Number.isNaN(a0));
2915
- return boolPrim();
2916
- case "Number":
2917
- if (typeof a0 === "number") return numLit(a0);
2918
- if (typeof a0 === "string") return numLit(Number(a0));
2919
- if (typeof a0 === "boolean") return numLit(a0 ? 1 : 0);
2920
- return numPrim();
2921
- case "String":
2922
- if (a0 !== void 0) return strLit(String(a0));
2923
- return strPrim();
2924
- case "Boolean":
2925
- if (a0 !== void 0) return boolLit(Boolean(a0));
2926
- return boolPrim();
2928
+ function foldCompare(op, a, b) {
2929
+ if (a === void 0 || b === void 0) return void 0;
2930
+ if (typeof a !== typeof b) {
2931
+ if (op === "eq") return pFalse;
2932
+ if (op === "ne") return pTrue;
2933
+ return void 0;
2934
+ }
2935
+ switch (op) {
2936
+ case "eq":
2937
+ return a === b ? pTrue : pFalse;
2938
+ case "ne":
2939
+ return a !== b ? pTrue : pFalse;
2940
+ case "lt":
2941
+ return a < b ? pTrue : pFalse;
2942
+ case "le":
2943
+ return a <= b ? pTrue : pFalse;
2944
+ case "gt":
2945
+ return a > b ? pTrue : pFalse;
2946
+ case "ge":
2947
+ return a >= b ? pTrue : pFalse;
2927
2948
  default:
2928
2949
  return void 0;
2929
2950
  }
2930
2951
  }
2931
- function evalArrayStatic(name, args) {
2932
- const a0 = args[0];
2933
- switch (name) {
2934
- case "isArray": {
2935
- if (!a0) return boolLit(false);
2936
- const k = a0.shape.k;
2937
- return boolLit(k === "arr" || k === "tuple");
2952
+ function predUsesMappedVars(p, map) {
2953
+ const walkTerm = (t) => {
2954
+ if (t.op === "var") return map.has(t.id);
2955
+ if (t.op === "app") return t.args.some(walkTerm);
2956
+ return false;
2957
+ };
2958
+ const walk = (q) => {
2959
+ switch (q.op) {
2960
+ case "true":
2961
+ case "false":
2962
+ return false;
2963
+ case "eq":
2964
+ case "ne":
2965
+ case "lt":
2966
+ case "le":
2967
+ case "gt":
2968
+ case "ge":
2969
+ return walkTerm(q.a) || walkTerm(q.b);
2970
+ case "and":
2971
+ case "or":
2972
+ return q.args.some(walk);
2973
+ case "not":
2974
+ return walk(q.arg);
2975
+ case "typeof":
2976
+ return walkTerm(q.t);
2977
+ }
2978
+ };
2979
+ return walk(p);
2980
+ }
2981
+ function mapHasShapeOnlyVar(p, map) {
2982
+ const walkTerm = (t) => {
2983
+ if (t.op === "var") {
2984
+ const arg = map.get(t.id);
2985
+ return !!arg && arg.term === void 0;
2986
+ }
2987
+ if (t.op === "app") return t.args.some(walkTerm);
2988
+ return false;
2989
+ };
2990
+ const walk = (q) => {
2991
+ switch (q.op) {
2992
+ case "true":
2993
+ case "false":
2994
+ return false;
2995
+ case "eq":
2996
+ case "ne":
2997
+ case "lt":
2998
+ case "le":
2999
+ case "gt":
3000
+ case "ge":
3001
+ return walkTerm(q.a) || walkTerm(q.b);
3002
+ case "and":
3003
+ case "or":
3004
+ return q.args.some(walk);
3005
+ case "not":
3006
+ return walk(q.arg);
3007
+ case "typeof":
3008
+ return walkTerm(q.t);
3009
+ }
3010
+ };
3011
+ return walk(p);
3012
+ }
3013
+ function substPredAbs(p, map) {
3014
+ if (!predUsesMappedVars(p, map)) return { pred: p, dropped: false };
3015
+ if (mapHasShapeOnlyVar(p, map)) return { pred: pTrue, dropped: true };
3016
+ const substTerm = (t) => {
3017
+ if (t.op === "var") {
3018
+ const arg = map.get(t.id);
3019
+ return arg?.term ?? t;
3020
+ }
3021
+ if (t.op === "app") {
3022
+ return { op: "app", fn: t.fn, args: t.args.map(substTerm) };
3023
+ }
3024
+ return t;
3025
+ };
3026
+ const replaced = substPred(p, substTerm);
3027
+ const fold = (q) => {
3028
+ switch (q.op) {
3029
+ case "true":
3030
+ case "false":
3031
+ return q;
3032
+ case "eq":
3033
+ case "ne":
3034
+ case "lt":
3035
+ case "le":
3036
+ case "gt":
3037
+ case "ge": {
3038
+ const a = litOfTerm(q.a);
3039
+ const b = litOfTerm(q.b);
3040
+ const folded = foldCompare(q.op, a, b);
3041
+ return folded ?? q;
3042
+ }
3043
+ case "and": {
3044
+ const args = q.args.map(fold);
3045
+ if (args.some((x) => x.op === "false")) return pFalse;
3046
+ const rest = args.filter((x) => x.op !== "true");
3047
+ if (rest.length === 0) return pTrue;
3048
+ if (rest.length === 1) return rest[0];
3049
+ return and(...rest);
3050
+ }
3051
+ case "or": {
3052
+ const args = q.args.map(fold);
3053
+ if (args.some((x) => x.op === "true")) return pTrue;
3054
+ const rest = args.filter((x) => x.op !== "false");
3055
+ if (rest.length === 0) return pFalse;
3056
+ if (rest.length === 1) return rest[0];
3057
+ return { op: "or", args: rest };
3058
+ }
3059
+ case "not": {
3060
+ const inner = fold(q.arg);
3061
+ if (inner.op === "true") return pFalse;
3062
+ if (inner.op === "false") return pTrue;
3063
+ return { op: "not", arg: inner };
3064
+ }
3065
+ case "typeof":
3066
+ return q;
2938
3067
  }
2939
- case "from":
2940
- case "of":
2941
- return abs({ k: "arr", element: a0 ?? unknown }, void 0, void 0, "path");
2942
- default:
2943
- return void 0;
2944
- }
2945
- }
2946
- function evalDateCtor(args) {
2947
- return abs(
2948
- { k: "brand", name: "Date", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2949
- void 0,
2950
- void 0,
2951
- "path"
2952
- );
2953
- }
2954
- function evalDateStatic(name, _args) {
2955
- if (name === "now") return numLit(Date.now());
2956
- return void 0;
3068
+ };
3069
+ return { pred: fold(replaced), dropped: false };
2957
3070
  }
2958
- function evalDateMethod(name, _recv, _args) {
2959
- switch (name) {
2960
- case "getTime":
2961
- case "valueOf":
2962
- return numPrim("path");
2963
- case "toISOString":
2964
- case "toString":
2965
- return strPrim("path");
2966
- default:
2967
- return void 0;
3071
+ function substTermAbs(t, map) {
3072
+ if (t.op === "var") {
3073
+ const arg = map.get(t.id);
3074
+ return arg?.term ?? t;
2968
3075
  }
2969
- }
2970
- function evalRegExpCtor(_args) {
2971
- return abs(
2972
- { k: "brand", name: "RegExp", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
2973
- void 0,
2974
- void 0,
2975
- "path"
2976
- );
2977
- }
2978
- function evalRegExpMethod(name, _recv, _args) {
2979
- switch (name) {
2980
- case "test":
2981
- return boolPrim();
2982
- case "exec":
2983
- return unknown;
2984
- default:
2985
- return void 0;
3076
+ if (t.op === "app") {
3077
+ return simplifyTerm({
3078
+ op: "app",
3079
+ fn: t.fn,
3080
+ args: t.args.map((x) => substTermAbs(x, map))
3081
+ });
2986
3082
  }
3083
+ return t;
2987
3084
  }
2988
- function evalPromiseCtor(_args) {
2989
- return abs(
2990
- { k: "eff", eff: "promise", inner: unknown },
2991
- void 0,
2992
- void 0,
2993
- "partial"
2994
- );
2995
- }
2996
- function evalPromiseStatic(name, args) {
2997
- switch (name) {
2998
- case "resolve": {
2999
- const inner = args[0] ?? unknown;
3000
- if (inner.shape.k === "eff" && inner.shape.eff === "promise") return inner;
3001
- return abs({ k: "eff", eff: "promise", inner }, void 0, void 0, "path");
3085
+ function substShape(s, map, cache, visiting) {
3086
+ switch (s.k) {
3087
+ case "never":
3088
+ case "any":
3089
+ case "unknown":
3090
+ case "prim":
3091
+ return s;
3092
+ case "brand":
3093
+ return { ...s, shape: substAbsInner(s.shape, map, cache, visiting) };
3094
+ case "eff":
3095
+ return { ...s, inner: substAbsInner(s.inner, map, cache, visiting) };
3096
+ case "arr":
3097
+ return { ...s, element: substAbsInner(s.element, map, cache, visiting) };
3098
+ case "tuple": {
3099
+ const elements = s.elements.map(
3100
+ (e) => substAbsInner(e, map, cache, visiting)
3101
+ );
3102
+ const next = { k: "tuple", elements };
3103
+ if (s.rest) next.rest = substAbsInner(s.rest, map, cache, visiting);
3104
+ return next;
3002
3105
  }
3003
- case "reject":
3004
- return abs({ k: "eff", eff: "promise", inner: unknown }, void 0, void 0, "partial");
3005
- case "all": {
3006
- const a0 = args[0];
3007
- if (a0?.shape.k === "arr" && a0.shape.element.shape.k === "eff") {
3008
- return abs(
3009
- { k: "eff", eff: "promise", inner: abs({ k: "arr", element: a0.shape.element.shape.inner }, void 0, void 0, "path") },
3010
- void 0,
3011
- void 0,
3012
- "path"
3106
+ case "fn": {
3107
+ const next = { k: "fn", params: s.params };
3108
+ if (s.name !== void 0) next.name = s.name;
3109
+ if (s.paramTypes) {
3110
+ next.paramTypes = s.paramTypes.map(
3111
+ (p) => substAbsInner(p, map, cache, visiting)
3013
3112
  );
3014
3113
  }
3015
- return abs({ k: "eff", eff: "promise", inner: abs({ k: "arr", element: unknown }, void 0, void 0, "partial") }, void 0, void 0, "partial");
3114
+ if (s.returnType !== void 0) {
3115
+ next.returnType = substAbsInner(s.returnType, map, cache, visiting);
3116
+ }
3117
+ return next;
3118
+ }
3119
+ case "sum":
3120
+ return {
3121
+ ...s,
3122
+ members: s.members.map((m) => substAbsInner(m, map, cache, visiting))
3123
+ };
3124
+ case "obj": {
3125
+ const slots = {};
3126
+ for (const [k, slot] of Object.entries(s.slots)) {
3127
+ const nextSlot = { value: substAbsInner(slot.value, map, cache, visiting) };
3128
+ if (slot.optional) nextSlot.optional = true;
3129
+ if (slot.readonly) nextSlot.readonly = true;
3130
+ slots[k] = nextSlot;
3131
+ }
3132
+ const next = { k: "obj", slots };
3133
+ if (s.index) {
3134
+ next.index = {
3135
+ key: substAbsInner(s.index.key, map, cache, visiting),
3136
+ value: substAbsInner(s.index.value, map, cache, visiting)
3137
+ };
3138
+ }
3139
+ if (s.open) next.open = true;
3140
+ return next;
3016
3141
  }
3017
- default:
3018
- return void 0;
3019
3142
  }
3020
3143
  }
3021
- function evalNamespaceCall(ns, method, args) {
3022
- switch (ns) {
3023
- case "Math":
3024
- return evalMathMethod(method, args);
3025
- case "Object":
3026
- return evalObjectMethod(method, args);
3027
- case "JSON":
3028
- return evalJsonMethod(method, args);
3029
- case "Number":
3030
- return evalNumberStatic(method, args);
3031
- case "Array":
3032
- return evalArrayStatic(method, args);
3033
- case "Date":
3034
- return evalDateStatic(method, args);
3035
- case "Promise":
3036
- return evalPromiseStatic(method, args);
3037
- default:
3038
- return void 0;
3144
+ function substAbsInner(a, map, cache, visiting) {
3145
+ if (a.term?.op === "var" && map.has(a.term.id)) {
3146
+ const repl = map.get(a.term.id);
3147
+ return {
3148
+ shape: repl.shape,
3149
+ term: repl.term,
3150
+ pred: repl.pred,
3151
+ conf: confJoin(a.conf, repl.conf)
3152
+ };
3039
3153
  }
3040
- }
3041
- function evalBuiltinNew(className, args) {
3042
- switch (className) {
3043
- case "Date":
3044
- return evalDateCtor(args);
3045
- case "RegExp":
3046
- return evalRegExpCtor(args);
3047
- case "Promise":
3048
- return evalPromiseCtor(args);
3049
- case "Map":
3050
- return abs(
3051
- { k: "brand", name: "Map", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
3052
- void 0,
3053
- void 0,
3054
- "path"
3055
- );
3056
- case "Set":
3057
- return abs(
3058
- { k: "brand", name: "Set", shape: abs({ k: "obj", slots: {} }, void 0, void 0, "exact") },
3059
- void 0,
3060
- void 0,
3061
- "path"
3062
- );
3063
- default:
3064
- return void 0;
3154
+ const hit = cache.get(a);
3155
+ if (hit !== void 0) return hit;
3156
+ if (visiting.has(a)) return a;
3157
+ visiting.add(a);
3158
+ const shape = substShape(a.shape, map, cache, visiting);
3159
+ const term = a.term ? substTermAbs(a.term, map) : void 0;
3160
+ let pred = a.pred;
3161
+ let conf = a.conf;
3162
+ if (a.pred) {
3163
+ const r = substPredAbs(a.pred, map);
3164
+ pred = r.pred;
3165
+ if (r.dropped) conf = confJoin(conf, "partial");
3065
3166
  }
3167
+ visiting.delete(a);
3168
+ const result = abs(shape, term, pred, conf);
3169
+ cache.set(a, result);
3170
+ return result;
3066
3171
  }
3067
- function evalBuiltinInstanceMethod(brandName, method, recv, args) {
3068
- if (brandName === "Date") return evalDateMethod(method, recv, args);
3069
- if (brandName === "RegExp") return evalRegExpMethod(method, recv, args);
3070
- if (brandName === "Map") {
3071
- switch (method) {
3072
- case "get":
3073
- return unknown;
3074
- case "has":
3075
- return boolPrim();
3076
- case "set":
3077
- return recv;
3078
- case "size":
3079
- return numPrim("path");
3080
- default:
3081
- return void 0;
3172
+ function substAbs(a, map) {
3173
+ if (map.size === 0) return a;
3174
+ return substAbsInner(a, map, /* @__PURE__ */ new Map(), /* @__PURE__ */ new Set());
3175
+ }
3176
+ function instantiateReturn(fn, args) {
3177
+ const shape = fn.shape;
3178
+ if (!shape || shape.k !== "fn") return unknown;
3179
+ const src = getFnImpl(fn)?.relation ?? {
3180
+ paramTypes: shape.paramTypes ?? [],
3181
+ returnType: shape.returnType ?? unknown
3182
+ };
3183
+ const map = /* @__PURE__ */ new Map();
3184
+ src.paramTypes.forEach((p, i) => {
3185
+ if (p.term?.op !== "var") return;
3186
+ const id = p.term.id;
3187
+ if (map.has(id)) return;
3188
+ map.set(id, args[i] ?? unknown);
3189
+ });
3190
+ return substAbs(src.returnType, map);
3191
+ }
3192
+ var applyCallbackHost;
3193
+ function setApplyCallbackHost(fn) {
3194
+ applyCallbackHost = fn;
3195
+ }
3196
+ function applyCallbackAbs(cb, args, env, phi2, budget) {
3197
+ if (!applyCallbackHost) {
3198
+ if (cb && typeof cb === "object" && "shape" in cb) {
3199
+ const a = cb;
3200
+ const impl = getFnImpl(a);
3201
+ if (impl?.relation) return instantiateReturn(a, args);
3202
+ if (isRelFn(a)) return instantiateReturn(a, args);
3082
3203
  }
3204
+ return unknown;
3083
3205
  }
3084
- if (brandName === "Set") {
3085
- switch (method) {
3086
- case "has":
3087
- return boolPrim();
3088
- case "add":
3089
- return recv;
3090
- case "size":
3091
- return numPrim("path");
3092
- default:
3093
- return void 0;
3094
- }
3206
+ return applyCallbackHost(cb, args, env, phi2, budget);
3207
+ }
3208
+ function undefAbs() {
3209
+ return abs(
3210
+ { k: "unknown" },
3211
+ { op: "lit", value: void 0 },
3212
+ pTrue,
3213
+ "exact"
3214
+ );
3215
+ }
3216
+ function mapElementFallback(cbAbs, elem, out) {
3217
+ if (out.shape.k !== "unknown" || elem.term?.op !== "var") return out;
3218
+ const slot = cbAbs?.shape.k === "fn" ? cbAbs.shape.returnType : void 0;
3219
+ return slot ?? out;
3220
+ }
3221
+ function projectFlatMapResult(arrConf, mapped) {
3222
+ const flatEls = [];
3223
+ let anyUnknown = false;
3224
+ for (const m of mapped) {
3225
+ if (m.shape.k === "arr") flatEls.push(m.shape.element);
3226
+ else if (m.shape.k === "tuple") flatEls.push(...m.shape.elements);
3227
+ else anyUnknown = true;
3095
3228
  }
3229
+ if (anyUnknown || flatEls.length === 0) return unknown;
3230
+ const first = flatEls[0];
3231
+ const sameIdentity = flatEls.every((e) => {
3232
+ if (e.shape.k !== first.shape.k) return false;
3233
+ if (!e.term && !first.term) return true;
3234
+ if (!e.term || !first.term) return false;
3235
+ return termToString(e.term) === termToString(first.term);
3236
+ });
3237
+ const el = sameIdentity ? first : flatEls.reduce((a, b) => joinAbs(a, b));
3238
+ return abs(
3239
+ { k: "arr", element: el },
3240
+ void 0,
3241
+ void 0,
3242
+ confJoin(arrConf, "path")
3243
+ );
3244
+ }
3245
+ function asAbs(v2) {
3246
+ if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
3096
3247
  return void 0;
3097
3248
  }
3098
3249
 
@@ -3109,29 +3260,6 @@ function numPrim2(conf = "path") {
3109
3260
  function strArr(conf = "path") {
3110
3261
  return abs({ k: "arr", element: strPrim2("path") }, void 0, void 0, conf);
3111
3262
  }
3112
- function knownPrefix(parts) {
3113
- let s = "";
3114
- for (const p of parts) {
3115
- if (p.term?.op === "lit" && typeof p.term.value === "string") s += p.term.value;
3116
- else break;
3117
- }
3118
- return s;
3119
- }
3120
- function knownSuffix(parts) {
3121
- let s = "";
3122
- for (let i = parts.length - 1; i >= 0; i--) {
3123
- const p = parts[i];
3124
- if (p.term?.op === "lit" && typeof p.term.value === "string") s = p.term.value + s;
3125
- else break;
3126
- }
3127
- return s;
3128
- }
3129
- function fixedLength(parts) {
3130
- if (parts.some((p) => !(p.term?.op === "lit" && typeof p.term.value === "string"))) {
3131
- return void 0;
3132
- }
3133
- return parts.reduce((n, p) => n + String(p.term && p.term.op === "lit" ? p.term.value : "").length, 0);
3134
- }
3135
3263
  function isStrRecv(recv) {
3136
3264
  return isTemplateLike(recv) || recv.shape.k === "prim" && recv.shape.type === "string" || recv.term?.op === "lit" && typeof recv.term.value === "string";
3137
3265
  }
@@ -3140,27 +3268,24 @@ function callAbsMethod(recv, name, args) {
3140
3268
  const a0 = args[0] ? litValue(args[0]) : void 0;
3141
3269
  const lit3 = recv.term?.op === "lit" && typeof recv.term.value === "string" ? recv.term.value : void 0;
3142
3270
  if (isTemplateLike(recv)) {
3143
- const parts = templatePartsOf(recv);
3144
- const prefix = knownPrefix(parts);
3145
- const suffix = knownSuffix(parts);
3271
+ const views = absTemplateViews(templatePartsOf(recv));
3272
+ const prefix = knownPrefixOfViews(views);
3273
+ const suffix = knownSuffixOfViews(views);
3146
3274
  switch (name) {
3147
3275
  case "startsWith": {
3148
3276
  if (typeof a0 !== "string") return boolPrim2();
3149
- if (prefix.length >= a0.length) return boolLit(prefix.startsWith(a0));
3150
- if (a0.startsWith(prefix)) return boolPrim2();
3151
- return boolLit(false);
3277
+ const d = decideStartsWith(prefix, a0);
3278
+ return d === "unknown" ? boolPrim2() : boolLit(d);
3152
3279
  }
3153
3280
  case "endsWith": {
3154
3281
  if (typeof a0 !== "string") return boolPrim2();
3155
- if (suffix.length >= a0.length) return boolLit(suffix.endsWith(a0));
3156
- if (a0.startsWith(prefix)) return boolPrim2();
3157
- return boolLit(false);
3282
+ const d = decideEndsWith(suffix, a0);
3283
+ return d === "unknown" ? boolPrim2() : boolLit(d);
3158
3284
  }
3159
3285
  case "includes": {
3160
3286
  if (typeof a0 !== "string") return boolPrim2();
3161
- const fixed = parts.filter((p) => p.term?.op === "lit" && typeof p.term.value === "string").map((p) => String(p.term && p.term.op === "lit" ? p.term.value : "")).join("");
3162
- if (fixed.includes(a0)) return boolLit(true);
3163
- return boolPrim2();
3287
+ const d = decideIncludes(allFixedTextOfViews(views), a0);
3288
+ return d === "unknown" ? boolPrim2() : boolLit(d);
3164
3289
  }
3165
3290
  case "toUpperCase":
3166
3291
  case "toLowerCase":
@@ -3246,8 +3371,7 @@ function callAbsMethod(recv, name, args) {
3246
3371
  function getAbsProperty(recv, name) {
3247
3372
  if (name === "length") {
3248
3373
  if (isTemplateLike(recv)) {
3249
- const parts = templatePartsOf(recv);
3250
- const n = fixedLength(parts);
3374
+ const n = fixedLengthOfViews(absTemplateViews(templatePartsOf(recv)));
3251
3375
  if (n !== void 0) return numLit(n);
3252
3376
  return numPrim2("path");
3253
3377
  }
@@ -3563,9 +3687,18 @@ function recordAbsNode(node, value) {
3563
3687
  }
3564
3688
  }
3565
3689
  var absAssignCollector = null;
3690
+ var assignFlowDepth = 0;
3566
3691
  function setAbsAssignCollector(collector) {
3567
3692
  absAssignCollector = collector;
3568
3693
  }
3694
+ function evalInConditionalFlow(body) {
3695
+ assignFlowDepth++;
3696
+ try {
3697
+ return body();
3698
+ } finally {
3699
+ assignFlowDepth--;
3700
+ }
3701
+ }
3569
3702
  function recordAbsAssign(name, prev, next, loc) {
3570
3703
  if (!absAssignCollector) return;
3571
3704
  try {
@@ -3574,7 +3707,8 @@ function recordAbsAssign(name, prev, next, loc) {
3574
3707
  prev,
3575
3708
  next,
3576
3709
  line: loc?.start.line,
3577
- column: loc?.start.column
3710
+ column: loc?.start.column,
3711
+ conditional: assignFlowDepth > 0
3578
3712
  });
3579
3713
  } catch {
3580
3714
  }
@@ -3952,14 +4086,14 @@ function evalNodeInner(node, env, phi2, budget) {
3952
4086
  }
3953
4087
  if (!m.computed && m.property.type === "Identifier" && obj2.shape.k === "obj") {
3954
4088
  const key = m.property.name;
3955
- const slot = obj2.shape.slots[key];
4089
+ const slot = getSlot(obj2.shape.slots, key);
3956
4090
  if (slot) return ok2(slot.value, phi2, env);
3957
4091
  }
3958
4092
  if (m.computed) {
3959
4093
  const key = evalNode(m.property, env, phi2, budget).value;
3960
4094
  const kl = litValue(key);
3961
4095
  if (typeof kl === "string" && obj2.shape.k === "obj") {
3962
- const slot = obj2.shape.slots[kl];
4096
+ const slot = getSlot(obj2.shape.slots, kl);
3963
4097
  if (slot) return ok2(slot.value, phi2, env);
3964
4098
  }
3965
4099
  if (typeof kl === "number") {
@@ -4011,11 +4145,11 @@ function evalNodeInner(node, env, phi2, budget) {
4011
4145
  if (els.length === 0) {
4012
4146
  return ok2(abs({ k: "arr", element: unknown }, void 0, void 0, "exact"), phi2, env);
4013
4147
  }
4014
- if (els.length <= 8) {
4148
+ if (!shouldWidenArrayLiteral(els.length)) {
4015
4149
  return ok2(abs({ k: "tuple", elements: els }, void 0, void 0, "exact"), phi2, env);
4016
4150
  }
4017
4151
  const elem = els.reduce((x, y) => joinAbs(x, y));
4018
- return ok2(abs({ k: "arr", element: elem }, void 0, void 0, "path"), phi2, env);
4152
+ return ok2(abs({ k: "arr", element: elem }, void 0, void 0, widenedArrayConf()), phi2, env);
4019
4153
  }
4020
4154
  default:
4021
4155
  return ok2(unknown, phi2, env);
@@ -4535,7 +4669,7 @@ function evalFor(node, env, phi2, budget) {
4535
4669
  const lv = litValue(t.value);
4536
4670
  if (lv === false || lv === null || lv === void 0) break;
4537
4671
  }
4538
- const bodyR = evalNode(node.body, local, phi2, budget);
4672
+ const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
4539
4673
  if (bodyR.returned) return bodyR;
4540
4674
  if (bodyR.threw) return bodyR;
4541
4675
  if (bodyR.brk) {
@@ -4558,7 +4692,7 @@ function evalWhile(node, env, phi2, budget) {
4558
4692
  const t = evalNode(node.test, local, phi2, budget);
4559
4693
  const lv = litValue(t.value);
4560
4694
  if (lv === false || lv === null || lv === void 0) break;
4561
- const bodyR = evalNode(node.body, local, phi2, budget);
4695
+ const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
4562
4696
  if (bodyR.returned || bodyR.threw) return bodyR;
4563
4697
  if (bodyR.brk) {
4564
4698
  local = bodyR.env;
@@ -4573,7 +4707,7 @@ function evalDoWhile(node, env, phi2, budget) {
4573
4707
  let local = env;
4574
4708
  let acc = unknown;
4575
4709
  for (let i = 0; i < MAX_LOOP_ITERS; i++) {
4576
- const bodyR = evalNode(node.body, local, phi2, budget);
4710
+ const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
4577
4711
  if (bodyR.returned || bodyR.threw) return bodyR;
4578
4712
  if (bodyR.brk) {
4579
4713
  local = bodyR.env;
@@ -4610,7 +4744,7 @@ function evalForOf(node, env, phi2, budget) {
4610
4744
  const n = Math.min(elements.length, MAX_LOOP_ITERS);
4611
4745
  for (let i = 0; i < n; i++) {
4612
4746
  local = withVar(local, bindName, elements[i]);
4613
- const bodyR = evalNode(node.body, local, phi2, budget);
4747
+ const bodyR = evalInConditionalFlow(() => evalNode(node.body, local, phi2, budget));
4614
4748
  if (bodyR.returned || bodyR.threw) return bodyR;
4615
4749
  if (bodyR.brk) {
4616
4750
  local = bodyR.env;
@@ -4661,6 +4795,7 @@ function evalVarDecl(node, env, phi2, budget) {
4661
4795
  for (const d of node.declarations) {
4662
4796
  if (d.id.type !== "Identifier" || !d.init) continue;
4663
4797
  const r = evalNode(d.init, local, phi2, budget);
4798
+ recordAbsNode(d.id, r.value);
4664
4799
  local = withVar(local, d.id.name, r.value);
4665
4800
  }
4666
4801
  return { value: unknown, phi: phi2, env: local };
@@ -4668,8 +4803,15 @@ function evalVarDecl(node, env, phi2, budget) {
4668
4803
  function evalIf(node, env, phi2, budget) {
4669
4804
  const t = evalNode(node.test, env, phi2, budget).value;
4670
4805
  const tv = litValue(t);
4806
+ const refineEnv = (branch) => {
4807
+ const m = matchRelIdentLit(node.test);
4808
+ if (!m || branch !== "true") return env;
4809
+ const cur = env.vars.get(m.name);
4810
+ if (!cur) return env;
4811
+ return withVar(env, m.name, refineAbsForRelTrue(cur, m.op, m.k));
4812
+ };
4671
4813
  if (tv === true) {
4672
- return evalNode(node.consequent, env, phi2, budget);
4814
+ return evalNode(node.consequent, refineEnv("true"), phi2, budget);
4673
4815
  }
4674
4816
  if (tv === false) {
4675
4817
  if (node.alternate) return evalNode(node.alternate, env, phi2, budget);
@@ -4677,9 +4819,15 @@ function evalIf(node, env, phi2, budget) {
4677
4819
  }
4678
4820
  const tCons = trueConstraint(t);
4679
4821
  const fCons = falseConstraint(t);
4680
- const a = evalNode(node.consequent, env, tCons ? and(phi2, tCons) : phi2, budget);
4681
- if (node.alternate) {
4682
- const b = evalNode(node.alternate, env, fCons ? and(phi2, fCons) : phi2, budget);
4822
+ const envT = refineEnv("true");
4823
+ const a = evalInConditionalFlow(
4824
+ () => evalNode(node.consequent, envT, tCons ? and(phi2, tCons) : phi2, budget)
4825
+ );
4826
+ const alt = node.alternate;
4827
+ if (alt) {
4828
+ const b = evalInConditionalFlow(
4829
+ () => evalNode(alt, env, fCons ? and(phi2, fCons) : phi2, budget)
4830
+ );
4683
4831
  return { value: joinAbs(a.value, b.value), phi: phi2, env, returned: a.returned || b.returned };
4684
4832
  }
4685
4833
  if (a.returned || a.threw) {
@@ -4814,6 +4962,15 @@ function $call(fn, args) {
4814
4962
 
4815
4963
  // src/algebra/exec/calls.ts
4816
4964
  var bCallCollector = null;
4965
+ var GLOBAL_FNS = /* @__PURE__ */ new Set([
4966
+ "parseInt",
4967
+ "parseFloat",
4968
+ "isNaN",
4969
+ "isFinite",
4970
+ "Number",
4971
+ "String",
4972
+ "Boolean"
4973
+ ]);
4817
4974
  function setBCallCollector(collector) {
4818
4975
  bCallCollector = collector;
4819
4976
  }
@@ -4832,7 +4989,8 @@ function $callNamed(name, fn, args, loc, argLocs) {
4832
4989
  if (loc) pushCallLoc({ line: loc[0], column: loc[1] });
4833
4990
  try {
4834
4991
  if (typeof fn === "function") {
4835
- result = fn(...args);
4992
+ const g = GLOBAL_FNS.has(name) && fn === globalThis[name] ? evalGlobalFn(name, args) : void 0;
4993
+ result = g ?? fn(...args);
4836
4994
  } else if (fn && typeof fn === "object" && "shape" in fn) {
4837
4995
  result = $call(fn, args);
4838
4996
  }
@@ -4955,12 +5113,32 @@ function litAbsFromJs(v2) {
4955
5113
  }
4956
5114
  return unknown;
4957
5115
  }
5116
+ function litTruth(a) {
5117
+ if (a.term?.op === "lit") {
5118
+ return Boolean(a.term.value);
5119
+ }
5120
+ switch (a.shape.k) {
5121
+ case "obj":
5122
+ case "arr":
5123
+ case "tuple":
5124
+ case "fn":
5125
+ case "brand":
5126
+ case "eff":
5127
+ return true;
5128
+ case "prim":
5129
+ return a.shape.type === "symbol" || a.shape.type === "bigint" ? true : void 0;
5130
+ case "never":
5131
+ return false;
5132
+ default:
5133
+ return void 0;
5134
+ }
5135
+ }
4958
5136
  function isDefinitelyTrue(a) {
4959
- return litValue(a) === true;
5137
+ return litTruth(a) === true;
4960
5138
  }
4961
5139
  function isDefinitelyFalse(a) {
4962
- const lv = litValue(a);
4963
- if (lv === false) return true;
5140
+ const t = litTruth(a);
5141
+ if (t === false) return true;
4964
5142
  if (a.shape.k === "never") return true;
4965
5143
  return false;
4966
5144
  }
@@ -5013,8 +5191,19 @@ function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
5013
5191
  }
5014
5192
  return exitJoin ? joinAbs(exitJoin, state) : state;
5015
5193
  }
5194
+ function tupleOrWiden(els, conf) {
5195
+ if (shouldWidenArrayLiteral(els.length)) {
5196
+ return abs(
5197
+ { k: "arr", element: els.reduce((x, y) => joinAbs(x, y)) },
5198
+ void 0,
5199
+ void 0,
5200
+ widenedArrayConf()
5201
+ );
5202
+ }
5203
+ return abs({ k: "tuple", elements: els }, void 0, void 0, conf);
5204
+ }
5016
5205
  function $arr(items) {
5017
- return abs({ k: "tuple", elements: items.map(asAbsVal) }, void 0, void 0, "exact");
5206
+ return tupleOrWiden(items.map(asAbsVal), "exact");
5018
5207
  }
5019
5208
  function $idx(a, i) {
5020
5209
  const iv = litValue(i);
@@ -5031,17 +5220,31 @@ function $idx(a, i) {
5031
5220
  if (a.shape.k === "sum") {
5032
5221
  return a.shape.members.map((m) => $idx(m, i)).reduce((x, y) => joinAbs(x, y));
5033
5222
  }
5223
+ const sv = litValue(a);
5224
+ if (typeof sv === "string") {
5225
+ if (typeof iv === "number" && Number.isInteger(iv)) {
5226
+ if (iv >= 0 && iv < sv.length) {
5227
+ return abs(
5228
+ { k: "prim", type: "string" },
5229
+ { op: "lit", value: sv[iv] },
5230
+ pTrue,
5231
+ "exact"
5232
+ );
5233
+ }
5234
+ return undef();
5235
+ }
5236
+ return unknown;
5237
+ }
5034
5238
  return unknown;
5035
5239
  }
5036
5240
  function $idxSet(a, i, value) {
5037
5241
  const iv = litValue(i);
5038
- if (a.shape.k === "tuple" && typeof iv === "number" && Number.isInteger(iv)) {
5242
+ if (a.shape.k === "tuple" && typeof iv === "number" && Number.isInteger(iv) && iv >= 0) {
5039
5243
  const els = [...a.shape.elements];
5040
- if (iv >= 0 && iv < els.length) {
5041
- els[iv] = asAbsVal(value);
5042
- const next = abs({ k: "tuple", elements: els }, void 0, void 0, a.conf);
5043
- return next;
5044
- }
5244
+ while (els.length < iv) els.push(undef());
5245
+ els[iv] = asAbsVal(value);
5246
+ const next = abs({ k: "tuple", elements: els }, void 0, void 0, a.conf);
5247
+ return next;
5045
5248
  }
5046
5249
  return a;
5047
5250
  }
@@ -5057,6 +5260,15 @@ function $len(a) {
5057
5260
  if (a.shape.k === "arr") {
5058
5261
  return abs({ k: "prim", type: "number" }, void 0, void 0, "path");
5059
5262
  }
5263
+ const sv = litValue(a);
5264
+ if (typeof sv === "string") {
5265
+ return abs(
5266
+ { k: "prim", type: "number" },
5267
+ { op: "lit", value: sv.length },
5268
+ pTrue,
5269
+ "exact"
5270
+ );
5271
+ }
5060
5272
  return unknown;
5061
5273
  }
5062
5274
  function $obj(slots) {
@@ -5070,33 +5282,33 @@ function $spread(a, b) {
5070
5282
  function $concat(a, b) {
5071
5283
  a = asAbsVal(a);
5072
5284
  b = asAbsVal(b);
5073
- if (a.shape.k === "tuple" && b.shape.k === "tuple") {
5074
- return abs(
5075
- { k: "tuple", elements: [...a.shape.elements, ...b.shape.elements] },
5076
- void 0,
5077
- void 0,
5078
- confJoin(a.conf, b.conf)
5079
- );
5285
+ const as = a.shape;
5286
+ const bs = b.shape;
5287
+ if (as.k === "tuple" && bs.k === "tuple") {
5288
+ return tupleOrWiden([...as.elements, ...bs.elements], confJoin(a.conf, b.conf));
5289
+ }
5290
+ if (as.k === "arr" || bs.k === "arr") {
5291
+ const ea = as.k === "tuple" ? as.elements.reduce((x, y) => joinAbs(x, y)) : as.k === "arr" ? as.element : a;
5292
+ const eb = bs.k === "tuple" ? bs.elements.reduce((x, y) => joinAbs(x, y)) : bs.k === "arr" ? bs.element : b;
5293
+ return abs({ k: "arr", element: joinAbs(ea, eb) }, void 0, void 0, "path");
5080
5294
  }
5081
- if (a.shape.k === "tuple" && b.shape.k !== "tuple") {
5295
+ if (as.k === "tuple") {
5082
5296
  return abs(
5083
- { k: "tuple", elements: [...a.shape.elements, b] },
5297
+ { k: "tuple", elements: [...as.elements, b] },
5084
5298
  void 0,
5085
5299
  void 0,
5086
5300
  confJoin(a.conf, b.conf)
5087
5301
  );
5088
5302
  }
5089
- if (a.shape.k !== "tuple" && b.shape.k === "tuple") {
5303
+ if (bs.k === "tuple") {
5090
5304
  return abs(
5091
- { k: "tuple", elements: [a, ...b.shape.elements] },
5305
+ { k: "tuple", elements: [a, ...bs.elements] },
5092
5306
  void 0,
5093
5307
  void 0,
5094
5308
  confJoin(a.conf, b.conf)
5095
5309
  );
5096
5310
  }
5097
- const ea = a.shape.k === "arr" ? a.shape.element : a;
5098
- const eb = b.shape.k === "arr" ? b.shape.element : b;
5099
- return abs({ k: "arr", element: joinAbs(ea, eb) }, void 0, void 0, "path");
5311
+ return abs({ k: "arr", element: joinAbs(a, b) }, void 0, void 0, "path");
5100
5312
  }
5101
5313
  function $elems(a) {
5102
5314
  if (a.shape.k === "tuple") return [...a.shape.elements];
@@ -5116,7 +5328,52 @@ function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS) {
5116
5328
  ));
5117
5329
  }
5118
5330
  }
5331
+ function namespaceNameOf(v2) {
5332
+ if (typeof v2 !== "object" && typeof v2 !== "function") return void 0;
5333
+ if (v2 === Math) return "Math";
5334
+ if (v2 === Number) return "Number";
5335
+ if (v2 === JSON) return "JSON";
5336
+ if (v2 === Object) return "Object";
5337
+ if (v2 === Array) return "Array";
5338
+ if (v2 === Date) return "Date";
5339
+ if (v2 === Promise) return "Promise";
5340
+ return void 0;
5341
+ }
5342
+ function $regex(pattern, flags = "") {
5343
+ const litStr = (v2) => abs({ k: "prim", type: "string" }, { op: "lit", value: v2 }, pTrue, "exact");
5344
+ return abs(
5345
+ {
5346
+ k: "brand",
5347
+ name: "RegExp",
5348
+ shape: objOf({
5349
+ source: { value: litStr(pattern) },
5350
+ flags: { value: litStr(flags) }
5351
+ })
5352
+ },
5353
+ void 0,
5354
+ void 0,
5355
+ "exact"
5356
+ );
5357
+ }
5119
5358
  function $get(o, key, opts) {
5359
+ if (!o || typeof o !== "object" || !("shape" in o)) {
5360
+ const ns = namespaceNameOf(o);
5361
+ if (ns) {
5362
+ try {
5363
+ const raw = o[key];
5364
+ if (typeof raw === "function") {
5365
+ return absFunction([`${ns}.${key}`], {
5366
+ body: noBody,
5367
+ apply: (args) => evalNamespaceCall(ns, key, args) ?? unknown
5368
+ });
5369
+ }
5370
+ return $lit(raw);
5371
+ } catch {
5372
+ return unknown;
5373
+ }
5374
+ }
5375
+ return unknown;
5376
+ }
5120
5377
  if (o.shape.k === "brand") return $get(o.shape.shape, key, opts);
5121
5378
  if (isObj(o)) {
5122
5379
  const slot = o.shape.slots[key];
@@ -5302,6 +5559,77 @@ var BIN_OPS = {
5302
5559
  "===": "$eq",
5303
5560
  "!==": "$ne"
5304
5561
  };
5562
+ var COMPOUND_OPS = {
5563
+ "+=": "$add",
5564
+ "-=": "$sub",
5565
+ "*=": "$mul",
5566
+ "/=": "$div",
5567
+ "%=": "$mod"
5568
+ };
5569
+ function memberPathOf(m, opts) {
5570
+ const layers = [];
5571
+ let cur = m;
5572
+ let rootSrc = null;
5573
+ while (cur.type === "MemberExpression") {
5574
+ const mm = cur;
5575
+ const k = mm.property;
5576
+ if (mm.computed) {
5577
+ if (k.type === "NumericLiteral") {
5578
+ const key = `$lit(${k.value})`;
5579
+ layers.unshift({
5580
+ get: (b) => `$idx(${b}, ${key})`,
5581
+ set: (b, v2) => `$idxSet(${b}, ${key}, ${v2})`
5582
+ });
5583
+ } else if (k.type === "StringLiteral") {
5584
+ const key = JSON.stringify(k.value);
5585
+ layers.unshift({
5586
+ get: (b) => `$get(${b}, ${key})`,
5587
+ set: (b, v2) => `$set(${b}, ${key}, ${v2})`
5588
+ });
5589
+ } else if (isExpression(k)) {
5590
+ const key = transpileExpression(k, opts);
5591
+ layers.unshift({
5592
+ get: (b) => `$idx(${b}, ${key})`,
5593
+ set: (b, v2) => `$idxSet(${b}, ${key}, ${v2})`
5594
+ });
5595
+ } else {
5596
+ return null;
5597
+ }
5598
+ } else if (k.type === "Identifier") {
5599
+ const key = JSON.stringify(k.name);
5600
+ layers.unshift({
5601
+ get: (b) => `$get(${b}, ${key})`,
5602
+ set: (b, v2) => `$set(${b}, ${key}, ${v2})`
5603
+ });
5604
+ } else {
5605
+ return null;
5606
+ }
5607
+ cur = mm.object;
5608
+ }
5609
+ if (cur.type === "Identifier") {
5610
+ rootSrc = cur.name;
5611
+ } else if (cur.type === "ThisExpression" && opts.thisParam) {
5612
+ rootSrc = opts.thisParam;
5613
+ } else {
5614
+ return null;
5615
+ }
5616
+ return { rootSrc, layers };
5617
+ }
5618
+ function readPathSrc(p) {
5619
+ return p.layers.reduce((acc, l) => l.get(acc), p.rootSrc);
5620
+ }
5621
+ function setPathSrc(p, valSrc) {
5622
+ let acc = valSrc;
5623
+ for (let i = p.layers.length - 1; i >= 0; i--) {
5624
+ const l = p.layers[i];
5625
+ const base = i === 0 ? p.rootSrc : readPrefix(p, i - 1);
5626
+ acc = l.set(base, acc);
5627
+ }
5628
+ return acc;
5629
+ }
5630
+ function readPrefix(p, j) {
5631
+ return p.layers.slice(0, j + 1).reduce((acc, l) => l.get(acc), p.rootSrc);
5632
+ }
5305
5633
  function transpileSource(source, opts = {}) {
5306
5634
  const file = parseSource(source);
5307
5635
  return transpileFile(file, { ...opts, source: opts.source ?? source });
@@ -5310,7 +5638,7 @@ function transpileFile(file, opts = {}) {
5310
5638
  const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
5311
5639
  const lines = [
5312
5640
  `// nudo B-path transpile \u2014 values are Abs; operators are overloaded calls`,
5313
- `import { $add, $sub, $mul, $div, $mod, $neg, $typeof, $not, $eq, $ne, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $while, $whileSeq, $arr, $idx, $idxSet, $len, $call, $throw, $class, $new, $invoke, $invokeSuper, $super, $async, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal } from ${JSON.stringify(runtime)};`,
5641
+ `import { $add, $sub, $mul, $div, $mod, $neg, $typeof, $not, $eq, $ne, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $while, $whileSeq, $arr, $idx, $idxSet, $len, $call, $throw, $class, $new, $invoke, $invokeSuper, $super, $async, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex } from ${JSON.stringify(runtime)};`,
5314
5642
  ``
5315
5643
  ];
5316
5644
  for (const stmt of file.program.body) {
@@ -5329,34 +5657,24 @@ function stmtReturns(stmt) {
5329
5657
  }
5330
5658
  return false;
5331
5659
  }
5332
- function stmtAlwaysExits(stmt) {
5333
- return stmtReturns(stmt) && stmt.type !== "ExpressionStatement";
5334
- }
5335
- function foldEarlyReturns(stmts) {
5336
- for (let i = stmts.length - 2; i >= 0; i--) {
5660
+ function transpileFnBodyStmts(stmts, depth, opts) {
5661
+ for (let i = 0; i < stmts.length; i++) {
5337
5662
  const stmt = stmts[i];
5338
5663
  if (stmt.type !== "IfStatement" || stmt.alternate != null) continue;
5339
5664
  if (!stmtReturns(stmt.consequent)) continue;
5340
- const tail = stmts.slice(i + 1);
5341
- if (tail.length === 0 || !tail.every(stmtAlwaysExits)) continue;
5342
- const alt = {
5343
- type: "BlockStatement",
5344
- body: tail,
5345
- directives: [],
5346
- start: stmt.consequent.start,
5347
- end: stmt.consequent.end,
5348
- loc: stmt.consequent.loc
5349
- };
5350
- const rewritten = {
5351
- ...stmt,
5352
- alternate: alt
5353
- };
5354
- return foldEarlyReturns([...stmts.slice(0, i), rewritten]);
5355
- }
5356
- return stmts;
5357
- }
5358
- function transpileFnBodyStmts(stmts, depth, opts) {
5359
- return foldEarlyReturns(stmts).map((s) => transpileStatement(s, depth, opts)).join("\n");
5665
+ const rest = stmts.slice(i + 1);
5666
+ if (rest.length === 0) continue;
5667
+ const head = stmts.slice(0, i).map((s) => transpileStatement(s, depth, opts)).join("\n");
5668
+ const test = transpileExpression(stmt.test, opts);
5669
+ const cons = transpileBlockAsThunk(stmt.consequent, depth, opts);
5670
+ const altBody = transpileFnBodyStmts(rest, depth + 1, opts);
5671
+ const promoted = `${indent(depth)}return $fork(${test}, ${cons}, () => {
5672
+ ${altBody}
5673
+ ${indent(depth)}});`;
5674
+ return head ? `${head}
5675
+ ${promoted}` : promoted;
5676
+ }
5677
+ return stmts.map((s) => transpileStatement(s, depth, opts)).join("\n");
5360
5678
  }
5361
5679
  function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
5362
5680
  if (pattern.type === "Identifier") {
@@ -5422,13 +5740,55 @@ function emitDestructure(pattern, fromSrc, kw, pad, opts, out, tmpSeq) {
5422
5740
  });
5423
5741
  }
5424
5742
  }
5743
+ function emitParamBinding(params, pad, opts) {
5744
+ const sig = [];
5745
+ const prologue = [];
5746
+ let rest;
5747
+ params.forEach((p, i) => {
5748
+ if (p.type === "Identifier") {
5749
+ sig.push(p.name);
5750
+ return;
5751
+ }
5752
+ if (p.type === "RestElement") {
5753
+ if (p.argument.type === "Identifier") {
5754
+ rest = p.argument.name;
5755
+ return;
5756
+ }
5757
+ const ph2 = `_rest${i}`;
5758
+ rest = ph2;
5759
+ emitDestructure(p.argument, ph2, "const", pad, opts, prologue, { n: 0 });
5760
+ return;
5761
+ }
5762
+ const ph = `_p${i}`;
5763
+ sig.push(ph);
5764
+ if (p.type === "AssignmentPattern") {
5765
+ const def = transpileExpression(p.right, opts);
5766
+ if (p.left.type === "Identifier") {
5767
+ prologue.push(`${pad}const ${p.left.name} = $orDefault(${ph}, () => ${def});`);
5768
+ } else {
5769
+ const t = `_pd${i}`;
5770
+ prologue.push(`${pad}const ${t} = $orDefault(${ph}, () => ${def});`);
5771
+ emitDestructure(p.left, t, "const", pad, opts, prologue, { n: 0 });
5772
+ }
5773
+ return;
5774
+ }
5775
+ if (p.type === "ObjectPattern" || p.type === "ArrayPattern") {
5776
+ emitDestructure(p, ph, "const", pad, opts, prologue, { n: 0 });
5777
+ }
5778
+ });
5779
+ return { sig, rest, prologue };
5780
+ }
5425
5781
  function transpileStatement(stmt, depth, opts) {
5426
5782
  const pad = indent(depth);
5427
5783
  switch (stmt.type) {
5428
5784
  case "ExportNamedDeclaration": {
5429
5785
  const decl = stmt.declaration;
5430
5786
  if (!decl) return `${pad}/* export specifiers skipped */`;
5431
- return transpileStatement(decl, depth, opts);
5787
+ const inner = transpileStatement(decl, depth, opts);
5788
+ if (depth === 0 && decl.type === "VariableDeclaration" && !pad) {
5789
+ return `export ${inner}`;
5790
+ }
5791
+ return inner;
5432
5792
  }
5433
5793
  case "ImportDeclaration": {
5434
5794
  const specs = stmt.specifiers.map((s) => {
@@ -5455,19 +5815,16 @@ function transpileStatement(stmt, depth, opts) {
5455
5815
  }
5456
5816
  case "FunctionDeclaration": {
5457
5817
  if (!stmt.id) return `${pad}// <anonymous fn skipped>`;
5458
- const paramParts = stmt.params.map((p) => {
5459
- if (p.type === "Identifier") return { kind: "id", name: p.name };
5460
- if (p.type === "RestElement" && p.argument.type === "Identifier") {
5461
- return { kind: "rest", name: p.argument.name };
5462
- }
5463
- return { kind: "id", name: "_" };
5464
- });
5465
- const named = paramParts.filter((p) => p.kind === "id" && p.name !== "_").map((p) => p.name);
5466
- const rest = paramParts.find((p) => p.kind === "rest");
5467
- const paramsSig = rest ? [...named, `...${rest.name}`] : named;
5818
+ const { sig, rest, prologue } = emitParamBinding(
5819
+ stmt.params,
5820
+ indent(depth + 2),
5821
+ opts
5822
+ );
5823
+ const named = sig;
5824
+ const paramsSig = rest ? [...named, `...${rest}`] : named;
5468
5825
  const params = paramsSig.join(", ");
5469
- const bodyStmts = stmt.body.type === "BlockStatement" ? transpileFnBodyStmts(stmt.body.body, depth + 2, opts) : `${indent(depth + 2)}return ${transpileExpression(stmt.body, opts)};`;
5470
- const restBind = rest ? `${indent(depth + 1)}const ${rest.name} = arguments.length > ${named.length} ? $arr(Array.from(arguments).slice(${named.length})) : $arr([]);
5826
+ const bodyStmts = stmt.body.type === "BlockStatement" ? [...prologue, transpileFnBodyStmts(stmt.body.body, depth + 2, opts)].join("\n") : `${indent(depth + 2)}return ${transpileExpression(stmt.body, opts)};`;
5827
+ const restBind = rest ? `${indent(depth + 1)}const ${rest} = arguments.length > ${named.length} ? $arr(Array.from(arguments).slice(${named.length})) : $arr([]);
5471
5828
  ` : "";
5472
5829
  if (stmt.generator) {
5473
5830
  return [
@@ -5509,7 +5866,7 @@ function transpileStatement(stmt, depth, opts) {
5509
5866
  case "ExpressionStatement":
5510
5867
  return `${pad}${transpileExpression(stmt.expression, opts)};`;
5511
5868
  case "VariableDeclaration": {
5512
- const kw = stmt.kind === "const" ? "const" : "let";
5869
+ const kw = "let";
5513
5870
  const asVar = matchAsOverride(stmt, opts);
5514
5871
  const lines = [];
5515
5872
  let tmpSeq = 0;
@@ -5562,7 +5919,7 @@ function transpileStatement(stmt, depth, opts) {
5562
5919
  ].join("\n");
5563
5920
  }
5564
5921
  case "BlockStatement":
5565
- return stmt.body.map((s) => transpileStatement(s, depth, opts)).join("\n");
5922
+ return transpileFnBodyStmts(stmt.body, depth, opts);
5566
5923
  case "SwitchStatement": {
5567
5924
  const disc = transpileExpression(stmt.discriminant, opts);
5568
5925
  const arms = [];
@@ -5822,6 +6179,15 @@ function transpileExpression(expr, opts = {}) {
5822
6179
  const r = transpileExpression(expr.right, opts);
5823
6180
  return op === "&&" ? `$fork(${l}, () => ${r}, () => ${l})` : `$fork(${l}, () => ${l}, () => ${r})`;
5824
6181
  }
6182
+ case "ConditionalExpression": {
6183
+ const test = transpileExpression(expr.test, opts);
6184
+ const c = transpileExpression(expr.consequent, opts);
6185
+ const a = transpileExpression(expr.alternate, opts);
6186
+ return `$fork(${test}, () => ${c}, () => ${a})`;
6187
+ }
6188
+ case "RegExpLiteral": {
6189
+ return `$regex(${JSON.stringify(expr.pattern)}${expr.flags ? `, ${JSON.stringify(expr.flags)}` : ""})`;
6190
+ }
5825
6191
  case "BinaryExpression": {
5826
6192
  const fn = BIN_OPS[expr.operator];
5827
6193
  if (!fn) return `/* unsupported ${expr.operator} */ $lit(undefined)`;
@@ -5837,6 +6203,14 @@ function transpileExpression(expr, opts = {}) {
5837
6203
  if (expr.operator === "+") return arg;
5838
6204
  return `/* unary ${expr.operator} */ $lit(undefined)`;
5839
6205
  }
6206
+ case "UpdateExpression": {
6207
+ const arg = expr.argument;
6208
+ if (arg.type === "Identifier") {
6209
+ const fn = expr.operator === "++" ? "$add" : "$sub";
6210
+ return `${arg.name} = ${fn}(${arg.name}, $lit(1))`;
6211
+ }
6212
+ return `/* update ${expr.operator} */ $lit(undefined)`;
6213
+ }
5840
6214
  case "AwaitExpression": {
5841
6215
  const arg = transpileExpression(expr.argument, opts);
5842
6216
  return `$await(${arg})`;
@@ -5938,19 +6312,23 @@ function transpileExpression(expr, opts = {}) {
5938
6312
  return acc ?? `$arr([])`;
5939
6313
  }
5940
6314
  case "AssignmentExpression": {
5941
- if (expr.operator !== "=") return `/* assign ${expr.operator} */ $lit(undefined)`;
6315
+ const compoundFn = COMPOUND_OPS[expr.operator];
5942
6316
  const right = transpileExpression(expr.right, opts);
5943
6317
  if (expr.left.type === "MemberExpression") {
5944
- if (!expr.left.computed && expr.left.object.type === "ThisExpression" && expr.left.property.type === "Identifier" && opts.thisParam) {
5945
- return `${opts.thisParam} = $set(${opts.thisParam}, ${JSON.stringify(expr.left.property.name)}, ${right})`;
6318
+ const m = expr.left;
6319
+ const path = memberPathOf(m, opts);
6320
+ if (path) {
6321
+ const valSrc = compoundFn ? `${compoundFn}(${readPathSrc(path)}, ${right})` : right;
6322
+ const writeSrc = setPathSrc(path, valSrc);
6323
+ return `${path.rootSrc} = ${writeSrc}`;
5946
6324
  }
5947
- if (!expr.left.computed && expr.left.property.type === "Identifier") {
5948
- const obj2 = transpileExpression(expr.left.object, opts);
5949
- return `$set(${obj2}, ${JSON.stringify(expr.left.property.name)}, ${right})`;
6325
+ if (!m.computed && m.property.type === "Identifier") {
6326
+ const obj2 = transpileExpression(m.object, opts);
6327
+ return `$set(${obj2}, ${JSON.stringify(m.property.name)}, ${right})`;
5950
6328
  }
5951
- if (expr.left.computed) {
5952
- const obj2 = transpileExpression(expr.left.object, opts);
5953
- const k = expr.left.property;
6329
+ if (m.computed) {
6330
+ const obj2 = transpileExpression(m.object, opts);
6331
+ const k = m.property;
5954
6332
  if (k.type === "NumericLiteral") {
5955
6333
  return `$idxSet(${obj2}, $lit(${k.value}), ${right})`;
5956
6334
  }
@@ -5961,11 +6339,15 @@ function transpileExpression(expr, opts = {}) {
5961
6339
  return `$idxSet(${obj2}, ${transpileExpression(k, opts)}, ${right})`;
5962
6340
  }
5963
6341
  }
6342
+ return `/* assign */ $lit(undefined)`;
5964
6343
  }
5965
6344
  if (expr.left.type === "Identifier") {
6345
+ if (compoundFn) {
6346
+ return `${expr.left.name} = ${compoundFn}(${expr.left.name}, ${right})`;
6347
+ }
5966
6348
  return `${expr.left.name} = ${right}`;
5967
6349
  }
5968
- return `/* assign */ $lit(undefined)`;
6350
+ return compoundFn ? `/* assign ${expr.operator} */ $lit(undefined)` : `/* assign */ $lit(undefined)`;
5969
6351
  }
5970
6352
  case "CallExpression":
5971
6353
  case "OptionalCallExpression": {
@@ -6020,16 +6402,11 @@ function transpileExpression(expr, opts = {}) {
6020
6402
  case "ArrowFunctionExpression":
6021
6403
  case "FunctionExpression": {
6022
6404
  const fn = expr;
6023
- const paramParts = fn.params.map((p) => {
6024
- if (p.type === "Identifier") return p.name;
6025
- if (p.type === "RestElement" && p.argument?.type === "Identifier") {
6026
- return `...${p.argument.name}`;
6027
- }
6028
- return "_p";
6029
- });
6030
- const nameList = `[${paramParts.map((p) => JSON.stringify(p.startsWith("...") ? p.slice(3) : p)).join(", ")}]`;
6405
+ const { sig, rest, prologue } = emitParamBinding(fn.params, indent(1), opts);
6406
+ const paramParts = rest ? [...sig, `...${rest}`] : sig;
6407
+ const nameList = `[${sig.map((p) => JSON.stringify(p)).join(", ")}]`;
6031
6408
  if (fn.body.type === "BlockStatement") {
6032
- const inner = transpileFnBodyStmts(fn.body.body, 1, opts);
6409
+ const inner = [...prologue, transpileFnBodyStmts(fn.body.body, 1, opts)].join("\n");
6033
6410
  if (fn.async) {
6034
6411
  return `$fnVal(${nameList}, (${paramParts.join(", ")}) => $async(() => {
6035
6412
  ${inner}
@@ -6040,6 +6417,13 @@ ${inner}
6040
6417
  })`;
6041
6418
  }
6042
6419
  const bodySrc = transpileExpression(fn.body, opts);
6420
+ if (prologue.length > 0) {
6421
+ const thunk = fn.async ? `$async(() => ${bodySrc})` : bodySrc;
6422
+ return `$fnVal(${nameList}, (${paramParts.join(", ")}) => {
6423
+ ${prologue.join("\n")}
6424
+ return ${thunk};
6425
+ })`;
6426
+ }
6043
6427
  if (fn.async) {
6044
6428
  return `$fnVal(${nameList}, (${paramParts.join(", ")}) => $async(() => ${bodySrc}))`;
6045
6429
  }
@@ -6128,6 +6512,21 @@ function findCtor(startName) {
6128
6512
  }
6129
6513
  function $new(cls, args) {
6130
6514
  if (typeof cls === "function") {
6515
+ if (cls === Array) {
6516
+ if (args.length === 1) {
6517
+ const n = litValue(args[0]);
6518
+ if (typeof n === "number" && Number.isInteger(n) && n >= 0 && n <= 4096) {
6519
+ const els = Array.from({ length: n }, () => undefAbs());
6520
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
6521
+ }
6522
+ return abs({ k: "arr", element: unknown }, void 0, void 0, "partial");
6523
+ }
6524
+ return abs({ k: "tuple", elements: args.map((a) => asAbs(a) ?? unknown) }, void 0, void 0, "exact");
6525
+ }
6526
+ if (cls === RegExp) {
6527
+ const p = args[0] ? litValue(args[0]) : void 0;
6528
+ if (typeof p === "string") return $regex(p, args[1] ? String(litValue(args[1]) ?? "") : "");
6529
+ }
6131
6530
  const name = cls.name || "Object";
6132
6531
  const shape = objOf({});
6133
6532
  return abs({ k: "brand", name, shape }, void 0, void 0, "path");
@@ -6168,12 +6567,82 @@ function $super(thisVal, childName, args) {
6168
6567
  }
6169
6568
  return after ?? thisVal;
6170
6569
  }
6570
+ function execRegexBrand(re, method, args) {
6571
+ if (re.shape.k !== "brand" || re.shape.name !== "RegExp") return void 0;
6572
+ if (method !== "exec" && method !== "test" && method !== "toString") return void 0;
6573
+ const inner = re.shape.shape;
6574
+ const patAbs = inner.shape.k === "obj" ? inner.shape.slots["source"]?.value : void 0;
6575
+ const flagsAbs = inner.shape.k === "obj" ? inner.shape.slots["flags"]?.value : void 0;
6576
+ const pat = patAbs ? litValue(patAbs) : void 0;
6577
+ if (typeof pat !== "string") return void 0;
6578
+ const flagsV = flagsAbs ? litValue(flagsAbs) : void 0;
6579
+ const flags = typeof flagsV === "string" ? flagsV : "";
6580
+ if (method === "toString") return strLit(`/${pat}/${flags}`);
6581
+ const subject = args[0] ? litValue(args[0]) : void 0;
6582
+ if (typeof subject !== "string") {
6583
+ return method === "test" ? abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial") : void 0;
6584
+ }
6585
+ let reReal;
6586
+ try {
6587
+ reReal = new RegExp(pat, flags);
6588
+ } catch {
6589
+ return void 0;
6590
+ }
6591
+ const m = reReal.exec(subject);
6592
+ if (method === "test") return boolLit(reReal.test(subject));
6593
+ if (!m) {
6594
+ return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
6595
+ }
6596
+ const els = m.map((g) => g === void 0 ? undefAbs() : strLit(g));
6597
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
6598
+ }
6599
+ function stringRegexMethod(recv, method, args) {
6600
+ if (method !== "match" && method !== "search") return void 0;
6601
+ const re = args[0];
6602
+ if (!re || re.shape.k !== "brand" || re.shape.name !== "RegExp") return void 0;
6603
+ const inner = re.shape.shape;
6604
+ const patAbs = inner.shape.k === "obj" ? inner.shape.slots["source"]?.value : void 0;
6605
+ const flagsAbs = inner.shape.k === "obj" ? inner.shape.slots["flags"]?.value : void 0;
6606
+ const pat = patAbs ? litValue(patAbs) : void 0;
6607
+ const sv = litValue(recv);
6608
+ if (typeof pat !== "string" || typeof sv !== "string") return void 0;
6609
+ const flagsV = flagsAbs ? litValue(flagsAbs) : void 0;
6610
+ const flags = typeof flagsV === "string" ? flagsV : "";
6611
+ let reReal;
6612
+ try {
6613
+ reReal = new RegExp(pat, flags);
6614
+ } catch {
6615
+ return void 0;
6616
+ }
6617
+ if (method === "search") {
6618
+ const idx = sv.search(reReal);
6619
+ return abs({ k: "prim", type: "number" }, { op: "lit", value: idx }, void 0, "exact");
6620
+ }
6621
+ if (flags.includes("g")) {
6622
+ const all = sv.match(reReal) ?? [];
6623
+ return abs({ k: "tuple", elements: all.map((s) => strLit(s)) }, void 0, void 0, "exact");
6624
+ }
6625
+ const m = reReal.exec(sv);
6626
+ if (!m) {
6627
+ return abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
6628
+ }
6629
+ const els = m.map((g) => g === void 0 ? undefAbs() : strLit(g));
6630
+ return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
6631
+ }
6171
6632
  function $invoke(thisVal, method, args, loc) {
6633
+ if (!thisVal || typeof thisVal !== "object" || !("shape" in thisVal)) {
6634
+ const ns = namespaceNameOf(thisVal);
6635
+ return (ns ? evalNamespaceCall(ns, method, args) : void 0) ?? unknown;
6636
+ }
6172
6637
  if (thisVal.shape.k === "sum") {
6173
6638
  const results = thisVal.shape.members.filter((m) => memberLikelyHasMethod(m, method)).map((m) => $invoke(m, method, args, loc));
6174
6639
  if (results.length === 0) return unknown;
6175
6640
  return results.reduce((a, b) => joinAbs(a, b));
6176
6641
  }
6642
+ {
6643
+ const reR = execRegexBrand(thisVal, method, args);
6644
+ if (reR !== void 0) return reR;
6645
+ }
6177
6646
  const brandName = thisVal.shape.k === "brand" ? thisVal.shape.name : void 0;
6178
6647
  if (brandName) {
6179
6648
  const m = findMethod(brandName, method);
@@ -6186,6 +6655,10 @@ function $invoke(thisVal, method, args, loc) {
6186
6655
  const arrR = invokeArrMethod(thisVal, method, args);
6187
6656
  if (arrR !== void 0) return arrR;
6188
6657
  }
6658
+ {
6659
+ const sm = stringRegexMethod(thisVal, method, args);
6660
+ if (sm !== void 0) return sm;
6661
+ }
6189
6662
  {
6190
6663
  const viaTable = callAbsMethod(thisVal, method, args);
6191
6664
  if (viaTable) return viaTable;
@@ -6280,6 +6753,18 @@ function invokeArrMethod(arr, method, args) {
6280
6753
  if (method === "join") {
6281
6754
  return abs({ k: "prim", type: "string" }, void 0, void 0, "path");
6282
6755
  }
6756
+ if (method === "fill" && args.length >= 1) {
6757
+ const v2 = asAbs(args[0]) ?? unknown;
6758
+ if (shape.k === "tuple") {
6759
+ return abs(
6760
+ { k: "tuple", elements: shape.elements.map(() => v2) },
6761
+ void 0,
6762
+ void 0,
6763
+ confJoin(arr.conf, v2.conf)
6764
+ );
6765
+ }
6766
+ return abs({ k: "arr", element: v2 }, void 0, void 0, confJoin(arr.conf, v2.conf));
6767
+ }
6283
6768
  if (method === "includes") {
6284
6769
  return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
6285
6770
  }
@@ -6328,6 +6813,7 @@ function $thisSet(thisVal, key, value) {
6328
6813
  return unknown;
6329
6814
  }
6330
6815
  function $orDefault(v2, dflt) {
6816
+ if (v2 === void 0) return asAbsVal(dflt());
6331
6817
  if (litValue(v2) === void 0 && v2.shape.k !== "never") {
6332
6818
  if (v2.term?.op === "lit" && v2.term.value === void 0) return asAbsVal(dflt());
6333
6819
  if (v2.shape.k === "unknown" && v2.term?.op === "lit") return asAbsVal(dflt());
@@ -6382,7 +6868,7 @@ var RUNTIME_IMPORT_RE = /^import\s*\{[^}]+\}\s*from\s*"[^"]+";\s*$/m;
6382
6868
  function rewriteUserImports(js) {
6383
6869
  js = js.replace(
6384
6870
  /^import\s*\{\s*\*\s+as\s+([A-Za-z_$][\w$]*)\s*\}\s*from\s*["']([^"']+)["'];\s*$/gm,
6385
- (_all, local, spec) => `const ${local} = __nudoBindNamespace(${JSON.stringify(spec)});`
6871
+ (_all, local, spec) => `let ${local} = __nudoBindNamespace(${JSON.stringify(spec)});`
6386
6872
  );
6387
6873
  js = js.replace(
6388
6874
  /^import\s*["']([^"']+)["'];\s*$/gm,
@@ -6395,7 +6881,7 @@ function rewriteUserImports(js) {
6395
6881
  return parts.map((p) => {
6396
6882
  const [imported, local] = p.split(/\s+as\s+/).map((x) => x.trim());
6397
6883
  const bind = local ?? imported;
6398
- return `const ${bind} = __nudoBindImport(${JSON.stringify(spec)}, ${JSON.stringify(imported)});`;
6884
+ return `let ${bind} = __nudoBindImport(${JSON.stringify(spec)}, ${JSON.stringify(imported)});`;
6399
6885
  }).join("\n");
6400
6886
  }
6401
6887
  );
@@ -6540,8 +7026,8 @@ ${js}`;
6540
7026
  }
6541
7027
  const exportFns = [...js.matchAll(/^export function (\w+)/gm)].map((m) => m[1]);
6542
7028
  js = js.replace(/^export function /gm, "function ");
6543
- const exportConsts = [...js.matchAll(/^export const (\w+)/gm)].map((m) => m[1]);
6544
- js = js.replace(/^export const /gm, "const ");
7029
+ const exportConsts = [...js.matchAll(/^export (?:const|let) (\w+)/gm)].map((m) => m[1]);
7030
+ js = js.replace(/^export (?:const|let) /gm, "let ");
6545
7031
  const names = [.../* @__PURE__ */ new Set([...exportFns, ...exportConsts])];
6546
7032
  const argNames = [
6547
7033
  ...runtimeArgNames(),
@@ -6595,6 +7081,17 @@ function callTranspiledExportFull(exports, name, args) {
6595
7081
  }
6596
7082
  }
6597
7083
  if (isAbsVal(fn)) {
7084
+ if (fn.shape.k === "fn") {
7085
+ try {
7086
+ const r = $call(fn, args);
7087
+ return { result: r, throws: never };
7088
+ } catch (e) {
7089
+ if (isNudoThrow(e)) {
7090
+ return { result: never, throws: e.absValue };
7091
+ }
7092
+ return { result: unknown, throws: never };
7093
+ }
7094
+ }
6598
7095
  return { result: fn, throws: never };
6599
7096
  }
6600
7097
  return { result: unknown, throws: never };
@@ -6604,10 +7101,6 @@ function callTranspiledExport(exports, name, args) {
6604
7101
  }
6605
7102
 
6606
7103
  export {
6607
- stripTypes,
6608
- resetParseSourceCache,
6609
- getParseSourceCacheSize,
6610
- parseSource,
6611
7104
  lit,
6612
7105
  v,
6613
7106
  app,
@@ -6657,6 +7150,26 @@ export {
6657
7150
  isStrPrim,
6658
7151
  isExactLit,
6659
7152
  litValue,
7153
+ viewTemplateParts,
7154
+ knownPrefixOfViews,
7155
+ knownSuffixOfViews,
7156
+ allFixedTextOfViews,
7157
+ fixedLengthOfViews,
7158
+ formatTemplateNameViews,
7159
+ mergeAdjacentFixedViews,
7160
+ templateMatchesValue,
7161
+ decideStartsWith,
7162
+ decideEndsWith,
7163
+ decideIncludes,
7164
+ absTemplateViews,
7165
+ templatePartsOf,
7166
+ createTemplateAbs,
7167
+ isTemplateLike,
7168
+ concatString,
7169
+ stripTypes,
7170
+ resetParseSourceCache,
7171
+ getParseSourceCacheSize,
7172
+ parseSource,
6660
7173
  attachFnImpl,
6661
7174
  getFnImpl,
6662
7175
  absFunction,
@@ -6665,11 +7178,11 @@ export {
6665
7178
  shapeOnlyFn,
6666
7179
  objOf,
6667
7180
  isObj,
7181
+ getSlot,
6668
7182
  spread,
6669
7183
  joinObjects,
6670
7184
  joinValues,
6671
7185
  makeSum,
6672
- collapseToOptional,
6673
7186
  fnOf,
6674
7187
  joinFunctions,
6675
7188
  joinAbs,
@@ -6692,18 +7205,15 @@ export {
6692
7205
  mapElementFallback,
6693
7206
  projectFlatMapResult,
6694
7207
  asAbs,
6695
- templatePartsOf,
6696
- createTemplateAbs,
6697
- isTemplateLike,
6698
- concatString,
6699
7208
  add,
6700
- numericBounds,
6701
7209
  sub,
6702
7210
  mul,
6703
7211
  div,
6704
7212
  mod,
6705
7213
  cmp,
6706
7214
  trueConstraint,
7215
+ refineAbsForRelTrue,
7216
+ matchRelIdentLit,
6707
7217
  falseConstraint,
6708
7218
  typeofAbs,
6709
7219
  negAbs,
@@ -6805,6 +7315,7 @@ export {
6805
7315
  asAbsVal,
6806
7316
  $fnVal,
6807
7317
  $lit,
7318
+ litTruth,
6808
7319
  isDefinitelyTrue,
6809
7320
  isDefinitelyFalse,
6810
7321
  $fork,
@@ -6820,6 +7331,8 @@ export {
6820
7331
  $concat,
6821
7332
  $elems,
6822
7333
  $forOf,
7334
+ namespaceNameOf,
7335
+ $regex,
6823
7336
  $get,
6824
7337
  $set,
6825
7338
  $while,