nudojs 1.1.0 → 1.2.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.
- package/dist/index.js +1422 -390
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -16209,6 +16209,10 @@ function joinValues(a, b) {
|
|
|
16209
16209
|
}
|
|
16210
16210
|
return makeSum(a, b);
|
|
16211
16211
|
}
|
|
16212
|
+
const hasPred = (x) => !!x.pred && x.pred.op !== "true";
|
|
16213
|
+
if (hasPred(a) || hasPred(b)) {
|
|
16214
|
+
return makeSum(a, b);
|
|
16215
|
+
}
|
|
16212
16216
|
return abs(a.shape, void 0, void 0, confJoin(confJoin(a.conf, b.conf), "path"));
|
|
16213
16217
|
}
|
|
16214
16218
|
return makeSum(a, b);
|
|
@@ -18268,6 +18272,335 @@ var init_invariants = __esm({
|
|
|
18268
18272
|
}
|
|
18269
18273
|
});
|
|
18270
18274
|
|
|
18275
|
+
// ../core/src/algebra/containers.ts
|
|
18276
|
+
function shouldWidenArrayLiteral(n) {
|
|
18277
|
+
return n > TUPLE_LITERAL_CAP;
|
|
18278
|
+
}
|
|
18279
|
+
function widenedArrayConf() {
|
|
18280
|
+
return "path";
|
|
18281
|
+
}
|
|
18282
|
+
var TUPLE_LITERAL_CAP, TUPLE_MATERIALIZE_CAP;
|
|
18283
|
+
var init_containers = __esm({
|
|
18284
|
+
"../core/src/algebra/containers.ts"() {
|
|
18285
|
+
"use strict";
|
|
18286
|
+
TUPLE_LITERAL_CAP = 8;
|
|
18287
|
+
TUPLE_MATERIALIZE_CAP = 4096;
|
|
18288
|
+
}
|
|
18289
|
+
});
|
|
18290
|
+
|
|
18291
|
+
// ../core/src/algebra/exec/runtime/state.ts
|
|
18292
|
+
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
18293
|
+
function writeInPlace(target, next) {
|
|
18294
|
+
target.shape = next.shape;
|
|
18295
|
+
target.conf = next.conf;
|
|
18296
|
+
target.term = void 0;
|
|
18297
|
+
target.pred = void 0;
|
|
18298
|
+
return target;
|
|
18299
|
+
}
|
|
18300
|
+
function clearStaleTermPred(v2) {
|
|
18301
|
+
v2.term = void 0;
|
|
18302
|
+
v2.pred = void 0;
|
|
18303
|
+
}
|
|
18304
|
+
function currentExecPhi() {
|
|
18305
|
+
return phi;
|
|
18306
|
+
}
|
|
18307
|
+
function withExecPhi(p, body) {
|
|
18308
|
+
const prev = phi;
|
|
18309
|
+
phi = p;
|
|
18310
|
+
try {
|
|
18311
|
+
return body();
|
|
18312
|
+
} finally {
|
|
18313
|
+
phi = prev;
|
|
18314
|
+
}
|
|
18315
|
+
}
|
|
18316
|
+
function asAbsVal(v2) {
|
|
18317
|
+
if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
|
|
18318
|
+
if (typeof v2 === "function") {
|
|
18319
|
+
const n = Math.max(0, v2.length);
|
|
18320
|
+
const params = Array.from({ length: n }, (_, i) => `arg${i}`);
|
|
18321
|
+
return absFunction(params, {
|
|
18322
|
+
body: noBody,
|
|
18323
|
+
// 与 $fnVal / $callNamed 同边界:callee 的 NudoReturn 不得冒泡成 caller
|
|
18324
|
+
apply: (args) => callAtFunctionBoundary(() => v2(...args))
|
|
18325
|
+
});
|
|
18326
|
+
}
|
|
18327
|
+
return $lit(v2);
|
|
18328
|
+
}
|
|
18329
|
+
function callAtFunctionBoundary(body) {
|
|
18330
|
+
let forwarded = [];
|
|
18331
|
+
try {
|
|
18332
|
+
return runWithLoopExits(() => {
|
|
18333
|
+
try {
|
|
18334
|
+
const r = body();
|
|
18335
|
+
forwarded = takeThrowExits();
|
|
18336
|
+
return r;
|
|
18337
|
+
} catch (e) {
|
|
18338
|
+
forwarded = takeThrowExits();
|
|
18339
|
+
if (isNudoReturn(e)) return e.absValue;
|
|
18340
|
+
throw e;
|
|
18341
|
+
}
|
|
18342
|
+
});
|
|
18343
|
+
} finally {
|
|
18344
|
+
for (const x of forwarded) pushThrowExit(x);
|
|
18345
|
+
}
|
|
18346
|
+
}
|
|
18347
|
+
function $fnVal(params, impl, opts) {
|
|
18348
|
+
return absFunction(params, {
|
|
18349
|
+
body: noBody,
|
|
18350
|
+
// bindThis(对象方法):receiver 走首参注入,无宿主 this;
|
|
18351
|
+
// 非方法 fn:宿主 this 传递(call/apply/bind 的 thisArg 经 $rawThis 进入函数体)
|
|
18352
|
+
apply: opts?.bindThis ? (args) => callAtFunctionBoundary(() => impl(...args)) : (args, thisVal) => callAtFunctionBoundary(() => impl.apply(thisVal, args)),
|
|
18353
|
+
...opts?.bindThis ? { bindThis: true } : {}
|
|
18354
|
+
});
|
|
18355
|
+
}
|
|
18356
|
+
function $rawThis(v2) {
|
|
18357
|
+
if (v2 === void 0 || v2 === globalThis) return $lit(void 0);
|
|
18358
|
+
if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
|
|
18359
|
+
return $lit(v2);
|
|
18360
|
+
}
|
|
18361
|
+
function throwStrictWrite() {
|
|
18362
|
+
throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
18363
|
+
}
|
|
18364
|
+
function $throwConstAssign() {
|
|
18365
|
+
throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
18366
|
+
}
|
|
18367
|
+
function $litTruth(a) {
|
|
18368
|
+
return litTruth(a);
|
|
18369
|
+
}
|
|
18370
|
+
function $lit(v2) {
|
|
18371
|
+
if (v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2) {
|
|
18372
|
+
return v2;
|
|
18373
|
+
}
|
|
18374
|
+
return litAbsFromJs(v2);
|
|
18375
|
+
}
|
|
18376
|
+
function litAbsFromJs(v2, depth = 0) {
|
|
18377
|
+
if (v2 === null || v2 === void 0) {
|
|
18378
|
+
return abs({ k: "unknown" }, { op: "lit", value: v2 }, pTrue, "exact");
|
|
18379
|
+
}
|
|
18380
|
+
const t = typeof v2;
|
|
18381
|
+
if (t === "number" || t === "string" || t === "boolean" || t === "bigint") {
|
|
18382
|
+
return abs(
|
|
18383
|
+
{ k: "prim", type: t },
|
|
18384
|
+
{ op: "lit", value: v2 },
|
|
18385
|
+
pTrue,
|
|
18386
|
+
"exact"
|
|
18387
|
+
);
|
|
18388
|
+
}
|
|
18389
|
+
if (depth < 8) {
|
|
18390
|
+
if (Array.isArray(v2)) {
|
|
18391
|
+
const els = v2.map((x) => litAbsFromJs(x, depth + 1));
|
|
18392
|
+
if (shouldWidenArrayLiteral(els.length)) {
|
|
18393
|
+
return abs(
|
|
18394
|
+
{ k: "arr", element: els.reduce((x, y) => joinAbs(x, y)) },
|
|
18395
|
+
void 0,
|
|
18396
|
+
void 0,
|
|
18397
|
+
widenedArrayConf()
|
|
18398
|
+
);
|
|
18399
|
+
}
|
|
18400
|
+
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
18401
|
+
}
|
|
18402
|
+
if (t === "object") {
|
|
18403
|
+
const proto = Object.getPrototypeOf(v2);
|
|
18404
|
+
if (proto === Object.prototype || proto === null) {
|
|
18405
|
+
const slots = {};
|
|
18406
|
+
for (const [k, val] of Object.entries(v2)) {
|
|
18407
|
+
Object.defineProperty(slots, k, {
|
|
18408
|
+
value: { value: litAbsFromJs(val, depth + 1) },
|
|
18409
|
+
enumerable: true,
|
|
18410
|
+
writable: true,
|
|
18411
|
+
configurable: true
|
|
18412
|
+
});
|
|
18413
|
+
}
|
|
18414
|
+
return objOf(slots);
|
|
18415
|
+
}
|
|
18416
|
+
}
|
|
18417
|
+
}
|
|
18418
|
+
return unknown;
|
|
18419
|
+
}
|
|
18420
|
+
function litTruth(a) {
|
|
18421
|
+
if (a.term?.op === "lit") {
|
|
18422
|
+
return Boolean(a.term.value);
|
|
18423
|
+
}
|
|
18424
|
+
switch (a.shape.k) {
|
|
18425
|
+
case "obj":
|
|
18426
|
+
case "arr":
|
|
18427
|
+
case "tuple":
|
|
18428
|
+
case "fn":
|
|
18429
|
+
case "brand":
|
|
18430
|
+
case "eff":
|
|
18431
|
+
return true;
|
|
18432
|
+
case "prim":
|
|
18433
|
+
return a.shape.type === "symbol" ? true : void 0;
|
|
18434
|
+
case "never":
|
|
18435
|
+
return false;
|
|
18436
|
+
default:
|
|
18437
|
+
return void 0;
|
|
18438
|
+
}
|
|
18439
|
+
}
|
|
18440
|
+
function isDefinitelyTrue(a) {
|
|
18441
|
+
return litTruth(a) === true;
|
|
18442
|
+
}
|
|
18443
|
+
function isDefinitelyFalse(a) {
|
|
18444
|
+
const t = litTruth(a);
|
|
18445
|
+
if (t === false) return true;
|
|
18446
|
+
if (a.shape.k === "never") return true;
|
|
18447
|
+
return false;
|
|
18448
|
+
}
|
|
18449
|
+
function undef() {
|
|
18450
|
+
return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
|
|
18451
|
+
}
|
|
18452
|
+
function runWithLoopExits(body) {
|
|
18453
|
+
return loopExitsAls.run(
|
|
18454
|
+
[],
|
|
18455
|
+
() => throwExitsAls.run(
|
|
18456
|
+
[],
|
|
18457
|
+
() => tryMarksAls.run([], () => softFrameActiveAls.run([], body))
|
|
18458
|
+
)
|
|
18459
|
+
);
|
|
18460
|
+
}
|
|
18461
|
+
function takeLoopExits() {
|
|
18462
|
+
return loopExitsAls.getStore() ?? [];
|
|
18463
|
+
}
|
|
18464
|
+
function takeThrowExits() {
|
|
18465
|
+
return throwExitsAls.getStore() ?? [];
|
|
18466
|
+
}
|
|
18467
|
+
function pushLoopExit(v2) {
|
|
18468
|
+
loopExitsAls.getStore()?.push(v2);
|
|
18469
|
+
}
|
|
18470
|
+
function pushThrowExit(v2) {
|
|
18471
|
+
throwExitsAls.getStore()?.push(v2);
|
|
18472
|
+
}
|
|
18473
|
+
function $pushLoopExit(v2) {
|
|
18474
|
+
pushLoopExit(v2);
|
|
18475
|
+
}
|
|
18476
|
+
function $tryMark() {
|
|
18477
|
+
$tryMarkSoft();
|
|
18478
|
+
softFrameActiveAls.getStore()?.push(true);
|
|
18479
|
+
const store = throwExitsAls.getStore();
|
|
18480
|
+
const m = store?.length ?? 0;
|
|
18481
|
+
tryMarksAls.getStore()?.push(m);
|
|
18482
|
+
return m;
|
|
18483
|
+
}
|
|
18484
|
+
function $tryCurrentMark() {
|
|
18485
|
+
const stack = tryMarksAls.getStore();
|
|
18486
|
+
return stack && stack.length > 0 ? stack[stack.length - 1] : 0;
|
|
18487
|
+
}
|
|
18488
|
+
function $tryPopMark() {
|
|
18489
|
+
tryMarksAls.getStore()?.pop();
|
|
18490
|
+
const soft = softFrameActiveAls.getStore();
|
|
18491
|
+
if (soft && soft.length > 0) {
|
|
18492
|
+
if (soft[soft.length - 1]) $tryReleaseSoftOut();
|
|
18493
|
+
soft.pop();
|
|
18494
|
+
}
|
|
18495
|
+
}
|
|
18496
|
+
function $tryTakeSince(mark) {
|
|
18497
|
+
const store = throwExitsAls.getStore();
|
|
18498
|
+
if (!store) return [];
|
|
18499
|
+
return store.splice(Math.min(mark, store.length));
|
|
18500
|
+
}
|
|
18501
|
+
function peekThrowExitsSince(mark) {
|
|
18502
|
+
const store = throwExitsAls.getStore();
|
|
18503
|
+
if (!store) return [];
|
|
18504
|
+
return store.slice(Math.min(mark, store.length));
|
|
18505
|
+
}
|
|
18506
|
+
function throwExitsMark() {
|
|
18507
|
+
return throwExitsAls.getStore()?.length ?? 0;
|
|
18508
|
+
}
|
|
18509
|
+
function $tryDigestSoftCatch() {
|
|
18510
|
+
const soft = softFrameActiveAls.getStore();
|
|
18511
|
+
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
|
|
18512
|
+
$tryDigestSoft();
|
|
18513
|
+
soft[soft.length - 1] = false;
|
|
18514
|
+
}
|
|
18515
|
+
function $tryReleaseSoftCatch() {
|
|
18516
|
+
const soft = softFrameActiveAls.getStore();
|
|
18517
|
+
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
|
|
18518
|
+
$tryReleaseSoft();
|
|
18519
|
+
soft[soft.length - 1] = false;
|
|
18520
|
+
}
|
|
18521
|
+
function $tryDetachSoftCatch() {
|
|
18522
|
+
const soft = softFrameActiveAls.getStore();
|
|
18523
|
+
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return [];
|
|
18524
|
+
const effects = popMayThrowFrame(false);
|
|
18525
|
+
soft[soft.length - 1] = false;
|
|
18526
|
+
return effects;
|
|
18527
|
+
}
|
|
18528
|
+
function $tryDiscardSoft(_effects) {
|
|
18529
|
+
}
|
|
18530
|
+
function $tryOrphanSoft(effects) {
|
|
18531
|
+
orphanMayThrowEffects(effects);
|
|
18532
|
+
}
|
|
18533
|
+
function $tryReleaseSoftOut() {
|
|
18534
|
+
const soft = softFrameActiveAls.getStore();
|
|
18535
|
+
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
|
|
18536
|
+
$tryReleaseSoft();
|
|
18537
|
+
soft[soft.length - 1] = false;
|
|
18538
|
+
}
|
|
18539
|
+
function isNudoReturn(e) {
|
|
18540
|
+
return e instanceof NudoReturn;
|
|
18541
|
+
}
|
|
18542
|
+
function $loopReturn(v2) {
|
|
18543
|
+
throw new NudoReturn(v2);
|
|
18544
|
+
}
|
|
18545
|
+
function $loopBreak(label) {
|
|
18546
|
+
throw new NudoLoopSignal("break", label || void 0);
|
|
18547
|
+
}
|
|
18548
|
+
function $loopContinue(label) {
|
|
18549
|
+
throw new NudoLoopSignal("continue", label || void 0);
|
|
18550
|
+
}
|
|
18551
|
+
function loopSignalMatches(e, label) {
|
|
18552
|
+
return e.label === void 0 || e.label === label;
|
|
18553
|
+
}
|
|
18554
|
+
function isNudoBreak(e, label) {
|
|
18555
|
+
return e instanceof NudoLoopSignal && e.kind === "break" && loopSignalMatches(e, label);
|
|
18556
|
+
}
|
|
18557
|
+
function isNudoContinue(e, label) {
|
|
18558
|
+
return e instanceof NudoLoopSignal && e.kind === "continue" && loopSignalMatches(e, label);
|
|
18559
|
+
}
|
|
18560
|
+
function $isBreakTo(e, label) {
|
|
18561
|
+
return e instanceof NudoLoopSignal && e.kind === "break" && e.label === label;
|
|
18562
|
+
}
|
|
18563
|
+
function $rethrowIfNudoReturn(e) {
|
|
18564
|
+
if (isNudoReturn(e)) throw e;
|
|
18565
|
+
}
|
|
18566
|
+
var phi, noBody, loopExitsAls, throwExitsAls, tryMarksAls, softFrameActiveAls, NudoReturn, NudoLoopSignal;
|
|
18567
|
+
var init_state = __esm({
|
|
18568
|
+
"../core/src/algebra/exec/runtime/state.ts"() {
|
|
18569
|
+
"use strict";
|
|
18570
|
+
init_abs();
|
|
18571
|
+
init_pred();
|
|
18572
|
+
init_abs_fn();
|
|
18573
|
+
init_nudo_throw();
|
|
18574
|
+
init_may_throw();
|
|
18575
|
+
init_containers();
|
|
18576
|
+
init_objects();
|
|
18577
|
+
phi = pTrue;
|
|
18578
|
+
noBody = { type: "BlockStatement", body: [], directives: [] };
|
|
18579
|
+
loopExitsAls = new AsyncLocalStorage2();
|
|
18580
|
+
throwExitsAls = new AsyncLocalStorage2();
|
|
18581
|
+
tryMarksAls = new AsyncLocalStorage2();
|
|
18582
|
+
softFrameActiveAls = new AsyncLocalStorage2();
|
|
18583
|
+
NudoReturn = class extends Error {
|
|
18584
|
+
absValue;
|
|
18585
|
+
constructor(absValue) {
|
|
18586
|
+
super("nudo:return");
|
|
18587
|
+
this.name = "NudoReturn";
|
|
18588
|
+
this.absValue = absValue;
|
|
18589
|
+
}
|
|
18590
|
+
};
|
|
18591
|
+
NudoLoopSignal = class extends Error {
|
|
18592
|
+
kind;
|
|
18593
|
+
label;
|
|
18594
|
+
constructor(kind, label) {
|
|
18595
|
+
super("nudo:loop");
|
|
18596
|
+
this.name = "NudoLoopSignal";
|
|
18597
|
+
this.kind = kind;
|
|
18598
|
+
this.label = label;
|
|
18599
|
+
}
|
|
18600
|
+
};
|
|
18601
|
+
}
|
|
18602
|
+
});
|
|
18603
|
+
|
|
18271
18604
|
// ../core/src/algebra/builtins/shared.ts
|
|
18272
18605
|
function numPrim(conf = "path") {
|
|
18273
18606
|
return abs({ k: "prim", type: "number" }, void 0, void 0, conf);
|
|
@@ -18291,12 +18624,12 @@ function isPrimLike(a) {
|
|
|
18291
18624
|
}
|
|
18292
18625
|
return false;
|
|
18293
18626
|
}
|
|
18294
|
-
var
|
|
18627
|
+
var noBody2;
|
|
18295
18628
|
var init_shared = __esm({
|
|
18296
18629
|
"../core/src/algebra/builtins/shared.ts"() {
|
|
18297
18630
|
"use strict";
|
|
18298
18631
|
init_abs();
|
|
18299
|
-
|
|
18632
|
+
noBody2 = { type: "BlockStatement", body: [], directives: [] };
|
|
18300
18633
|
}
|
|
18301
18634
|
});
|
|
18302
18635
|
|
|
@@ -18316,8 +18649,194 @@ function mathMethod(name) {
|
|
|
18316
18649
|
const impl = Math[name];
|
|
18317
18650
|
return typeof impl === "function" ? impl : void 0;
|
|
18318
18651
|
}
|
|
18652
|
+
function isNonNaN(a, phi2) {
|
|
18653
|
+
if (a.term?.op === "lit") {
|
|
18654
|
+
return typeof a.term.value === "number" && !Number.isNaN(a.term.value);
|
|
18655
|
+
}
|
|
18656
|
+
const hasNonNaNFact = (p) => {
|
|
18657
|
+
if (!p) return false;
|
|
18658
|
+
if (p.op === "and") return p.args.some(hasNonNaNFact);
|
|
18659
|
+
if (p.op === "assumeFinite") {
|
|
18660
|
+
return !!a.term && termEquals(p.t, a.term);
|
|
18661
|
+
}
|
|
18662
|
+
if (p.op === "ne") {
|
|
18663
|
+
if (p.b.op === "lit" && typeof p.b.value === "number" && Number.isNaN(p.b.value) && a.term && termEquals(p.a, a.term)) {
|
|
18664
|
+
return true;
|
|
18665
|
+
}
|
|
18666
|
+
}
|
|
18667
|
+
if (p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le") {
|
|
18668
|
+
if (a.term && (termEquals(p.a, a.term) || termEquals(p.b, a.term))) return true;
|
|
18669
|
+
}
|
|
18670
|
+
return false;
|
|
18671
|
+
};
|
|
18672
|
+
if (hasNonNaNFact(a.pred)) return true;
|
|
18673
|
+
if (a.term?.op === "var") {
|
|
18674
|
+
const id = a.term.id;
|
|
18675
|
+
const conjs = phi2.op === "and" ? phi2.args : [phi2];
|
|
18676
|
+
for (const p of conjs) {
|
|
18677
|
+
if (p.op === "assumeFinite" && p.t.op === "var" && p.t.id === id) {
|
|
18678
|
+
return true;
|
|
18679
|
+
}
|
|
18680
|
+
if (p.op === "ne") {
|
|
18681
|
+
const b = p.b;
|
|
18682
|
+
if (b.op === "lit" && typeof b.value === "number" && Number.isNaN(b.value) && p.a.op === "var" && p.a.id === id) {
|
|
18683
|
+
return true;
|
|
18684
|
+
}
|
|
18685
|
+
}
|
|
18686
|
+
if (p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le") {
|
|
18687
|
+
const sides = [p.a, p.b];
|
|
18688
|
+
if (sides.some((t) => t.op === "var" && t.id === id) && sides.some((t) => t.op === "lit" && typeof t.value === "number")) {
|
|
18689
|
+
return true;
|
|
18690
|
+
}
|
|
18691
|
+
}
|
|
18692
|
+
}
|
|
18693
|
+
}
|
|
18694
|
+
return false;
|
|
18695
|
+
}
|
|
18696
|
+
function ieeeBoundNum(n) {
|
|
18697
|
+
return Number.isFinite(n) || n === Infinity || n === -Infinity ? n : void 0;
|
|
18698
|
+
}
|
|
18699
|
+
function loMin(a, b) {
|
|
18700
|
+
if (a.lo === void 0 || b.lo === void 0) return void 0;
|
|
18701
|
+
if (b.lo.value < a.lo.value) return b.lo;
|
|
18702
|
+
if (b.lo.value === a.lo.value && b.lo.strict && !a.lo.strict) return b.lo;
|
|
18703
|
+
return a.lo;
|
|
18704
|
+
}
|
|
18705
|
+
function loMax(a, b) {
|
|
18706
|
+
if (a.lo === void 0) return b.lo;
|
|
18707
|
+
if (b.lo === void 0) return a.lo;
|
|
18708
|
+
if (b.lo.value > a.lo.value) return b.lo;
|
|
18709
|
+
if (b.lo.value === a.lo.value && b.lo.strict && !a.lo.strict) return b.lo;
|
|
18710
|
+
return a.lo;
|
|
18711
|
+
}
|
|
18712
|
+
function hiMin(a, b) {
|
|
18713
|
+
if (a.hi === void 0) return b.hi;
|
|
18714
|
+
if (b.hi === void 0) return a.hi;
|
|
18715
|
+
if (b.hi.value < a.hi.value) return b.hi;
|
|
18716
|
+
if (b.hi.value === a.hi.value && b.hi.strict && !a.hi.strict) return b.hi;
|
|
18717
|
+
return a.hi;
|
|
18718
|
+
}
|
|
18719
|
+
function hiMax(a, b) {
|
|
18720
|
+
if (a.hi === void 0 || b.hi === void 0) return void 0;
|
|
18721
|
+
if (b.hi.value > a.hi.value) return b.hi;
|
|
18722
|
+
if (b.hi.value === a.hi.value && b.hi.strict && !a.hi.strict) return b.hi;
|
|
18723
|
+
return a.hi;
|
|
18724
|
+
}
|
|
18725
|
+
function boundsToPred(t, b) {
|
|
18726
|
+
const facts = [];
|
|
18727
|
+
if (b.lo !== void 0) {
|
|
18728
|
+
const v2 = ieeeBoundNum(b.lo.value);
|
|
18729
|
+
if (v2 !== void 0) {
|
|
18730
|
+
facts.push(b.lo.strict ? { op: "gt", a: t, b: lit(v2) } : { op: "ge", a: t, b: lit(v2) });
|
|
18731
|
+
}
|
|
18732
|
+
}
|
|
18733
|
+
if (b.hi !== void 0) {
|
|
18734
|
+
const v2 = ieeeBoundNum(b.hi.value);
|
|
18735
|
+
if (v2 !== void 0) {
|
|
18736
|
+
facts.push(b.hi.strict ? { op: "lt", a: t, b: lit(v2) } : { op: "le", a: t, b: lit(v2) });
|
|
18737
|
+
}
|
|
18738
|
+
}
|
|
18739
|
+
if (facts.length === 0) return void 0;
|
|
18740
|
+
return facts.length === 1 ? facts[0] : and(...facts);
|
|
18741
|
+
}
|
|
18742
|
+
function minMaxAbs(name, args) {
|
|
18743
|
+
const phi2 = currentExecPhi();
|
|
18744
|
+
const empty = {};
|
|
18745
|
+
let acc = empty;
|
|
18746
|
+
const termArgs = args.map(
|
|
18747
|
+
(a, i) => a.term ?? app(`arg${i}`, [])
|
|
18748
|
+
);
|
|
18749
|
+
const term = simplifyTerm(app(`Math.${name}`, termArgs));
|
|
18750
|
+
let first = true;
|
|
18751
|
+
let mayNaN = false;
|
|
18752
|
+
for (const a of args) {
|
|
18753
|
+
if (!isNonNaN(a, phi2)) mayNaN = true;
|
|
18754
|
+
const b = numericBounds(a, phi2) ?? {};
|
|
18755
|
+
if (first) {
|
|
18756
|
+
acc = { lo: b.lo, hi: b.hi };
|
|
18757
|
+
first = false;
|
|
18758
|
+
continue;
|
|
18759
|
+
}
|
|
18760
|
+
if (name === "min") {
|
|
18761
|
+
acc = { lo: loMin(acc, b), hi: hiMin(acc, b) };
|
|
18762
|
+
} else {
|
|
18763
|
+
acc = { lo: loMax(acc, b), hi: hiMax(acc, b) };
|
|
18764
|
+
}
|
|
18765
|
+
}
|
|
18766
|
+
const pred = boundsToPred(term, acc);
|
|
18767
|
+
const bounded = abs({ k: "prim", type: "number" }, term, pred, "path");
|
|
18768
|
+
if (!mayNaN) return bounded;
|
|
18769
|
+
const nanArm = numLit(NaN);
|
|
18770
|
+
return makeSum(nanArm, bounded);
|
|
18771
|
+
}
|
|
18772
|
+
function roundingAbs(name, arg) {
|
|
18773
|
+
const phi2 = currentExecPhi();
|
|
18774
|
+
const impl = name === "round" ? Math.round : name === "floor" ? Math.floor : name === "ceil" ? Math.ceil : Math.trunc;
|
|
18775
|
+
const b = numericBounds(arg, phi2);
|
|
18776
|
+
const mayNaN = !isNonNaN(arg, phi2);
|
|
18777
|
+
const term = arg.term ? simplifyTerm(app(`Math.${name}`, [arg.term])) : void 0;
|
|
18778
|
+
let out = {};
|
|
18779
|
+
if (b) {
|
|
18780
|
+
if (b.lo !== void 0) {
|
|
18781
|
+
const v2 = impl(b.lo.value);
|
|
18782
|
+
out.lo = Number.isNaN(v2) ? void 0 : { value: v2, strict: false };
|
|
18783
|
+
}
|
|
18784
|
+
if (b.hi !== void 0) {
|
|
18785
|
+
const v2 = impl(b.hi.value);
|
|
18786
|
+
out.hi = Number.isNaN(v2) ? void 0 : { value: v2, strict: false };
|
|
18787
|
+
}
|
|
18788
|
+
}
|
|
18789
|
+
const pred = term ? boundsToPred(term, out) : void 0;
|
|
18790
|
+
const bounded = abs({ k: "prim", type: "number" }, term, pred, "path");
|
|
18791
|
+
if (!mayNaN) return bounded;
|
|
18792
|
+
return makeSum(numLit(NaN), bounded);
|
|
18793
|
+
}
|
|
18319
18794
|
function evalMathMethod(name, args) {
|
|
18320
18795
|
if (name === "random") return numPrim("path");
|
|
18796
|
+
if (name === "min" || name === "max") {
|
|
18797
|
+
const nums2 = [];
|
|
18798
|
+
let allLit = true;
|
|
18799
|
+
for (const a of args) {
|
|
18800
|
+
const n = coerceMathArg(a);
|
|
18801
|
+
if (n === void 0) {
|
|
18802
|
+
allLit = false;
|
|
18803
|
+
break;
|
|
18804
|
+
}
|
|
18805
|
+
if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
18806
|
+
nums2.push(n);
|
|
18807
|
+
}
|
|
18808
|
+
if (allLit) {
|
|
18809
|
+
try {
|
|
18810
|
+
return numLit((name === "min" ? Math.min : Math.max)(...nums2));
|
|
18811
|
+
} catch {
|
|
18812
|
+
return numPrim();
|
|
18813
|
+
}
|
|
18814
|
+
}
|
|
18815
|
+
for (const a of args) {
|
|
18816
|
+
const n = coerceMathArg(a);
|
|
18817
|
+
if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
18818
|
+
}
|
|
18819
|
+
return minMaxAbs(name, args);
|
|
18820
|
+
}
|
|
18821
|
+
if (name === "round" || name === "floor" || name === "ceil" || name === "trunc") {
|
|
18822
|
+
const n = coerceMathArg(args[0]);
|
|
18823
|
+
if (n === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
18824
|
+
if (typeof n === "number") {
|
|
18825
|
+
try {
|
|
18826
|
+
return numLit(
|
|
18827
|
+
name === "round" ? Math.round(n) : name === "floor" ? Math.floor(n) : name === "ceil" ? Math.ceil(n) : Math.trunc(n)
|
|
18828
|
+
);
|
|
18829
|
+
} catch {
|
|
18830
|
+
return numPrim();
|
|
18831
|
+
}
|
|
18832
|
+
}
|
|
18833
|
+
if (args[0]) {
|
|
18834
|
+
const c2 = coerceMathArg(args[0]);
|
|
18835
|
+
if (c2 === "throw") throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
18836
|
+
return roundingAbs(name, args[0]);
|
|
18837
|
+
}
|
|
18838
|
+
return numPrim();
|
|
18839
|
+
}
|
|
18321
18840
|
const impl = mathMethod(name);
|
|
18322
18841
|
if (!impl) return void 0;
|
|
18323
18842
|
const nums = [];
|
|
@@ -18337,28 +18856,17 @@ var init_math = __esm({
|
|
|
18337
18856
|
"../core/src/algebra/builtins/math.ts"() {
|
|
18338
18857
|
"use strict";
|
|
18339
18858
|
init_abs();
|
|
18859
|
+
init_term();
|
|
18860
|
+
init_pred();
|
|
18861
|
+
init_arithmetic();
|
|
18862
|
+
init_objects();
|
|
18863
|
+
init_state();
|
|
18340
18864
|
init_shared();
|
|
18341
18865
|
init_nudo_throw();
|
|
18342
18866
|
init_may_throw();
|
|
18343
18867
|
}
|
|
18344
18868
|
});
|
|
18345
18869
|
|
|
18346
|
-
// ../core/src/algebra/containers.ts
|
|
18347
|
-
function shouldWidenArrayLiteral(n) {
|
|
18348
|
-
return n > TUPLE_LITERAL_CAP;
|
|
18349
|
-
}
|
|
18350
|
-
function widenedArrayConf() {
|
|
18351
|
-
return "path";
|
|
18352
|
-
}
|
|
18353
|
-
var TUPLE_LITERAL_CAP, TUPLE_MATERIALIZE_CAP;
|
|
18354
|
-
var init_containers = __esm({
|
|
18355
|
-
"../core/src/algebra/containers.ts"() {
|
|
18356
|
-
"use strict";
|
|
18357
|
-
TUPLE_LITERAL_CAP = 8;
|
|
18358
|
-
TUPLE_MATERIALIZE_CAP = 4096;
|
|
18359
|
-
}
|
|
18360
|
-
});
|
|
18361
|
-
|
|
18362
18870
|
// ../core/src/algebra/builtins/ctor.ts
|
|
18363
18871
|
function builtinCtorAbs(name) {
|
|
18364
18872
|
let a = builtinCtorByName.get(name);
|
|
@@ -19130,8 +19638,19 @@ function evalNumberStatic(name, args) {
|
|
|
19130
19638
|
switch (name) {
|
|
19131
19639
|
case "isInteger":
|
|
19132
19640
|
return foldStrictNumberPred(Number.isInteger) ?? boolPrim();
|
|
19133
|
-
case "isNaN":
|
|
19134
|
-
|
|
19641
|
+
case "isNaN": {
|
|
19642
|
+
const folded = foldStrictNumberPred(Number.isNaN);
|
|
19643
|
+
if (folded) return folded;
|
|
19644
|
+
if (a0Arg?.term) {
|
|
19645
|
+
return abs(
|
|
19646
|
+
{ k: "prim", type: "boolean" },
|
|
19647
|
+
void 0,
|
|
19648
|
+
{ op: "eq", a: a0Arg.term, b: { op: "lit", value: NaN } },
|
|
19649
|
+
"path"
|
|
19650
|
+
);
|
|
19651
|
+
}
|
|
19652
|
+
return boolPrim();
|
|
19653
|
+
}
|
|
19135
19654
|
case "isFinite":
|
|
19136
19655
|
return foldStrictNumberPred(Number.isFinite) ?? boolPrim();
|
|
19137
19656
|
case "parseInt": {
|
|
@@ -20036,7 +20555,7 @@ function arrayJoinToString(recv) {
|
|
|
20036
20555
|
}
|
|
20037
20556
|
function arrayMethodAbs(name) {
|
|
20038
20557
|
return absFunction(["thisArg"], {
|
|
20039
|
-
body:
|
|
20558
|
+
body: noBody2,
|
|
20040
20559
|
bindThis: true,
|
|
20041
20560
|
apply: (a) => {
|
|
20042
20561
|
const recv = a[0] ?? undefAbs();
|
|
@@ -20452,11 +20971,11 @@ function evalPromiseCtor(args) {
|
|
|
20452
20971
|
return undefAbs();
|
|
20453
20972
|
};
|
|
20454
20973
|
const resolveAbs = absFunction(["value"], {
|
|
20455
|
-
body:
|
|
20974
|
+
body: noBody2,
|
|
20456
20975
|
apply: (args2) => onResolve(args2[0])
|
|
20457
20976
|
});
|
|
20458
20977
|
const rejectAbs = absFunction(["reason"], {
|
|
20459
|
-
body:
|
|
20978
|
+
body: noBody2,
|
|
20460
20979
|
apply: (args2) => onReject(args2[0])
|
|
20461
20980
|
});
|
|
20462
20981
|
enterPromiseExecutorScope();
|
|
@@ -21193,7 +21712,7 @@ function evalObjectProtoMethod(name, thisVal, args) {
|
|
|
21193
21712
|
}
|
|
21194
21713
|
function objectProtoMethodAbs(name) {
|
|
21195
21714
|
return absFunction(["thisArg", "arg0"], {
|
|
21196
|
-
body:
|
|
21715
|
+
body: noBody2,
|
|
21197
21716
|
bindThis: true,
|
|
21198
21717
|
apply: (a) => {
|
|
21199
21718
|
const recv = a[0] ?? undefLit();
|
|
@@ -28294,319 +28813,6 @@ var init_transpile = __esm({
|
|
|
28294
28813
|
}
|
|
28295
28814
|
});
|
|
28296
28815
|
|
|
28297
|
-
// ../core/src/algebra/exec/runtime/state.ts
|
|
28298
|
-
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
28299
|
-
function writeInPlace(target, next) {
|
|
28300
|
-
target.shape = next.shape;
|
|
28301
|
-
target.conf = next.conf;
|
|
28302
|
-
target.term = void 0;
|
|
28303
|
-
target.pred = void 0;
|
|
28304
|
-
return target;
|
|
28305
|
-
}
|
|
28306
|
-
function clearStaleTermPred(v2) {
|
|
28307
|
-
v2.term = void 0;
|
|
28308
|
-
v2.pred = void 0;
|
|
28309
|
-
}
|
|
28310
|
-
function currentExecPhi() {
|
|
28311
|
-
return phi;
|
|
28312
|
-
}
|
|
28313
|
-
function withExecPhi(p, body) {
|
|
28314
|
-
const prev = phi;
|
|
28315
|
-
phi = p;
|
|
28316
|
-
try {
|
|
28317
|
-
return body();
|
|
28318
|
-
} finally {
|
|
28319
|
-
phi = prev;
|
|
28320
|
-
}
|
|
28321
|
-
}
|
|
28322
|
-
function asAbsVal(v2) {
|
|
28323
|
-
if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
|
|
28324
|
-
if (typeof v2 === "function") {
|
|
28325
|
-
const n = Math.max(0, v2.length);
|
|
28326
|
-
const params = Array.from({ length: n }, (_, i) => `arg${i}`);
|
|
28327
|
-
return absFunction(params, {
|
|
28328
|
-
body: noBody2,
|
|
28329
|
-
// 与 $fnVal / $callNamed 同边界:callee 的 NudoReturn 不得冒泡成 caller
|
|
28330
|
-
apply: (args) => callAtFunctionBoundary(() => v2(...args))
|
|
28331
|
-
});
|
|
28332
|
-
}
|
|
28333
|
-
return $lit(v2);
|
|
28334
|
-
}
|
|
28335
|
-
function callAtFunctionBoundary(body) {
|
|
28336
|
-
let forwarded = [];
|
|
28337
|
-
try {
|
|
28338
|
-
return runWithLoopExits(() => {
|
|
28339
|
-
try {
|
|
28340
|
-
const r = body();
|
|
28341
|
-
forwarded = takeThrowExits();
|
|
28342
|
-
return r;
|
|
28343
|
-
} catch (e) {
|
|
28344
|
-
forwarded = takeThrowExits();
|
|
28345
|
-
if (isNudoReturn(e)) return e.absValue;
|
|
28346
|
-
throw e;
|
|
28347
|
-
}
|
|
28348
|
-
});
|
|
28349
|
-
} finally {
|
|
28350
|
-
for (const x of forwarded) pushThrowExit(x);
|
|
28351
|
-
}
|
|
28352
|
-
}
|
|
28353
|
-
function $fnVal(params, impl, opts) {
|
|
28354
|
-
return absFunction(params, {
|
|
28355
|
-
body: noBody2,
|
|
28356
|
-
// bindThis(对象方法):receiver 走首参注入,无宿主 this;
|
|
28357
|
-
// 非方法 fn:宿主 this 传递(call/apply/bind 的 thisArg 经 $rawThis 进入函数体)
|
|
28358
|
-
apply: opts?.bindThis ? (args) => callAtFunctionBoundary(() => impl(...args)) : (args, thisVal) => callAtFunctionBoundary(() => impl.apply(thisVal, args)),
|
|
28359
|
-
...opts?.bindThis ? { bindThis: true } : {}
|
|
28360
|
-
});
|
|
28361
|
-
}
|
|
28362
|
-
function $rawThis(v2) {
|
|
28363
|
-
if (v2 === void 0 || v2 === globalThis) return $lit(void 0);
|
|
28364
|
-
if (v2 && typeof v2 === "object" && "shape" in v2) return v2;
|
|
28365
|
-
return $lit(v2);
|
|
28366
|
-
}
|
|
28367
|
-
function throwStrictWrite() {
|
|
28368
|
-
throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
28369
|
-
}
|
|
28370
|
-
function $throwConstAssign() {
|
|
28371
|
-
throw new NudoThrow(errorTypeAbs("TypeError"));
|
|
28372
|
-
}
|
|
28373
|
-
function $litTruth(a) {
|
|
28374
|
-
return litTruth(a);
|
|
28375
|
-
}
|
|
28376
|
-
function $lit(v2) {
|
|
28377
|
-
if (v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2) {
|
|
28378
|
-
return v2;
|
|
28379
|
-
}
|
|
28380
|
-
return litAbsFromJs(v2);
|
|
28381
|
-
}
|
|
28382
|
-
function litAbsFromJs(v2, depth = 0) {
|
|
28383
|
-
if (v2 === null || v2 === void 0) {
|
|
28384
|
-
return abs({ k: "unknown" }, { op: "lit", value: v2 }, pTrue, "exact");
|
|
28385
|
-
}
|
|
28386
|
-
const t = typeof v2;
|
|
28387
|
-
if (t === "number" || t === "string" || t === "boolean" || t === "bigint") {
|
|
28388
|
-
return abs(
|
|
28389
|
-
{ k: "prim", type: t },
|
|
28390
|
-
{ op: "lit", value: v2 },
|
|
28391
|
-
pTrue,
|
|
28392
|
-
"exact"
|
|
28393
|
-
);
|
|
28394
|
-
}
|
|
28395
|
-
if (depth < 8) {
|
|
28396
|
-
if (Array.isArray(v2)) {
|
|
28397
|
-
const els = v2.map((x) => litAbsFromJs(x, depth + 1));
|
|
28398
|
-
if (shouldWidenArrayLiteral(els.length)) {
|
|
28399
|
-
return abs(
|
|
28400
|
-
{ k: "arr", element: els.reduce((x, y) => joinAbs(x, y)) },
|
|
28401
|
-
void 0,
|
|
28402
|
-
void 0,
|
|
28403
|
-
widenedArrayConf()
|
|
28404
|
-
);
|
|
28405
|
-
}
|
|
28406
|
-
return abs({ k: "tuple", elements: els }, void 0, void 0, "exact");
|
|
28407
|
-
}
|
|
28408
|
-
if (t === "object") {
|
|
28409
|
-
const proto = Object.getPrototypeOf(v2);
|
|
28410
|
-
if (proto === Object.prototype || proto === null) {
|
|
28411
|
-
const slots = {};
|
|
28412
|
-
for (const [k, val] of Object.entries(v2)) {
|
|
28413
|
-
Object.defineProperty(slots, k, {
|
|
28414
|
-
value: { value: litAbsFromJs(val, depth + 1) },
|
|
28415
|
-
enumerable: true,
|
|
28416
|
-
writable: true,
|
|
28417
|
-
configurable: true
|
|
28418
|
-
});
|
|
28419
|
-
}
|
|
28420
|
-
return objOf(slots);
|
|
28421
|
-
}
|
|
28422
|
-
}
|
|
28423
|
-
}
|
|
28424
|
-
return unknown;
|
|
28425
|
-
}
|
|
28426
|
-
function litTruth(a) {
|
|
28427
|
-
if (a.term?.op === "lit") {
|
|
28428
|
-
return Boolean(a.term.value);
|
|
28429
|
-
}
|
|
28430
|
-
switch (a.shape.k) {
|
|
28431
|
-
case "obj":
|
|
28432
|
-
case "arr":
|
|
28433
|
-
case "tuple":
|
|
28434
|
-
case "fn":
|
|
28435
|
-
case "brand":
|
|
28436
|
-
case "eff":
|
|
28437
|
-
return true;
|
|
28438
|
-
case "prim":
|
|
28439
|
-
return a.shape.type === "symbol" ? true : void 0;
|
|
28440
|
-
case "never":
|
|
28441
|
-
return false;
|
|
28442
|
-
default:
|
|
28443
|
-
return void 0;
|
|
28444
|
-
}
|
|
28445
|
-
}
|
|
28446
|
-
function isDefinitelyTrue(a) {
|
|
28447
|
-
return litTruth(a) === true;
|
|
28448
|
-
}
|
|
28449
|
-
function isDefinitelyFalse(a) {
|
|
28450
|
-
const t = litTruth(a);
|
|
28451
|
-
if (t === false) return true;
|
|
28452
|
-
if (a.shape.k === "never") return true;
|
|
28453
|
-
return false;
|
|
28454
|
-
}
|
|
28455
|
-
function undef() {
|
|
28456
|
-
return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
|
|
28457
|
-
}
|
|
28458
|
-
function runWithLoopExits(body) {
|
|
28459
|
-
return loopExitsAls.run(
|
|
28460
|
-
[],
|
|
28461
|
-
() => throwExitsAls.run(
|
|
28462
|
-
[],
|
|
28463
|
-
() => tryMarksAls.run([], () => softFrameActiveAls.run([], body))
|
|
28464
|
-
)
|
|
28465
|
-
);
|
|
28466
|
-
}
|
|
28467
|
-
function takeLoopExits() {
|
|
28468
|
-
return loopExitsAls.getStore() ?? [];
|
|
28469
|
-
}
|
|
28470
|
-
function takeThrowExits() {
|
|
28471
|
-
return throwExitsAls.getStore() ?? [];
|
|
28472
|
-
}
|
|
28473
|
-
function pushLoopExit(v2) {
|
|
28474
|
-
loopExitsAls.getStore()?.push(v2);
|
|
28475
|
-
}
|
|
28476
|
-
function pushThrowExit(v2) {
|
|
28477
|
-
throwExitsAls.getStore()?.push(v2);
|
|
28478
|
-
}
|
|
28479
|
-
function $pushLoopExit(v2) {
|
|
28480
|
-
pushLoopExit(v2);
|
|
28481
|
-
}
|
|
28482
|
-
function $tryMark() {
|
|
28483
|
-
$tryMarkSoft();
|
|
28484
|
-
softFrameActiveAls.getStore()?.push(true);
|
|
28485
|
-
const store = throwExitsAls.getStore();
|
|
28486
|
-
const m = store?.length ?? 0;
|
|
28487
|
-
tryMarksAls.getStore()?.push(m);
|
|
28488
|
-
return m;
|
|
28489
|
-
}
|
|
28490
|
-
function $tryCurrentMark() {
|
|
28491
|
-
const stack = tryMarksAls.getStore();
|
|
28492
|
-
return stack && stack.length > 0 ? stack[stack.length - 1] : 0;
|
|
28493
|
-
}
|
|
28494
|
-
function $tryPopMark() {
|
|
28495
|
-
tryMarksAls.getStore()?.pop();
|
|
28496
|
-
const soft = softFrameActiveAls.getStore();
|
|
28497
|
-
if (soft && soft.length > 0) {
|
|
28498
|
-
if (soft[soft.length - 1]) $tryReleaseSoftOut();
|
|
28499
|
-
soft.pop();
|
|
28500
|
-
}
|
|
28501
|
-
}
|
|
28502
|
-
function $tryTakeSince(mark) {
|
|
28503
|
-
const store = throwExitsAls.getStore();
|
|
28504
|
-
if (!store) return [];
|
|
28505
|
-
return store.splice(Math.min(mark, store.length));
|
|
28506
|
-
}
|
|
28507
|
-
function peekThrowExitsSince(mark) {
|
|
28508
|
-
const store = throwExitsAls.getStore();
|
|
28509
|
-
if (!store) return [];
|
|
28510
|
-
return store.slice(Math.min(mark, store.length));
|
|
28511
|
-
}
|
|
28512
|
-
function throwExitsMark() {
|
|
28513
|
-
return throwExitsAls.getStore()?.length ?? 0;
|
|
28514
|
-
}
|
|
28515
|
-
function $tryDigestSoftCatch() {
|
|
28516
|
-
const soft = softFrameActiveAls.getStore();
|
|
28517
|
-
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
|
|
28518
|
-
$tryDigestSoft();
|
|
28519
|
-
soft[soft.length - 1] = false;
|
|
28520
|
-
}
|
|
28521
|
-
function $tryReleaseSoftCatch() {
|
|
28522
|
-
const soft = softFrameActiveAls.getStore();
|
|
28523
|
-
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
|
|
28524
|
-
$tryReleaseSoft();
|
|
28525
|
-
soft[soft.length - 1] = false;
|
|
28526
|
-
}
|
|
28527
|
-
function $tryDetachSoftCatch() {
|
|
28528
|
-
const soft = softFrameActiveAls.getStore();
|
|
28529
|
-
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return [];
|
|
28530
|
-
const effects = popMayThrowFrame(false);
|
|
28531
|
-
soft[soft.length - 1] = false;
|
|
28532
|
-
return effects;
|
|
28533
|
-
}
|
|
28534
|
-
function $tryDiscardSoft(_effects) {
|
|
28535
|
-
}
|
|
28536
|
-
function $tryOrphanSoft(effects) {
|
|
28537
|
-
orphanMayThrowEffects(effects);
|
|
28538
|
-
}
|
|
28539
|
-
function $tryReleaseSoftOut() {
|
|
28540
|
-
const soft = softFrameActiveAls.getStore();
|
|
28541
|
-
if (!soft || soft.length === 0 || !soft[soft.length - 1]) return;
|
|
28542
|
-
$tryReleaseSoft();
|
|
28543
|
-
soft[soft.length - 1] = false;
|
|
28544
|
-
}
|
|
28545
|
-
function isNudoReturn(e) {
|
|
28546
|
-
return e instanceof NudoReturn;
|
|
28547
|
-
}
|
|
28548
|
-
function $loopReturn(v2) {
|
|
28549
|
-
throw new NudoReturn(v2);
|
|
28550
|
-
}
|
|
28551
|
-
function $loopBreak(label) {
|
|
28552
|
-
throw new NudoLoopSignal("break", label || void 0);
|
|
28553
|
-
}
|
|
28554
|
-
function $loopContinue(label) {
|
|
28555
|
-
throw new NudoLoopSignal("continue", label || void 0);
|
|
28556
|
-
}
|
|
28557
|
-
function loopSignalMatches(e, label) {
|
|
28558
|
-
return e.label === void 0 || e.label === label;
|
|
28559
|
-
}
|
|
28560
|
-
function isNudoBreak(e, label) {
|
|
28561
|
-
return e instanceof NudoLoopSignal && e.kind === "break" && loopSignalMatches(e, label);
|
|
28562
|
-
}
|
|
28563
|
-
function isNudoContinue(e, label) {
|
|
28564
|
-
return e instanceof NudoLoopSignal && e.kind === "continue" && loopSignalMatches(e, label);
|
|
28565
|
-
}
|
|
28566
|
-
function $isBreakTo(e, label) {
|
|
28567
|
-
return e instanceof NudoLoopSignal && e.kind === "break" && e.label === label;
|
|
28568
|
-
}
|
|
28569
|
-
function $rethrowIfNudoReturn(e) {
|
|
28570
|
-
if (isNudoReturn(e)) throw e;
|
|
28571
|
-
}
|
|
28572
|
-
var phi, noBody2, loopExitsAls, throwExitsAls, tryMarksAls, softFrameActiveAls, NudoReturn, NudoLoopSignal;
|
|
28573
|
-
var init_state = __esm({
|
|
28574
|
-
"../core/src/algebra/exec/runtime/state.ts"() {
|
|
28575
|
-
"use strict";
|
|
28576
|
-
init_abs();
|
|
28577
|
-
init_pred();
|
|
28578
|
-
init_abs_fn();
|
|
28579
|
-
init_nudo_throw();
|
|
28580
|
-
init_may_throw();
|
|
28581
|
-
init_containers();
|
|
28582
|
-
init_objects();
|
|
28583
|
-
phi = pTrue;
|
|
28584
|
-
noBody2 = { type: "BlockStatement", body: [], directives: [] };
|
|
28585
|
-
loopExitsAls = new AsyncLocalStorage2();
|
|
28586
|
-
throwExitsAls = new AsyncLocalStorage2();
|
|
28587
|
-
tryMarksAls = new AsyncLocalStorage2();
|
|
28588
|
-
softFrameActiveAls = new AsyncLocalStorage2();
|
|
28589
|
-
NudoReturn = class extends Error {
|
|
28590
|
-
absValue;
|
|
28591
|
-
constructor(absValue) {
|
|
28592
|
-
super("nudo:return");
|
|
28593
|
-
this.name = "NudoReturn";
|
|
28594
|
-
this.absValue = absValue;
|
|
28595
|
-
}
|
|
28596
|
-
};
|
|
28597
|
-
NudoLoopSignal = class extends Error {
|
|
28598
|
-
kind;
|
|
28599
|
-
label;
|
|
28600
|
-
constructor(kind, label) {
|
|
28601
|
-
super("nudo:loop");
|
|
28602
|
-
this.name = "NudoLoopSignal";
|
|
28603
|
-
this.kind = kind;
|
|
28604
|
-
this.label = label;
|
|
28605
|
-
}
|
|
28606
|
-
};
|
|
28607
|
-
}
|
|
28608
|
-
});
|
|
28609
|
-
|
|
28610
28816
|
// ../core/src/algebra/exec/runtime/ops.ts
|
|
28611
28817
|
function $unknown() {
|
|
28612
28818
|
return abs({ k: "unknown" }, void 0, void 0, "opaque");
|
|
@@ -29173,7 +29379,7 @@ function $instanceofNonIdent(_left) {
|
|
|
29173
29379
|
}
|
|
29174
29380
|
function $classExpr() {
|
|
29175
29381
|
return absFunction(["_rest"], {
|
|
29176
|
-
body:
|
|
29382
|
+
body: noBody,
|
|
29177
29383
|
apply: () => unknown
|
|
29178
29384
|
});
|
|
29179
29385
|
}
|
|
@@ -30100,7 +30306,7 @@ function $get(o, key, opts) {
|
|
|
30100
30306
|
const raw = o[key];
|
|
30101
30307
|
if (typeof raw === "function") {
|
|
30102
30308
|
return absFunction([`${ns}.${key}`], {
|
|
30103
|
-
body:
|
|
30309
|
+
body: noBody,
|
|
30104
30310
|
apply: (args) => evalNamespaceCall(ns, key, args) ?? unknown
|
|
30105
30311
|
});
|
|
30106
30312
|
}
|
|
@@ -30119,7 +30325,7 @@ function $get(o, key, opts) {
|
|
|
30119
30325
|
}
|
|
30120
30326
|
if (o.shape.k === "eff" && o.shape.eff === "promise" && (key === "then" || key === "catch" || key === "finally")) {
|
|
30121
30327
|
return absFunction([key === "then" ? "onFulfilled" : key === "catch" ? "onRejected" : "onFinally"], {
|
|
30122
|
-
body:
|
|
30328
|
+
body: noBody
|
|
30123
30329
|
});
|
|
30124
30330
|
}
|
|
30125
30331
|
if (o.shape.k === "brand") {
|
|
@@ -30130,7 +30336,7 @@ function $get(o, key, opts) {
|
|
|
30130
30336
|
const isClassVal = classNameOfValue(o) === o.shape.name;
|
|
30131
30337
|
const builtinM = BUILTIN_BRAND_METHODS[o.shape.name];
|
|
30132
30338
|
if (builtinM && !isClassVal && (key === "@@iterator" || builtinM.has(key))) {
|
|
30133
|
-
return absFunction([], { body:
|
|
30339
|
+
return absFunction([], { body: noBody });
|
|
30134
30340
|
}
|
|
30135
30341
|
if (key === "size" && o.shape.name === "Map") return mapSizeAbs(o);
|
|
30136
30342
|
if (key === "size" && o.shape.name === "Set") return setSizeAbs(o);
|
|
@@ -30146,14 +30352,14 @@ function $get(o, key, opts) {
|
|
|
30146
30352
|
for (const n of evalClassChain(o.shape.name)) {
|
|
30147
30353
|
const spec = getEvalClass(n);
|
|
30148
30354
|
if (spec?.staticMethods?.[key]) {
|
|
30149
|
-
return absFunction(spec.staticMethodParams?.[key] ?? [], { body:
|
|
30355
|
+
return absFunction(spec.staticMethodParams?.[key] ?? [], { body: noBody });
|
|
30150
30356
|
}
|
|
30151
30357
|
}
|
|
30152
30358
|
if (key === "prototype") {
|
|
30153
30359
|
return abs({ k: "obj", slots: {} }, void 0, void 0, "path");
|
|
30154
30360
|
}
|
|
30155
30361
|
if (key === "call" || key === "apply" || key === "bind") {
|
|
30156
|
-
return absFunction([], { body:
|
|
30362
|
+
return absFunction([], { body: noBody });
|
|
30157
30363
|
}
|
|
30158
30364
|
} else {
|
|
30159
30365
|
const acc = findClassAccessor(o.shape.name, key);
|
|
@@ -30162,7 +30368,7 @@ function $get(o, key, opts) {
|
|
|
30162
30368
|
for (const n of evalClassChain(o.shape.name)) {
|
|
30163
30369
|
const spec = getEvalClass(n);
|
|
30164
30370
|
if (spec?.methods?.[key]) {
|
|
30165
|
-
return absFunction(spec.methodParams?.[key] ?? [], { body:
|
|
30371
|
+
return absFunction(spec.methodParams?.[key] ?? [], { body: noBody });
|
|
30166
30372
|
}
|
|
30167
30373
|
}
|
|
30168
30374
|
}
|
|
@@ -36268,60 +36474,92 @@ function isBoundedEvidenceMissing(ret, constraint) {
|
|
|
36268
36474
|
if (ret.pred && ret.pred.op !== "true") return false;
|
|
36269
36475
|
return true;
|
|
36270
36476
|
}
|
|
36477
|
+
function flattenSumArms(ret) {
|
|
36478
|
+
if (ret.shape.k !== "sum") return [ret];
|
|
36479
|
+
const out = [];
|
|
36480
|
+
for (const m of ret.shape.members) {
|
|
36481
|
+
if (m.shape.k === "sum") out.push(...flattenSumArms(m));
|
|
36482
|
+
else out.push(m);
|
|
36483
|
+
}
|
|
36484
|
+
return out;
|
|
36485
|
+
}
|
|
36486
|
+
function isWidenedSumArm(m, parent) {
|
|
36487
|
+
return parent.conf === "partial" && m.shape.k === "prim" && !m.term && (!m.pred || m.pred.op === "true");
|
|
36488
|
+
}
|
|
36271
36489
|
function assertImplies(ret, constraint, opts) {
|
|
36272
36490
|
const phi2 = opts?.phi ?? pTrue;
|
|
36273
36491
|
if (ret.shape.k === "never") return proved();
|
|
36274
36492
|
if (isAnyConstraint(constraint)) return proved();
|
|
36275
|
-
const nullishOk = constraintAdmitsNullish(constraint);
|
|
36276
|
-
if (isNullishLitAbs(ret)) {
|
|
36277
|
-
return nullishOk ? proved() : disproved(`nullish return \u22AD ${formatConstraint(constraint)}`);
|
|
36278
|
-
}
|
|
36279
|
-
let sumMembers;
|
|
36280
|
-
if (ret.shape.k === "sum") {
|
|
36281
|
-
const members = ret.shape.members;
|
|
36282
|
-
const nullishMembers = members.filter((m) => isNullishLitAbs(m));
|
|
36283
|
-
if (nullishMembers.length > 0 && !nullishOk) {
|
|
36284
|
-
return disproved(
|
|
36285
|
-
`nullish return arm \u22AD ${formatConstraint(constraint)} (contract does not admit nullish)`
|
|
36286
|
-
);
|
|
36287
|
-
}
|
|
36288
|
-
sumMembers = members.filter((m) => !isNullishLitAbs(m));
|
|
36289
|
-
}
|
|
36290
36493
|
if (isValueSetUnknown(ret)) {
|
|
36291
36494
|
return unprovable(
|
|
36292
36495
|
ret.shape.k === "any" ? "any does not establish the return contract" : "inference failure (unknown/opaque) \u2014 cannot prove the return contract"
|
|
36293
36496
|
);
|
|
36294
36497
|
}
|
|
36498
|
+
const arms = flattenSumArms(ret);
|
|
36499
|
+
if (arms.length > 1) {
|
|
36500
|
+
return assertSumArms(arms, ret, constraint, opts, phi2);
|
|
36501
|
+
}
|
|
36502
|
+
return assertImpliesSingle(arms[0], constraint, opts, phi2);
|
|
36503
|
+
}
|
|
36504
|
+
function assertSumArms(arms, parent, constraint, opts, phi2) {
|
|
36505
|
+
const hasWidenedArm = arms.some(
|
|
36506
|
+
(a) => isValueSetUnknown(a) || isWidenedSumArm(a, parent)
|
|
36507
|
+
);
|
|
36508
|
+
let sawUnprovable = false;
|
|
36509
|
+
for (const arm of arms) {
|
|
36510
|
+
if (isNullishLitAbs(arm)) {
|
|
36511
|
+
if (!constraintAdmitsNullish(constraint)) {
|
|
36512
|
+
return disproved(
|
|
36513
|
+
`nullish return arm \u22AD ${formatConstraint(constraint)} (contract does not admit nullish)`
|
|
36514
|
+
);
|
|
36515
|
+
}
|
|
36516
|
+
continue;
|
|
36517
|
+
}
|
|
36518
|
+
if (isValueSetUnknown(arm) || isWidenedSumArm(arm, parent)) {
|
|
36519
|
+
sawUnprovable = true;
|
|
36520
|
+
continue;
|
|
36521
|
+
}
|
|
36522
|
+
const r = assertImpliesSingle(arm, constraint, opts, phi2);
|
|
36523
|
+
if (r.status === "disproved") {
|
|
36524
|
+
if (hasWidenedArm) {
|
|
36525
|
+
sawUnprovable = true;
|
|
36526
|
+
continue;
|
|
36527
|
+
}
|
|
36528
|
+
return r;
|
|
36529
|
+
}
|
|
36530
|
+
if (r.status === "unprovable") sawUnprovable = true;
|
|
36531
|
+
}
|
|
36532
|
+
return sawUnprovable ? unprovable("sum: some arms unprovable") : proved();
|
|
36533
|
+
}
|
|
36534
|
+
function assertImpliesSingle(arm, constraint, opts, phi2) {
|
|
36535
|
+
if (isNullishLitAbs(arm)) {
|
|
36536
|
+
return constraintAdmitsNullish(constraint) ? proved() : disproved(`nullish return \u22AD ${formatConstraint(constraint)}`);
|
|
36537
|
+
}
|
|
36538
|
+
if (isValueSetUnknown(arm)) {
|
|
36539
|
+
return unprovable(
|
|
36540
|
+
arm.shape.k === "any" ? "any does not establish the return contract" : "inference failure (unknown/opaque) \u2014 cannot prove the return contract"
|
|
36541
|
+
);
|
|
36542
|
+
}
|
|
36295
36543
|
if (constraint.members && constraint.members.length > 0) {
|
|
36296
36544
|
let sawUnprovable = false;
|
|
36297
36545
|
for (const m of constraint.members) {
|
|
36298
|
-
const r = assertImplies(
|
|
36546
|
+
const r = assertImplies(arm, m, opts);
|
|
36299
36547
|
if (r.status === "proved") return proved();
|
|
36300
36548
|
if (r.status === "unprovable") sawUnprovable = true;
|
|
36301
36549
|
}
|
|
36302
36550
|
return sawUnprovable ? unprovable("union: no member proved the return contract") : disproved(`return \u22AD union(${constraint.members.map((m) => formatConstraint(m)).join(", ")})`);
|
|
36303
36551
|
}
|
|
36304
|
-
if (sumMembers && (constraint.fields || constraint.element)) {
|
|
36305
|
-
let sawUnprovable = false;
|
|
36306
|
-
for (const m of sumMembers) {
|
|
36307
|
-
if (isValueSetUnknown(m)) continue;
|
|
36308
|
-
const r = assertImplies(m, constraint, opts);
|
|
36309
|
-
if (r.status === "disproved") return r;
|
|
36310
|
-
if (r.status === "unprovable") sawUnprovable = true;
|
|
36311
|
-
}
|
|
36312
|
-
return sawUnprovable ? unprovable("sum: some arms unprovable") : proved();
|
|
36313
|
-
}
|
|
36314
36552
|
if (constraint.fields) {
|
|
36315
|
-
return assertShapeFields(
|
|
36553
|
+
return assertShapeFields(arm, constraint, opts);
|
|
36316
36554
|
}
|
|
36317
36555
|
if (constraint.element) {
|
|
36318
|
-
if (
|
|
36319
|
-
return disproved(`return shape ${
|
|
36556
|
+
if (arm.shape.k !== "arr" && arm.shape.k !== "tuple") {
|
|
36557
|
+
return disproved(`return shape ${arm.shape.k} \u22AD array(...)`);
|
|
36320
36558
|
}
|
|
36321
36559
|
return proved();
|
|
36322
36560
|
}
|
|
36323
36561
|
if (constraint.fn) return proved();
|
|
36324
|
-
return assertScalar(
|
|
36562
|
+
return assertScalar(arm, constraint, phi2);
|
|
36325
36563
|
}
|
|
36326
36564
|
function isAnyConstraint(c) {
|
|
36327
36565
|
return !c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.members && !c.fn && !isIntFlag(c);
|
|
@@ -39360,7 +39598,7 @@ function checkSourceInner(filePath, source, file, phi2, opts, issues, signatures
|
|
|
39360
39598
|
message: `${name} (export): may throw ${gateDisplay}`,
|
|
39361
39599
|
actual: `${name}(\u2026) throws ${gateDisplay}`,
|
|
39362
39600
|
expected: "entry total, or @nudo:throws / try-catch",
|
|
39363
|
-
suggestion: first.cause ? `${first.cause} \u2192 ${first.kind === "ReferenceError" ? "re-export `export { x } from` \u4E0D\u662F\u5C40\u90E8\u7ED1\u5B9A\u2014\u2014\u6539 `import { x }` / @nudo:throws ReferenceError" : `@nudo:throws ${first.kind}
|
|
39601
|
+
suggestion: first.cause ? `${first.cause} \u2192 ${first.kind === "ReferenceError" ? "re-export `export { x } from` \u4E0D\u662F\u5C40\u90E8\u7ED1\u5B9A\u2014\u2014\u6539 `import { x }` / @nudo:throws ReferenceError" : `@nudo:throws ${first.kind} | sidecar: fn({ \u2026 }): shape({ <body-read fields> }) | refine / guard / try-catch`}` : first.kind === "ReferenceError" ? "re-export `export { x } from` \u4E0D\u662F\u5C40\u90E8\u7ED1\u5B9A\u2014\u2014\u6539 `import { x }` / @nudo:throws ReferenceError" : `@nudo:throws ${first.kind} | sidecar: fn({ \u2026 }): shape({ <body-read fields> }) | refine / guard / try-catch`,
|
|
39364
39602
|
fn: name,
|
|
39365
39603
|
...loc.line !== void 0 ? { line: loc.line } : {},
|
|
39366
39604
|
...loc.column !== void 0 ? { column: loc.column } : {}
|
|
@@ -39405,7 +39643,7 @@ function checkSourceInner(filePath, source, file, phi2, opts, issues, signatures
|
|
|
39405
39643
|
message: `${name} (export): may throw ${gateDisplay}`,
|
|
39406
39644
|
actual: `${formatEntrySigLine(name, g, gateDisplay)}`,
|
|
39407
39645
|
expected: "entry total, or @nudo:throws / try-catch",
|
|
39408
|
-
suggestion: first.cause ? `${first.cause} \u2192 ${first.kind === "ReferenceError" ? "re-export `export { x } from` \u4E0D\u662F\u5C40\u90E8\u7ED1\u5B9A\u2014\u2014\u6539 `import { x }` / @nudo:throws ReferenceError" : `@nudo:throws ${first.kind}
|
|
39646
|
+
suggestion: first.cause ? `${first.cause} \u2192 ${first.kind === "ReferenceError" ? "re-export `export { x } from` \u4E0D\u662F\u5C40\u90E8\u7ED1\u5B9A\u2014\u2014\u6539 `import { x }` / @nudo:throws ReferenceError" : `@nudo:throws ${first.kind} | sidecar: fn({ \u2026 }): shape({ <body-read fields> }) | refine / guard / try-catch`}` : first.kind === "ReferenceError" ? "re-export `export { x } from` \u4E0D\u662F\u5C40\u90E8\u7ED1\u5B9A\u2014\u2014\u6539 `import { x }` / @nudo:throws ReferenceError" : `@nudo:throws ${first.kind} | sidecar: fn({ \u2026 }): shape({ <body-read fields> }) | refine / guard / try-catch`,
|
|
39409
39647
|
fn: name,
|
|
39410
39648
|
...loc.line !== void 0 ? { line: loc.line } : {},
|
|
39411
39649
|
...loc.column !== void 0 ? { column: loc.column } : {}
|
|
@@ -39805,6 +40043,19 @@ function actionsForIssue(i) {
|
|
|
39805
40043
|
label: "migration switch: ignore this throw class on L2"
|
|
39806
40044
|
}
|
|
39807
40045
|
];
|
|
40046
|
+
case "nudo:unproven-return":
|
|
40047
|
+
return [
|
|
40048
|
+
{
|
|
40049
|
+
kind: "relax",
|
|
40050
|
+
label: `relax the return contract${i.fn ? ` of ${i.fn}` : ""} to the inferred surface (review the diff \u2014 not a silent green)`,
|
|
40051
|
+
...i.expected ? { hint: i.expected } : {}
|
|
40052
|
+
},
|
|
40053
|
+
draft,
|
|
40054
|
+
{
|
|
40055
|
+
kind: "info",
|
|
40056
|
+
label: "or narrow the return expression / add a precondition so the bound is implied"
|
|
40057
|
+
}
|
|
40058
|
+
];
|
|
39808
40059
|
case "nudo:unknown-inference":
|
|
39809
40060
|
case "nudo:opaque-result":
|
|
39810
40061
|
return [
|
|
@@ -277240,14 +277491,20 @@ __export(emit_exports, {
|
|
|
277240
277491
|
absToStandardSchemaModule: () => absToStandardSchemaModule,
|
|
277241
277492
|
absToTSType: () => absToTSType,
|
|
277242
277493
|
absToZodSchemaModule: () => absToZodSchemaModule,
|
|
277494
|
+
addBudgetAnnotation: () => addBudgetAnnotation,
|
|
277495
|
+
addThrowsAnnotation: () => addThrowsAnnotation,
|
|
277496
|
+
applyTextEdits: () => applyTextEdits,
|
|
277497
|
+
bodyReadFieldsFor: () => bodyReadFieldsFor,
|
|
277243
277498
|
buildCaseDirective: () => buildCaseDirective,
|
|
277244
277499
|
collectParamBodyAccesses: () => collectParamBodyAccesses,
|
|
277500
|
+
collectParamBodyReadTypes: () => collectParamBodyReadTypes,
|
|
277245
277501
|
constraintToSchemaNode: () => constraintToSchemaNode,
|
|
277246
277502
|
deriveFromRoot: () => deriveFromRoot,
|
|
277247
277503
|
draftInterface: () => draftInterface,
|
|
277248
277504
|
emitDerivedFromRoot: () => emitDerivedFromRoot,
|
|
277249
277505
|
emitInterface: () => emitInterface,
|
|
277250
277506
|
extractFnConstraintSources: () => extractFnConstraintSources,
|
|
277507
|
+
findFnDeclStart: () => findFnDeclStart,
|
|
277251
277508
|
formatDerivedSection: () => formatDerivedSection,
|
|
277252
277509
|
formatDraftModule: () => formatDraftModule,
|
|
277253
277510
|
formatDraftSummary: () => formatDraftSummary,
|
|
@@ -277261,15 +277518,19 @@ __export(emit_exports, {
|
|
|
277261
277518
|
insertGeneratedCaseDirectives: () => insertGeneratedCaseDirectives,
|
|
277262
277519
|
interfaceSurface: () => interfaceSurface,
|
|
277263
277520
|
isDraftableEntry: () => isDraftableEntry,
|
|
277521
|
+
materializeAction: () => materializeAction,
|
|
277264
277522
|
projectAbsToSchema: () => projectAbsToSchema,
|
|
277265
277523
|
schemaNodeToZod: () => schemaNodeToZod,
|
|
277266
277524
|
serializeCaseArg: () => serializeCaseArg,
|
|
277267
277525
|
serializeCaseJson: () => serializeCaseJson,
|
|
277526
|
+
shapeDslFromFields: () => shapeDslFromFields,
|
|
277268
277527
|
sidecarDraftPath: () => sidecarDraftPath,
|
|
277269
277528
|
stripGeneratedCaseDirectives: () => stripGeneratedCaseDirectives,
|
|
277529
|
+
titleKindFor: () => titleKindFor,
|
|
277270
277530
|
typeExprToDirective: () => typeExprToDirective2,
|
|
277271
277531
|
unifiedDiff: () => unifiedDiff,
|
|
277272
277532
|
validateSchemaNode: () => validateSchemaNode,
|
|
277533
|
+
wrapReturnNullable: () => wrapReturnNullable,
|
|
277273
277534
|
writeInterfaceDraft: () => writeInterfaceDraft
|
|
277274
277535
|
});
|
|
277275
277536
|
import { readFileSync as readFileSync19, existsSync as existsSync18 } from "fs";
|
|
@@ -278123,6 +278384,302 @@ function joinSections(base, sectionTexts) {
|
|
|
278123
278384
|
`;
|
|
278124
278385
|
return lead + normalized.join("\n");
|
|
278125
278386
|
}
|
|
278387
|
+
function keyOf(node) {
|
|
278388
|
+
if (!node) return void 0;
|
|
278389
|
+
if (node.type === "Identifier") return node.name;
|
|
278390
|
+
if (node.type === "StringLiteral") return node.value;
|
|
278391
|
+
return void 0;
|
|
278392
|
+
}
|
|
278393
|
+
function litKind(node) {
|
|
278394
|
+
if (!node) return void 0;
|
|
278395
|
+
if (node.type === "StringLiteral") return "string";
|
|
278396
|
+
if (node.type === "NumericLiteral") return "number";
|
|
278397
|
+
if (node.type === "BooleanLiteral") return "boolean";
|
|
278398
|
+
return void 0;
|
|
278399
|
+
}
|
|
278400
|
+
function hintFromUse(parent, key) {
|
|
278401
|
+
if (!parent) return void 0;
|
|
278402
|
+
const t = parent.type;
|
|
278403
|
+
if (t === "BinaryExpression") {
|
|
278404
|
+
const op = parent.operator;
|
|
278405
|
+
const other = key === "left" ? parent.right : parent.left;
|
|
278406
|
+
const lk = litKind(other);
|
|
278407
|
+
if (op === "===" || op === "==" || op === "!==" || op === "!=") {
|
|
278408
|
+
if (lk === "string") return { type: "string()", via: "compare string lit" };
|
|
278409
|
+
if (lk === "number") return { type: "number()", via: "compare number lit" };
|
|
278410
|
+
if (lk === "boolean") return { type: "boolean()", via: "compare boolean lit" };
|
|
278411
|
+
}
|
|
278412
|
+
if (op === "+") {
|
|
278413
|
+
if (lk === "number") return { type: "number()", via: "add number" };
|
|
278414
|
+
if (lk === "string") return { type: "string()", via: "concat string" };
|
|
278415
|
+
return { type: "any()", via: "add (unknown coerce)" };
|
|
278416
|
+
}
|
|
278417
|
+
if (op === "-" || op === "*" || op === "/" || op === "%" || op === "**") {
|
|
278418
|
+
return { type: "number()", via: `arith ${op}` };
|
|
278419
|
+
}
|
|
278420
|
+
if (op === "<" || op === ">" || op === "<=" || op === ">=") {
|
|
278421
|
+
return { type: "number()", via: `rel ${op}` };
|
|
278422
|
+
}
|
|
278423
|
+
return void 0;
|
|
278424
|
+
}
|
|
278425
|
+
if (t === "UnaryExpression" && parent.operator === "!") {
|
|
278426
|
+
return { type: "boolean()", via: "truthiness" };
|
|
278427
|
+
}
|
|
278428
|
+
if (t === "MemberExpression" || t === "OptionalMemberExpression") {
|
|
278429
|
+
const prop = keyOf(parent.property);
|
|
278430
|
+
if (prop && STRING_METHODS2.has(prop) && prop !== "includes" && prop !== "indexOf" && prop !== "slice" && prop !== "concat" && prop !== "at") {
|
|
278431
|
+
return { type: "string()", via: `.${prop}()` };
|
|
278432
|
+
}
|
|
278433
|
+
if (prop && NUMBER_METHODS.has(prop)) {
|
|
278434
|
+
return { type: "number()", via: `.${prop}()` };
|
|
278435
|
+
}
|
|
278436
|
+
if (prop === "length") {
|
|
278437
|
+
return { type: "union(string(), array(any()))", via: ".length" };
|
|
278438
|
+
}
|
|
278439
|
+
if (prop === "size") {
|
|
278440
|
+
return { type: "any()", via: ".size (Set/Map)" };
|
|
278441
|
+
}
|
|
278442
|
+
if (prop && ARRAY_METHODS.has(prop)) {
|
|
278443
|
+
return { type: "array(any())", via: `.${prop}()` };
|
|
278444
|
+
}
|
|
278445
|
+
return void 0;
|
|
278446
|
+
}
|
|
278447
|
+
if (t === "CallExpression" || t === "OptionalCallExpression") {
|
|
278448
|
+
const callee = parent.callee;
|
|
278449
|
+
const cname = callee?.type === "Identifier" ? callee.name : void 0;
|
|
278450
|
+
if (cname === "String") return { type: "string()", via: "String()" };
|
|
278451
|
+
if (cname === "Number") return { type: "number()", via: "Number()" };
|
|
278452
|
+
if (cname === "Boolean") return { type: "boolean()", via: "Boolean()" };
|
|
278453
|
+
if (callee?.type === "MemberExpression" && callee.object?.type === "Identifier" && callee.object.name === "Array" && callee.property?.type === "Identifier" && callee.property.name === "isArray") {
|
|
278454
|
+
return { type: "array(any())", via: "Array.isArray" };
|
|
278455
|
+
}
|
|
278456
|
+
return void 0;
|
|
278457
|
+
}
|
|
278458
|
+
if (t === "UnaryExpression" && parent.operator === "typeof") {
|
|
278459
|
+
return void 0;
|
|
278460
|
+
}
|
|
278461
|
+
return void 0;
|
|
278462
|
+
}
|
|
278463
|
+
function hintFromTypeof(typeofNode, cmp2) {
|
|
278464
|
+
if (!typeofNode || !cmp2) return void 0;
|
|
278465
|
+
if (typeofNode.type !== "UnaryExpression" || typeofNode.operator !== "typeof") return void 0;
|
|
278466
|
+
if (cmp2.type !== "BinaryExpression") return void 0;
|
|
278467
|
+
const op = cmp2.operator;
|
|
278468
|
+
if (op !== "===" && op !== "==" && op !== "!==" && op !== "!=") return void 0;
|
|
278469
|
+
const other = cmp2.left === typeofNode ? cmp2.right : cmp2.left;
|
|
278470
|
+
const lk = litKind(other);
|
|
278471
|
+
if (lk !== "string") return void 0;
|
|
278472
|
+
const name = other?.value;
|
|
278473
|
+
const map = {
|
|
278474
|
+
string: "string()",
|
|
278475
|
+
number: "number()",
|
|
278476
|
+
boolean: "boolean()",
|
|
278477
|
+
object: "any()",
|
|
278478
|
+
function: "any()",
|
|
278479
|
+
undefined: "any()",
|
|
278480
|
+
bigint: "any()",
|
|
278481
|
+
symbol: "any()"
|
|
278482
|
+
};
|
|
278483
|
+
const type = name ? map[name] : void 0;
|
|
278484
|
+
if (!type) return void 0;
|
|
278485
|
+
return { type, via: `typeof === "${name}"` };
|
|
278486
|
+
}
|
|
278487
|
+
function collectParamBodyReadTypes(source) {
|
|
278488
|
+
const out = /* @__PURE__ */ new Map();
|
|
278489
|
+
let ast;
|
|
278490
|
+
try {
|
|
278491
|
+
ast = parse2(source);
|
|
278492
|
+
} catch {
|
|
278493
|
+
return out;
|
|
278494
|
+
}
|
|
278495
|
+
const visitFn = (fnName, fnNode, paramNames) => {
|
|
278496
|
+
if (paramNames.size === 0) return;
|
|
278497
|
+
const byParam = /* @__PURE__ */ new Map();
|
|
278498
|
+
const add2 = (pname, field, hint) => {
|
|
278499
|
+
if (!byParam.has(pname)) byParam.set(pname, /* @__PURE__ */ new Map());
|
|
278500
|
+
const fields = byParam.get(pname);
|
|
278501
|
+
if (!fields.has(field)) fields.set(field, []);
|
|
278502
|
+
if (hint) fields.get(field).push(hint);
|
|
278503
|
+
};
|
|
278504
|
+
const walk = (node, shadowed, parent, parentKey) => {
|
|
278505
|
+
if (!node || typeof node !== "object") return;
|
|
278506
|
+
const n = node;
|
|
278507
|
+
if ((n.type === "VariableDeclarator" || n.type === "FunctionDeclaration") && n.id?.type === "Identifier") {
|
|
278508
|
+
const id = n.id.name;
|
|
278509
|
+
if (paramNames.has(id)) shadowed = new Set(shadowed).add(id);
|
|
278510
|
+
}
|
|
278511
|
+
if (n.type === "UnaryExpression" && n.operator === "typeof") {
|
|
278512
|
+
const arg = n.argument;
|
|
278513
|
+
const mem = arg;
|
|
278514
|
+
if (mem && (mem.type === "MemberExpression" || mem.type === "OptionalMemberExpression")) {
|
|
278515
|
+
const obj2 = mem.object;
|
|
278516
|
+
const prop = mem.property;
|
|
278517
|
+
if (obj2?.type === "Identifier" && paramNames.has(obj2.name) && !shadowed.has(obj2.name) && prop && mem.computed !== true) {
|
|
278518
|
+
const key = keyOf(prop);
|
|
278519
|
+
const pname = obj2.name;
|
|
278520
|
+
if (key !== void 0) {
|
|
278521
|
+
const gp = parent;
|
|
278522
|
+
add2(pname, key, hintFromTypeof(n, gp));
|
|
278523
|
+
}
|
|
278524
|
+
}
|
|
278525
|
+
}
|
|
278526
|
+
}
|
|
278527
|
+
if (n.type === "MemberExpression" || n.type === "OptionalMemberExpression") {
|
|
278528
|
+
const obj2 = n.object;
|
|
278529
|
+
const prop = n.property;
|
|
278530
|
+
const computed = n.computed === true;
|
|
278531
|
+
if (obj2?.type === "Identifier" && paramNames.has(obj2.name) && !shadowed.has(obj2.name) && prop && !computed) {
|
|
278532
|
+
const key = keyOf(prop);
|
|
278533
|
+
const pname = obj2.name;
|
|
278534
|
+
if (key !== void 0) {
|
|
278535
|
+
const hint = hintFromUse(parent, parentKey ?? "object");
|
|
278536
|
+
add2(pname, key, hint);
|
|
278537
|
+
}
|
|
278538
|
+
}
|
|
278539
|
+
}
|
|
278540
|
+
for (const k of Object.keys(n)) {
|
|
278541
|
+
if (k === "loc" || k === "start" || k === "end") continue;
|
|
278542
|
+
const child = n[k];
|
|
278543
|
+
if (Array.isArray(child)) {
|
|
278544
|
+
for (const item of child) walk(item, shadowed, n, k);
|
|
278545
|
+
} else if (child && typeof child === "object") {
|
|
278546
|
+
walk(child, shadowed, n, k);
|
|
278547
|
+
}
|
|
278548
|
+
}
|
|
278549
|
+
};
|
|
278550
|
+
walk(fnNode, /* @__PURE__ */ new Set());
|
|
278551
|
+
if (byParam.size === 0) return;
|
|
278552
|
+
const fieldsOf = /* @__PURE__ */ new Map();
|
|
278553
|
+
for (const [pname, fieldMap] of byParam) {
|
|
278554
|
+
const list = [];
|
|
278555
|
+
for (const [field, hints] of fieldMap) {
|
|
278556
|
+
list.push({ field, ...mergeHints(hints) });
|
|
278557
|
+
}
|
|
278558
|
+
list.sort((a, b) => a.field < b.field ? -1 : 1);
|
|
278559
|
+
fieldsOf.set(pname, list);
|
|
278560
|
+
}
|
|
278561
|
+
out.set(fnName, fieldsOf);
|
|
278562
|
+
};
|
|
278563
|
+
const paramSet = (fnNode) => {
|
|
278564
|
+
const names2 = /* @__PURE__ */ new Set();
|
|
278565
|
+
const params = fnNode.params ?? [];
|
|
278566
|
+
for (const p of params) {
|
|
278567
|
+
if (!p) continue;
|
|
278568
|
+
if (p.type === "Identifier") names2.add(p.name);
|
|
278569
|
+
else if (p.type === "AssignmentPattern" && p.left?.type === "Identifier") {
|
|
278570
|
+
names2.add(p.left.name);
|
|
278571
|
+
} else if (p.type === "RestElement" && p.argument?.type === "Identifier") {
|
|
278572
|
+
names2.add(p.argument.name);
|
|
278573
|
+
} else if (p.type === "ObjectPattern") {
|
|
278574
|
+
for (const prop of p.properties ?? []) {
|
|
278575
|
+
if (prop.type === "ObjectProperty") {
|
|
278576
|
+
const v2 = prop.value;
|
|
278577
|
+
if (v2.type === "Identifier") names2.add(v2.name);
|
|
278578
|
+
else if (v2.type === "AssignmentPattern" && v2.left?.type === "Identifier") {
|
|
278579
|
+
names2.add(v2.left.name);
|
|
278580
|
+
}
|
|
278581
|
+
}
|
|
278582
|
+
}
|
|
278583
|
+
}
|
|
278584
|
+
}
|
|
278585
|
+
return names2;
|
|
278586
|
+
};
|
|
278587
|
+
const visitClassMethods = (className, classNode) => {
|
|
278588
|
+
const body = classNode.body?.body ?? [];
|
|
278589
|
+
for (const m of body) {
|
|
278590
|
+
const mem = m;
|
|
278591
|
+
const isMethod3 = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
278592
|
+
if (!isMethod3 || mem.static) continue;
|
|
278593
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
278594
|
+
const keyName = mem.key?.type === "Identifier" ? mem.key.name : void 0;
|
|
278595
|
+
if (!keyName) continue;
|
|
278596
|
+
const methodNode = mem.type === "MethodDefinition" ? mem.value : mem;
|
|
278597
|
+
if (!methodNode) continue;
|
|
278598
|
+
visitFn(`${className}.${keyName}`, methodNode, paramSet(methodNode));
|
|
278599
|
+
}
|
|
278600
|
+
};
|
|
278601
|
+
const considerDecl = (decl, exported) => {
|
|
278602
|
+
if (!decl) return;
|
|
278603
|
+
if (decl.type === "FunctionDeclaration" && decl.id) {
|
|
278604
|
+
const id = decl.id;
|
|
278605
|
+
visitFn(id.name, decl, paramSet(decl));
|
|
278606
|
+
return;
|
|
278607
|
+
}
|
|
278608
|
+
if (decl.type === "ClassDeclaration" && decl.id?.name) {
|
|
278609
|
+
visitClassMethods(decl.id.name, decl);
|
|
278610
|
+
return;
|
|
278611
|
+
}
|
|
278612
|
+
if (decl.type === "VariableDeclaration") {
|
|
278613
|
+
for (const d of decl.declarations ?? []) {
|
|
278614
|
+
const id = d.id;
|
|
278615
|
+
const init = d.init;
|
|
278616
|
+
if (exported && id?.type === "Identifier" && init && (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression")) {
|
|
278617
|
+
visitFn(id.name, init, paramSet(init));
|
|
278618
|
+
}
|
|
278619
|
+
}
|
|
278620
|
+
}
|
|
278621
|
+
};
|
|
278622
|
+
const program3 = ast.program;
|
|
278623
|
+
const bodyStmts = program3?.body ?? [];
|
|
278624
|
+
for (const stmt of bodyStmts) {
|
|
278625
|
+
if (stmt.type === "ExportNamedDeclaration") {
|
|
278626
|
+
considerDecl(stmt.declaration, true);
|
|
278627
|
+
} else if (stmt.type === "ExportDefaultDeclaration") {
|
|
278628
|
+
considerDecl(stmt.declaration, true);
|
|
278629
|
+
} else if (stmt.type === "ClassDeclaration") {
|
|
278630
|
+
const id = stmt.id;
|
|
278631
|
+
if (id?.name) visitClassMethods(id.name, stmt);
|
|
278632
|
+
} else if (stmt.type === "FunctionDeclaration") {
|
|
278633
|
+
considerDecl(stmt, false);
|
|
278634
|
+
}
|
|
278635
|
+
}
|
|
278636
|
+
return out;
|
|
278637
|
+
}
|
|
278638
|
+
function mergeHints(hints) {
|
|
278639
|
+
if (hints.length === 0) return { type: "any()", via: "read (no type evidence)" };
|
|
278640
|
+
const types2 = [...new Set(hints.map((h) => h.type))];
|
|
278641
|
+
if (types2.length === 1) {
|
|
278642
|
+
return { type: types2[0], via: hints[0].via };
|
|
278643
|
+
}
|
|
278644
|
+
const concrete = types2.filter((t) => t !== "any()");
|
|
278645
|
+
if (concrete.length === 0) return { type: "any()", via: hints[0].via };
|
|
278646
|
+
if (concrete.length === 1) {
|
|
278647
|
+
const h = hints.find((x) => x.type === concrete[0]);
|
|
278648
|
+
return { type: concrete[0], via: h.via };
|
|
278649
|
+
}
|
|
278650
|
+
const specific = concrete.filter((t) => !t.startsWith("union("));
|
|
278651
|
+
if (specific.length === 1) {
|
|
278652
|
+
const h = hints.find((x) => x.type === specific[0]);
|
|
278653
|
+
return { type: specific[0], via: h.via };
|
|
278654
|
+
}
|
|
278655
|
+
if (specific.length > 1) {
|
|
278656
|
+
return {
|
|
278657
|
+
type: `union(${specific.join(", ")})`,
|
|
278658
|
+
via: hints.filter((h) => specific.includes(h.type)).map((h) => h.via).join(" + ")
|
|
278659
|
+
};
|
|
278660
|
+
}
|
|
278661
|
+
const flat = /* @__PURE__ */ new Set();
|
|
278662
|
+
for (const t of concrete) {
|
|
278663
|
+
if (t.startsWith("union(") && t.endsWith(")")) {
|
|
278664
|
+
for (const part of t.slice(6, -1).split(",")) flat.add(part.trim());
|
|
278665
|
+
} else {
|
|
278666
|
+
flat.add(t);
|
|
278667
|
+
}
|
|
278668
|
+
}
|
|
278669
|
+
const parts = [...flat];
|
|
278670
|
+
return {
|
|
278671
|
+
type: parts.length === 1 ? parts[0] : `union(${parts.join(", ")})`,
|
|
278672
|
+
via: hints.map((h) => h.via).join(" + ")
|
|
278673
|
+
};
|
|
278674
|
+
}
|
|
278675
|
+
function bodyReadFieldsFor(map, fnName, paramName2) {
|
|
278676
|
+
return map.get(fnName)?.get(paramName2);
|
|
278677
|
+
}
|
|
278678
|
+
function shapeDslFromFields(fields) {
|
|
278679
|
+
if (fields.length === 0) return "shape({})";
|
|
278680
|
+
const parts = fields.map((f) => `${f.field}: ${f.type}`);
|
|
278681
|
+
return `shape({ ${parts.join(", ")} })`;
|
|
278682
|
+
}
|
|
278126
278683
|
function collectParamBodyAccesses(source) {
|
|
278127
278684
|
const out = /* @__PURE__ */ new Map();
|
|
278128
278685
|
let ast;
|
|
@@ -278131,7 +278688,7 @@ function collectParamBodyAccesses(source) {
|
|
|
278131
278688
|
} catch {
|
|
278132
278689
|
return out;
|
|
278133
278690
|
}
|
|
278134
|
-
const
|
|
278691
|
+
const keyOf2 = (node) => {
|
|
278135
278692
|
if (node.type === "Identifier") return node.name;
|
|
278136
278693
|
if (node.type === "StringLiteral") return node.value;
|
|
278137
278694
|
return void 0;
|
|
@@ -278153,7 +278710,7 @@ function collectParamBodyAccesses(source) {
|
|
|
278153
278710
|
const prop = n.property;
|
|
278154
278711
|
const computed = n.computed === true;
|
|
278155
278712
|
if (obj2?.type === "Identifier" && paramNames.has(obj2.name) && !shadowed.has(obj2.name) && prop && !computed) {
|
|
278156
|
-
const key =
|
|
278713
|
+
const key = keyOf2(prop);
|
|
278157
278714
|
const pname = obj2.name;
|
|
278158
278715
|
if (key !== void 0) {
|
|
278159
278716
|
if (!byParam.has(pname)) byParam.set(pname, /* @__PURE__ */ new Set());
|
|
@@ -278332,7 +278889,7 @@ function litPrimOf(c) {
|
|
|
278332
278889
|
if (typeof v2 === "boolean") return "boolean";
|
|
278333
278890
|
return c.members?.[0] ? litPrimOf(c.members[0]) : void 0;
|
|
278334
278891
|
}
|
|
278335
|
-
function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
278892
|
+
function projectDraftParams(fn2, paramCases, bodyByParam, formals, bodyReadByParam) {
|
|
278336
278893
|
const bodyFor = (name, index2) => {
|
|
278337
278894
|
if (!bodyByParam) return void 0;
|
|
278338
278895
|
const hit = bodyByParam.get(name);
|
|
@@ -278346,8 +278903,23 @@ function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
|
278346
278903
|
}
|
|
278347
278904
|
return bodyByParam.get(`_p${index2}`);
|
|
278348
278905
|
};
|
|
278906
|
+
const fieldsFor = (name, index2) => {
|
|
278907
|
+
if (!bodyReadByParam) return void 0;
|
|
278908
|
+
const hit = bodyReadByParam.get(name);
|
|
278909
|
+
if (hit && hit.length > 0) return hit;
|
|
278910
|
+
const formal = formals?.[index2];
|
|
278911
|
+
if (formal && formal.kind === "pattern") {
|
|
278912
|
+
for (const b of formal.bound) {
|
|
278913
|
+
const boundHit = bodyReadByParam.get(b);
|
|
278914
|
+
if (boundHit && boundHit.length > 0) return boundHit;
|
|
278915
|
+
}
|
|
278916
|
+
}
|
|
278917
|
+
return bodyReadByParam.get(`_p${index2}`);
|
|
278918
|
+
};
|
|
278349
278919
|
return fn2.paramNames.map((name, i) => {
|
|
278350
278920
|
const bodyAccesses = bodyFor(name, i) ? [...bodyFor(name, i)].sort() : void 0;
|
|
278921
|
+
const bodyReadFields = fieldsFor(name, i);
|
|
278922
|
+
const bodyExtra = bodyReadFields ? { bodyAccesses: bodyReadFields.map((f) => f.field), bodyReadFields } : bodyAccesses ? { bodyAccesses } : {};
|
|
278351
278923
|
const argAbs = [];
|
|
278352
278924
|
for (const c of paramCases) {
|
|
278353
278925
|
const a = c.argAbs[i];
|
|
@@ -278355,11 +278927,12 @@ function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
|
278355
278927
|
}
|
|
278356
278928
|
if (argAbs.length === 0) {
|
|
278357
278929
|
if (bodyAccesses && bodyAccesses.length > 0) {
|
|
278930
|
+
const shapeText = bodyReadFields ? shapeDslFromFields(bodyReadFields) : `shape({ ${bodyAccesses.map((k) => `${k}: any()`).join(", ")} })`;
|
|
278358
278931
|
return {
|
|
278359
278932
|
name,
|
|
278360
|
-
display: `/* body-read
|
|
278933
|
+
display: `/* body-read ${shapeText} */`,
|
|
278361
278934
|
projected: false,
|
|
278362
|
-
|
|
278935
|
+
...bodyExtra
|
|
278363
278936
|
};
|
|
278364
278937
|
}
|
|
278365
278938
|
return { name, display: "/* no evidence \u2014 tighten */", projected: false };
|
|
@@ -278370,7 +278943,7 @@ function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
|
278370
278943
|
name,
|
|
278371
278944
|
display: `/* not projectable: ${argAbs.map((a) => formatShape(a)).join(" | ")} */`,
|
|
278372
278945
|
projected: false,
|
|
278373
|
-
...
|
|
278946
|
+
...bodyExtra
|
|
278374
278947
|
};
|
|
278375
278948
|
}
|
|
278376
278949
|
const constraint = widenDraftConstraint(raw);
|
|
@@ -278380,7 +278953,7 @@ function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
|
278380
278953
|
name,
|
|
278381
278954
|
display: `/* observed: ${observed2} \u2014 widen/confirm before accepting */`,
|
|
278382
278955
|
projected: false,
|
|
278383
|
-
...
|
|
278956
|
+
...bodyExtra
|
|
278384
278957
|
};
|
|
278385
278958
|
}
|
|
278386
278959
|
let display = formatConstraint(constraint);
|
|
@@ -278388,7 +278961,9 @@ function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
|
278388
278961
|
if (observed !== display) {
|
|
278389
278962
|
display += ` /* observed: ${observed} */`;
|
|
278390
278963
|
}
|
|
278391
|
-
if (
|
|
278964
|
+
if (bodyReadFields && bodyReadFields.length > 0) {
|
|
278965
|
+
display += ` /* body also reads: ${shapeDslFromFields(bodyReadFields)} */`;
|
|
278966
|
+
} else if (bodyAccesses && bodyAccesses.length > 0) {
|
|
278392
278967
|
display += ` /* body also reads: ${bodyAccesses.join(", ")} */`;
|
|
278393
278968
|
}
|
|
278394
278969
|
return {
|
|
@@ -278396,7 +278971,7 @@ function projectDraftParams(fn2, paramCases, bodyByParam, formals) {
|
|
|
278396
278971
|
constraint,
|
|
278397
278972
|
display,
|
|
278398
278973
|
projected: true,
|
|
278399
|
-
...
|
|
278974
|
+
...bodyExtra
|
|
278400
278975
|
};
|
|
278401
278976
|
});
|
|
278402
278977
|
}
|
|
@@ -278483,8 +279058,8 @@ function suggestedBodyDsl(fnName, params) {
|
|
|
278483
279058
|
const withBody = params.filter((p) => p.bodyAccesses && p.bodyAccesses.length > 0 && !p.projected);
|
|
278484
279059
|
if (withBody.length === 0) return void 0;
|
|
278485
279060
|
const parts = withBody.map((p) => {
|
|
278486
|
-
const
|
|
278487
|
-
return `${p.name}:
|
|
279061
|
+
const shapeText = p.bodyReadFields ? shapeDslFromFields(p.bodyReadFields) : `shape({ ${p.bodyAccesses.map((k) => `${k}: any()`).join(", ")} })`;
|
|
279062
|
+
return `${p.name}: ${shapeText}`;
|
|
278488
279063
|
});
|
|
278489
279064
|
return `// suggested (body-read, not a contract): ${sanitizeCommentText(
|
|
278490
279065
|
`${fnName} = fn({ ${parts.join(", ")} })`
|
|
@@ -278499,6 +279074,7 @@ async function draftInterface(filePath, opts = {}) {
|
|
|
278499
279074
|
const exported = localNamedExports(source);
|
|
278500
279075
|
const selected = opts.fnNames && opts.fnNames.length > 0 ? new Set(opts.fnNames) : exported;
|
|
278501
279076
|
const bodyMap = wantBody ? collectParamBodyAccesses(source) : /* @__PURE__ */ new Map();
|
|
279077
|
+
const bodyReadTypes = wantBody ? collectParamBodyReadTypes(source) : /* @__PURE__ */ new Map();
|
|
278502
279078
|
const entries = [];
|
|
278503
279079
|
for (const fn2 of analysis.functions) {
|
|
278504
279080
|
if (!selected.has(fn2.name) && !opts.fnNames?.includes(fn2.name)) continue;
|
|
@@ -278547,7 +279123,8 @@ async function draftInterface(filePath, opts = {}) {
|
|
|
278547
279123
|
}
|
|
278548
279124
|
const { paramCases, returnCases, paramEvidence, rawReturnEvidence } = caseEvidence(fn2);
|
|
278549
279125
|
const bodyByParam = bodyMap.get(fn2.name);
|
|
278550
|
-
const
|
|
279126
|
+
const bodyReadByParam = bodyReadTypes.get(fn2.name);
|
|
279127
|
+
const params = projectDraftParams(fn2, paramCases, bodyByParam, fn2.formals, bodyReadByParam);
|
|
278551
279128
|
const ret = projectDraftReturn(fn2, returnCases, source, rawReturnEvidence, loadModule, filePath);
|
|
278552
279129
|
const { evidence: returnEvidence, ...returns } = ret;
|
|
278553
279130
|
let evidence = paramEvidence;
|
|
@@ -280780,7 +281357,287 @@ function serializeCaseJson(result, file) {
|
|
|
280780
281357
|
if (external) json.externalFunctions = external;
|
|
280781
281358
|
return json;
|
|
280782
281359
|
}
|
|
280783
|
-
|
|
281360
|
+
function titlePrefix(k) {
|
|
281361
|
+
return `[${k}]`;
|
|
281362
|
+
}
|
|
281363
|
+
function titleKindFor(code2, action) {
|
|
281364
|
+
switch (action.kind) {
|
|
281365
|
+
case "draft":
|
|
281366
|
+
return "fix";
|
|
281367
|
+
case "relax":
|
|
281368
|
+
return code2 === "nudo:unproven-return" ? "review" : "silence";
|
|
281369
|
+
case "mock":
|
|
281370
|
+
case "assume":
|
|
281371
|
+
case "emit":
|
|
281372
|
+
return "scaffold";
|
|
281373
|
+
case "ignore-throws":
|
|
281374
|
+
return "silence";
|
|
281375
|
+
case "callsite":
|
|
281376
|
+
return "fix";
|
|
281377
|
+
default:
|
|
281378
|
+
return "adjust";
|
|
281379
|
+
}
|
|
281380
|
+
}
|
|
281381
|
+
function escapeRegExp22(s) {
|
|
281382
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
281383
|
+
}
|
|
281384
|
+
function findFnDeclStart(lines, fnName) {
|
|
281385
|
+
const re = new RegExp(
|
|
281386
|
+
`(?:export\\s+)?(?:async\\s+)?function\\s+(?<![\\w$])${escapeRegExp22(fnName)}(?![\\w$])|(?:export\\s+)?const\\s+(?<![\\w$])${escapeRegExp22(fnName)}(?![\\w$])\\s*=`
|
|
281387
|
+
);
|
|
281388
|
+
for (let i = 0; i < lines.length; i++) {
|
|
281389
|
+
if (re.test(lines[i])) {
|
|
281390
|
+
let j = i - 1;
|
|
281391
|
+
while (j >= 0 && (lines[j].trim() === "" || lines[j].trim().startsWith("*") || lines[j].trim().startsWith("/*") || lines[j].trim().startsWith("//"))) {
|
|
281392
|
+
if (lines[j].includes("/**") || lines[j].trim().startsWith("//")) return j;
|
|
281393
|
+
j--;
|
|
281394
|
+
}
|
|
281395
|
+
return i;
|
|
281396
|
+
}
|
|
281397
|
+
}
|
|
281398
|
+
return -1;
|
|
281399
|
+
}
|
|
281400
|
+
function addThrowsAnnotation(source, fnName, kind) {
|
|
281401
|
+
const lines = source.split("\n");
|
|
281402
|
+
const start = findFnDeclStart(lines, fnName);
|
|
281403
|
+
if (start < 0) return void 0;
|
|
281404
|
+
const kindSafe = kind.replace(/[^\w.$]/g, "") || "Error";
|
|
281405
|
+
const tag = ` * @nudo:throws ${kindSafe}`;
|
|
281406
|
+
for (let i = Math.max(0, start - 15); i < Math.min(lines.length, start + 3); i++) {
|
|
281407
|
+
if (lines[i].includes(`@nudo:throws ${kindSafe}`)) return { edits: [] };
|
|
281408
|
+
}
|
|
281409
|
+
for (let i = start; i < Math.min(lines.length, start + 30); i++) {
|
|
281410
|
+
const t = lines[i];
|
|
281411
|
+
const closeIdx = t.indexOf("*/");
|
|
281412
|
+
const openIdx = t.indexOf("/**");
|
|
281413
|
+
if (openIdx !== -1 && closeIdx > openIdx) {
|
|
281414
|
+
const inner = t.slice(openIdx + 3, closeIdx).trim();
|
|
281415
|
+
const innerLine = inner ? ` * ${inner}
|
|
281416
|
+
` : "";
|
|
281417
|
+
return {
|
|
281418
|
+
edits: [
|
|
281419
|
+
{
|
|
281420
|
+
startLine: i,
|
|
281421
|
+
startCol: 0,
|
|
281422
|
+
endLine: i,
|
|
281423
|
+
endCol: t.length,
|
|
281424
|
+
newText: `/**
|
|
281425
|
+
${innerLine}${tag}
|
|
281426
|
+
*/`
|
|
281427
|
+
}
|
|
281428
|
+
]
|
|
281429
|
+
};
|
|
281430
|
+
}
|
|
281431
|
+
if (closeIdx !== -1) {
|
|
281432
|
+
return {
|
|
281433
|
+
edits: [
|
|
281434
|
+
{
|
|
281435
|
+
startLine: i,
|
|
281436
|
+
startCol: 0,
|
|
281437
|
+
endLine: i,
|
|
281438
|
+
endCol: 0,
|
|
281439
|
+
newText: `${tag}
|
|
281440
|
+
`
|
|
281441
|
+
}
|
|
281442
|
+
]
|
|
281443
|
+
};
|
|
281444
|
+
}
|
|
281445
|
+
if (t.trim().startsWith("/**")) continue;
|
|
281446
|
+
if (i > start && !t.trim().startsWith("*") && !t.trim().startsWith("/*")) break;
|
|
281447
|
+
}
|
|
281448
|
+
return {
|
|
281449
|
+
edits: [
|
|
281450
|
+
{
|
|
281451
|
+
startLine: start,
|
|
281452
|
+
startCol: 0,
|
|
281453
|
+
endLine: start,
|
|
281454
|
+
endCol: 0,
|
|
281455
|
+
newText: `/**
|
|
281456
|
+
${tag}
|
|
281457
|
+
*/
|
|
281458
|
+
`
|
|
281459
|
+
}
|
|
281460
|
+
]
|
|
281461
|
+
};
|
|
281462
|
+
}
|
|
281463
|
+
function wrapReturnNullable(sidecarSource, fnName) {
|
|
281464
|
+
const fn2 = escapeRegExp22(fnName);
|
|
281465
|
+
const startRe = new RegExp(
|
|
281466
|
+
`(?:export\\s+const\\s+${fn2}\\s*=\\s*|(?<![\\w$])${fn2}\\s*=\\s*)fn\\s*\\(`
|
|
281467
|
+
);
|
|
281468
|
+
const m = sidecarSource.match(startRe);
|
|
281469
|
+
if (!m || m.index === void 0) return void 0;
|
|
281470
|
+
const start = m.index;
|
|
281471
|
+
const open = start + m[0].lastIndexOf("(");
|
|
281472
|
+
let depth = 0;
|
|
281473
|
+
let end = -1;
|
|
281474
|
+
for (let i = open; i < sidecarSource.length; i++) {
|
|
281475
|
+
const ch = sidecarSource[i];
|
|
281476
|
+
if (ch === "(") depth++;
|
|
281477
|
+
else if (ch === ")") {
|
|
281478
|
+
depth--;
|
|
281479
|
+
if (depth === 0) {
|
|
281480
|
+
end = i;
|
|
281481
|
+
break;
|
|
281482
|
+
}
|
|
281483
|
+
}
|
|
281484
|
+
}
|
|
281485
|
+
if (end < 0) return void 0;
|
|
281486
|
+
const region = sidecarSource.slice(start, end + 1);
|
|
281487
|
+
let argDepth = 0;
|
|
281488
|
+
let comma = -1;
|
|
281489
|
+
for (let i = open + 1; i < end; i++) {
|
|
281490
|
+
const ch = sidecarSource[i];
|
|
281491
|
+
if (ch === "(" || ch === "{" || ch === "[") argDepth++;
|
|
281492
|
+
else if (ch === ")" || ch === "}" || ch === "]") argDepth--;
|
|
281493
|
+
else if (ch === "," && argDepth === 0) {
|
|
281494
|
+
comma = i;
|
|
281495
|
+
break;
|
|
281496
|
+
}
|
|
281497
|
+
}
|
|
281498
|
+
if (comma < 0) return void 0;
|
|
281499
|
+
let retStart = comma + 1;
|
|
281500
|
+
while (retStart < end && /\s/.test(sidecarSource[retStart])) retStart++;
|
|
281501
|
+
const retExpr = sidecarSource.slice(retStart, end).trim();
|
|
281502
|
+
if (!retExpr || retExpr.startsWith("nullable(") || retExpr.startsWith("union(")) {
|
|
281503
|
+
return void 0;
|
|
281504
|
+
}
|
|
281505
|
+
const next = sidecarSource.slice(0, retStart) + `nullable(${retExpr})` + sidecarSource.slice(end);
|
|
281506
|
+
return next;
|
|
281507
|
+
}
|
|
281508
|
+
function addBudgetAnnotation(source, fnName, forks = 64) {
|
|
281509
|
+
const lines = source.split("\n");
|
|
281510
|
+
const start = findFnDeclStart(lines, fnName);
|
|
281511
|
+
if (start < 0) return void 0;
|
|
281512
|
+
if (source.includes(`@nudo:budget`)) return { edits: [] };
|
|
281513
|
+
return {
|
|
281514
|
+
edits: [
|
|
281515
|
+
{
|
|
281516
|
+
startLine: start,
|
|
281517
|
+
startCol: 0,
|
|
281518
|
+
endLine: start,
|
|
281519
|
+
endCol: 0,
|
|
281520
|
+
newText: `/**
|
|
281521
|
+
* @nudo:budget forks=${forks}
|
|
281522
|
+
*/
|
|
281523
|
+
`
|
|
281524
|
+
}
|
|
281525
|
+
]
|
|
281526
|
+
};
|
|
281527
|
+
}
|
|
281528
|
+
function applyTextEdits(source, edits) {
|
|
281529
|
+
const lines = source.split("\n");
|
|
281530
|
+
const sorted = [...edits].sort(
|
|
281531
|
+
(a, b) => b.startLine - a.startLine || b.startCol - a.startCol
|
|
281532
|
+
);
|
|
281533
|
+
for (const e of sorted) {
|
|
281534
|
+
const before = lines.slice(0, e.startLine);
|
|
281535
|
+
const after = lines.slice(e.endLine + 1);
|
|
281536
|
+
const startLineText = lines[e.startLine] ?? "";
|
|
281537
|
+
const endLineText = lines[e.endLine] ?? startLineText;
|
|
281538
|
+
const merged = startLineText.slice(0, e.startCol) + e.newText + endLineText.slice(e.endCol);
|
|
281539
|
+
lines.splice(e.startLine, e.endLine - e.startLine + 1, merged);
|
|
281540
|
+
}
|
|
281541
|
+
return lines.join("\n");
|
|
281542
|
+
}
|
|
281543
|
+
function materializeAction(input) {
|
|
281544
|
+
const { code: code2, action, fn: fn2, source, sidecarText, sidecarPath } = input;
|
|
281545
|
+
const tk = titleKindFor(code2, action);
|
|
281546
|
+
if (code2 === "nudo:entry-may-throw" && action.kind === "relax" && fn2) {
|
|
281547
|
+
const kind = input.throwsKind ?? input.suggestion?.match(/@nudo:throws\s+(\w+)/)?.[1] ?? "Error";
|
|
281548
|
+
const r = addThrowsAnnotation(source, fn2, kind);
|
|
281549
|
+
if (!r) return void 0;
|
|
281550
|
+
return {
|
|
281551
|
+
titleKind: "silence",
|
|
281552
|
+
title: `${titlePrefix("silence")} Declare @nudo:throws ${kind} on ${fn2}`,
|
|
281553
|
+
edits: r.edits
|
|
281554
|
+
};
|
|
281555
|
+
}
|
|
281556
|
+
if (code2 === "nudo:entry-may-throw" && action.kind === "draft" && fn2) {
|
|
281557
|
+
const bodyRead = input.suggestion?.match(/body-read\s*\{([^}]+)\}/)?.[1];
|
|
281558
|
+
const fieldNames = bodyRead?.split(",").map((s) => s.trim()).filter(Boolean);
|
|
281559
|
+
const inferred = collectParamBodyReadTypes(source).get(fn2);
|
|
281560
|
+
let fields;
|
|
281561
|
+
let paramName2 = "arg";
|
|
281562
|
+
if (inferred) {
|
|
281563
|
+
for (const [pname, list] of inferred) {
|
|
281564
|
+
if (fieldNames && fieldNames.length > 0) {
|
|
281565
|
+
const hit = list.filter((f) => fieldNames.includes(f.field));
|
|
281566
|
+
if (hit.length > 0) {
|
|
281567
|
+
fields = hit;
|
|
281568
|
+
paramName2 = pname;
|
|
281569
|
+
break;
|
|
281570
|
+
}
|
|
281571
|
+
} else if (list.length > 0) {
|
|
281572
|
+
fields = list;
|
|
281573
|
+
paramName2 = pname;
|
|
281574
|
+
break;
|
|
281575
|
+
}
|
|
281576
|
+
}
|
|
281577
|
+
}
|
|
281578
|
+
if (!fields || fields.length === 0) {
|
|
281579
|
+
if (!fieldNames || fieldNames.length === 0) {
|
|
281580
|
+
return {
|
|
281581
|
+
titleKind: "fix",
|
|
281582
|
+
title: `${titlePrefix("fix")} Add sidecar param contract for ${fn2} (via nudo contract --draft)`,
|
|
281583
|
+
edits: [],
|
|
281584
|
+
openPath: sidecarPath
|
|
281585
|
+
};
|
|
281586
|
+
}
|
|
281587
|
+
fields = fieldNames.map((f) => ({ field: f, type: "any()", via: "read (no type evidence)" }));
|
|
281588
|
+
}
|
|
281589
|
+
const shapeText = shapeDslFromFields(fields);
|
|
281590
|
+
const clause = `export const ${fn2} = fn({ ${paramName2}: ${shapeText} });
|
|
281591
|
+
`;
|
|
281592
|
+
const next = sidecarText && sidecarText.trim().length > 0 ? sidecarText.endsWith("\n") ? sidecarText + clause : sidecarText + "\n" + clause : `// Generated by quickfix \u2014 review before accepting
|
|
281593
|
+
${clause}`;
|
|
281594
|
+
return {
|
|
281595
|
+
titleKind: "fix",
|
|
281596
|
+
title: `${titlePrefix("fix")} Add sidecar param contract for ${fn2} (${fields.map((f) => `${f.field}: ${f.type}`).join(", ")})`,
|
|
281597
|
+
edits: [],
|
|
281598
|
+
sidecar: { path: sidecarPath, newText: next },
|
|
281599
|
+
openPath: sidecarPath
|
|
281600
|
+
};
|
|
281601
|
+
}
|
|
281602
|
+
if (code2 === "nudo:constraint-violated" && (action.kind === "relax" || action.kind === "draft") && fn2 && sidecarText && (/nullish/i.test(input.suggestion ?? "") || /nullish/i.test(input.expected ?? "") || /use nullable/i.test(input.suggestion ?? ""))) {
|
|
281603
|
+
const next = wrapReturnNullable(sidecarText, fn2);
|
|
281604
|
+
if (next && next !== sidecarText) {
|
|
281605
|
+
return {
|
|
281606
|
+
titleKind: "fix",
|
|
281607
|
+
title: `${titlePrefix("fix")} Wrap ${fn2} return contract in nullable(\u2026)`,
|
|
281608
|
+
edits: [],
|
|
281609
|
+
sidecar: { path: sidecarPath, newText: next }
|
|
281610
|
+
};
|
|
281611
|
+
}
|
|
281612
|
+
}
|
|
281613
|
+
if (code2 === "nudo:unproven-return" && action.kind === "relax" && fn2 && sidecarText) {
|
|
281614
|
+
return {
|
|
281615
|
+
titleKind: "review",
|
|
281616
|
+
title: `${titlePrefix("review")} Relax return contract for ${fn2} to inferred surface`,
|
|
281617
|
+
edits: [],
|
|
281618
|
+
openPath: sidecarPath
|
|
281619
|
+
};
|
|
281620
|
+
}
|
|
281621
|
+
if (code2 === "nudo:recursion-truncated" && fn2) {
|
|
281622
|
+
const r = addBudgetAnnotation(source, fn2);
|
|
281623
|
+
if (!r) return void 0;
|
|
281624
|
+
return {
|
|
281625
|
+
titleKind: "adjust",
|
|
281626
|
+
title: `${titlePrefix("adjust")} Add @nudo:budget forks=64 on ${fn2}`,
|
|
281627
|
+
edits: r.edits
|
|
281628
|
+
};
|
|
281629
|
+
}
|
|
281630
|
+
if ((code2 === "nudo:unknown-inference" || code2 === "nudo:opaque-result") && (action.kind === "mock" || action.kind === "draft")) {
|
|
281631
|
+
return {
|
|
281632
|
+
titleKind: "scaffold",
|
|
281633
|
+
title: `${titlePrefix("scaffold")} ${action.label}`,
|
|
281634
|
+
edits: [],
|
|
281635
|
+
openPath: code2 === "nudo:opaque-result" ? input.file : sidecarPath
|
|
281636
|
+
};
|
|
281637
|
+
}
|
|
281638
|
+
return void 0;
|
|
281639
|
+
}
|
|
281640
|
+
var GENERATED_PREFIX, GENERATED_CASE_LINE_REGEX, IDENT_KEY_REGEX, NUMBER_LITERAL_REGEX, UNSAFE_STRING_CHARS, UNSAFE_KEY_CHARS, CONTROL_CHARS, DIFF_CONTEXT, GENERATED_HEADER, STRING_METHODS2, NUMBER_METHODS, ARRAY_METHODS, NameAllocator, DERIVED_HEADER, TS_PARAM_RESERVED, DIALECT_RENDERERS, CHECK_FN_SOURCE;
|
|
280784
281641
|
var init_emit2 = __esm({
|
|
280785
281642
|
"../service/dist/emit/index.js"() {
|
|
280786
281643
|
"use strict";
|
|
@@ -280795,6 +281652,7 @@ var init_emit2 = __esm({
|
|
|
280795
281652
|
init_internal();
|
|
280796
281653
|
init_src2();
|
|
280797
281654
|
init_src2();
|
|
281655
|
+
init_src2();
|
|
280798
281656
|
init_src();
|
|
280799
281657
|
init_internal();
|
|
280800
281658
|
init_src();
|
|
@@ -280817,6 +281675,66 @@ var init_emit2 = __esm({
|
|
|
280817
281675
|
CONTROL_CHARS = /[\x00-\x1f\x7f]/;
|
|
280818
281676
|
DIFF_CONTEXT = 3;
|
|
280819
281677
|
GENERATED_HEADER = "// @generated by nudo \u2014 do not edit; regenerate with `nudo contract --emit`";
|
|
281678
|
+
STRING_METHODS2 = /* @__PURE__ */ new Set([
|
|
281679
|
+
"toLowerCase",
|
|
281680
|
+
"toUpperCase",
|
|
281681
|
+
"trim",
|
|
281682
|
+
"trimStart",
|
|
281683
|
+
"trimEnd",
|
|
281684
|
+
"slice",
|
|
281685
|
+
"substring",
|
|
281686
|
+
"substr",
|
|
281687
|
+
"charAt",
|
|
281688
|
+
"charCodeAt",
|
|
281689
|
+
"codePointAt",
|
|
281690
|
+
"includes",
|
|
281691
|
+
"startsWith",
|
|
281692
|
+
"endsWith",
|
|
281693
|
+
"split",
|
|
281694
|
+
"replace",
|
|
281695
|
+
"replaceAll",
|
|
281696
|
+
"repeat",
|
|
281697
|
+
"padStart",
|
|
281698
|
+
"padEnd",
|
|
281699
|
+
"normalize",
|
|
281700
|
+
"concat",
|
|
281701
|
+
"match",
|
|
281702
|
+
"matchAll",
|
|
281703
|
+
"search",
|
|
281704
|
+
"at",
|
|
281705
|
+
"indexOf",
|
|
281706
|
+
"lastIndexOf"
|
|
281707
|
+
]);
|
|
281708
|
+
NUMBER_METHODS = /* @__PURE__ */ new Set([
|
|
281709
|
+
"toFixed",
|
|
281710
|
+
"toPrecision",
|
|
281711
|
+
"toExponential",
|
|
281712
|
+
"valueOf"
|
|
281713
|
+
]);
|
|
281714
|
+
ARRAY_METHODS = /* @__PURE__ */ new Set([
|
|
281715
|
+
"map",
|
|
281716
|
+
"filter",
|
|
281717
|
+
"reduce",
|
|
281718
|
+
"forEach",
|
|
281719
|
+
"find",
|
|
281720
|
+
"findIndex",
|
|
281721
|
+
"some",
|
|
281722
|
+
"every",
|
|
281723
|
+
"push",
|
|
281724
|
+
"pop",
|
|
281725
|
+
"shift",
|
|
281726
|
+
"unshift",
|
|
281727
|
+
"sort",
|
|
281728
|
+
"reverse",
|
|
281729
|
+
"join",
|
|
281730
|
+
"flat",
|
|
281731
|
+
"flatMap",
|
|
281732
|
+
"includes",
|
|
281733
|
+
"indexOf",
|
|
281734
|
+
"slice",
|
|
281735
|
+
"splice",
|
|
281736
|
+
"concat"
|
|
281737
|
+
]);
|
|
280820
281738
|
NameAllocator = class {
|
|
280821
281739
|
taken;
|
|
280822
281740
|
constructor(initial) {
|
|
@@ -282690,6 +283608,109 @@ async function runCheck(file, opts = {}) {
|
|
|
282690
283608
|
process.exitCode = 1;
|
|
282691
283609
|
}
|
|
282692
283610
|
}
|
|
283611
|
+
async function runCheckFix(opts) {
|
|
283612
|
+
const core = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
283613
|
+
const { checkSource: checkSource2, pTrue: pTrue3, sidecarPathOf: sidecarPathOf2, actionsForIssue: actionsForIssue2 } = core;
|
|
283614
|
+
const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3 } = await Promise.resolve().then(() => (init_src4(), src_exports4));
|
|
283615
|
+
const {
|
|
283616
|
+
materializeAction: materializeAction2,
|
|
283617
|
+
applyTextEdits: applyTextEdits2,
|
|
283618
|
+
unifiedDiff: unifiedDiff2
|
|
283619
|
+
} = await Promise.resolve().then(() => (init_emit2(), emit_exports));
|
|
283620
|
+
const { writeFileSync: writeFileSync11, readFileSync: readFileSync29, existsSync: existsSync26 } = await import("fs");
|
|
283621
|
+
const only = opts.only && opts.only.length > 0 ? new Set(opts.only) : void 0;
|
|
283622
|
+
let planned = 0;
|
|
283623
|
+
let written = 0;
|
|
283624
|
+
for (const file of opts.targets) {
|
|
283625
|
+
let source;
|
|
283626
|
+
try {
|
|
283627
|
+
source = readFileSync29(file, "utf-8");
|
|
283628
|
+
} catch {
|
|
283629
|
+
continue;
|
|
283630
|
+
}
|
|
283631
|
+
const report = checkSource2(file, source, pTrue3, {
|
|
283632
|
+
loadModule: defaultLoadModule3,
|
|
283633
|
+
fromFile: file,
|
|
283634
|
+
...opts.ignoreThrows ? { ignoreThrows: opts.ignoreThrows } : {},
|
|
283635
|
+
...opts.entryThrows ? { entryThrows: opts.entryThrows } : {},
|
|
283636
|
+
skips: collectSkipReturns2(source)
|
|
283637
|
+
});
|
|
283638
|
+
const sidecar = sidecarPathOf2(file);
|
|
283639
|
+
let sidecarText;
|
|
283640
|
+
try {
|
|
283641
|
+
sidecarText = existsSync26(sidecar) ? readFileSync29(sidecar, "utf-8") : void 0;
|
|
283642
|
+
} catch {
|
|
283643
|
+
sidecarText = void 0;
|
|
283644
|
+
}
|
|
283645
|
+
for (const issue of report.issues) {
|
|
283646
|
+
if (only && !only.has(issue.code)) continue;
|
|
283647
|
+
const acts = issue.actions ?? actionsForIssue2(issue);
|
|
283648
|
+
const throwsKind = issue.suggestion?.match(/@nudo:throws\s+(\w+)/)?.[1] ?? issue.actual?.match(/throws\s+([A-Za-z]+)/)?.[1];
|
|
283649
|
+
const rank = (k) => k === "fix" ? 0 : k === "adjust" ? 1 : 2;
|
|
283650
|
+
const plans = [];
|
|
283651
|
+
for (const action of acts) {
|
|
283652
|
+
if (action.kind === "info") continue;
|
|
283653
|
+
const plan2 = materializeAction2({
|
|
283654
|
+
code: issue.code,
|
|
283655
|
+
fn: issue.fn,
|
|
283656
|
+
file,
|
|
283657
|
+
source,
|
|
283658
|
+
sidecarText,
|
|
283659
|
+
sidecarPath: sidecar,
|
|
283660
|
+
action,
|
|
283661
|
+
throwsKind,
|
|
283662
|
+
expected: issue.expected,
|
|
283663
|
+
suggestion: issue.suggestion
|
|
283664
|
+
});
|
|
283665
|
+
if (plan2) plans.push(plan2);
|
|
283666
|
+
}
|
|
283667
|
+
plans.sort((a, b) => rank(a.titleKind) - rank(b.titleKind));
|
|
283668
|
+
const plan = plans.find((p) => rank(p.titleKind) <= 1);
|
|
283669
|
+
if (!plan) continue;
|
|
283670
|
+
if (plan.edits.length > 0) {
|
|
283671
|
+
const next = applyTextEdits2(source, plan.edits);
|
|
283672
|
+
if (next !== source) {
|
|
283673
|
+
planned++;
|
|
283674
|
+
console.log(`
|
|
283675
|
+
--- ${file}`);
|
|
283676
|
+
console.log(`+++ ${file} (${plan.title})`);
|
|
283677
|
+
console.log(unifiedDiff2(source, next, file) || "(no line diff)");
|
|
283678
|
+
if (opts.write) {
|
|
283679
|
+
writeFileSync11(file, next, "utf-8");
|
|
283680
|
+
source = next;
|
|
283681
|
+
written++;
|
|
283682
|
+
}
|
|
283683
|
+
}
|
|
283684
|
+
}
|
|
283685
|
+
if (plan.sidecar) {
|
|
283686
|
+
const cur = sidecarText ?? "";
|
|
283687
|
+
const next = plan.sidecar.newText;
|
|
283688
|
+
if (next !== cur) {
|
|
283689
|
+
planned++;
|
|
283690
|
+
console.log(`
|
|
283691
|
+
--- ${plan.sidecar.path}`);
|
|
283692
|
+
console.log(`+++ ${plan.sidecar.path} (${plan.title})`);
|
|
283693
|
+
console.log(unifiedDiff2(cur, next, plan.sidecar.path) || "(new file)");
|
|
283694
|
+
if (opts.write) {
|
|
283695
|
+
writeFileSync11(plan.sidecar.path, next, "utf-8");
|
|
283696
|
+
sidecarText = next;
|
|
283697
|
+
written++;
|
|
283698
|
+
}
|
|
283699
|
+
}
|
|
283700
|
+
}
|
|
283701
|
+
}
|
|
283702
|
+
}
|
|
283703
|
+
const mode = opts.write ? "written" : "planned (dry-run)";
|
|
283704
|
+
console.log(
|
|
283705
|
+
`
|
|
283706
|
+
check --fix: ${planned} edit(s) ${mode}${opts.write ? `, ${written} applied` : " \u2014 pass --write to apply"}`
|
|
283707
|
+
);
|
|
283708
|
+
if (!opts.write && planned > 0) {
|
|
283709
|
+
console.log(
|
|
283710
|
+
"hint: only [fix]/[adjust] are auto-applied; [silence]/[review] need a human (or LSP quickfix)"
|
|
283711
|
+
);
|
|
283712
|
+
}
|
|
283713
|
+
}
|
|
282693
283714
|
function registerCheckCommand(program3) {
|
|
282694
283715
|
program3.command("check").description("Gate contracts + entry throws; print signatures (CI). Day 0 observation lives here.").argument("<paths...>", "File(s) or directory(s) to check").option("--watch, -w", "Watch files and re-run check on change").option("--json", "Emit stable CheckJson (1 file) or CheckJsonMulti envelope (N files) for CI / Agent").option("--gha", "GitHub Actions inline annotations (::error/::warning). Auto when GITHUB_ACTIONS=true").option("--gitlab", "GitLab Code Quality JSON array (write as gl-code-quality-report.json)").option("--verbose", "Expand Abs signatures (term/pred/conf detail)").option("--abs", "Algebra face: term/pred/conf per function").option("--fn <name>", "With --abs: only this function").option("--assume <pred...>", "With --abs: assume constraints, e.g. x>0 y>=1").option("--generalize", "With --abs: polymorphic signatures via symbolic execution").option(
|
|
282695
283716
|
"--from <paths...>",
|
|
@@ -282706,7 +283727,7 @@ function registerCheckCommand(program3) {
|
|
|
282706
283727
|
).option(
|
|
282707
283728
|
"--what-if <binding...>",
|
|
282708
283729
|
"AI3: assume `name:type` bindings (e.g. raw:string) and report --target"
|
|
282709
|
-
).option("--target <name>", "With --what-if: binding name whose inferred type to print").action(
|
|
283730
|
+
).option("--target <name>", "With --what-if: binding name whose inferred type to print").option("--fix", "Materialize one fix/adjust edit per issue (default --dry-run: print unified diff)").option("--only <codes...>", "With --fix: only these diagnostic codes (e.g. nudo:entry-may-throw)").option("--write", "With --fix: apply edits to disk (default dry-run)").option("--dry-run", "With --fix: print diffs only (default; kept for explicitness)").action(
|
|
282710
283731
|
async (paths, opts) => {
|
|
282711
283732
|
if (opts.whatIf && opts.whatIf.length > 0) {
|
|
282712
283733
|
const targets2 = [];
|
|
@@ -282764,6 +283785,17 @@ function registerCheckCommand(program3) {
|
|
|
282764
283785
|
}
|
|
282765
283786
|
const entryThrows = isEntryThrowsMode(opts.entryThrows) ? opts.entryThrows : void 0;
|
|
282766
283787
|
const profile = isGateProfile(opts.profile) ? opts.profile : void 0;
|
|
283788
|
+
if (opts.fix) {
|
|
283789
|
+
await runCheckFix({
|
|
283790
|
+
targets,
|
|
283791
|
+
only: opts.only,
|
|
283792
|
+
write: opts.write === true,
|
|
283793
|
+
ignoreThrows,
|
|
283794
|
+
entryThrows,
|
|
283795
|
+
profile
|
|
283796
|
+
});
|
|
283797
|
+
return;
|
|
283798
|
+
}
|
|
282767
283799
|
const shared = {
|
|
282768
283800
|
from: externalRecords,
|
|
282769
283801
|
verbose: opts.verbose,
|