@nudojs/core 1.9.4 → 1.10.1

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.
@@ -47,7 +47,7 @@ import {
47
47
  withEvalBudgetOverride,
48
48
  withExecPhi,
49
49
  withFnBudgetOverride
50
- } from "./chunk-PGTNSUTE.js";
50
+ } from "./chunk-2ZIOQGW3.js";
51
51
 
52
52
  // src/algebra/directive-scan.ts
53
53
  function cleanDirectiveLine(raw, kind) {
@@ -988,6 +988,75 @@ function rewriteSidecarSource(src, fromFile) {
988
988
  }
989
989
  }
990
990
  }
991
+ const aliasToImported = /* @__PURE__ */ new Map();
992
+ const fnAliases = /* @__PURE__ */ new Set(["fn"]);
993
+ for (const imp of imports) {
994
+ for (const n of imp.names) {
995
+ if (n.ns) continue;
996
+ if (n.imported !== void 0 && n.local !== void 0 && n.imported !== n.local) {
997
+ aliasToImported.set(n.local, n.imported);
998
+ }
999
+ if (n.imported === "fn" && n.local !== void 0) fnAliases.add(n.local);
1000
+ }
1001
+ }
1002
+ const paramTextsOfFnCall = (init) => {
1003
+ const call = init;
1004
+ if (!call || call.type !== "CallExpression") return void 0;
1005
+ if (call.callee?.type !== "Identifier" || !fnAliases.has(call.callee.name ?? "")) {
1006
+ return void 0;
1007
+ }
1008
+ const first = call.arguments?.[0];
1009
+ if (!first || first.type !== "ObjectExpression") return void 0;
1010
+ const texts = /* @__PURE__ */ new Map();
1011
+ for (const prop of first.properties ?? []) {
1012
+ if (prop.type !== "ObjectProperty" || prop.computed) continue;
1013
+ const key = prop.key?.type === "Identifier" ? prop.key.name : prop.key?.type === "StringLiteral" ? prop.key.value : void 0;
1014
+ if (key === void 0) continue;
1015
+ const v2 = prop.value;
1016
+ if (!v2 || v2.start == null || v2.end == null) continue;
1017
+ texts.set(
1018
+ key,
1019
+ v2.type === "Identifier" && aliasToImported.has(v2.name ?? "") ? aliasToImported.get(v2.name ?? "") : src.slice(v2.start, v2.end)
1020
+ );
1021
+ }
1022
+ return texts;
1023
+ };
1024
+ const paramInfosByLocal = /* @__PURE__ */ new Map();
1025
+ const collectVarFns = (decls) => {
1026
+ for (const d of decls) {
1027
+ if (d?.id?.type !== "Identifier" || d.id.name === void 0) continue;
1028
+ const texts = paramTextsOfFnCall(d.init);
1029
+ if (texts)
1030
+ paramInfosByLocal.set(d.id.name, {
1031
+ texts,
1032
+ line: d.loc?.start?.line ?? 1
1033
+ });
1034
+ }
1035
+ };
1036
+ for (const stmt of ast.program.body) {
1037
+ if (stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration") {
1038
+ collectVarFns(
1039
+ stmt.declaration?.declarations ?? []
1040
+ );
1041
+ } else if (stmt.type === "VariableDeclaration") {
1042
+ collectVarFns(
1043
+ stmt.declarations ?? []
1044
+ );
1045
+ } else if (stmt.type === "ExportDefaultDeclaration") {
1046
+ const decl = stmt.declaration;
1047
+ const texts = paramTextsOfFnCall(decl);
1048
+ if (texts)
1049
+ paramInfosByLocal.set(DEFAULT_LOCAL, {
1050
+ texts,
1051
+ line: stmt.loc?.start?.line ?? 1
1052
+ });
1053
+ }
1054
+ }
1055
+ const bindingInfos = /* @__PURE__ */ new Map();
1056
+ for (const p of exportPairs) {
1057
+ const info = paramInfosByLocal.get(p.expr);
1058
+ if (info) bindingInfos.set(p.key, info);
1059
+ }
991
1060
  if (fromFile?.endsWith(".nudo.ts")) {
992
1061
  for (const cut of collectTsSyntaxCuts(ast.program, src)) {
993
1062
  cuts.push({ start: cut.start, end: cut.end, text: "" });
@@ -1011,7 +1080,7 @@ function rewriteSidecarSource(src, fromFile) {
1011
1080
  pos = c.end;
1012
1081
  }
1013
1082
  code += src.slice(pos);
1014
- return { code, exportPairs, imports };
1083
+ return { code, exportPairs, imports, bindingInfos };
1015
1084
  }
1016
1085
  var TS_STMT_CUT_TYPES = /* @__PURE__ */ new Set([
1017
1086
  "TSInterfaceDeclaration",
@@ -1083,9 +1152,25 @@ function collectTsSyntaxCuts(node, src, cuts = []) {
1083
1152
  }
1084
1153
  return cuts;
1085
1154
  }
1155
+ function registerSidecarParamTexts(sidecarPath, contentKey, infos) {
1156
+ let perPath = sidecarParamTextsRegistry.get(sidecarPath);
1157
+ if (perPath === void 0) {
1158
+ perPath = /* @__PURE__ */ new Map();
1159
+ sidecarParamTextsRegistry.set(sidecarPath, perPath);
1160
+ if (sidecarParamTextsRegistry.size > MAX_SIDECAR_PARAM_TEXTS_PATHS) {
1161
+ const oldest = sidecarParamTextsRegistry.keys().next().value;
1162
+ if (oldest !== void 0) sidecarParamTextsRegistry.delete(oldest);
1163
+ }
1164
+ }
1165
+ perPath.set(contentKey, infos);
1166
+ if (perPath.size > MAX_SIDECAR_PARAM_TEXTS_VERSIONS) {
1167
+ const oldest = perPath.keys().next().value;
1168
+ if (oldest !== void 0) perPath.delete(oldest);
1169
+ }
1170
+ }
1086
1171
  function execSidecar(src, opts, chain, preloaded) {
1087
1172
  const fromFile = opts?.fromFile;
1088
- const { code, exportPairs, imports } = rewriteSidecarSource(src, fromFile);
1173
+ const { code, exportPairs, imports, bindingInfos } = rewriteSidecarSource(src, fromFile);
1089
1174
  const prologue = [];
1090
1175
  const deps = {};
1091
1176
  for (const imp of imports) {
@@ -1167,12 +1252,13 @@ function execSidecar(src, opts, chain, preloaded) {
1167
1252
  for (const n of imp.names) deps[n.local] = void 0;
1168
1253
  continue;
1169
1254
  }
1170
- const depExports = execSidecar(
1255
+ const depOut = execSidecar(
1171
1256
  depSrc,
1172
1257
  { loadModule: load, fromFile: canonical },
1173
1258
  [...chain, canonical],
1174
1259
  preloaded
1175
1260
  );
1261
+ const depExports = depOut.exports;
1176
1262
  for (const n of imp.names) {
1177
1263
  if (n.ns) {
1178
1264
  deps[n.local] = depExports;
@@ -1212,7 +1298,11 @@ return { ${returnObj} };`;
1212
1298
  "__nudoDeps",
1213
1299
  body
1214
1300
  );
1215
- return fn(...Object.values(sidecarInjects), sidecarInjects, deps);
1301
+ const result = fn(...Object.values(sidecarInjects), sidecarInjects, deps);
1302
+ if (fromFile !== void 0 && bindingInfos.size > 0) {
1303
+ registerSidecarParamTexts(fromFile, hashSource(src), bindingInfos);
1304
+ }
1305
+ return { exports: result, bindingInfos };
1216
1306
  }
1217
1307
  function execNudoModule(src, opts) {
1218
1308
  return execNudoModuleCached(src, opts ?? {});
@@ -1268,22 +1358,29 @@ function execNudoModuleCached(src, opts) {
1268
1358
  if (hit !== void 0) {
1269
1359
  nudoModuleExecCache.delete(key);
1270
1360
  nudoModuleExecCache.set(key, hit);
1271
- return hit;
1361
+ if (opts.fromFile !== void 0 && hit.bindingInfos.size > 0) {
1362
+ registerSidecarParamTexts(
1363
+ opts.fromFile,
1364
+ hashSource(src),
1365
+ hit.bindingInfos
1366
+ );
1367
+ }
1368
+ return hit.exports;
1272
1369
  }
1273
1370
  if (nudoModuleFailCache.has(key)) {
1274
1371
  throw nudoModuleFailCache.get(key);
1275
1372
  }
1276
1373
  }
1277
1374
  try {
1278
- const out = execSidecar(src, opts, opts.fromFile ? [opts.fromFile] : [], preloaded);
1375
+ const { exports, bindingInfos } = execSidecar(src, opts, opts.fromFile ? [opts.fromFile] : [], preloaded);
1279
1376
  if (key !== void 0) {
1280
1377
  if (nudoModuleExecCache.size >= MAX_NUDO_MODULE_EXEC) {
1281
1378
  const oldest = nudoModuleExecCache.keys().next().value;
1282
1379
  if (oldest !== void 0) nudoModuleExecCache.delete(oldest);
1283
1380
  }
1284
- nudoModuleExecCache.set(key, out);
1381
+ nudoModuleExecCache.set(key, { exports, bindingInfos });
1285
1382
  }
1286
- return out;
1383
+ return exports;
1287
1384
  } catch (e) {
1288
1385
  if (key !== void 0) {
1289
1386
  if (nudoModuleFailCache.size >= MAX_NUDO_MODULE_EXEC) {
@@ -1298,6 +1395,17 @@ function execNudoModuleCached(src, opts) {
1298
1395
  function resetNudoModuleExecCache() {
1299
1396
  nudoModuleExecCache.clear();
1300
1397
  nudoModuleFailCache.clear();
1398
+ sidecarParamTextsRegistry.clear();
1399
+ }
1400
+ var sidecarParamTextsRegistry = /* @__PURE__ */ new Map();
1401
+ var MAX_SIDECAR_PARAM_TEXTS_PATHS = 64;
1402
+ var MAX_SIDECAR_PARAM_TEXTS_VERSIONS = 32;
1403
+ function lookupSidecarParamTexts(sidecarPath, srcHash, bindingName) {
1404
+ const perPath = sidecarParamTextsRegistry.get(sidecarPath);
1405
+ if (perPath === void 0) return void 0;
1406
+ const perHash = perPath.get(srcHash);
1407
+ if (perHash === void 0) return void 0;
1408
+ return perHash.get(bindingName);
1301
1409
  }
1302
1410
  function collectConstraints(source, opts) {
1303
1411
  const map = /* @__PURE__ */ new Map();
@@ -1411,7 +1519,8 @@ function extractRefinesFromSource(source, fnName, opts = {}) {
1411
1519
  out.push({
1412
1520
  param,
1413
1521
  pred: instantiateConstraint(c, param),
1414
- constraint: c
1522
+ constraint: c,
1523
+ name: cName
1415
1524
  });
1416
1525
  }
1417
1526
  }
@@ -1858,18 +1967,25 @@ function loadSidecarBinding(source, fnName, opts) {
1858
1967
  return { ok: false };
1859
1968
  }
1860
1969
  let binding = Object.hasOwn(exports, fnName) ? exports[fnName] : void 0;
1970
+ let bindingKey;
1971
+ if (binding !== void 0) bindingKey = fnName;
1861
1972
  if (binding === void 0) {
1862
1973
  const aliasExport2 = exportedNameOfLocal(source, fnName);
1863
1974
  if (aliasExport2 !== void 0 && Object.hasOwn(exports, aliasExport2)) {
1864
1975
  binding = exports[aliasExport2];
1976
+ bindingKey = aliasExport2;
1865
1977
  }
1866
1978
  }
1867
1979
  if (binding === void 0 && exports.default !== void 0 && isDefaultExportLocal(source, fnName)) {
1868
1980
  binding = exports.default;
1981
+ bindingKey = "default";
1869
1982
  }
1870
1983
  if (binding === void 0 && fnName.includes(".")) {
1871
1984
  const [cls, method] = fnName.split(".", 2);
1872
- binding = Object.hasOwn(exports, `${cls}_${method}`) ? exports[`${cls}_${method}`] : void 0;
1985
+ if (Object.hasOwn(exports, `${cls}_${method}`)) {
1986
+ binding = exports[`${cls}_${method}`];
1987
+ bindingKey = `${cls}_${method}`;
1988
+ }
1873
1989
  if (binding === void 0) {
1874
1990
  const bag = Object.hasOwn(exports, cls) ? exports[cls] : void 0;
1875
1991
  if (bag && typeof bag === "object" && !isNudoConstraint(bag)) {
@@ -1907,11 +2023,14 @@ function loadSidecarBinding(source, fnName, opts) {
1907
2023
  const [cls, method] = fnName.split(".", 2);
1908
2024
  return generatedNames.has(`${cls}_${method}`) || generatedNames.has(cls);
1909
2025
  })() : false);
2026
+ const info = bindingKey !== void 0 ? lookupSidecarParamTexts(sidecarPath, hashSource(sidecarSrc), bindingKey) : void 0;
1910
2027
  return {
1911
2028
  ok: true,
1912
2029
  sidecarPath,
1913
2030
  constraint: binding,
1914
- generated: isGenerated
2031
+ generated: isGenerated,
2032
+ ...info?.texts !== void 0 ? { paramTexts: info.texts } : {},
2033
+ ...info?.line !== void 0 ? { sidecarLine: info.line } : {}
1915
2034
  };
1916
2035
  }
1917
2036
  function boundsOf(c) {
@@ -2014,8 +2133,24 @@ function effectiveInterface(source, fnName, opts = {}) {
2014
2133
  collectDiag2({ code: d.code, message: d.message, ...d.file ? { file: d.file } : {} });
2015
2134
  }
2016
2135
  const sidecarFn = sidecar.ok ? sidecar.constraint : void 0;
2136
+ const sidecarParamTexts = sidecar.ok ? sidecar.paramTexts : void 0;
2017
2137
  const sidecarGenerated = sidecar.ok && sidecar.generated;
2018
2138
  const sidecarParams = sidecarFn ? fnConstraintToEntryReqs(sidecarFn) : [];
2139
+ const sidecarParamSet = new Set(sidecarParams.map((p) => p.param));
2140
+ const sidecarTexts = /* @__PURE__ */ new Map();
2141
+ if (sidecarParamTexts) {
2142
+ for (const param of sidecarParamSet) {
2143
+ const t = sidecarParamTexts.get(param);
2144
+ if (t !== void 0) sidecarTexts.set(param, t);
2145
+ }
2146
+ }
2147
+ const directiveNames = /* @__PURE__ */ new Map();
2148
+ for (const e of sourceEntries) {
2149
+ if (e.name === void 0) continue;
2150
+ const list = directiveNames.get(e.param);
2151
+ if (list === void 0) directiveNames.set(e.param, [e.name]);
2152
+ else if (!list.includes(e.name)) list.push(e.name);
2153
+ }
2019
2154
  const sidecarReturns = sidecarFn?.fn.returns;
2020
2155
  const sidecarThrowsKinds = throwConstraintToKinds(sidecarFn?.fn.throws);
2021
2156
  const mergedThrows = (() => {
@@ -2028,9 +2163,16 @@ function effectiveInterface(source, fnName, opts = {}) {
2028
2163
  if (sidecarFn !== void 0 && sidecarGenerated) {
2029
2164
  return {
2030
2165
  fnName,
2031
- params: sidecarParams,
2166
+ params: sidecarParams.map(({ param, constraint }) => {
2167
+ const display = sidecarTexts.get(param);
2168
+ return display !== void 0 ? { param, constraint, display } : { param, constraint };
2169
+ }),
2032
2170
  ...sidecarReturns !== void 0 ? { returns: { constraint: sidecarReturns } } : {},
2033
2171
  ...mergedThrows !== void 0 ? { throws: { kinds: mergedThrows } } : {},
2172
+ ...sidecar.ok ? {
2173
+ sidecarPath: sidecar.sidecarPath,
2174
+ ...sidecar.sidecarLine !== void 0 ? { sidecarLine: sidecar.sidecarLine } : {}
2175
+ } : {},
2034
2176
  source: "generated"
2035
2177
  };
2036
2178
  }
@@ -2083,9 +2225,27 @@ function effectiveInterface(source, fnName, opts = {}) {
2083
2225
  }
2084
2226
  return {
2085
2227
  fnName,
2086
- params: [...params.entries()].map(([param, constraint]) => ({ param, constraint })),
2228
+ params: [...params.entries()].map(([param, constraint]) => {
2229
+ const sidecarText = sidecarTexts.get(param);
2230
+ const names = directiveNames.get(param);
2231
+ const fromSidecar = sidecarFn !== void 0 && !sidecarGenerated && sidecarParamSet.has(param);
2232
+ const fromDirective = names !== void 0;
2233
+ let display;
2234
+ if (fromSidecar && fromDirective) {
2235
+ display = sidecarText !== void 0 ? `${sidecarText} \u2227 ${names.join(" \u2227 ")}` : void 0;
2236
+ } else if (fromSidecar) {
2237
+ display = sidecarText;
2238
+ } else if (fromDirective) {
2239
+ display = names.join(" \u2227 ");
2240
+ }
2241
+ return display !== void 0 ? { param, constraint, display } : { param, constraint };
2242
+ }),
2087
2243
  ...returnsC !== void 0 ? { returns: { constraint: returnsC } } : {},
2088
2244
  ...mergedThrows !== void 0 ? { throws: { kinds: mergedThrows } } : {},
2245
+ ...sidecar.ok ? {
2246
+ sidecarPath: sidecar.sidecarPath,
2247
+ ...sidecar.sidecarLine !== void 0 ? { sidecarLine: sidecar.sidecarLine } : {}
2248
+ } : {},
2089
2249
  source: "handwritten",
2090
2250
  ...conflictParams.length > 0 || conflictReturns ? {
2091
2251
  conflict: {
@@ -2236,7 +2396,7 @@ function formatConstraint(c) {
2236
2396
  return fmtConstraint(c);
2237
2397
  }
2238
2398
  function formatEffectiveInterfaceDisplay(eff) {
2239
- const params = eff.params.map((p) => `${p.param}: ${formatConstraint(p.constraint)}`).join(", ");
2399
+ const params = eff.params.map((p) => `${p.param}: ${p.display ?? formatConstraint(p.constraint)}`).join(", ");
2240
2400
  let s = `(${params})`;
2241
2401
  if (eff.returns) s += ` \u2192 ${formatConstraint(eff.returns.constraint)}`;
2242
2402
  return s;
@@ -2254,7 +2414,12 @@ function interfaceTierOf(source, fnName, fromFile, opts = {}) {
2254
2414
  const eff = effectiveInterface(source, fnName, { fromFile, ...opts });
2255
2415
  const src = eff?.source ?? "implicit";
2256
2416
  if (eff && src !== "implicit") {
2257
- return { source: src, display: formatEffectiveInterfaceDisplay(eff) };
2417
+ return {
2418
+ source: src,
2419
+ display: formatEffectiveInterfaceDisplay(eff),
2420
+ ...eff.sidecarPath !== void 0 ? { sidecarPath: eff.sidecarPath } : {},
2421
+ ...eff.sidecarLine !== void 0 ? { sidecarLine: eff.sidecarLine } : {}
2422
+ };
2258
2423
  }
2259
2424
  return { source: src };
2260
2425
  }
@@ -3480,7 +3645,8 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
3480
3645
  if (reqs.length > 0) {
3481
3646
  entryReqs = reqs.map((e) => ({
3482
3647
  param: e.param,
3483
- pred: instantiateConstraint(e.constraint, e.param)
3648
+ pred: instantiateConstraint(e.constraint, e.param),
3649
+ ...e.display !== void 0 ? { display: e.display } : {}
3484
3650
  }));
3485
3651
  const patternFields = /* @__PURE__ */ new Map();
3486
3652
  for (const e of reqs) {
package/dist/exec.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as Abs, M as MayThrowEffect, b as Phi } from './run-WZKUu1y1.js';
2
- export { W as $assignRecord, X as $call, Y as $callNamed, Z as $recordBinding, a5 as EvalAbsAssignRecord, a6 as EvalCallRecord, a7 as EvalFallback, g as EvalFallbackStats, aa as MAX_EVAL_CALL_DEPTH, ab as MAX_EVAL_TOTAL_CALLS, ac as RUNTIME_IMPORT_RE, V as RunTranspiledOptions, ae as TranspiledCallResult, as as bindingsOf, av as callTranspiledExport, aw as callTranspiledExportApply, ax as callTranspiledExportFull, l as clearPureCallMemo, m as clearPureMemo, n as enterEvalCallBudgetSession, aC as evalExprAbs, p as exitEvalCallBudgetSession, v as getEvalCallBudgetState, aF as getEvalCallCollector, w as getEvalFallbackStats, aN as isAbsVal, b3 as noteEvalCallRecord, b4 as noteEvalFallback, bl as resetEvalCallBudget, H as resetEvalFallbackStats, bF as routeApplyThrows, bm as runTranspiled, bn as runTranspiledOptionsMemoKey, bo as setEvalAssignCollector, bp as setEvalBindingSink, bq as setEvalCallCollector, br as setEvalFallbackCollector, bC as tryRunTranspiled, O as withEvalBudgetOverride } from './run-WZKUu1y1.js';
1
+ import { A as Abs, M as MayThrowEffect, b as Phi } from './run-Bgj2tCrv.js';
2
+ export { W as $assignRecord, X as $call, Y as $callNamed, bI as $nodoPos, Z as $recordBinding, a5 as EvalAbsAssignRecord, a6 as EvalCallRecord, a7 as EvalFallback, g as EvalFallbackStats, a8 as EvalPosRecord, ab as MAX_EVAL_CALL_DEPTH, ac as MAX_EVAL_TOTAL_CALLS, ad as RUNTIME_IMPORT_RE, V as RunTranspiledOptions, af as TranspiledCallResult, at as bindingsOf, aw as callTranspiledExport, ax as callTranspiledExportApply, ay as callTranspiledExportFull, l as clearPureCallMemo, m as clearPureMemo, n as enterEvalCallBudgetSession, aD as evalExprAbs, p as exitEvalCallBudgetSession, v as getEvalCallBudgetState, aG as getEvalCallCollector, w as getEvalFallbackStats, bJ as getPosCollector, aO as isAbsVal, aQ as isCjsMainRun, b5 as noteEvalCallRecord, b6 as noteEvalFallback, bn as resetEvalCallBudget, H as resetEvalFallbackStats, bK as routeApplyThrows, bo as runTranspiled, bp as runTranspiledOptionsMemoKey, bq as setEvalAssignCollector, br as setEvalBindingSink, bs as setEvalCallCollector, bt as setEvalFallbackCollector, bv as setPosCollector, bF as tryRunTranspiled, O as withEvalBudgetOverride } from './run-Bgj2tCrv.js';
3
3
  import { Node, Expression, File } from '@babel/types';
4
4
 
5
5
  /**
@@ -181,19 +181,13 @@ declare function $join(a: Abs, b: Abs): Abs;
181
181
  * 访问器(get/set)侧表、in / instanceof / delete 路由。
182
182
  */
183
183
 
184
- /** 注册对象字面量访问器(transpile 调用;返回原 obj 以便链式包裹) */
185
- declare function $objAccessor(o: Abs, key: string, get: ((t: Abs) => Abs) | null, set: ((t: Abs, v: Abs) => Abs) | null): Abs;
186
184
  /** 计算键访问器注册(`{ get [expr]() {} }`):键为 Abs,ToPropertyKey 后注册。
187
185
  * 非字面量键无法静态定键——保占位槽(键存在性),不注册派发。 */
188
186
  declare function $objAccessorKey(o: Abs, key: Abs, get: ((t: Abs) => Abs) | null, set: ((t: Abs, v: Abs) => Abs) | null): Abs;
189
- /** 对象字面量访问器查询(供 $get/$set/$spread/Object.assign 共用) */
190
- declare function lookupObjAccessor(o: Abs, key: string): {
191
- get?: (t: Abs) => Abs;
192
- set?: (t: Abs, v: Abs) => Abs;
193
- } | undefined;
194
187
  /**
195
- * `key in obj`:闭形状精确判定(含 Object.prototype 名、数组下标/length、
196
- * class 方法/访问器与内建 brand 方法);prim/nullish 接收者原生抛 TypeError →
188
+ * `key in obj`:闭形状精确判定(含 Object.prototype/Array.prototype 名、
189
+ * 数组下标/length、class 方法/访问器与内建 brand 方法/访问器);
190
+ * prim/nullish 接收者原生抛 TypeError →
197
191
  * unknown;抽象键/开形状 → boolean。
198
192
  */
199
193
  declare function $in(key: Abs, o: Abs): Abs;
@@ -225,6 +219,21 @@ declare function $delRes(o: Abs, _key: Abs): Abs;
225
219
  */
226
220
  declare function $del(o: Abs, key: Abs): Abs;
227
221
 
222
+ /**
223
+ * 对象字面量访问器(get/set)侧表 —— 叶子模块。
224
+ * 下沉原因:objects.ts 的 joinObjects 需感知访问器(join 不迁移侧表会丢
225
+ * getter 读域),而 members.ts 依赖 objects.ts;表放无运行时依赖的叶子上
226
+ * 才能被两层共用而不成环。in / instanceof / delete 路由仍在 members.ts。
227
+ */
228
+
229
+ /** 注册对象字面量访问器(transpile 调用;返回原 obj 以便链式包裹) */
230
+ declare function $objAccessor(o: Abs, key: string, get: ((t: Abs) => Abs) | null, set: ((t: Abs, v: Abs) => Abs) | null): Abs;
231
+ /** 对象字面量访问器查询(供 $get/$set/$spread/Object.assign 共用) */
232
+ declare function lookupObjAccessor(o: Abs, key: string): {
233
+ get?: (t: Abs) => Abs;
234
+ set?: (t: Abs, v: Abs) => Abs;
235
+ } | undefined;
236
+
228
237
  /**
229
238
  * 循环展开上限(leaf)—— 从 control.ts 拆出,打断 control ↔ containers 环。
230
239
  */
@@ -338,8 +347,11 @@ declare function $idx(a: Abs, i: Abs, opts?: {
338
347
  }): Abs;
339
348
  /** 下标写 a[i]=v → 新 tuple(越界写按 JS 语义增长,空洞为 undefined) */
340
349
  declare function $idxSet(a: Abs, i: Abs, value: Abs): Abs;
341
- /** 数组/字符串长度 */
342
- declare function $len(a: Abs): Abs;
350
+ /** 数组/字符串长度。opts.silent:可选链(a?.length)守卫臂——接收者已过
351
+ * $removeNullish,仅 any 不记 may-throw(Bug 3,与 $get 的 silent 同口径)。 */
352
+ declare function $len(a: Abs, opts?: {
353
+ silent?: boolean;
354
+ }): Abs;
343
355
  /** 对象字面量 → Abs obj(槽位写走 setSlot,`__proto__` 不踩宿主 setter) */
344
356
  declare function $obj(slots: Record<string, Abs>): Abs;
345
357
  /**
@@ -368,7 +380,9 @@ declare function $iterCheck(a: unknown): void;
368
380
  /** 元素列表(tuple 展开;arr 抽象;C1 Set/Map 逐条目;matchAll 迭代器逐匹配项;
369
381
  * 字符串按 code points)。Map 迭代语义是 entry `[key, value]` 元组,不是裸 value。
370
382
  * 消费前先过可迭代性守卫(Bug 6):prim 字面量接收者 → 原生 definite
371
- * TypeError;any/unknown → may。$forOf 与 call/new spread 实参路径继承。 */
383
+ * TypeError;any/unknown → may。$forOf 与 call/new spread 实参路径继承。
384
+ * Bug 34:生成器对象的体内延迟异常(definite 抛 / soft may-throw 重记)
385
+ * 在消费点重放——迭代不再静默截断成前缀。 */
372
386
  declare function $elems(a: Abs): Abs[];
373
387
  /** 模板标签对象(GetTemplateObject,Bug 34):冻结的类数组 obj——数字槽
374
388
  * 为 cooked 字符串(无效转义序列时 cooked 是 undefined,原生实测)、
@@ -428,15 +442,17 @@ declare function $asyncReturn(v: Abs): Abs;
428
442
  /** function* 体:收集所有 yield 值;返回带迭代器协议面的生成器对象 Abs;
429
443
  * 抽象分支时降 conf(P0-6)
430
444
  *
431
- * Bug 58:调用生成器是原生全操作——体只在首个 next() 执行。此前 body()
432
- * eager 执行把体内 may-throw(成员读 any)/显式 throw 折进**调用方** throws
433
- * 域(每生成器入口假 entry-may-throw)。现以丢弃式 may-throw 帧包裹:
434
- * soft 效果进帧后丢弃、NudoThrow/宿主异常吞掉(迭代期语义,调用期不表面)。
435
- * yield 收集保持 eager(既有值域建模,注释口径不变)。
445
+ * Bug 58:调用生成器是原生全操作——体只在首个 next() 执行。body() eager
446
+ * 执行的体内效果(成员读 may-throw / 显式 throw)不折进**调用方** throws
447
+ * 域——以捕获式 may-throw 帧包裹:soft 效果与 NudoThrow 挂生成器对象
448
+ * (Bug 34 延迟重放:首个触达抛点的 next()/迭代消费,仅构造不消费不
449
+ * 表面)。yield 收集保持 eager(既有值域建模,注释口径不变)。
450
+ * Bug 2:thunk 返回值 = 终末 return 值——不再丢弃,经 makeGenObject 在
451
+ * 首个 done:true 作为 value 交付(node 实测:此后 next 回 undefined)。
436
452
  * Bug 22:结果从 yield 元组数组改为生成器对象(next/return/throw 方法面 +
437
453
  * constructor 身份);元素域经侧表保留($arr 的 ≤cap tuple / >cap arr
438
454
  * widen 策略不变),迭代路径(for-of/spread/Array.from)继续工作。 */
439
- declare function $gen(body: () => void): Abs;
455
+ declare function $gen(body: () => Abs): Abs;
440
456
  /** yield v:压入当前生成器收集器;表达式值用 unknown */
441
457
  declare function $yield(v: Abs): Abs;
442
458
  /** yield* v(Bug 82):委托迭代 ≠ yield v——GetIterator 校验先行($elems
@@ -496,6 +512,18 @@ declare function $removeMemberNullish(a: Abs, key: string): Abs;
496
512
  * 原样返回(臂不可达的保守近似,与 $removeNullish 空集口径一致)。
497
513
  */
498
514
  declare function $narrowTypeOf(a: Abs, typeOf: string, keep: boolean): Abs;
515
+ /**
516
+ * 关系守卫臂剪影(Bug 1):`x >= 0` 真臂把 x 重绑为带 ge(x,0) 界的 Abs
517
+ * ——守卫建立的隐含约束随**普通变量读取**进入返回值 / 签名面。此前只有
518
+ * 算术折叠消费 exec Φ(`x + 0` 携带界),裸 `return x` 丢守卫事实 →
519
+ * return-constraint gate 假阳(可证合规的函数过不了 CI)。只做事实臂:
520
+ * ¬(x≥0) 含 NaN 可能(NaN 与任何比较皆假),补集界不可健全表示。精确
521
+ * 字面量(lit term)的界由域隶属折叠,不加 pred 保持精确面干净。
522
+ * 只精化 number prim:any 的真臂还含 bigint(`10n >= 0` 为真)与
523
+ * ToPrimitive 对象面,refineAbsForRelTrue 的 number|string 并集会
524
+ * 凭空排除 bigint → 假证明;any/unknown 保持原样(宁缺毋假)。
525
+ */
526
+ declare function $refineRel(a: Abs, op: "gt" | "ge" | "lt" | "le", k: number): Abs;
499
527
  /**
500
528
  * 判别等值守卫臂剪影(issue #126):`x.key === lit` 事实臂(keep=true)内把
501
529
  * x 重绑为「key 值域可能等于 lit」的成员子集(剪 "never" 成员);对偶补集臂
@@ -575,6 +603,16 @@ type TranspileOptions = {
575
603
  destrTmpSeq?: {
576
604
  n: number;
577
605
  };
606
+ /**
607
+ * try 临时名单调计数器(`__nudoTm_`/`__nudoE_`;transpileFile /
608
+ * transpileBodyNode 创建,单次转译输出内共享)。此前按源行号命名——
609
+ * 同一作用域同一行两个 try(压缩/生成代码)重名 → 重复 `const` 声明 →
610
+ * `new Function` SyntaxError 整模块 fail-closed;计数器与行号解耦
611
+ * (含 loc 缺失 `?? 0` 的碰撞),跨语句单调。
612
+ */
613
+ tryTmpSeq?: {
614
+ n: number;
615
+ };
578
616
  /**
579
617
  * 当前词法作用域可见的 const 绑定名(用户层再赋值须 TypeError)。
580
618
  * 成员/下标写对根的内部重绑不在用户赋值路径,不走此表。
@@ -591,6 +629,14 @@ type TranspileOptions = {
591
629
  * 声明语句),此类名字从提升集扣除、不发改赋值。
592
630
  */
593
631
  keepVarDecl?: boolean;
632
+ /**
633
+ * 节点级 Abs 记录插桩(hover 重放用):Identifier 值读与
634
+ * 静态成员读的转译输出包 `$nodoPos(<src>, line, column)`,
635
+ * 运行时把 (行, 列) → Abs 记入活跃的位置 collector(无收
636
+ * 集器时 no-op 直通)。默认关——热路径(check/模块图)不
637
+ * 承担插桩开销;仅 replayFnAbsNodes 重放开。
638
+ */
639
+ recordPositions?: boolean;
594
640
  };
595
641
 
596
642
  /**
@@ -619,6 +665,12 @@ declare function transpileBodyNode(node: Node, opts: TranspileOptions): string;
619
665
  * 表达式发射:transpileExpression / transpileShortCircuitExpr。
620
666
  */
621
667
 
668
+ /**
669
+ * 表达式发射入口(位置插桩包装层)。recordPositions 时把
670
+ * Identifier 值读 / 静态成员读的转译输出包 `$nodoPos`——
671
+ * 运行时记 (行, 列) → Abs 并原样返回(语义恒等;无收集
672
+ * 器时直通)。内部递归经本包装——每个子表达式恰包一次。
673
+ */
622
674
  declare function transpileExpression(expr: Expression, opts?: TranspileOptions): string;
623
675
 
624
676
  /**
@@ -773,4 +825,4 @@ declare class NudoUnsupportedError extends Error {
773
825
  detail?: string);
774
826
  }
775
827
 
776
- export { $absVal, $add, $arguments, $arr, $arrMutContainer, $arrRest, $arrWithHoles, $async, $asyncReturn, $await, $bitand, $bitnot, $bitor, $bitxor, $catchVal, $class, $classExpr, $collectionForEach, $concat, $copy, $del, $delRes, $div, $dynamicImport, $elems, $eq, $eqLoose, $fnVal, $for, $forInKeys, $forIter, $forOf, $fork, $ge, $gen, $get, $getSuper, $getSuperObj, $gt, $idx, $idxSet, $importMeta, $in, $instanceof, $instanceofNonIdent, $invoke, $invokeSuper, $invokeSuperKey, $invokeSuperObj, $isBreakTo, $isForkExit, $iterCheck, $join, $le, $len, $lit, $loopBreak, $loopContinue, $loopReturn, $lt, $mod, $mul, $narrowMemberEq, $narrowTypeOf, $ne, $neLoose, $neg, $new, $newTarget, $not, $nullishTest, $obj, $objAccessor, $objAccessorKey, $objRest, $optionalGet, $optionalInvoke, $orDefault, $pow, $pushLoopExit, $rawThis, $reStateCall, $regex, $removeMemberNullish, $removeNull, $removeNullish, $removeUndefined, $restBind, $rethrowIfNudoReturn, $set, $setKey, $setProto, $shl, $shr, $spread, $staticInit, $staticInvoke, $sub, $super, $switch, $thisGet, $thisSet, $throw, $toNumber, $toNumeric, $tpl, $tryCurrentMark, $tryDetachSoftCatch, $tryDigestSoftCatch, $tryDiscardSoft, $tryMark, $tryOrphanSoft, $tryPopMark, $tryReleaseSoftCatch, $tryReleaseSoftOut, $tryTakeSince, $typeof, $unknown, $updateAdd, $updateSub, $ushr, $while, $whileSeq, $yield, $yieldStar, DEFAULT_MAX_LOOP_ITERS, type EvalClassSpec, NudoLoopSignal, NudoReturn, NudoThrow, NudoUnsupportedError, type TranspileOptions, asAbsVal, callAtFunctionBoundary, clearBClasses, clearStaleTermPred, currentExecPhi, fillTuple, foldRequireSpecArg, foldStaticStringExpr, getEvalClass, isArrMutator, isDefinitelyFalse, isDefinitelyTrue, isNudoBreak, isNudoContinue, isNudoReturn, isNudoThrow, litTruth, lookupObjAccessor, namespaceNameOf, pushLoopExit, pushThrowExit, registerEvalClass, runWithLoopExits, runtimeImportOf, takeLoopExits, takeThrowExits, transpile, transpileBodyNode, transpileExpression, transpileFile, transpileSource, withExecPhi };
828
+ export { $absVal, $add, $arguments, $arr, $arrMutContainer, $arrRest, $arrWithHoles, $async, $asyncReturn, $await, $bitand, $bitnot, $bitor, $bitxor, $catchVal, $class, $classExpr, $collectionForEach, $concat, $copy, $del, $delRes, $div, $dynamicImport, $elems, $eq, $eqLoose, $fnVal, $for, $forInKeys, $forIter, $forOf, $fork, $ge, $gen, $get, $getSuper, $getSuperObj, $gt, $idx, $idxSet, $importMeta, $in, $instanceof, $instanceofNonIdent, $invoke, $invokeSuper, $invokeSuperKey, $invokeSuperObj, $isBreakTo, $isForkExit, $iterCheck, $join, $le, $len, $lit, $loopBreak, $loopContinue, $loopReturn, $lt, $mod, $mul, $narrowMemberEq, $narrowTypeOf, $ne, $neLoose, $neg, $new, $newTarget, $not, $nullishTest, $obj, $objAccessor, $objAccessorKey, $objRest, $optionalGet, $optionalInvoke, $orDefault, $pow, $pushLoopExit, $rawThis, $reStateCall, $refineRel, $regex, $removeMemberNullish, $removeNull, $removeNullish, $removeUndefined, $restBind, $rethrowIfNudoReturn, $set, $setKey, $setProto, $shl, $shr, $spread, $staticInit, $staticInvoke, $sub, $super, $switch, $thisGet, $thisSet, $throw, $toNumber, $toNumeric, $tpl, $tryCurrentMark, $tryDetachSoftCatch, $tryDigestSoftCatch, $tryDiscardSoft, $tryMark, $tryOrphanSoft, $tryPopMark, $tryReleaseSoftCatch, $tryReleaseSoftOut, $tryTakeSince, $typeof, $unknown, $updateAdd, $updateSub, $ushr, $while, $whileSeq, $yield, $yieldStar, DEFAULT_MAX_LOOP_ITERS, type EvalClassSpec, NudoLoopSignal, NudoReturn, NudoThrow, NudoUnsupportedError, type TranspileOptions, asAbsVal, callAtFunctionBoundary, clearBClasses, clearStaleTermPred, currentExecPhi, fillTuple, foldRequireSpecArg, foldStaticStringExpr, getEvalClass, isArrMutator, isDefinitelyFalse, isDefinitelyTrue, isNudoBreak, isNudoContinue, isNudoReturn, isNudoThrow, litTruth, lookupObjAccessor, namespaceNameOf, pushLoopExit, pushThrowExit, registerEvalClass, runWithLoopExits, runtimeImportOf, takeLoopExits, takeThrowExits, transpile, transpileBodyNode, transpileExpression, transpileFile, transpileSource, withExecPhi };
package/dist/exec.js CHANGED
@@ -72,6 +72,7 @@ import {
72
72
  $neg,
73
73
  $new,
74
74
  $newTarget,
75
+ $nodoPos,
75
76
  $not,
76
77
  $nullishTest,
77
78
  $obj,
@@ -86,6 +87,7 @@ import {
86
87
  $rawThis,
87
88
  $reStateCall,
88
89
  $recordBinding,
90
+ $refineRel,
89
91
  $regex,
90
92
  $removeMemberNullish,
91
93
  $removeNull,
@@ -158,8 +160,10 @@ import {
158
160
  getEvalCallCollector,
159
161
  getEvalClass,
160
162
  getEvalFallbackStats,
163
+ getPosCollector,
161
164
  isAbsVal,
162
165
  isArrMutator,
166
+ isCjsMainRun,
163
167
  isDefinitelyFalse,
164
168
  isDefinitelyTrue,
165
169
  isNudoBreak,
@@ -185,6 +189,7 @@ import {
185
189
  setEvalBindingSink,
186
190
  setEvalCallCollector,
187
191
  setEvalFallbackCollector,
192
+ setPosCollector,
188
193
  takeLoopExits,
189
194
  takeThrowExits,
190
195
  transpile,
@@ -195,7 +200,7 @@ import {
195
200
  tryRunTranspiled,
196
201
  withEvalBudgetOverride,
197
202
  withExecPhi
198
- } from "./chunk-PGTNSUTE.js";
203
+ } from "./chunk-2ZIOQGW3.js";
199
204
  export {
200
205
  $absVal,
201
206
  $add,
@@ -269,6 +274,7 @@ export {
269
274
  $neg,
270
275
  $new,
271
276
  $newTarget,
277
+ $nodoPos,
272
278
  $not,
273
279
  $nullishTest,
274
280
  $obj,
@@ -283,6 +289,7 @@ export {
283
289
  $rawThis,
284
290
  $reStateCall,
285
291
  $recordBinding,
292
+ $refineRel,
286
293
  $regex,
287
294
  $removeMemberNullish,
288
295
  $removeNull,
@@ -355,8 +362,10 @@ export {
355
362
  getEvalCallCollector,
356
363
  getEvalClass,
357
364
  getEvalFallbackStats,
365
+ getPosCollector,
358
366
  isAbsVal,
359
367
  isArrMutator,
368
+ isCjsMainRun,
360
369
  isDefinitelyFalse,
361
370
  isDefinitelyTrue,
362
371
  isNudoBreak,
@@ -382,6 +391,7 @@ export {
382
391
  setEvalBindingSink,
383
392
  setEvalCallCollector,
384
393
  setEvalFallbackCollector,
394
+ setPosCollector,
385
395
  takeLoopExits,
386
396
  takeThrowExits,
387
397
  transpile,