@nudojs/core 1.9.3 → 1.10.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/{chunk-VMGJYMIF.js → chunk-HX4IEPRI.js} +256 -43
- package/dist/{chunk-HD6XZFOU.js → chunk-YREYFITQ.js} +13215 -11479
- package/dist/exec.d.ts +58 -14
- package/dist/exec.js +11 -1
- package/dist/index.d.ts +34 -13
- package/dist/index.js +23 -14
- package/dist/internal.d.ts +6 -4
- package/dist/internal.js +10 -5
- package/dist/{projection-budget-Dm1YWZ1U.d.ts → projection-budget-Dey0IUJa.d.ts} +22 -3
- package/dist/{run-WZKUu1y1.d.ts → run-Bgj2tCrv.d.ts} +40 -1
- package/package.json +1 -1
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
fnConstraintToEntryReqs,
|
|
16
16
|
foldRequireSpecArg,
|
|
17
17
|
formalParamDisplayNames,
|
|
18
|
+
formalParamSignatureNames,
|
|
18
19
|
formalParamsFromNodes,
|
|
19
20
|
formatAbs,
|
|
20
21
|
formatShape,
|
|
@@ -46,7 +47,7 @@ import {
|
|
|
46
47
|
withEvalBudgetOverride,
|
|
47
48
|
withExecPhi,
|
|
48
49
|
withFnBudgetOverride
|
|
49
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-YREYFITQ.js";
|
|
50
51
|
|
|
51
52
|
// src/algebra/directive-scan.ts
|
|
52
53
|
function cleanDirectiveLine(raw, kind) {
|
|
@@ -987,6 +988,75 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
987
988
|
}
|
|
988
989
|
}
|
|
989
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
|
+
}
|
|
990
1060
|
if (fromFile?.endsWith(".nudo.ts")) {
|
|
991
1061
|
for (const cut of collectTsSyntaxCuts(ast.program, src)) {
|
|
992
1062
|
cuts.push({ start: cut.start, end: cut.end, text: "" });
|
|
@@ -1010,7 +1080,7 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1010
1080
|
pos = c.end;
|
|
1011
1081
|
}
|
|
1012
1082
|
code += src.slice(pos);
|
|
1013
|
-
return { code, exportPairs, imports };
|
|
1083
|
+
return { code, exportPairs, imports, bindingInfos };
|
|
1014
1084
|
}
|
|
1015
1085
|
var TS_STMT_CUT_TYPES = /* @__PURE__ */ new Set([
|
|
1016
1086
|
"TSInterfaceDeclaration",
|
|
@@ -1082,9 +1152,25 @@ function collectTsSyntaxCuts(node, src, cuts = []) {
|
|
|
1082
1152
|
}
|
|
1083
1153
|
return cuts;
|
|
1084
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
|
+
}
|
|
1085
1171
|
function execSidecar(src, opts, chain, preloaded) {
|
|
1086
1172
|
const fromFile = opts?.fromFile;
|
|
1087
|
-
const { code, exportPairs, imports } = rewriteSidecarSource(src, fromFile);
|
|
1173
|
+
const { code, exportPairs, imports, bindingInfos } = rewriteSidecarSource(src, fromFile);
|
|
1088
1174
|
const prologue = [];
|
|
1089
1175
|
const deps = {};
|
|
1090
1176
|
for (const imp of imports) {
|
|
@@ -1166,12 +1252,13 @@ function execSidecar(src, opts, chain, preloaded) {
|
|
|
1166
1252
|
for (const n of imp.names) deps[n.local] = void 0;
|
|
1167
1253
|
continue;
|
|
1168
1254
|
}
|
|
1169
|
-
const
|
|
1255
|
+
const depOut = execSidecar(
|
|
1170
1256
|
depSrc,
|
|
1171
1257
|
{ loadModule: load, fromFile: canonical },
|
|
1172
1258
|
[...chain, canonical],
|
|
1173
1259
|
preloaded
|
|
1174
1260
|
);
|
|
1261
|
+
const depExports = depOut.exports;
|
|
1175
1262
|
for (const n of imp.names) {
|
|
1176
1263
|
if (n.ns) {
|
|
1177
1264
|
deps[n.local] = depExports;
|
|
@@ -1211,7 +1298,11 @@ return { ${returnObj} };`;
|
|
|
1211
1298
|
"__nudoDeps",
|
|
1212
1299
|
body
|
|
1213
1300
|
);
|
|
1214
|
-
|
|
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 };
|
|
1215
1306
|
}
|
|
1216
1307
|
function execNudoModule(src, opts) {
|
|
1217
1308
|
return execNudoModuleCached(src, opts ?? {});
|
|
@@ -1267,22 +1358,29 @@ function execNudoModuleCached(src, opts) {
|
|
|
1267
1358
|
if (hit !== void 0) {
|
|
1268
1359
|
nudoModuleExecCache.delete(key);
|
|
1269
1360
|
nudoModuleExecCache.set(key, hit);
|
|
1270
|
-
|
|
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;
|
|
1271
1369
|
}
|
|
1272
1370
|
if (nudoModuleFailCache.has(key)) {
|
|
1273
1371
|
throw nudoModuleFailCache.get(key);
|
|
1274
1372
|
}
|
|
1275
1373
|
}
|
|
1276
1374
|
try {
|
|
1277
|
-
const
|
|
1375
|
+
const { exports, bindingInfos } = execSidecar(src, opts, opts.fromFile ? [opts.fromFile] : [], preloaded);
|
|
1278
1376
|
if (key !== void 0) {
|
|
1279
1377
|
if (nudoModuleExecCache.size >= MAX_NUDO_MODULE_EXEC) {
|
|
1280
1378
|
const oldest = nudoModuleExecCache.keys().next().value;
|
|
1281
1379
|
if (oldest !== void 0) nudoModuleExecCache.delete(oldest);
|
|
1282
1380
|
}
|
|
1283
|
-
nudoModuleExecCache.set(key,
|
|
1381
|
+
nudoModuleExecCache.set(key, { exports, bindingInfos });
|
|
1284
1382
|
}
|
|
1285
|
-
return
|
|
1383
|
+
return exports;
|
|
1286
1384
|
} catch (e) {
|
|
1287
1385
|
if (key !== void 0) {
|
|
1288
1386
|
if (nudoModuleFailCache.size >= MAX_NUDO_MODULE_EXEC) {
|
|
@@ -1297,6 +1395,17 @@ function execNudoModuleCached(src, opts) {
|
|
|
1297
1395
|
function resetNudoModuleExecCache() {
|
|
1298
1396
|
nudoModuleExecCache.clear();
|
|
1299
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);
|
|
1300
1409
|
}
|
|
1301
1410
|
function collectConstraints(source, opts) {
|
|
1302
1411
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -1410,7 +1519,8 @@ function extractRefinesFromSource(source, fnName, opts = {}) {
|
|
|
1410
1519
|
out.push({
|
|
1411
1520
|
param,
|
|
1412
1521
|
pred: instantiateConstraint(c, param),
|
|
1413
|
-
constraint: c
|
|
1522
|
+
constraint: c,
|
|
1523
|
+
name: cName
|
|
1414
1524
|
});
|
|
1415
1525
|
}
|
|
1416
1526
|
}
|
|
@@ -1857,18 +1967,25 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
1857
1967
|
return { ok: false };
|
|
1858
1968
|
}
|
|
1859
1969
|
let binding = Object.hasOwn(exports, fnName) ? exports[fnName] : void 0;
|
|
1970
|
+
let bindingKey;
|
|
1971
|
+
if (binding !== void 0) bindingKey = fnName;
|
|
1860
1972
|
if (binding === void 0) {
|
|
1861
1973
|
const aliasExport2 = exportedNameOfLocal(source, fnName);
|
|
1862
1974
|
if (aliasExport2 !== void 0 && Object.hasOwn(exports, aliasExport2)) {
|
|
1863
1975
|
binding = exports[aliasExport2];
|
|
1976
|
+
bindingKey = aliasExport2;
|
|
1864
1977
|
}
|
|
1865
1978
|
}
|
|
1866
1979
|
if (binding === void 0 && exports.default !== void 0 && isDefaultExportLocal(source, fnName)) {
|
|
1867
1980
|
binding = exports.default;
|
|
1981
|
+
bindingKey = "default";
|
|
1868
1982
|
}
|
|
1869
1983
|
if (binding === void 0 && fnName.includes(".")) {
|
|
1870
1984
|
const [cls, method] = fnName.split(".", 2);
|
|
1871
|
-
|
|
1985
|
+
if (Object.hasOwn(exports, `${cls}_${method}`)) {
|
|
1986
|
+
binding = exports[`${cls}_${method}`];
|
|
1987
|
+
bindingKey = `${cls}_${method}`;
|
|
1988
|
+
}
|
|
1872
1989
|
if (binding === void 0) {
|
|
1873
1990
|
const bag = Object.hasOwn(exports, cls) ? exports[cls] : void 0;
|
|
1874
1991
|
if (bag && typeof bag === "object" && !isNudoConstraint(bag)) {
|
|
@@ -1906,11 +2023,14 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
1906
2023
|
const [cls, method] = fnName.split(".", 2);
|
|
1907
2024
|
return generatedNames.has(`${cls}_${method}`) || generatedNames.has(cls);
|
|
1908
2025
|
})() : false);
|
|
2026
|
+
const info = bindingKey !== void 0 ? lookupSidecarParamTexts(sidecarPath, hashSource(sidecarSrc), bindingKey) : void 0;
|
|
1909
2027
|
return {
|
|
1910
2028
|
ok: true,
|
|
1911
2029
|
sidecarPath,
|
|
1912
2030
|
constraint: binding,
|
|
1913
|
-
generated: isGenerated
|
|
2031
|
+
generated: isGenerated,
|
|
2032
|
+
...info?.texts !== void 0 ? { paramTexts: info.texts } : {},
|
|
2033
|
+
...info?.line !== void 0 ? { sidecarLine: info.line } : {}
|
|
1914
2034
|
};
|
|
1915
2035
|
}
|
|
1916
2036
|
function boundsOf(c) {
|
|
@@ -2013,8 +2133,24 @@ function effectiveInterface(source, fnName, opts = {}) {
|
|
|
2013
2133
|
collectDiag2({ code: d.code, message: d.message, ...d.file ? { file: d.file } : {} });
|
|
2014
2134
|
}
|
|
2015
2135
|
const sidecarFn = sidecar.ok ? sidecar.constraint : void 0;
|
|
2136
|
+
const sidecarParamTexts = sidecar.ok ? sidecar.paramTexts : void 0;
|
|
2016
2137
|
const sidecarGenerated = sidecar.ok && sidecar.generated;
|
|
2017
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
|
+
}
|
|
2018
2154
|
const sidecarReturns = sidecarFn?.fn.returns;
|
|
2019
2155
|
const sidecarThrowsKinds = throwConstraintToKinds(sidecarFn?.fn.throws);
|
|
2020
2156
|
const mergedThrows = (() => {
|
|
@@ -2027,9 +2163,16 @@ function effectiveInterface(source, fnName, opts = {}) {
|
|
|
2027
2163
|
if (sidecarFn !== void 0 && sidecarGenerated) {
|
|
2028
2164
|
return {
|
|
2029
2165
|
fnName,
|
|
2030
|
-
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
|
+
}),
|
|
2031
2170
|
...sidecarReturns !== void 0 ? { returns: { constraint: sidecarReturns } } : {},
|
|
2032
2171
|
...mergedThrows !== void 0 ? { throws: { kinds: mergedThrows } } : {},
|
|
2172
|
+
...sidecar.ok ? {
|
|
2173
|
+
sidecarPath: sidecar.sidecarPath,
|
|
2174
|
+
...sidecar.sidecarLine !== void 0 ? { sidecarLine: sidecar.sidecarLine } : {}
|
|
2175
|
+
} : {},
|
|
2033
2176
|
source: "generated"
|
|
2034
2177
|
};
|
|
2035
2178
|
}
|
|
@@ -2082,9 +2225,27 @@ function effectiveInterface(source, fnName, opts = {}) {
|
|
|
2082
2225
|
}
|
|
2083
2226
|
return {
|
|
2084
2227
|
fnName,
|
|
2085
|
-
params: [...params.entries()].map(([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
|
+
}),
|
|
2086
2243
|
...returnsC !== void 0 ? { returns: { constraint: returnsC } } : {},
|
|
2087
2244
|
...mergedThrows !== void 0 ? { throws: { kinds: mergedThrows } } : {},
|
|
2245
|
+
...sidecar.ok ? {
|
|
2246
|
+
sidecarPath: sidecar.sidecarPath,
|
|
2247
|
+
...sidecar.sidecarLine !== void 0 ? { sidecarLine: sidecar.sidecarLine } : {}
|
|
2248
|
+
} : {},
|
|
2088
2249
|
source: "handwritten",
|
|
2089
2250
|
...conflictParams.length > 0 || conflictReturns ? {
|
|
2090
2251
|
conflict: {
|
|
@@ -2235,7 +2396,7 @@ function formatConstraint(c) {
|
|
|
2235
2396
|
return fmtConstraint(c);
|
|
2236
2397
|
}
|
|
2237
2398
|
function formatEffectiveInterfaceDisplay(eff) {
|
|
2238
|
-
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(", ");
|
|
2239
2400
|
let s = `(${params})`;
|
|
2240
2401
|
if (eff.returns) s += ` \u2192 ${formatConstraint(eff.returns.constraint)}`;
|
|
2241
2402
|
return s;
|
|
@@ -2253,7 +2414,12 @@ function interfaceTierOf(source, fnName, fromFile, opts = {}) {
|
|
|
2253
2414
|
const eff = effectiveInterface(source, fnName, { fromFile, ...opts });
|
|
2254
2415
|
const src = eff?.source ?? "implicit";
|
|
2255
2416
|
if (eff && src !== "implicit") {
|
|
2256
|
-
return {
|
|
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
|
+
};
|
|
2257
2423
|
}
|
|
2258
2424
|
return { source: src };
|
|
2259
2425
|
}
|
|
@@ -3479,7 +3645,8 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3479
3645
|
if (reqs.length > 0) {
|
|
3480
3646
|
entryReqs = reqs.map((e) => ({
|
|
3481
3647
|
param: e.param,
|
|
3482
|
-
pred: instantiateConstraint(e.constraint, e.param)
|
|
3648
|
+
pred: instantiateConstraint(e.constraint, e.param),
|
|
3649
|
+
...e.display !== void 0 ? { display: e.display } : {}
|
|
3483
3650
|
}));
|
|
3484
3651
|
const patternFields = /* @__PURE__ */ new Map();
|
|
3485
3652
|
for (const e of reqs) {
|
|
@@ -3504,10 +3671,33 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3504
3671
|
patternFields.set(hit.index, bag);
|
|
3505
3672
|
}
|
|
3506
3673
|
const fieldAbs = constraintToEntryAbs(e.constraint, e.param);
|
|
3507
|
-
|
|
3674
|
+
const leaf = {
|
|
3508
3675
|
abs: fieldAbs,
|
|
3509
3676
|
...e.constraint.isOptional ? { optional: true } : {}
|
|
3510
3677
|
};
|
|
3678
|
+
const segs = hit.fieldPath ?? [hit.field];
|
|
3679
|
+
if (segs.length <= 1) {
|
|
3680
|
+
bag[hit.field] = leaf;
|
|
3681
|
+
continue;
|
|
3682
|
+
}
|
|
3683
|
+
let level = bag;
|
|
3684
|
+
let skip = false;
|
|
3685
|
+
for (let i = 0; i < segs.length - 1; i++) {
|
|
3686
|
+
const node = level[segs[i]];
|
|
3687
|
+
if (node === void 0) {
|
|
3688
|
+
const sub = { slots: {} };
|
|
3689
|
+
level[segs[i]] = sub;
|
|
3690
|
+
level = sub.slots;
|
|
3691
|
+
} else if ("slots" in node) {
|
|
3692
|
+
level = node.slots;
|
|
3693
|
+
} else {
|
|
3694
|
+
skip = true;
|
|
3695
|
+
break;
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
if (!skip) {
|
|
3699
|
+
level[segs[segs.length - 1]] = leaf;
|
|
3700
|
+
}
|
|
3511
3701
|
} else if (hit) {
|
|
3512
3702
|
const entryAbs = constraintToEntryAbs(e.constraint, e.param);
|
|
3513
3703
|
typeParams[hit.index] = {
|
|
@@ -3520,20 +3710,34 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3520
3710
|
});
|
|
3521
3711
|
}
|
|
3522
3712
|
}
|
|
3523
|
-
|
|
3713
|
+
const sigNames = formalParamSignatureNames(formals);
|
|
3714
|
+
const buildPatternObjAbs = (slotsBag, sigName, walked) => {
|
|
3524
3715
|
const slots = {};
|
|
3525
|
-
for (const [key,
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3716
|
+
for (const [key, node] of Object.entries(slotsBag)) {
|
|
3717
|
+
if ("abs" in node) {
|
|
3718
|
+
slots[key] = {
|
|
3719
|
+
value: node.abs,
|
|
3720
|
+
...node.optional ? { optional: true } : {}
|
|
3721
|
+
};
|
|
3722
|
+
} else {
|
|
3723
|
+
slots[key] = {
|
|
3724
|
+
value: buildPatternObjAbs(node.slots, sigName, [...walked, key])
|
|
3725
|
+
};
|
|
3726
|
+
}
|
|
3530
3727
|
}
|
|
3531
|
-
|
|
3728
|
+
return abs(
|
|
3532
3729
|
{ k: "obj", slots },
|
|
3533
|
-
v(
|
|
3730
|
+
v(walked.length === 0 ? sigName : `${sigName}.${walked.join(".")}`),
|
|
3534
3731
|
void 0,
|
|
3535
3732
|
"path"
|
|
3536
3733
|
);
|
|
3734
|
+
};
|
|
3735
|
+
for (const [pIdx, bag] of patternFields) {
|
|
3736
|
+
const objAbs = buildPatternObjAbs(
|
|
3737
|
+
bag,
|
|
3738
|
+
sigNames[pIdx] ?? params[pIdx] ?? `_p${pIdx}`,
|
|
3739
|
+
[]
|
|
3740
|
+
);
|
|
3537
3741
|
typeParams[pIdx] = {
|
|
3538
3742
|
id: typeParams[pIdx].id,
|
|
3539
3743
|
value: objAbs
|
|
@@ -3677,6 +3881,7 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3677
3881
|
}));
|
|
3678
3882
|
}
|
|
3679
3883
|
}
|
|
3884
|
+
const renderNames = formals.length > 0 ? formalParamSignatureNames(formals) : params;
|
|
3680
3885
|
return {
|
|
3681
3886
|
name: fnName,
|
|
3682
3887
|
params,
|
|
@@ -3685,6 +3890,7 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3685
3890
|
instantiate: (args, phi) => run(args, phi ?? pTrue),
|
|
3686
3891
|
display: formatPoly(
|
|
3687
3892
|
fnName,
|
|
3893
|
+
renderNames,
|
|
3688
3894
|
params,
|
|
3689
3895
|
typeParams,
|
|
3690
3896
|
symbolic,
|
|
@@ -3699,12 +3905,13 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3699
3905
|
...hofSites ? { hofSites } : {}
|
|
3700
3906
|
};
|
|
3701
3907
|
}
|
|
3702
|
-
function formatPoly(name, params, typeParams, symbolic, entryReqs, entryShapes, fnRels) {
|
|
3908
|
+
function formatPoly(name, renderNames, params, typeParams, symbolic, entryReqs, entryShapes, fnRels) {
|
|
3703
3909
|
const reqByParam = new Map((entryReqs ?? []).map((r) => [r.param, r.pred]));
|
|
3704
|
-
const ps =
|
|
3910
|
+
const ps = renderNames.map((p, i) => {
|
|
3911
|
+
const key = params[i] ?? p;
|
|
3705
3912
|
const id = typeParams[i]?.id ?? "unknown";
|
|
3706
|
-
const pred = reqByParam.get(
|
|
3707
|
-
const promoted = entryShapes?.get(
|
|
3913
|
+
const pred = reqByParam.get(key);
|
|
3914
|
+
const promoted = entryShapes?.get(key)?.abs ?? fnRels?.get(key)?.abs;
|
|
3708
3915
|
if (promoted) {
|
|
3709
3916
|
const slot = formatShapeSlot(promoted);
|
|
3710
3917
|
if (pred && pred.op !== "true") {
|
|
@@ -4480,13 +4687,17 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4480
4687
|
eiCache.set(key, r);
|
|
4481
4688
|
return r;
|
|
4482
4689
|
};
|
|
4483
|
-
const
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4690
|
+
const projectArgPath = (arg, segments) => {
|
|
4691
|
+
let cur = arg;
|
|
4692
|
+
for (const seg of segments) {
|
|
4693
|
+
if (!cur) return void 0;
|
|
4694
|
+
if (cur.shape.k === "brand") {
|
|
4695
|
+
cur = cur.shape.shape;
|
|
4696
|
+
}
|
|
4697
|
+
if (cur.shape.k !== "obj") return void 0;
|
|
4698
|
+
cur = getSlot(cur.shape.slots, seg)?.value;
|
|
4487
4699
|
}
|
|
4488
|
-
|
|
4489
|
-
return getSlot(arg.shape.slots, field)?.value;
|
|
4700
|
+
return cur;
|
|
4490
4701
|
};
|
|
4491
4702
|
const interfaceToIndexed = (ei, paramNames, formals) => {
|
|
4492
4703
|
const conflict = new Set(ei.conflict?.params ?? []);
|
|
@@ -4508,7 +4719,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4508
4719
|
entries.push([
|
|
4509
4720
|
hit.index,
|
|
4510
4721
|
{ param, pred: instantiateConstraint(constraint, param), constraint },
|
|
4511
|
-
hit.field
|
|
4722
|
+
hit.fieldPath ?? (hit.field !== void 0 ? [hit.field] : void 0)
|
|
4512
4723
|
]);
|
|
4513
4724
|
}
|
|
4514
4725
|
}
|
|
@@ -4544,17 +4755,18 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4544
4755
|
return lv <= n;
|
|
4545
4756
|
};
|
|
4546
4757
|
const checkReqs = (displayName, reqs, paramNames, absArgs, argIndexOf, loc) => {
|
|
4547
|
-
for (const [idx, pred,
|
|
4758
|
+
for (const [idx, pred, fieldPath, contractParam] of reqs) {
|
|
4548
4759
|
const argIdx = argIndexOf(idx);
|
|
4549
4760
|
if (argIdx === void 0) continue;
|
|
4550
4761
|
let arg = absArgs[argIdx];
|
|
4551
4762
|
if (!arg) continue;
|
|
4552
4763
|
const paramName = contractParam || paramNames[idx] || `arg${idx}`;
|
|
4553
|
-
if (
|
|
4554
|
-
const projected =
|
|
4764
|
+
if (fieldPath) {
|
|
4765
|
+
const projected = projectArgPath(arg, fieldPath);
|
|
4555
4766
|
if (!projected) {
|
|
4556
4767
|
const k = arg.shape.k;
|
|
4557
4768
|
if (k !== "unknown" && k !== "any") {
|
|
4769
|
+
const field = fieldPath.join(".");
|
|
4558
4770
|
out.push({
|
|
4559
4771
|
severity: "error",
|
|
4560
4772
|
code: "nudo:constraint-violated",
|
|
@@ -4895,7 +5107,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4895
5107
|
}
|
|
4896
5108
|
};
|
|
4897
5109
|
const checkShapeReqs = (displayName, reqs, paramNames, absArgs, argIndexOf, loc) => {
|
|
4898
|
-
for (const [idx, entry,
|
|
5110
|
+
for (const [idx, entry, fieldPath] of reqs) {
|
|
4899
5111
|
const c = entry.constraint;
|
|
4900
5112
|
if (!c.fields && !c.element && !isIntFlag(c) && !c.prim) continue;
|
|
4901
5113
|
const argIdx = argIndexOf(idx);
|
|
@@ -4903,11 +5115,12 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4903
5115
|
let arg = absArgs[argIdx];
|
|
4904
5116
|
if (!arg) continue;
|
|
4905
5117
|
const paramName = entry.param || paramNames[idx] || `arg${idx}`;
|
|
4906
|
-
if (
|
|
4907
|
-
const projected =
|
|
5118
|
+
if (fieldPath) {
|
|
5119
|
+
const projected = projectArgPath(arg, fieldPath);
|
|
4908
5120
|
if (!projected) {
|
|
4909
5121
|
const k = arg.shape.k;
|
|
4910
5122
|
if (k !== "unknown" && k !== "any") {
|
|
5123
|
+
const field = fieldPath.join(".");
|
|
4911
5124
|
out.push({
|
|
4912
5125
|
severity: "error",
|
|
4913
5126
|
code: "nudo:constraint-violated",
|