@nudojs/core 1.0.1 → 2.0.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.
- package/dist/{chunk-P3G2TODS.js → chunk-6REHMIAE.js} +3331 -441
- package/dist/exec.d.ts +1 -1
- package/dist/exec.js +55 -1
- package/dist/{index-FITqyJ8v.d.ts → index-DxjxtxOJ.d.ts} +112 -18
- package/dist/index.d.ts +241 -14
- package/dist/index.js +819 -257
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
$add,
|
|
3
3
|
$arr,
|
|
4
|
+
$arrMutContainer,
|
|
5
|
+
$arrRest,
|
|
4
6
|
$async,
|
|
5
7
|
$asyncReturn,
|
|
6
8
|
$await,
|
|
@@ -12,6 +14,7 @@ import {
|
|
|
12
14
|
$div,
|
|
13
15
|
$elems,
|
|
14
16
|
$eq,
|
|
17
|
+
$eqLoose,
|
|
15
18
|
$fnVal,
|
|
16
19
|
$for,
|
|
17
20
|
$forIter,
|
|
@@ -25,22 +28,29 @@ import {
|
|
|
25
28
|
$idxSet,
|
|
26
29
|
$invoke,
|
|
27
30
|
$invokeSuper,
|
|
31
|
+
$isForkExit,
|
|
28
32
|
$join,
|
|
29
33
|
$le,
|
|
30
34
|
$len,
|
|
31
35
|
$lit,
|
|
36
|
+
$loopReturn,
|
|
32
37
|
$lt,
|
|
33
38
|
$mod,
|
|
34
39
|
$mul,
|
|
35
40
|
$ne,
|
|
41
|
+
$neLoose,
|
|
36
42
|
$neg,
|
|
37
43
|
$new,
|
|
38
44
|
$not,
|
|
45
|
+
$nullishTest,
|
|
39
46
|
$obj,
|
|
47
|
+
$objRest,
|
|
40
48
|
$optionalGet,
|
|
41
49
|
$optionalInvoke,
|
|
42
50
|
$orDefault,
|
|
51
|
+
$pushLoopExit,
|
|
43
52
|
$regex,
|
|
53
|
+
$rethrowIfNudoReturn,
|
|
44
54
|
$set,
|
|
45
55
|
$setKey,
|
|
46
56
|
$spread,
|
|
@@ -51,6 +61,10 @@ import {
|
|
|
51
61
|
$thisGet,
|
|
52
62
|
$thisSet,
|
|
53
63
|
$throw,
|
|
64
|
+
$tryCurrentMark,
|
|
65
|
+
$tryMark,
|
|
66
|
+
$tryPopMark,
|
|
67
|
+
$tryTakeSince,
|
|
54
68
|
$typeof,
|
|
55
69
|
$while,
|
|
56
70
|
$whileSeq,
|
|
@@ -58,6 +72,7 @@ import {
|
|
|
58
72
|
DEFAULT_MAX_LOOP_ITERS,
|
|
59
73
|
MAX_CALL_DEPTH,
|
|
60
74
|
MAX_TOTAL_CALLS,
|
|
75
|
+
NudoReturn,
|
|
61
76
|
NudoThrow,
|
|
62
77
|
abortDerivationSession,
|
|
63
78
|
abs,
|
|
@@ -79,22 +94,27 @@ import {
|
|
|
79
94
|
asAbsVal,
|
|
80
95
|
attachFnImpl,
|
|
81
96
|
awaitAbs,
|
|
97
|
+
beginCollectionFork,
|
|
82
98
|
beginDerivationSession,
|
|
83
99
|
betaOf,
|
|
84
100
|
bindImports,
|
|
85
101
|
bool,
|
|
86
102
|
boolLit,
|
|
87
103
|
callAbsMethod,
|
|
104
|
+
callAtFunctionBoundary,
|
|
88
105
|
callFunction,
|
|
89
106
|
callFunctionFull,
|
|
90
107
|
callTranspiledExport,
|
|
91
108
|
callTranspiledExportFull,
|
|
92
109
|
classFromMethods,
|
|
93
110
|
clearBClasses,
|
|
111
|
+
clearCollectionTables,
|
|
94
112
|
cmp,
|
|
95
113
|
coerceAsyncReturn,
|
|
96
114
|
collectAbsExports,
|
|
97
115
|
collectAbsNodeTypes,
|
|
116
|
+
collectionElementJoin,
|
|
117
|
+
collectionExactLen,
|
|
98
118
|
concatString,
|
|
99
119
|
confJoin,
|
|
100
120
|
createHofCollectCtx,
|
|
@@ -110,8 +130,10 @@ import {
|
|
|
110
130
|
div,
|
|
111
131
|
emptyEnv,
|
|
112
132
|
emptyPhi,
|
|
133
|
+
endCollectionFork,
|
|
113
134
|
endDerivationSession,
|
|
114
135
|
eq,
|
|
136
|
+
errorBrandAbs,
|
|
115
137
|
evalArrayStatic,
|
|
116
138
|
evalBuiltinInstanceMethod,
|
|
117
139
|
evalBuiltinNew,
|
|
@@ -157,14 +179,20 @@ import {
|
|
|
157
179
|
instanceOf,
|
|
158
180
|
instantiateClass,
|
|
159
181
|
instantiateReturn,
|
|
182
|
+
isArrMutator,
|
|
160
183
|
isDefinitelyFalse,
|
|
161
184
|
isDefinitelyTrue,
|
|
185
|
+
isErrorCtorName,
|
|
186
|
+
isEvalMissingSlotEnabled,
|
|
162
187
|
isExactLit,
|
|
188
|
+
isMapAbs,
|
|
189
|
+
isNudoReturn,
|
|
163
190
|
isNudoThrow,
|
|
164
191
|
isNullishLitAbs,
|
|
165
192
|
isNumPrim,
|
|
166
193
|
isObj,
|
|
167
194
|
isRelFn,
|
|
195
|
+
isSetAbs,
|
|
168
196
|
isStrPrim,
|
|
169
197
|
isTemplateLike,
|
|
170
198
|
joinAbs,
|
|
@@ -183,13 +211,25 @@ import {
|
|
|
183
211
|
lookupMethod,
|
|
184
212
|
lookupMethodWithOwner,
|
|
185
213
|
lookupSuperMethod,
|
|
214
|
+
looseEqAbs,
|
|
186
215
|
lt,
|
|
187
216
|
ltNum,
|
|
217
|
+
makeMapAbs,
|
|
218
|
+
makeSetAbs,
|
|
188
219
|
makeSum,
|
|
220
|
+
mapClearEntries,
|
|
221
|
+
mapDeleteEntry,
|
|
189
222
|
mapElementFallback,
|
|
223
|
+
mapEntriesAbs,
|
|
224
|
+
mapGetEntry,
|
|
225
|
+
mapHasEntry,
|
|
226
|
+
mapSetEntry,
|
|
227
|
+
mapSizeAbs,
|
|
228
|
+
mapValuesAbs,
|
|
190
229
|
matchRelIdentLit,
|
|
191
230
|
maybeLeak,
|
|
192
231
|
mergeAdjacentFixedViews,
|
|
232
|
+
mergeCollectionArms,
|
|
193
233
|
mod,
|
|
194
234
|
mul,
|
|
195
235
|
namespaceNameOf,
|
|
@@ -198,9 +238,11 @@ import {
|
|
|
198
238
|
never,
|
|
199
239
|
not,
|
|
200
240
|
notAbs,
|
|
241
|
+
noteCollectionWrite,
|
|
201
242
|
noteDerivationAdd,
|
|
202
243
|
noteDerivationJoin,
|
|
203
244
|
noteMemberDispatchMiss,
|
|
245
|
+
noteObjSlotMissing,
|
|
204
246
|
notePrimMemberMissing,
|
|
205
247
|
noteUnknownMemberMissing,
|
|
206
248
|
num,
|
|
@@ -213,6 +255,7 @@ import {
|
|
|
213
255
|
pTrue,
|
|
214
256
|
parseSource,
|
|
215
257
|
phiAnd,
|
|
258
|
+
popCollectionArm,
|
|
216
259
|
predEquals,
|
|
217
260
|
predToString,
|
|
218
261
|
predVars,
|
|
@@ -221,24 +264,37 @@ import {
|
|
|
221
264
|
projectFlatMapResult,
|
|
222
265
|
promoteParamShape,
|
|
223
266
|
ptypeof,
|
|
267
|
+
pushCollectionArm,
|
|
268
|
+
pushLoopExit,
|
|
269
|
+
pushThrowExit,
|
|
224
270
|
recordMemberDiag,
|
|
225
271
|
refineAbsForRelTrue,
|
|
226
272
|
registerBClass,
|
|
227
273
|
relationFingerprint,
|
|
228
274
|
relationFn,
|
|
275
|
+
requiredFnArity,
|
|
229
276
|
resetAbsCallBudget,
|
|
230
277
|
resetLeakCounter,
|
|
231
278
|
resetParseSourceCache,
|
|
232
279
|
runTranspiled,
|
|
280
|
+
runWithEvalMissingSlot,
|
|
281
|
+
runWithLoopExits,
|
|
233
282
|
setAbsAssignCollector,
|
|
234
283
|
setAbsCallCollector,
|
|
235
284
|
setAbsNodeCollector,
|
|
236
285
|
setAbsTruncationCollector,
|
|
286
|
+
setAddEntry,
|
|
237
287
|
setApplyCallbackHost,
|
|
238
288
|
setBCallCollector,
|
|
289
|
+
setClearEntries,
|
|
290
|
+
setDeleteEntry,
|
|
239
291
|
setDerivation,
|
|
240
292
|
setDerivationCollector,
|
|
293
|
+
setElementsAbs,
|
|
294
|
+
setEvalMissingSlotEnabled,
|
|
295
|
+
setHasEntry,
|
|
241
296
|
setMemberDiagCollector,
|
|
297
|
+
setSizeAbs,
|
|
242
298
|
shapeOfTerm,
|
|
243
299
|
shapeOnlyFn,
|
|
244
300
|
shapeToString,
|
|
@@ -256,6 +312,8 @@ import {
|
|
|
256
312
|
superNameOf,
|
|
257
313
|
tagAbsOrigin,
|
|
258
314
|
tagDerivationRoot,
|
|
315
|
+
takeLoopExits,
|
|
316
|
+
takeThrowExits,
|
|
259
317
|
templateMatchesValue,
|
|
260
318
|
templatePartsOf,
|
|
261
319
|
termDepth,
|
|
@@ -280,7 +338,7 @@ import {
|
|
|
280
338
|
withExecPhi,
|
|
281
339
|
withVar,
|
|
282
340
|
wrapPromise
|
|
283
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-6REHMIAE.js";
|
|
284
342
|
|
|
285
343
|
// src/environment.ts
|
|
286
344
|
function createEnvironment(parent, bindings = /* @__PURE__ */ new Map()) {
|
|
@@ -409,6 +467,9 @@ function formatAbs(a, opts = {}) {
|
|
|
409
467
|
parts.push(`where ${predToString(a.pred)}`);
|
|
410
468
|
}
|
|
411
469
|
parts.push(`#${a.conf}`);
|
|
470
|
+
if (a.pathNote) {
|
|
471
|
+
parts.push(a.pathNote);
|
|
472
|
+
}
|
|
412
473
|
return parts.join(" ");
|
|
413
474
|
}
|
|
414
475
|
function formatShapeSlot(a) {
|
|
@@ -425,8 +486,10 @@ function formatShape(a) {
|
|
|
425
486
|
return "never";
|
|
426
487
|
case "any":
|
|
427
488
|
return "any";
|
|
428
|
-
case "unknown":
|
|
489
|
+
case "unknown": {
|
|
490
|
+
if (a.term?.op === "lit" && a.term.value === void 0) return "undefined";
|
|
429
491
|
return "unknown";
|
|
492
|
+
}
|
|
430
493
|
case "prim": {
|
|
431
494
|
const lv = litValue(a);
|
|
432
495
|
if (typeof lv === "number" && !Number.isFinite(lv)) return String(lv);
|
|
@@ -449,13 +512,39 @@ function formatShape(a) {
|
|
|
449
512
|
case "tuple":
|
|
450
513
|
return `[${s.elements.map(formatShape).join(", ")}]`;
|
|
451
514
|
case "fn": {
|
|
452
|
-
if (s.paramTypes && s.paramTypes.length > 0) {
|
|
453
|
-
const ps = s.paramTypes.map((p) => formatShapeSlot(p));
|
|
454
|
-
const ret2 = s.returnType !== void 0 ? formatShapeSlot(s.returnType) : "?";
|
|
455
|
-
return `(${ps.join(", ")}) => ${ret2}`;
|
|
456
|
-
}
|
|
457
515
|
const ret = s.returnType !== void 0 ? formatShapeSlot(s.returnType) : "?";
|
|
458
|
-
|
|
516
|
+
const labels = s.params ?? [];
|
|
517
|
+
const paramTypes = s.paramTypes;
|
|
518
|
+
const hasMarkers = labels.some(
|
|
519
|
+
(p) => p.startsWith("...") || p.endsWith("?")
|
|
520
|
+
);
|
|
521
|
+
const renderLabeled = () => {
|
|
522
|
+
const ps = [];
|
|
523
|
+
const n = paramTypes ? Math.max(paramTypes.length, labels.length) : labels.length;
|
|
524
|
+
for (let i = 0; i < n; i++) {
|
|
525
|
+
const label = labels[i];
|
|
526
|
+
const type = paramTypes?.[i];
|
|
527
|
+
const typeText = type !== void 0 ? formatShapeSlot(type) : void 0;
|
|
528
|
+
if (label?.startsWith("...")) {
|
|
529
|
+
ps.push(typeText ? `...${label.slice(3)}: ${typeText}` : label);
|
|
530
|
+
} else if (label?.endsWith("?")) {
|
|
531
|
+
ps.push(typeText ? `${label.slice(0, -1)}?: ${typeText}` : label);
|
|
532
|
+
} else if (typeText !== void 0) {
|
|
533
|
+
ps.push(typeText);
|
|
534
|
+
} else if (label) {
|
|
535
|
+
ps.push(label);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return ps;
|
|
539
|
+
};
|
|
540
|
+
if (hasMarkers) {
|
|
541
|
+
return `(${renderLabeled().join(", ")}) => ${ret}`;
|
|
542
|
+
}
|
|
543
|
+
if (paramTypes && paramTypes.length > 0) {
|
|
544
|
+
const ps = paramTypes.map((p) => formatShapeSlot(p));
|
|
545
|
+
return `(${ps.join(", ")}) => ${ret}`;
|
|
546
|
+
}
|
|
547
|
+
return `(${labels.join(", ")}) => ${ret}`;
|
|
459
548
|
}
|
|
460
549
|
case "brand":
|
|
461
550
|
return `${s.name}`;
|
|
@@ -573,6 +662,9 @@ function string() {
|
|
|
573
662
|
function boolean() {
|
|
574
663
|
return makeBuilder("boolean", []);
|
|
575
664
|
}
|
|
665
|
+
function any() {
|
|
666
|
+
return makeBuilder(void 0, []);
|
|
667
|
+
}
|
|
576
668
|
function array(item) {
|
|
577
669
|
if (!isConstraint(item))
|
|
578
670
|
throw new Error("nudo: array(item) \u671F\u671B\u7EA6\u675F\u503C\uFF08number()/string()/\u2026\u6216\u5176\u7EC4\u5408\u5B50\uFF09");
|
|
@@ -1039,12 +1131,13 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1039
1131
|
const keepTs = fromFile?.endsWith(".nudo.ts") === true;
|
|
1040
1132
|
const ast = parseSource(src, keepTs ? { keepTs: true } : void 0);
|
|
1041
1133
|
const cuts = [];
|
|
1042
|
-
const
|
|
1134
|
+
const exportPairs = [];
|
|
1043
1135
|
const imports = [];
|
|
1136
|
+
const DEFAULT_LOCAL = "__nudoDefault";
|
|
1044
1137
|
const badExport = (what) => {
|
|
1045
1138
|
collectDiag({
|
|
1046
1139
|
code: "nudo:interface-load",
|
|
1047
|
-
message: `sidecar ${what};
|
|
1140
|
+
message: `sidecar ${what}; recognized export forms are 'export const <name> = \u2026' and 'export default <constraint|fn>'`,
|
|
1048
1141
|
file: fromFile
|
|
1049
1142
|
});
|
|
1050
1143
|
};
|
|
@@ -1068,7 +1161,7 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1068
1161
|
if (decl.kind === "const") {
|
|
1069
1162
|
let simple = true;
|
|
1070
1163
|
for (const d of decl.declarations) {
|
|
1071
|
-
if (d.id.type === "Identifier")
|
|
1164
|
+
if (d.id.type === "Identifier") exportPairs.push({ key: d.id.name, expr: d.id.name });
|
|
1072
1165
|
else simple = false;
|
|
1073
1166
|
}
|
|
1074
1167
|
if (!simple) badExport("'export const' with destructuring pattern");
|
|
@@ -1092,15 +1185,40 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1092
1185
|
}
|
|
1093
1186
|
if (stmt.type === "ExportDefaultDeclaration") {
|
|
1094
1187
|
const decl = stmt.declaration;
|
|
1095
|
-
if ((decl
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1188
|
+
if (decl && (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") && stmt.start != null && decl.start != null) {
|
|
1189
|
+
if (decl.id?.name) {
|
|
1190
|
+
exportPairs.push({ key: decl.id.name, expr: decl.id.name });
|
|
1191
|
+
exportPairs.push({ key: "default", expr: decl.id.name });
|
|
1192
|
+
} else {
|
|
1193
|
+
exportPairs.push({ key: "default", expr: DEFAULT_LOCAL });
|
|
1194
|
+
if (decl.start != null && decl.end != null) {
|
|
1195
|
+
const kind = decl.type === "FunctionDeclaration" ? "function" : "class";
|
|
1196
|
+
cuts.push({
|
|
1197
|
+
start: stmt.start,
|
|
1198
|
+
end: decl.start,
|
|
1199
|
+
text: `var ${DEFAULT_LOCAL} = `
|
|
1200
|
+
});
|
|
1201
|
+
void kind;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (decl.id?.name) {
|
|
1205
|
+
cuts.push({ start: stmt.start, end: decl.start, text: "" });
|
|
1103
1206
|
}
|
|
1207
|
+
continue;
|
|
1208
|
+
}
|
|
1209
|
+
if (decl && stmt.start != null && decl.start != null && decl.end != null) {
|
|
1210
|
+
exportPairs.push({ key: "default", expr: DEFAULT_LOCAL });
|
|
1211
|
+
cuts.push({
|
|
1212
|
+
start: stmt.start,
|
|
1213
|
+
end: decl.start,
|
|
1214
|
+
text: `var ${DEFAULT_LOCAL} = `
|
|
1215
|
+
});
|
|
1216
|
+
cuts.push({ start: decl.end, end: stmt.end ?? decl.end, text: ";" });
|
|
1217
|
+
continue;
|
|
1218
|
+
}
|
|
1219
|
+
badExport("'export default'");
|
|
1220
|
+
if (stmt.start != null && stmt.end != null) {
|
|
1221
|
+
cuts.push({ start: stmt.start, end: stmt.end, text: "" });
|
|
1104
1222
|
}
|
|
1105
1223
|
continue;
|
|
1106
1224
|
}
|
|
@@ -1120,20 +1238,21 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1120
1238
|
const merged = [];
|
|
1121
1239
|
for (const c of cuts) {
|
|
1122
1240
|
const last = merged[merged.length - 1];
|
|
1123
|
-
if (last && c.start <= last.end) {
|
|
1241
|
+
if (last && c.start <= last.end && last.text === "" && c.text === "") {
|
|
1124
1242
|
last.end = Math.max(last.end, c.end);
|
|
1125
1243
|
} else {
|
|
1126
|
-
merged.push({ start: c.start, end: c.end });
|
|
1244
|
+
merged.push({ start: c.start, end: c.end, text: c.text });
|
|
1127
1245
|
}
|
|
1128
1246
|
}
|
|
1129
1247
|
let code = "";
|
|
1130
1248
|
let pos = 0;
|
|
1131
1249
|
for (const c of merged) {
|
|
1132
|
-
|
|
1250
|
+
if (c.start < pos) continue;
|
|
1251
|
+
code += src.slice(pos, c.start) + c.text;
|
|
1133
1252
|
pos = c.end;
|
|
1134
1253
|
}
|
|
1135
1254
|
code += src.slice(pos);
|
|
1136
|
-
return { code,
|
|
1255
|
+
return { code, exportPairs, imports };
|
|
1137
1256
|
}
|
|
1138
1257
|
var TS_STMT_CUT_TYPES = /* @__PURE__ */ new Set([
|
|
1139
1258
|
"TSInterfaceDeclaration",
|
|
@@ -1207,7 +1326,7 @@ function collectTsSyntaxCuts(node, src, cuts = []) {
|
|
|
1207
1326
|
}
|
|
1208
1327
|
function execSidecar(src, opts, chain, preloaded) {
|
|
1209
1328
|
const fromFile = opts?.fromFile;
|
|
1210
|
-
const { code,
|
|
1329
|
+
const { code, exportPairs, imports } = rewriteSidecarSource(src, fromFile);
|
|
1211
1330
|
const prologue = [];
|
|
1212
1331
|
const deps = {};
|
|
1213
1332
|
for (const imp of imports) {
|
|
@@ -1319,9 +1438,12 @@ function execSidecar(src, opts, chain, preloaded) {
|
|
|
1319
1438
|
for (const local of Object.keys(deps)) {
|
|
1320
1439
|
prologue.push(`var ${local} = __nudoDeps[${JSON.stringify(local)}];`);
|
|
1321
1440
|
}
|
|
1441
|
+
const returnObj = exportPairs.map(
|
|
1442
|
+
(p) => p.key === p.expr ? p.key : `${JSON.stringify(p.key)}: ${p.expr}`
|
|
1443
|
+
).join(", ");
|
|
1322
1444
|
const body = `${prologue.length > 0 ? `${prologue.join("\n")}
|
|
1323
1445
|
` : ""}${code}
|
|
1324
|
-
return { ${
|
|
1446
|
+
return { ${returnObj} };`;
|
|
1325
1447
|
const fn2 = new Function(
|
|
1326
1448
|
...Object.keys(sidecarInjects),
|
|
1327
1449
|
"__nudoInjects",
|
|
@@ -1573,28 +1695,134 @@ function localNamedExports(source) {
|
|
|
1573
1695
|
}
|
|
1574
1696
|
}
|
|
1575
1697
|
}
|
|
1698
|
+
const identName = (n) => {
|
|
1699
|
+
if (!n) return void 0;
|
|
1700
|
+
if (n.type === "Identifier" && typeof n.name === "string") return n.name;
|
|
1701
|
+
if (n.type === "Literal" && typeof n.value === "string") return n.value;
|
|
1702
|
+
return void 0;
|
|
1703
|
+
};
|
|
1704
|
+
const localClasses = /* @__PURE__ */ new Map();
|
|
1576
1705
|
for (const stmt of ast.program.body) {
|
|
1577
|
-
|
|
1578
|
-
if (
|
|
1579
|
-
const
|
|
1580
|
-
if (
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1706
|
+
const s = stmt;
|
|
1707
|
+
if (s.type !== "ClassDeclaration") continue;
|
|
1708
|
+
const idName = identName(s.id);
|
|
1709
|
+
if (idName) localClasses.set(idName, s);
|
|
1710
|
+
}
|
|
1711
|
+
const addClassMethodKeys = (out2, decl) => {
|
|
1712
|
+
if (!decl || decl.type !== "ClassDeclaration") return;
|
|
1713
|
+
const idName = identName(decl.id);
|
|
1714
|
+
if (!idName) return;
|
|
1715
|
+
const body = decl.body?.body ?? [];
|
|
1716
|
+
for (const m of body) {
|
|
1717
|
+
const mem = m;
|
|
1718
|
+
const isMethod = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
1719
|
+
if (!isMethod) continue;
|
|
1720
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
1721
|
+
if (mem.static) continue;
|
|
1722
|
+
const keyName = identName(mem.key);
|
|
1723
|
+
if (keyName) out2.add(`${idName}.${keyName}`);
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1726
|
+
const isExportsTarget = (n) => {
|
|
1727
|
+
if (!n) return false;
|
|
1728
|
+
if (n.type === "Identifier") return n.name === "exports";
|
|
1729
|
+
if (n.type === "MemberExpression") {
|
|
1730
|
+
return identName(n.object) === "module" && n.property !== void 0 ? identName(n.property) === "exports" : false;
|
|
1731
|
+
}
|
|
1732
|
+
return false;
|
|
1733
|
+
};
|
|
1734
|
+
const cjsPropName = (left) => {
|
|
1735
|
+
if (!left || left.type !== "MemberExpression") return void 0;
|
|
1736
|
+
if (left.computed === true) return void 0;
|
|
1737
|
+
const obj2 = left.object;
|
|
1738
|
+
if (!isExportsTarget(obj2)) return void 0;
|
|
1739
|
+
return identName(left.property);
|
|
1740
|
+
};
|
|
1741
|
+
for (const stmt of ast.program.body) {
|
|
1742
|
+
const s = stmt;
|
|
1743
|
+
if (s.type === "ExportNamedDeclaration") {
|
|
1744
|
+
if (s.source) continue;
|
|
1745
|
+
const d = s.declaration;
|
|
1746
|
+
if (!d) {
|
|
1747
|
+
const specs = s.specifiers ?? [];
|
|
1748
|
+
for (const spec of specs) {
|
|
1749
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
1750
|
+
const name = identName(spec.exported);
|
|
1751
|
+
if (!name) continue;
|
|
1752
|
+
const localName = identName(spec.local);
|
|
1753
|
+
if (name === "default") {
|
|
1754
|
+
out.add("default");
|
|
1755
|
+
if (localName && !importedLocalNames.has(localName)) out.add(localName);
|
|
1756
|
+
if (localName && !importedLocalNames.has(localName)) {
|
|
1757
|
+
addClassMethodKeys(out, localClasses.get(localName));
|
|
1758
|
+
}
|
|
1759
|
+
continue;
|
|
1760
|
+
}
|
|
1761
|
+
if (localName && importedLocalNames.has(localName)) continue;
|
|
1762
|
+
out.add(name);
|
|
1763
|
+
if (localName) addClassMethodKeys(out, localClasses.get(localName));
|
|
1764
|
+
}
|
|
1765
|
+
continue;
|
|
1766
|
+
}
|
|
1767
|
+
if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
1768
|
+
const idName = identName(d.id);
|
|
1769
|
+
if (idName) out.add(idName);
|
|
1770
|
+
if (d.type === "ClassDeclaration" && idName) {
|
|
1771
|
+
addClassMethodKeys(out, d);
|
|
1772
|
+
}
|
|
1773
|
+
} else if (d.type === "VariableDeclaration") {
|
|
1774
|
+
const decls = d.declarations ?? [];
|
|
1775
|
+
for (const decl of decls) {
|
|
1776
|
+
const idName = identName(decl.id);
|
|
1777
|
+
if (idName) out.add(idName);
|
|
1778
|
+
}
|
|
1590
1779
|
}
|
|
1591
1780
|
continue;
|
|
1592
1781
|
}
|
|
1593
|
-
if (
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
if (
|
|
1782
|
+
if (s.type === "ExportDefaultDeclaration") {
|
|
1783
|
+
out.add("default");
|
|
1784
|
+
const d = s.declaration;
|
|
1785
|
+
if (d) {
|
|
1786
|
+
if ((d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") && d.id) {
|
|
1787
|
+
const idName = identName(d.id);
|
|
1788
|
+
if (idName) out.add(idName);
|
|
1789
|
+
if (d.type === "ClassDeclaration" && idName) {
|
|
1790
|
+
addClassMethodKeys(out, d);
|
|
1791
|
+
}
|
|
1792
|
+
} else if (d.type === "Identifier") {
|
|
1793
|
+
const n = identName(d);
|
|
1794
|
+
if (n && !importedLocalNames.has(n)) {
|
|
1795
|
+
out.add(n);
|
|
1796
|
+
addClassMethodKeys(out, localClasses.get(n));
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
continue;
|
|
1801
|
+
}
|
|
1802
|
+
if (s.type === "ExpressionStatement") {
|
|
1803
|
+
const expr = s.expression;
|
|
1804
|
+
if (!expr || expr.type !== "AssignmentExpression" || expr.operator !== "=") continue;
|
|
1805
|
+
const left = expr.left;
|
|
1806
|
+
const right = expr.right;
|
|
1807
|
+
if (!left || !right) continue;
|
|
1808
|
+
const prop = cjsPropName(left);
|
|
1809
|
+
if (prop && prop !== "default") out.add(prop);
|
|
1810
|
+
if (isExportsTarget(left)) {
|
|
1811
|
+
if (right.type === "ObjectExpression") {
|
|
1812
|
+
const props = right.properties ?? [];
|
|
1813
|
+
for (const p of props) {
|
|
1814
|
+
if (p.type !== "ObjectProperty" && p.type !== "Property") continue;
|
|
1815
|
+
const keyName = identName(p.key);
|
|
1816
|
+
if (keyName && keyName !== "default") out.add(keyName);
|
|
1817
|
+
else {
|
|
1818
|
+
const valName = identName(p.value);
|
|
1819
|
+
if (valName) out.add(valName);
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
} else if (right.type === "Identifier") {
|
|
1823
|
+
const n = identName(right);
|
|
1824
|
+
if (n && !importedLocalNames.has(n)) out.add(n);
|
|
1825
|
+
}
|
|
1598
1826
|
}
|
|
1599
1827
|
}
|
|
1600
1828
|
}
|
|
@@ -1651,6 +1879,18 @@ function sidecarAutoBindAllowed(sidecarPath, autoBind) {
|
|
|
1651
1879
|
if (typeof autoBind === "function") return autoBind(sidecarPath) === true;
|
|
1652
1880
|
return false;
|
|
1653
1881
|
}
|
|
1882
|
+
function isDefaultExportLocal(source, localName) {
|
|
1883
|
+
const reList = new RegExp(
|
|
1884
|
+
`export\\s*\\{[^}]*\\b${localName}\\s+as\\s+default\\b[^}]*\\}`,
|
|
1885
|
+
"m"
|
|
1886
|
+
);
|
|
1887
|
+
const reDefaultFn = new RegExp(
|
|
1888
|
+
`export\\s+default\\s+(?:async\\s+)?function\\s+${localName}\\b`,
|
|
1889
|
+
"m"
|
|
1890
|
+
);
|
|
1891
|
+
const reDefaultId = new RegExp(`export\\s+default\\s+${localName}\\b`, "m");
|
|
1892
|
+
return reList.test(source) || reDefaultFn.test(source) || reDefaultId.test(source);
|
|
1893
|
+
}
|
|
1654
1894
|
function loadSidecarBinding(source, fnName, opts) {
|
|
1655
1895
|
const { loadModule, fromFile, autoBind } = opts;
|
|
1656
1896
|
if (!loadModule || !fromFile) return { ok: false };
|
|
@@ -1660,6 +1900,7 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
1660
1900
|
const spec = `./${sidecarPath.slice(sidecarPath.lastIndexOf("/") + 1)}`;
|
|
1661
1901
|
const sidecarSrc = loadModule(spec, fromFile);
|
|
1662
1902
|
if (sidecarSrc === void 0) return { ok: false };
|
|
1903
|
+
if (sidecarSrc === source) return { ok: false };
|
|
1663
1904
|
let exports;
|
|
1664
1905
|
try {
|
|
1665
1906
|
exports = execNudoModule(sidecarSrc, { loadModule, fromFile: sidecarPath });
|
|
@@ -1671,7 +1912,20 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
1671
1912
|
});
|
|
1672
1913
|
return { ok: false };
|
|
1673
1914
|
}
|
|
1674
|
-
|
|
1915
|
+
let binding = exports[fnName];
|
|
1916
|
+
if (binding === void 0 && exports.default !== void 0 && isDefaultExportLocal(source, fnName)) {
|
|
1917
|
+
binding = exports.default;
|
|
1918
|
+
}
|
|
1919
|
+
if (binding === void 0 && fnName.includes(".")) {
|
|
1920
|
+
const [cls, method] = fnName.split(".", 2);
|
|
1921
|
+
binding = exports[`${cls}_${method}`];
|
|
1922
|
+
if (binding === void 0) {
|
|
1923
|
+
const bag = exports[cls];
|
|
1924
|
+
if (bag && typeof bag === "object" && !isNudoConstraint(bag)) {
|
|
1925
|
+
binding = bag[method];
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1675
1929
|
if (binding === void 0) return { ok: false };
|
|
1676
1930
|
if (!isNudoConstraint(binding)) {
|
|
1677
1931
|
collectDiag2({
|
|
@@ -1689,11 +1943,16 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
1689
1943
|
});
|
|
1690
1944
|
return { ok: false };
|
|
1691
1945
|
}
|
|
1946
|
+
const generatedNames = generatedExportNames(sidecarSrc);
|
|
1947
|
+
const isGenerated = generatedNames.has(fnName) || (fnName.includes(".") ? (() => {
|
|
1948
|
+
const [cls, method] = fnName.split(".", 2);
|
|
1949
|
+
return generatedNames.has(`${cls}_${method}`) || generatedNames.has(cls);
|
|
1950
|
+
})() : false);
|
|
1692
1951
|
return {
|
|
1693
1952
|
ok: true,
|
|
1694
1953
|
sidecarPath,
|
|
1695
1954
|
constraint: binding,
|
|
1696
|
-
generated:
|
|
1955
|
+
generated: isGenerated
|
|
1697
1956
|
};
|
|
1698
1957
|
}
|
|
1699
1958
|
function boundsOf(c) {
|
|
@@ -1990,6 +2249,27 @@ function fmtConstraint(c) {
|
|
|
1990
2249
|
function formatConstraint(c) {
|
|
1991
2250
|
return fmtConstraint(c);
|
|
1992
2251
|
}
|
|
2252
|
+
function formatEffectiveInterfaceDisplay(eff) {
|
|
2253
|
+
const params = eff.params.map((p) => `${p.param}: ${formatConstraint(p.constraint)}`).join(", ");
|
|
2254
|
+
let s = `(${params})`;
|
|
2255
|
+
if (eff.returns) s += ` \u2192 ${formatConstraint(eff.returns.constraint)}`;
|
|
2256
|
+
return s;
|
|
2257
|
+
}
|
|
2258
|
+
function formatInterfaceTierLine(source) {
|
|
2259
|
+
return `\u25CF interface / ${source}`;
|
|
2260
|
+
}
|
|
2261
|
+
function interfaceTierOf(source, fnName, fromFile, opts = {}) {
|
|
2262
|
+
if (!localNamedExports(source).has(fnName)) return void 0;
|
|
2263
|
+
const eff = effectiveInterface(source, fnName, { fromFile, ...opts });
|
|
2264
|
+
const src = eff?.source ?? "implicit";
|
|
2265
|
+
if (eff && src !== "implicit") {
|
|
2266
|
+
return { source: src, display: formatEffectiveInterfaceDisplay(eff) };
|
|
2267
|
+
}
|
|
2268
|
+
return { source: src };
|
|
2269
|
+
}
|
|
2270
|
+
function interfaceSourceOf(source, fnName, fromFile, opts = {}) {
|
|
2271
|
+
return interfaceTierOf(source, fnName, fromFile, opts)?.source;
|
|
2272
|
+
}
|
|
1993
2273
|
|
|
1994
2274
|
// src/algebra/fn-fp.ts
|
|
1995
2275
|
var fnFpCache = /* @__PURE__ */ new Map();
|
|
@@ -2176,11 +2456,167 @@ function canSkipLiteralCallScan(source, file) {
|
|
|
2176
2456
|
return true;
|
|
2177
2457
|
}
|
|
2178
2458
|
|
|
2459
|
+
// src/algebra/param-surface.ts
|
|
2460
|
+
function collectPatternNames(p, top, nested, depth, propKey) {
|
|
2461
|
+
if (!p) return;
|
|
2462
|
+
if (p.type === "Identifier" && p.name) {
|
|
2463
|
+
if (depth === 0) top.push(p.name);
|
|
2464
|
+
else nested.push(p.name);
|
|
2465
|
+
return;
|
|
2466
|
+
}
|
|
2467
|
+
if (p.type === "AssignmentPattern") {
|
|
2468
|
+
collectPatternNames(p.left, top, nested, depth, propKey);
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2471
|
+
if (p.type === "RestElement") {
|
|
2472
|
+
collectPatternNames(p.argument, top, nested, depth, propKey);
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
2475
|
+
if (p.type === "ObjectPattern") {
|
|
2476
|
+
for (const prop of p.properties ?? []) {
|
|
2477
|
+
if (prop.type === "RestElement" || prop.argument) {
|
|
2478
|
+
collectPatternNames(prop.argument, top, nested, depth, propKey);
|
|
2479
|
+
continue;
|
|
2480
|
+
}
|
|
2481
|
+
const keyName = prop.key?.type === "Identifier" && prop.key.name ? prop.key.name : prop.key && "value" in prop.key ? String(prop.key.value ?? "") : void 0;
|
|
2482
|
+
const v2 = prop.value ?? prop.key;
|
|
2483
|
+
if (!v2) continue;
|
|
2484
|
+
if (keyName && v2.type === "Identifier" && v2.name && keyName !== v2.name) {
|
|
2485
|
+
if (depth === 0) top.push(keyName);
|
|
2486
|
+
else nested.push(keyName);
|
|
2487
|
+
if (propKey && depth === 0) propKey[keyName] = keyName;
|
|
2488
|
+
}
|
|
2489
|
+
if (v2.type === "Identifier" && v2.name) {
|
|
2490
|
+
if (depth === 0) {
|
|
2491
|
+
top.push(v2.name);
|
|
2492
|
+
if (propKey && keyName) propKey[v2.name] = keyName;
|
|
2493
|
+
} else nested.push(v2.name);
|
|
2494
|
+
} else {
|
|
2495
|
+
collectPatternNames(v2, top, nested, depth + 1, propKey);
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
return;
|
|
2499
|
+
}
|
|
2500
|
+
if (p.type === "ArrayPattern") {
|
|
2501
|
+
for (const el of p.elements ?? []) {
|
|
2502
|
+
if (!el) continue;
|
|
2503
|
+
if (el.type === "Identifier" && el.name) {
|
|
2504
|
+
if (depth === 0) top.push(el.name);
|
|
2505
|
+
else nested.push(el.name);
|
|
2506
|
+
} else {
|
|
2507
|
+
collectPatternNames(el, top, nested, depth + 1, propKey);
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
function formalParamsFromNodes(params) {
|
|
2513
|
+
const list = params ?? [];
|
|
2514
|
+
return list.map((p, index) => {
|
|
2515
|
+
if (p?.type === "Identifier" && p.name) {
|
|
2516
|
+
return { kind: "id", name: p.name, index };
|
|
2517
|
+
}
|
|
2518
|
+
if (p?.type === "AssignmentPattern") {
|
|
2519
|
+
const left = p.left;
|
|
2520
|
+
if (left?.type === "Identifier" && left.name) {
|
|
2521
|
+
return { kind: "default", name: left.name, index };
|
|
2522
|
+
}
|
|
2523
|
+
const top2 = [];
|
|
2524
|
+
const nested2 = [];
|
|
2525
|
+
const propKey2 = {};
|
|
2526
|
+
if (left) collectPatternNames(left, top2, nested2, 0, propKey2);
|
|
2527
|
+
return {
|
|
2528
|
+
kind: "pattern",
|
|
2529
|
+
placeholder: `_p${index}`,
|
|
2530
|
+
bound: top2,
|
|
2531
|
+
propKey: propKey2,
|
|
2532
|
+
nested: nested2,
|
|
2533
|
+
index
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
if (p?.type === "RestElement") {
|
|
2537
|
+
const arg = p.argument;
|
|
2538
|
+
const name = arg?.type === "Identifier" && arg.name ? arg.name : `arg${index}`;
|
|
2539
|
+
return { kind: "rest", name, display: `...${name}`, index };
|
|
2540
|
+
}
|
|
2541
|
+
const top = [];
|
|
2542
|
+
const nested = [];
|
|
2543
|
+
const propKey = {};
|
|
2544
|
+
if (p) collectPatternNames(p, top, nested, 0, propKey);
|
|
2545
|
+
return {
|
|
2546
|
+
kind: "pattern",
|
|
2547
|
+
placeholder: `_p${index}`,
|
|
2548
|
+
bound: top,
|
|
2549
|
+
propKey,
|
|
2550
|
+
nested,
|
|
2551
|
+
index
|
|
2552
|
+
};
|
|
2553
|
+
});
|
|
2554
|
+
}
|
|
2555
|
+
function formalParamDisplayNames(formals) {
|
|
2556
|
+
return formals.map((f) => {
|
|
2557
|
+
switch (f.kind) {
|
|
2558
|
+
case "id":
|
|
2559
|
+
case "default":
|
|
2560
|
+
return f.name;
|
|
2561
|
+
case "rest":
|
|
2562
|
+
return f.display;
|
|
2563
|
+
case "pattern":
|
|
2564
|
+
return f.placeholder;
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
function contractParamNameSet(formals) {
|
|
2569
|
+
const out = /* @__PURE__ */ new Set();
|
|
2570
|
+
for (const f of formals) {
|
|
2571
|
+
if (f.kind === "id" || f.kind === "default") out.add(f.name);
|
|
2572
|
+
else if (f.kind === "rest") {
|
|
2573
|
+
out.add(f.name);
|
|
2574
|
+
out.add(f.display);
|
|
2575
|
+
} else if (f.kind === "pattern") {
|
|
2576
|
+
out.add(f.placeholder);
|
|
2577
|
+
out.add("_");
|
|
2578
|
+
for (const b of f.bound) out.add(b);
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
return out;
|
|
2582
|
+
}
|
|
2583
|
+
function locateContractParam(formals, contractName) {
|
|
2584
|
+
for (const f of formals) {
|
|
2585
|
+
if (f.kind === "id" || f.kind === "default") {
|
|
2586
|
+
if (f.name === contractName) return { index: f.index };
|
|
2587
|
+
} else if (f.kind === "rest") {
|
|
2588
|
+
if (f.name === contractName || f.display === contractName) {
|
|
2589
|
+
return { index: f.index, rest: true };
|
|
2590
|
+
}
|
|
2591
|
+
} else if (f.kind === "pattern") {
|
|
2592
|
+
if (f.placeholder === contractName || contractName === "_") {
|
|
2593
|
+
return { index: f.index };
|
|
2594
|
+
}
|
|
2595
|
+
if (f.bound.includes(contractName)) {
|
|
2596
|
+
return { index: f.index, field: f.propKey?.[contractName] ?? contractName };
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
return void 0;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2179
2603
|
// src/algebra/load-deps-fp.ts
|
|
2180
2604
|
var MAX_LOAD_DEP_NODES = 64;
|
|
2181
2605
|
function extractAllLoadSpecs(source) {
|
|
2182
2606
|
const specs = /* @__PURE__ */ new Set();
|
|
2183
2607
|
for (const imp of extractNudoImports(source)) specs.add(imp.spec);
|
|
2608
|
+
const isPathLikeSpec = (spec) => spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/") || /\.(ts|js|mjs|cjs|tsx|jsx)$/.test(spec);
|
|
2609
|
+
const envRe = /@nudo:env\s+([^\n*]+)/g;
|
|
2610
|
+
let envM;
|
|
2611
|
+
while (envM = envRe.exec(source)) {
|
|
2612
|
+
for (const part of envM[1].split(",")) {
|
|
2613
|
+
const spec = part.trim().replace(/^['"]|['"]$/g, "");
|
|
2614
|
+
if (spec && isPathLikeSpec(spec)) specs.add(spec);
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
const mockFromRe = /@nudo:mock-module\s+"[^"]+"\s+(?:\{[^}]*\}\s+)?from\s+["']([^"']+)["']/g;
|
|
2618
|
+
let mockM;
|
|
2619
|
+
while (mockM = mockFromRe.exec(source)) specs.add(mockM[1]);
|
|
2184
2620
|
const patterns = [
|
|
2185
2621
|
/\bfrom\s*['"]([^'"]+)['"]/g,
|
|
2186
2622
|
/\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
@@ -2200,6 +2636,7 @@ function sidecarSpecsOf(source) {
|
|
|
2200
2636
|
function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
2201
2637
|
const parts = [];
|
|
2202
2638
|
const paths = [];
|
|
2639
|
+
const contents = [];
|
|
2203
2640
|
const seen = /* @__PURE__ */ new Set();
|
|
2204
2641
|
const queue = extractAllLoadSpecs(source).map(
|
|
2205
2642
|
(spec) => ({ spec, from: fromFile })
|
|
@@ -2208,7 +2645,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2208
2645
|
let truncated = false;
|
|
2209
2646
|
const finish = () => {
|
|
2210
2647
|
parts.sort();
|
|
2211
|
-
return truncated ? { fp: `trunc:${parts.join(",")}`, paths, truncated: true } : { fp: parts.join(","), paths, truncated: false };
|
|
2648
|
+
return truncated ? { fp: `trunc:${parts.join(",")}`, paths, contents, truncated: true } : { fp: parts.join(","), paths, contents, truncated: false };
|
|
2212
2649
|
};
|
|
2213
2650
|
const absorbSidecarClosure = (entryFile) => {
|
|
2214
2651
|
const sidecarPath = sidecarPathOf(entryFile);
|
|
@@ -2224,6 +2661,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2224
2661
|
n++;
|
|
2225
2662
|
parts.push(`sidecar:${sidecarPath}=${hashSource(sidecarSrc)}`);
|
|
2226
2663
|
paths.push(sidecarPath);
|
|
2664
|
+
contents.push({ path: sidecarPath, content: sidecarSrc });
|
|
2227
2665
|
const sidecarQueue = sidecarSpecsOf(
|
|
2228
2666
|
sidecarSrc
|
|
2229
2667
|
).map((spec) => ({ spec, from: sidecarPath }));
|
|
@@ -2240,6 +2678,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2240
2678
|
const src = loadModule(cur.spec, cur.from);
|
|
2241
2679
|
parts.push(`sidecar:${path}=${src === void 0 ? "miss" : hashSource(src)}`);
|
|
2242
2680
|
paths.push(path);
|
|
2681
|
+
contents.push({ path, content: src ?? null });
|
|
2243
2682
|
if (src === void 0) continue;
|
|
2244
2683
|
for (const next of sidecarSpecsOf(src)) {
|
|
2245
2684
|
const nextPath = resolveDepPath(path, next);
|
|
@@ -2260,6 +2699,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2260
2699
|
const src = loadModule(cur.spec, cur.from);
|
|
2261
2700
|
parts.push(`${path}=${src === void 0 ? "miss" : hashSource(src)}`);
|
|
2262
2701
|
paths.push(path);
|
|
2702
|
+
contents.push({ path, content: src ?? null });
|
|
2263
2703
|
if (src === void 0) continue;
|
|
2264
2704
|
for (const next of extractAllLoadSpecs(src)) {
|
|
2265
2705
|
const nextPath = resolveDepPath(path, next);
|
|
@@ -2324,14 +2764,14 @@ function loadModuleId(fn2) {
|
|
|
2324
2764
|
}
|
|
2325
2765
|
function refineDepsFingerprint(source, refine) {
|
|
2326
2766
|
if (!refine?.loadModule || !refine.fromFile) {
|
|
2327
|
-
return { fp: "-", paths: [], truncated: false };
|
|
2767
|
+
return { fp: "-", paths: [], contents: [], truncated: false };
|
|
2328
2768
|
}
|
|
2329
2769
|
return loadModuleDepsFingerprint(source, refine.loadModule, refine.fromFile);
|
|
2330
2770
|
}
|
|
2331
2771
|
function generalizeMemoKey(fnName, source, opts) {
|
|
2332
2772
|
const r = opts.refine;
|
|
2333
2773
|
const budget = opts.budget ?? defaultLeakBudget;
|
|
2334
|
-
const deps = opts.depsFp ?? (r ? refineDepsFingerprint(source, r) : { fp: "-", paths: [], truncated: false });
|
|
2774
|
+
const deps = opts.depsFp ?? (r ? refineDepsFingerprint(source, r) : { fp: "-", paths: [], contents: [], truncated: false });
|
|
2335
2775
|
const sc = opts.sidecarFp ?? (r?.loadModule && r.fromFile ? sidecarClosureFingerprint(r.fromFile, r) : void 0);
|
|
2336
2776
|
const scPath = sc !== void 0 && !sc.startsWith("trunc:") && r?.fromFile ? normPath(sidecarPathOf(r.fromFile)) : void 0;
|
|
2337
2777
|
const srcPart = generalizeSourceKeyPart(source, fnName, opts.file);
|
|
@@ -2529,6 +2969,11 @@ function collectAbsVars(a, acc, seen) {
|
|
|
2529
2969
|
return;
|
|
2530
2970
|
}
|
|
2531
2971
|
}
|
|
2972
|
+
function collectAbsFreeVars(a) {
|
|
2973
|
+
const acc = /* @__PURE__ */ new Set();
|
|
2974
|
+
collectAbsVars(a, acc, /* @__PURE__ */ new Set());
|
|
2975
|
+
return acc;
|
|
2976
|
+
}
|
|
2532
2977
|
function renameTerm(t, map) {
|
|
2533
2978
|
if (t.op === "var") {
|
|
2534
2979
|
const to = map.get(t.id);
|
|
@@ -2645,6 +3090,7 @@ function alphaRenameResult(result, fromOrder, toOrder) {
|
|
|
2645
3090
|
function extractFn(source, fnName, fileAst) {
|
|
2646
3091
|
const file = fileAst ?? parseSource(source);
|
|
2647
3092
|
const env = emptyEnv();
|
|
3093
|
+
const formalsByName = /* @__PURE__ */ new Map();
|
|
2648
3094
|
for (const stmt of file.program.body) {
|
|
2649
3095
|
let decl = stmt;
|
|
2650
3096
|
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration) {
|
|
@@ -2654,30 +3100,53 @@ function extractFn(source, fnName, fileAst) {
|
|
|
2654
3100
|
decl = stmt.declaration;
|
|
2655
3101
|
}
|
|
2656
3102
|
if (decl.type === "FunctionDeclaration" && decl.id) {
|
|
3103
|
+
const formals = formalParamsFromNodes(decl.params);
|
|
2657
3104
|
env.fns.set(decl.id.name, {
|
|
2658
|
-
params:
|
|
3105
|
+
params: formalParamDisplayNames(formals),
|
|
2659
3106
|
body: decl.body,
|
|
2660
3107
|
async: decl.async === true
|
|
2661
3108
|
});
|
|
3109
|
+
formalsByName.set(decl.id.name, formals);
|
|
3110
|
+
}
|
|
3111
|
+
if (decl.type === "ClassDeclaration" && decl.id?.name) {
|
|
3112
|
+
const cname = decl.id.name;
|
|
3113
|
+
const body = decl.body?.body ?? [];
|
|
3114
|
+
for (const m of body) {
|
|
3115
|
+
const mem = m;
|
|
3116
|
+
const isMethod = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
3117
|
+
if (!isMethod || !mem.body) continue;
|
|
3118
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
3119
|
+
if (mem.static) continue;
|
|
3120
|
+
const keyName = mem.key?.type === "Identifier" ? mem.key.name : void 0;
|
|
3121
|
+
if (!keyName) continue;
|
|
3122
|
+
const fullName = `${cname}.${keyName}`;
|
|
3123
|
+
const formals = formalParamsFromNodes(mem.params ?? []);
|
|
3124
|
+
env.fns.set(fullName, {
|
|
3125
|
+
params: formalParamDisplayNames(formals),
|
|
3126
|
+
body: mem.body,
|
|
3127
|
+
async: mem.async === true
|
|
3128
|
+
});
|
|
3129
|
+
formalsByName.set(fullName, formals);
|
|
3130
|
+
}
|
|
2662
3131
|
}
|
|
2663
3132
|
if (decl.type === "VariableDeclaration") {
|
|
2664
3133
|
for (const d of decl.declarations) {
|
|
2665
3134
|
if (d.id.type === "Identifier" && d.init && (d.init.type === "ArrowFunctionExpression" || d.init.type === "FunctionExpression")) {
|
|
2666
3135
|
const init = d.init;
|
|
3136
|
+
const formals = formalParamsFromNodes(init.params);
|
|
2667
3137
|
env.fns.set(d.id.name, {
|
|
2668
|
-
params:
|
|
2669
|
-
(p) => p.type === "Identifier" ? p.name ?? "_" : "_"
|
|
2670
|
-
),
|
|
3138
|
+
params: formalParamDisplayNames(formals),
|
|
2671
3139
|
body: init.body,
|
|
2672
3140
|
async: init.async === true
|
|
2673
3141
|
});
|
|
3142
|
+
formalsByName.set(d.id.name, formals);
|
|
2674
3143
|
}
|
|
2675
3144
|
}
|
|
2676
3145
|
}
|
|
2677
3146
|
}
|
|
2678
3147
|
const fn2 = env.fns.get(fnName);
|
|
2679
3148
|
if (!fn2) return void 0;
|
|
2680
|
-
return { params: fn2.params, body: fn2.body, env };
|
|
3149
|
+
return { params: fn2.params, body: fn2.body, env, formals: formalsByName.get(fnName) ?? [] };
|
|
2681
3150
|
}
|
|
2682
3151
|
function generalizeFromAst(fnName, source, opts = {}) {
|
|
2683
3152
|
const { key, depPaths, truncated } = generalizeMemoKey(fnName, source, opts);
|
|
@@ -2696,7 +3165,7 @@ function generalizeFromAst(fnName, source, opts = {}) {
|
|
|
2696
3165
|
function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
2697
3166
|
const extracted = extractFn(source, fnName, opts.file);
|
|
2698
3167
|
if (!extracted) return void 0;
|
|
2699
|
-
const { params, body, env } = extracted;
|
|
3168
|
+
const { params, body, env, formals } = extracted;
|
|
2700
3169
|
const budget = opts.budget ?? defaultLeakBudget;
|
|
2701
3170
|
const label = opts.label ?? "A";
|
|
2702
3171
|
const typeParams = params.map((p, i) => ({
|
|
@@ -2812,6 +3281,7 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
2812
3281
|
entryShapes,
|
|
2813
3282
|
fnRels
|
|
2814
3283
|
),
|
|
3284
|
+
...formals.length > 0 ? { formals } : {},
|
|
2815
3285
|
...entryReqs ? { entryReqs } : {},
|
|
2816
3286
|
...fnRels ? { fnRels } : {},
|
|
2817
3287
|
...entryShapes ? { entryShapes } : {},
|
|
@@ -3506,6 +3976,26 @@ function hofFnArgOk(src, tgt) {
|
|
|
3506
3976
|
function listTopFunctions(source, file) {
|
|
3507
3977
|
const f = file ?? parseSource(source);
|
|
3508
3978
|
const names = [];
|
|
3979
|
+
const localClasses = /* @__PURE__ */ new Map();
|
|
3980
|
+
for (const stmt of f.program.body) {
|
|
3981
|
+
if (stmt.type === "ClassDeclaration") {
|
|
3982
|
+
const cname = stmt.id?.name;
|
|
3983
|
+
if (cname) localClasses.set(cname, stmt);
|
|
3984
|
+
}
|
|
3985
|
+
}
|
|
3986
|
+
const exportedClassNames = /* @__PURE__ */ new Set();
|
|
3987
|
+
const collectClassMethods = (cname, decl) => {
|
|
3988
|
+
const body = decl.body?.body ?? [];
|
|
3989
|
+
for (const m of body) {
|
|
3990
|
+
const mem = m;
|
|
3991
|
+
const isMethod = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
3992
|
+
if (!isMethod) continue;
|
|
3993
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
3994
|
+
if (mem.static) continue;
|
|
3995
|
+
const keyName = mem.key?.type === "Identifier" ? mem.key.name : void 0;
|
|
3996
|
+
if (keyName) names.push(`${cname}.${keyName}`);
|
|
3997
|
+
}
|
|
3998
|
+
};
|
|
3509
3999
|
for (const stmt of f.program.body) {
|
|
3510
4000
|
let decl = stmt;
|
|
3511
4001
|
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration) {
|
|
@@ -3522,121 +4012,48 @@ function listTopFunctions(source, file) {
|
|
|
3522
4012
|
}
|
|
3523
4013
|
}
|
|
3524
4014
|
}
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
return { shape: { k: "unknown" }, conf: "partial" };
|
|
3530
|
-
}
|
|
3531
|
-
function collectParamStructReqs(source, fnName, fileAst) {
|
|
3532
|
-
const reqs = /* @__PURE__ */ new Map();
|
|
3533
|
-
const extracted = extractFn(source, fnName, fileAst);
|
|
3534
|
-
if (!extracted) return reqs;
|
|
3535
|
-
const params = new Set(extracted.params);
|
|
3536
|
-
const body = extracted.body;
|
|
3537
|
-
const BUILTIN_METHODS = /* @__PURE__ */ new Set([
|
|
3538
|
-
"map",
|
|
3539
|
-
"filter",
|
|
3540
|
-
"reduce",
|
|
3541
|
-
"flatMap",
|
|
3542
|
-
"forEach",
|
|
3543
|
-
"some",
|
|
3544
|
-
"every",
|
|
3545
|
-
"find",
|
|
3546
|
-
"findIndex",
|
|
3547
|
-
"includes",
|
|
3548
|
-
"indexOf",
|
|
3549
|
-
"lastIndexOf",
|
|
3550
|
-
"join",
|
|
3551
|
-
"slice",
|
|
3552
|
-
"splice",
|
|
3553
|
-
"push",
|
|
3554
|
-
"pop",
|
|
3555
|
-
"shift",
|
|
3556
|
-
"unshift",
|
|
3557
|
-
"sort",
|
|
3558
|
-
"reverse",
|
|
3559
|
-
"concat",
|
|
3560
|
-
"at",
|
|
3561
|
-
"replace",
|
|
3562
|
-
"replaceAll",
|
|
3563
|
-
"split",
|
|
3564
|
-
"trim",
|
|
3565
|
-
"toLowerCase",
|
|
3566
|
-
"toUpperCase",
|
|
3567
|
-
"startsWith",
|
|
3568
|
-
"endsWith",
|
|
3569
|
-
"charAt",
|
|
3570
|
-
"charCodeAt",
|
|
3571
|
-
"padStart",
|
|
3572
|
-
"padEnd",
|
|
3573
|
-
"repeat",
|
|
3574
|
-
"toString",
|
|
3575
|
-
"valueOf",
|
|
3576
|
-
"substring",
|
|
3577
|
-
"match",
|
|
3578
|
-
"search",
|
|
3579
|
-
"hasOwnProperty",
|
|
3580
|
-
"keys",
|
|
3581
|
-
"values",
|
|
3582
|
-
"entries",
|
|
3583
|
-
"then",
|
|
3584
|
-
"catch",
|
|
3585
|
-
"finally"
|
|
3586
|
-
]);
|
|
3587
|
-
const visit = (n, isMethodCallee = false, guarded = false) => {
|
|
3588
|
-
if (!n || typeof n !== "object") return;
|
|
3589
|
-
const obj2 = n;
|
|
3590
|
-
if (obj2.type === "LogicalExpression") {
|
|
3591
|
-
visit(obj2.left, false, guarded);
|
|
3592
|
-
visit(obj2.right, false, true);
|
|
3593
|
-
return;
|
|
4015
|
+
if (decl.type === "ClassDeclaration" && decl.id?.name && (stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration")) {
|
|
4016
|
+
const cname = decl.id.name;
|
|
4017
|
+
exportedClassNames.add(cname);
|
|
4018
|
+
collectClassMethods(cname, decl);
|
|
3594
4019
|
}
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
if (obj2.type === "MemberExpression" && !obj2.computed && !isMethodCallee) {
|
|
3608
|
-
const o = obj2.object;
|
|
3609
|
-
const p = obj2.property;
|
|
3610
|
-
if (o?.type === "Identifier" && o.name && params.has(o.name) && p?.type === "Identifier" && p.name) {
|
|
3611
|
-
if (BUILTIN_METHODS.has(p.name)) return;
|
|
3612
|
-
if (guarded) return;
|
|
3613
|
-
let set = reqs.get(o.name);
|
|
3614
|
-
if (!set) {
|
|
3615
|
-
set = /* @__PURE__ */ new Set();
|
|
3616
|
-
reqs.set(o.name, set);
|
|
4020
|
+
}
|
|
4021
|
+
for (const stmt of f.program.body) {
|
|
4022
|
+
if (stmt.type === "ExportNamedDeclaration" && !stmt.declaration) {
|
|
4023
|
+
const specs = stmt.specifiers ?? [];
|
|
4024
|
+
for (const spec of specs) {
|
|
4025
|
+
const s = spec;
|
|
4026
|
+
if (s.type !== "ExportSpecifier") continue;
|
|
4027
|
+
const localName = s.local?.name;
|
|
4028
|
+
if (!localName || exportedClassNames.has(localName)) continue;
|
|
4029
|
+
const exportedName = s.exported?.name ?? s.exported?.value;
|
|
4030
|
+
const isDefault = exportedName === "default";
|
|
4031
|
+
if (!isDefault && exportedName !== localName) {
|
|
3617
4032
|
}
|
|
3618
|
-
|
|
4033
|
+
const decl = localClasses.get(localName);
|
|
4034
|
+
if (!decl) continue;
|
|
4035
|
+
exportedClassNames.add(localName);
|
|
4036
|
+
collectClassMethods(localName, decl);
|
|
3619
4037
|
}
|
|
3620
4038
|
}
|
|
3621
|
-
if (
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
4039
|
+
if (stmt.type === "ExportDefaultDeclaration" && stmt.declaration) {
|
|
4040
|
+
const d = stmt.declaration;
|
|
4041
|
+
if (d.type === "Identifier") {
|
|
4042
|
+
const localName = d.name;
|
|
4043
|
+
if (!exportedClassNames.has(localName)) {
|
|
4044
|
+
const decl = localClasses.get(localName);
|
|
4045
|
+
if (decl) {
|
|
4046
|
+
exportedClassNames.add(localName);
|
|
4047
|
+
collectClassMethods(localName, decl);
|
|
4048
|
+
}
|
|
4049
|
+
}
|
|
3628
4050
|
}
|
|
3629
|
-
return;
|
|
3630
|
-
}
|
|
3631
|
-
for (const key of Object.keys(obj2)) {
|
|
3632
|
-
if (key === "loc" || key === "start" || key === "end") continue;
|
|
3633
|
-
const val = obj2[key];
|
|
3634
|
-
if (Array.isArray(val)) val.forEach((v2) => visit(v2, isMethodCallee, guarded));
|
|
3635
|
-
else if (val && typeof val === "object") visit(val, isMethodCallee, guarded);
|
|
3636
4051
|
}
|
|
3637
|
-
}
|
|
3638
|
-
|
|
3639
|
-
|
|
4052
|
+
}
|
|
4053
|
+
return names;
|
|
4054
|
+
}
|
|
4055
|
+
function absUnknown() {
|
|
4056
|
+
return { shape: { k: "unknown" }, conf: "partial" };
|
|
3640
4057
|
}
|
|
3641
4058
|
function evalArgAbs(node, lookupVar) {
|
|
3642
4059
|
if (node.type === "Identifier" && typeof node.name === "string" && lookupVar) {
|
|
@@ -4009,14 +4426,37 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4009
4426
|
eiCache.set(key, r);
|
|
4010
4427
|
return r;
|
|
4011
4428
|
};
|
|
4012
|
-
const
|
|
4429
|
+
const projectArgField = (arg, field) => {
|
|
4430
|
+
if (!arg) return void 0;
|
|
4431
|
+
if (arg.shape.k === "brand") {
|
|
4432
|
+
return projectArgField(arg.shape.shape, field);
|
|
4433
|
+
}
|
|
4434
|
+
if (arg.shape.k !== "obj") return void 0;
|
|
4435
|
+
return getSlot(arg.shape.slots, field)?.value;
|
|
4436
|
+
};
|
|
4437
|
+
const interfaceToIndexed = (ei, paramNames, formals) => {
|
|
4013
4438
|
const conflict = new Set(ei.conflict?.params ?? []);
|
|
4014
4439
|
const entries = [];
|
|
4015
4440
|
for (const { param, constraint } of ei.params) {
|
|
4016
|
-
if (conflict.has(param)) continue;
|
|
4441
|
+
if (!param || conflict.has(param)) continue;
|
|
4017
4442
|
const idx = paramNames.indexOf(param);
|
|
4018
4443
|
if (idx >= 0) {
|
|
4019
|
-
entries.push([
|
|
4444
|
+
entries.push([
|
|
4445
|
+
idx,
|
|
4446
|
+
{ param, pred: instantiateConstraint(constraint, param), constraint },
|
|
4447
|
+
void 0
|
|
4448
|
+
]);
|
|
4449
|
+
continue;
|
|
4450
|
+
}
|
|
4451
|
+
if (formals && formals.length > 0) {
|
|
4452
|
+
const hit = locateContractParam(formals, param);
|
|
4453
|
+
if (hit) {
|
|
4454
|
+
entries.push([
|
|
4455
|
+
hit.index,
|
|
4456
|
+
{ param, pred: instantiateConstraint(constraint, param), constraint },
|
|
4457
|
+
hit.field
|
|
4458
|
+
]);
|
|
4459
|
+
}
|
|
4020
4460
|
}
|
|
4021
4461
|
}
|
|
4022
4462
|
return entries;
|
|
@@ -4050,15 +4490,36 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4050
4490
|
return lv <= n;
|
|
4051
4491
|
};
|
|
4052
4492
|
const checkReqs = (displayName, reqs, paramNames, absArgs, argIndexOf, loc) => {
|
|
4053
|
-
for (const [idx, pred] of reqs) {
|
|
4493
|
+
for (const [idx, pred, field, contractParam] of reqs) {
|
|
4054
4494
|
const argIdx = argIndexOf(idx);
|
|
4055
4495
|
if (argIdx === void 0) continue;
|
|
4056
|
-
|
|
4496
|
+
let arg = absArgs[argIdx];
|
|
4057
4497
|
if (!arg) continue;
|
|
4498
|
+
const paramName = contractParam || paramNames[idx] || `arg${idx}`;
|
|
4499
|
+
if (field) {
|
|
4500
|
+
const projected = projectArgField(arg, field);
|
|
4501
|
+
if (!projected) {
|
|
4502
|
+
const k = arg.shape.k;
|
|
4503
|
+
if (k !== "unknown" && k !== "any") {
|
|
4504
|
+
out.push({
|
|
4505
|
+
severity: "error",
|
|
4506
|
+
code: "nudo:constraint-violated",
|
|
4507
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
4508
|
+
actual: formatAbs(arg),
|
|
4509
|
+
expected: `missing field ${field}`,
|
|
4510
|
+
suggestion: `\u8865\u5168\u5B57\u6BB5 ${field}`,
|
|
4511
|
+
fn: displayName,
|
|
4512
|
+
line: loc?.start.line,
|
|
4513
|
+
column: loc?.start.column
|
|
4514
|
+
});
|
|
4515
|
+
}
|
|
4516
|
+
continue;
|
|
4517
|
+
}
|
|
4518
|
+
arg = projected;
|
|
4519
|
+
}
|
|
4058
4520
|
const lv = litValue(arg);
|
|
4059
4521
|
const isStr = arg.shape.k === "prim" && arg.shape.type === "string";
|
|
4060
4522
|
const strLen = typeof lv === "string" ? lv.length : void 0;
|
|
4061
|
-
const paramName = paramNames[idx] ?? `arg${idx}`;
|
|
4062
4523
|
for (const p of flattenPred(pred)) {
|
|
4063
4524
|
if (p.op === "typeof") {
|
|
4064
4525
|
if (p.t.op !== "var") continue;
|
|
@@ -4135,14 +4596,13 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4135
4596
|
if (p.op === "lt") ok2 = strLen < n;
|
|
4136
4597
|
if (p.op === "le") ok2 = strLen <= n;
|
|
4137
4598
|
if (!ok2) {
|
|
4138
|
-
const paramName2 = paramNames[idx] ?? `arg${idx}`;
|
|
4139
4599
|
out.push({
|
|
4140
4600
|
severity: "error",
|
|
4141
4601
|
code: "nudo:constraint-violated",
|
|
4142
|
-
message: `${displayName}[${
|
|
4602
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
4143
4603
|
actual: formatAbs(arg),
|
|
4144
|
-
expected: `length(${
|
|
4145
|
-
suggestion: `\u6539\u7528\u6EE1\u8DB3\u957F\u5EA6 ${opSym} ${n} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${
|
|
4604
|
+
expected: `length(${paramName}) ${opSym} ${n}`,
|
|
4605
|
+
suggestion: `\u6539\u7528\u6EE1\u8DB3\u957F\u5EA6 ${opSym} ${n} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${paramName} \u7684\u524D\u7F6E`,
|
|
4146
4606
|
fn: displayName,
|
|
4147
4607
|
line: loc?.start.line,
|
|
4148
4608
|
column: loc?.start.column
|
|
@@ -4157,14 +4617,13 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4157
4617
|
if (p.op === "lt") ok = lv < n;
|
|
4158
4618
|
if (p.op === "le") ok = lv <= n;
|
|
4159
4619
|
if (!ok) {
|
|
4160
|
-
const paramName2 = paramNames[idx] ?? `arg${idx}`;
|
|
4161
4620
|
out.push({
|
|
4162
4621
|
severity: "error",
|
|
4163
4622
|
code: "nudo:constraint-violated",
|
|
4164
|
-
message: `${displayName}[${
|
|
4623
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
4165
4624
|
actual: formatAbs(arg),
|
|
4166
4625
|
expected: predToString(p),
|
|
4167
|
-
suggestion: `\u6539\u7528\u6EE1\u8DB3 ${predToString(p)} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${
|
|
4626
|
+
suggestion: `\u6539\u7528\u6EE1\u8DB3 ${predToString(p)} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${paramName} \u7684\u524D\u7F6E`,
|
|
4168
4627
|
fn: displayName,
|
|
4169
4628
|
line: loc?.start.line,
|
|
4170
4629
|
column: loc?.start.column
|
|
@@ -4346,14 +4805,35 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4346
4805
|
}
|
|
4347
4806
|
};
|
|
4348
4807
|
const checkShapeReqs = (displayName, reqs, paramNames, absArgs, argIndexOf, loc) => {
|
|
4349
|
-
for (const [idx, entry] of reqs) {
|
|
4808
|
+
for (const [idx, entry, field] of reqs) {
|
|
4350
4809
|
const c = entry.constraint;
|
|
4351
4810
|
if (!c.fields && !c.element && !isIntFlag(c) && !c.prim) continue;
|
|
4352
4811
|
const argIdx = argIndexOf(idx);
|
|
4353
4812
|
if (argIdx === void 0) continue;
|
|
4354
|
-
|
|
4813
|
+
let arg = absArgs[argIdx];
|
|
4355
4814
|
if (!arg) continue;
|
|
4356
4815
|
const paramName = entry.param || paramNames[idx] || `arg${idx}`;
|
|
4816
|
+
if (field) {
|
|
4817
|
+
const projected = projectArgField(arg, field);
|
|
4818
|
+
if (!projected) {
|
|
4819
|
+
const k = arg.shape.k;
|
|
4820
|
+
if (k !== "unknown" && k !== "any") {
|
|
4821
|
+
out.push({
|
|
4822
|
+
severity: "error",
|
|
4823
|
+
code: "nudo:constraint-violated",
|
|
4824
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
4825
|
+
actual: formatAbs(arg),
|
|
4826
|
+
expected: `missing field ${field}`,
|
|
4827
|
+
suggestion: `\u8865\u5168\u5B57\u6BB5 ${field}`,
|
|
4828
|
+
fn: displayName,
|
|
4829
|
+
line: loc?.start.line,
|
|
4830
|
+
column: loc?.start.column
|
|
4831
|
+
});
|
|
4832
|
+
}
|
|
4833
|
+
continue;
|
|
4834
|
+
}
|
|
4835
|
+
arg = projected;
|
|
4836
|
+
}
|
|
4357
4837
|
if (c.fields) {
|
|
4358
4838
|
checkShapeAgainstAbs(displayName, paramName, c, arg, paramName, loc);
|
|
4359
4839
|
}
|
|
@@ -4468,11 +4948,11 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4468
4948
|
};
|
|
4469
4949
|
const ownEi = effectiveInterfaceOf(fnName, source, optsR);
|
|
4470
4950
|
if (ownEi?.source === "handwritten") {
|
|
4471
|
-
const ownFull = interfaceToIndexed(ownEi, paramNames);
|
|
4951
|
+
const ownFull = interfaceToIndexed(ownEi, paramNames, g?.formals);
|
|
4472
4952
|
checkShapeReqs(fnName, ownFull, paramNames, absArgs, (i) => i, loc);
|
|
4473
4953
|
checkReqs(
|
|
4474
4954
|
fnName,
|
|
4475
|
-
ownFull.map(([i, e]) => [i, e.pred]),
|
|
4955
|
+
ownFull.map(([i, e, f]) => [i, e.pred, f, e.param]),
|
|
4476
4956
|
paramNames,
|
|
4477
4957
|
absArgs,
|
|
4478
4958
|
(i) => i,
|
|
@@ -4484,7 +4964,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4484
4964
|
const tg = generalizeFromAst(fwd.target, source, file ? { file } : {});
|
|
4485
4965
|
const tParams = tg?.params ?? [];
|
|
4486
4966
|
const tEi = effectiveInterfaceOf(fwd.target, source, optsR);
|
|
4487
|
-
const tFull = tEi?.source === "handwritten" ? interfaceToIndexed(tEi, tParams) : [];
|
|
4967
|
+
const tFull = tEi?.source === "handwritten" ? interfaceToIndexed(tEi, tParams, tg?.formals) : [];
|
|
4488
4968
|
if (tFull.length > 0) {
|
|
4489
4969
|
const wrapperArgOfTarget = /* @__PURE__ */ new Map();
|
|
4490
4970
|
fwd.map.forEach((wrapperIdx, targetIdx) => {
|
|
@@ -4494,7 +4974,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4494
4974
|
checkShapeReqs(`${fnName}\u2192${fwd.target}`, tFull, tParams, absArgs, mapArg, loc);
|
|
4495
4975
|
checkReqs(
|
|
4496
4976
|
`${fnName}\u2192${fwd.target}`,
|
|
4497
|
-
tFull.map(([i, e]) => [i, e.pred]),
|
|
4977
|
+
tFull.map(([i, e, f]) => [i, e.pred, f, e.param]),
|
|
4498
4978
|
tParams,
|
|
4499
4979
|
absArgs,
|
|
4500
4980
|
mapArg,
|
|
@@ -4520,7 +5000,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4520
5000
|
};
|
|
4521
5001
|
const ei = effectiveInterfaceOf(ext.fnName, ext.source, eiOpts);
|
|
4522
5002
|
if (ei?.source === "handwritten") {
|
|
4523
|
-
full = interfaceToIndexed(ei, paramNames);
|
|
5003
|
+
full = interfaceToIndexed(ei, paramNames, g?.formals);
|
|
4524
5004
|
}
|
|
4525
5005
|
} catch {
|
|
4526
5006
|
out.push({
|
|
@@ -4536,7 +5016,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4536
5016
|
checkShapeReqs(displayName, full, paramNames, absArgs, (i) => i, loc);
|
|
4537
5017
|
checkReqs(
|
|
4538
5018
|
displayName,
|
|
4539
|
-
full.map(([i, e]) => [i, e.pred]),
|
|
5019
|
+
full.map(([i, e, f]) => [i, e.pred, f, e.param]),
|
|
4540
5020
|
paramNames,
|
|
4541
5021
|
absArgs,
|
|
4542
5022
|
(i) => i,
|
|
@@ -4580,19 +5060,15 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4580
5060
|
}
|
|
4581
5061
|
}
|
|
4582
5062
|
};
|
|
4583
|
-
const checkArgStructures = (fnName, fnSource, args, loc, displayName,
|
|
4584
|
-
let structReqs;
|
|
4585
|
-
let paramNames;
|
|
5063
|
+
const checkArgStructures = (fnName, fnSource, args, loc, displayName, _interfaceFromFile) => {
|
|
4586
5064
|
let gFn;
|
|
4587
5065
|
try {
|
|
4588
5066
|
const sameFile = fnSource === source;
|
|
4589
|
-
structReqs = collectParamStructReqs(fnSource, fnName, sameFile ? file : void 0);
|
|
4590
5067
|
gFn = generalizeFromAst(
|
|
4591
5068
|
fnName,
|
|
4592
5069
|
fnSource,
|
|
4593
5070
|
sameFile && file ? { file } : {}
|
|
4594
5071
|
);
|
|
4595
|
-
paramNames = gFn?.params ?? [];
|
|
4596
5072
|
} catch (e) {
|
|
4597
5073
|
out.push({
|
|
4598
5074
|
severity: "warning",
|
|
@@ -4613,65 +5089,6 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4613
5089
|
(n) => evalArgAbs(n, (x) => varAbs.get(x))
|
|
4614
5090
|
);
|
|
4615
5091
|
}
|
|
4616
|
-
if (structReqs.size === 0) return;
|
|
4617
|
-
let refinedParams;
|
|
4618
|
-
try {
|
|
4619
|
-
const sameFile = fnSource === source;
|
|
4620
|
-
const eiOpts = sameFile ? {
|
|
4621
|
-
loadModule: opts?.loadModule,
|
|
4622
|
-
fromFile: opts?.fromFile ?? "",
|
|
4623
|
-
...opts?.autoBind !== void 0 ? { autoBind: opts.autoBind } : {}
|
|
4624
|
-
} : {
|
|
4625
|
-
loadModule: opts?.loadModule,
|
|
4626
|
-
fromFile: interfaceFromFile ?? opts?.fromFile ?? "",
|
|
4627
|
-
...interfaceFromFile ? opts?.autoBind !== void 0 ? { autoBind: opts.autoBind } : {} : { autoBind: false }
|
|
4628
|
-
};
|
|
4629
|
-
const ei = effectiveInterfaceOf(fnName, fnSource, eiOpts);
|
|
4630
|
-
if (ei?.source === "handwritten" && ei.params.length > 0) {
|
|
4631
|
-
refinedParams = new Set(ei.params.map((p) => p.param));
|
|
4632
|
-
}
|
|
4633
|
-
} catch {
|
|
4634
|
-
out.push({
|
|
4635
|
-
severity: "warning",
|
|
4636
|
-
code: "nudo:no-signature",
|
|
4637
|
-
message: `${displayName ?? fnName}: handwritten interface load failed; falling back to body structure inference`,
|
|
4638
|
-
fn: displayName ?? fnName,
|
|
4639
|
-
line: loc?.start.line,
|
|
4640
|
-
column: loc?.start.column
|
|
4641
|
-
});
|
|
4642
|
-
}
|
|
4643
|
-
for (let i = 0; i < args.length; i++) {
|
|
4644
|
-
const pname = paramNames[i];
|
|
4645
|
-
if (!pname) continue;
|
|
4646
|
-
if (refinedParams?.has(pname)) continue;
|
|
4647
|
-
const keys = structReqs.get(pname);
|
|
4648
|
-
if (!keys || keys.size === 0) continue;
|
|
4649
|
-
const argNode = args[i];
|
|
4650
|
-
if (!argNode) continue;
|
|
4651
|
-
const absArg = evalArgAbs(argNode, (n) => varAbs.get(n));
|
|
4652
|
-
if (!absArg || absArg.shape.k === "unknown") continue;
|
|
4653
|
-
const isLeny = absArg.shape.k === "arr" || absArg.shape.k === "tuple" || absArg.shape.k === "prim" && absArg.shape.type === "string";
|
|
4654
|
-
const needKeys = isLeny ? [...keys].filter((k) => k !== "length") : [...keys];
|
|
4655
|
-
if (needKeys.length === 0) continue;
|
|
4656
|
-
const slots = {};
|
|
4657
|
-
for (const k of needKeys) slots[k] = { value: absUnknown() };
|
|
4658
|
-
const target = abs({ k: "obj", slots }, void 0, void 0, "exact");
|
|
4659
|
-
const leq = leqAbs(absArg, target);
|
|
4660
|
-
if (!leq.ok) {
|
|
4661
|
-
const name = displayName ?? fnName;
|
|
4662
|
-
out.push({
|
|
4663
|
-
severity: "error",
|
|
4664
|
-
code: "nudo:arg-structure",
|
|
4665
|
-
message: `${name}[${pname}]: \u5B9E\u53C2\u7ED3\u6784 \u22AD \u5F62\u53C2`,
|
|
4666
|
-
actual: formatAbs(absArg),
|
|
4667
|
-
expected: formatAbs(target),
|
|
4668
|
-
suggestion: leq.reason ?? `\u8865\u5168 ${pname} \u4E0A\u88AB\u8BBF\u95EE\u7684\u5B57\u6BB5`,
|
|
4669
|
-
fn: name,
|
|
4670
|
-
line: loc?.start.line,
|
|
4671
|
-
column: loc?.start.column
|
|
4672
|
-
});
|
|
4673
|
-
}
|
|
4674
|
-
}
|
|
4675
5092
|
};
|
|
4676
5093
|
const visit = (n) => {
|
|
4677
5094
|
if (!n || typeof n !== "object") return;
|
|
@@ -4768,6 +5185,14 @@ function extractLiteralEvidence(rec, idx) {
|
|
|
4768
5185
|
}
|
|
4769
5186
|
|
|
4770
5187
|
// src/algebra/check.ts
|
|
5188
|
+
function projectCaseArgField(arg, field) {
|
|
5189
|
+
if (!arg) return void 0;
|
|
5190
|
+
if (arg.shape.k === "brand") {
|
|
5191
|
+
return projectCaseArgField(arg.shape.shape, field);
|
|
5192
|
+
}
|
|
5193
|
+
if (arg.shape.k !== "obj") return void 0;
|
|
5194
|
+
return getSlot(arg.shape.slots, field)?.value;
|
|
5195
|
+
}
|
|
4771
5196
|
var checkReportMemo = /* @__PURE__ */ new Map();
|
|
4772
5197
|
var checkKeyDeps = /* @__PURE__ */ new Map();
|
|
4773
5198
|
var checkDepIndex = /* @__PURE__ */ new Map();
|
|
@@ -4791,7 +5216,7 @@ function loadModuleId2(fn2) {
|
|
|
4791
5216
|
}
|
|
4792
5217
|
function checkDepsFingerprint(source, opts) {
|
|
4793
5218
|
if (!opts.loadModule || !opts.fromFile) {
|
|
4794
|
-
return { fp: "-", paths: [], truncated: false };
|
|
5219
|
+
return { fp: "-", paths: [], contents: [], truncated: false };
|
|
4795
5220
|
}
|
|
4796
5221
|
return loadModuleDepsFingerprint(source, opts.loadModule, opts.fromFile);
|
|
4797
5222
|
}
|
|
@@ -4838,7 +5263,8 @@ function checkMemoKey(filePath, source, identityOpts, deps, sidecarFp) {
|
|
|
4838
5263
|
filePath,
|
|
4839
5264
|
`${loadModuleId2(identityOpts.loadModule)}:${identityOpts.fromFile ?? ""}`,
|
|
4840
5265
|
deps.fp,
|
|
4841
|
-
sidecarFp ?? "-"
|
|
5266
|
+
sidecarFp ?? "-",
|
|
5267
|
+
identityOpts.autoBind === false ? "ab0" : "ab1"
|
|
4842
5268
|
].join("|");
|
|
4843
5269
|
}
|
|
4844
5270
|
function checkMemoGet(key) {
|
|
@@ -5011,6 +5437,26 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
|
|
|
5011
5437
|
});
|
|
5012
5438
|
if (hasRefineDirective || (exportedNames?.has(name) ?? false)) {
|
|
5013
5439
|
const eff = effectiveInterfaceCached(name);
|
|
5440
|
+
if (eff?.source === "handwritten") {
|
|
5441
|
+
const contractNames = contractParamNameSet(g.formals ?? []);
|
|
5442
|
+
const formalDisplay = new Set(g.params);
|
|
5443
|
+
const conflictNames = new Set(eff.conflict?.params ?? []);
|
|
5444
|
+
const unknownParams = eff.params.map((p) => p.param).filter(
|
|
5445
|
+
(p) => p && !formalDisplay.has(p) && !contractNames.has(p) && !conflictNames.has(p)
|
|
5446
|
+
);
|
|
5447
|
+
if (unknownParams.length > 0) {
|
|
5448
|
+
const surface = [...contractNames].filter((n) => !n.startsWith("_p") && n !== "_").join(", ");
|
|
5449
|
+
issues.push({
|
|
5450
|
+
severity: "error",
|
|
5451
|
+
code: "nudo:interface-param-mismatch",
|
|
5452
|
+
message: `${name}: \u5951\u7EA6\u53C2\u6570\u540D\u4E0D\u5728\u5F62\u53C2\u8868\uFF08${unknownParams.join(", ")}\uFF09`,
|
|
5453
|
+
actual: unknownParams.join(", "),
|
|
5454
|
+
expected: surface || g.params.join(", ") || "(\u65E0\u53C2)",
|
|
5455
|
+
suggestion: `\u628A @nudo:refine / \u4FA7\u8F66\u7ED1\u5B9A\u53C2\u6570\u540D\u6539\u6210\u5F62\u53C2\u4E4B\u4E00\uFF1A${surface || g.params.join(", ") || "\uFF08\u51FD\u6570\u65E0\u53C2\uFF09"}`,
|
|
5456
|
+
fn: name
|
|
5457
|
+
});
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5014
5460
|
if (eff?.conflict) {
|
|
5015
5461
|
if (eff.conflict.params.length > 0) {
|
|
5016
5462
|
issues.push({
|
|
@@ -5340,10 +5786,19 @@ function scanCaseInconsistency(source, knownFns, opts) {
|
|
|
5340
5786
|
});
|
|
5341
5787
|
if (!eff || eff.source !== "handwritten") return;
|
|
5342
5788
|
const conflictParams = new Set(eff.conflict?.params ?? []);
|
|
5789
|
+
const formals = g.formals ?? [];
|
|
5343
5790
|
const reqs = [];
|
|
5344
5791
|
for (const p of eff.params) {
|
|
5345
5792
|
if (conflictParams.has(p.param)) continue;
|
|
5346
|
-
|
|
5793
|
+
let idx = paramNames.indexOf(p.param);
|
|
5794
|
+
let field;
|
|
5795
|
+
if (idx < 0 && formals.length > 0) {
|
|
5796
|
+
const hit = locateContractParam(formals, p.param);
|
|
5797
|
+
if (hit) {
|
|
5798
|
+
idx = hit.index;
|
|
5799
|
+
field = hit.field;
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5347
5802
|
if (idx < 0) continue;
|
|
5348
5803
|
reqs.push([
|
|
5349
5804
|
idx,
|
|
@@ -5351,15 +5806,40 @@ function scanCaseInconsistency(source, knownFns, opts) {
|
|
|
5351
5806
|
param: p.param,
|
|
5352
5807
|
pred: instantiateConstraint(p.constraint, p.param),
|
|
5353
5808
|
constraint: p.constraint
|
|
5354
|
-
}
|
|
5809
|
+
},
|
|
5810
|
+
field
|
|
5355
5811
|
]);
|
|
5356
5812
|
}
|
|
5357
5813
|
if (reqs.length === 0) return;
|
|
5358
5814
|
const absArgs = args.map((a) => parseLitArg(a) ?? absUnknown());
|
|
5359
|
-
for (const
|
|
5815
|
+
for (const req of reqs) {
|
|
5816
|
+
const idx = req[0];
|
|
5817
|
+
const entry = req[1];
|
|
5818
|
+
const field = req[2];
|
|
5360
5819
|
if (entry.constraint.fields) continue;
|
|
5361
|
-
|
|
5820
|
+
let arg = absArgs[idx];
|
|
5362
5821
|
if (!arg) continue;
|
|
5822
|
+
if (field) {
|
|
5823
|
+
const projected = projectCaseArgField(arg, field);
|
|
5824
|
+
if (!projected) {
|
|
5825
|
+
const k = arg.shape.k;
|
|
5826
|
+
if (k !== "unknown" && k !== "any") {
|
|
5827
|
+
const paramName = entry.param || paramNames[idx] || `arg${idx}`;
|
|
5828
|
+
out.push({
|
|
5829
|
+
severity: "error",
|
|
5830
|
+
code: "nudo:case-inconsistency",
|
|
5831
|
+
message: `${fnName} case "${caseName}": \u89C1\u8BC1 \u22AD \u5951\u7EA6`,
|
|
5832
|
+
actual: formatAbs(arg),
|
|
5833
|
+
expected: `missing field ${field}`,
|
|
5834
|
+
suggestion: `case \u5B9E\u53C2\u8865\u5168\u5B57\u6BB5 ${field}\uFF08\u5951\u7EA6\u4F4D ${paramName}\uFF09`,
|
|
5835
|
+
fn: fnName,
|
|
5836
|
+
line
|
|
5837
|
+
});
|
|
5838
|
+
}
|
|
5839
|
+
continue;
|
|
5840
|
+
}
|
|
5841
|
+
arg = projected;
|
|
5842
|
+
}
|
|
5363
5843
|
const lv = litValue(arg);
|
|
5364
5844
|
if (lv === void 0 || typeof lv !== "number" && typeof lv !== "string" && typeof lv !== "boolean") {
|
|
5365
5845
|
continue;
|
|
@@ -5658,8 +6138,12 @@ function formatReturnDisplay(g) {
|
|
|
5658
6138
|
}
|
|
5659
6139
|
return memberPath(abs2).text;
|
|
5660
6140
|
}
|
|
5661
|
-
function collectAbsInlays(source,
|
|
6141
|
+
function collectAbsInlays(source, opts) {
|
|
5662
6142
|
const inlays = [];
|
|
6143
|
+
const refineOpts = opts?.loadModule || opts?.fromFile ? {
|
|
6144
|
+
...opts.loadModule ? { loadModule: opts.loadModule } : {},
|
|
6145
|
+
...opts.fromFile ? { fromFile: opts.fromFile } : {}
|
|
6146
|
+
} : void 0;
|
|
5663
6147
|
for (const { name, node } of listFunctions(source)) {
|
|
5664
6148
|
let g;
|
|
5665
6149
|
try {
|
|
@@ -5668,6 +6152,12 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
5668
6152
|
continue;
|
|
5669
6153
|
}
|
|
5670
6154
|
if (!g) continue;
|
|
6155
|
+
const tier = opts?.fromFile !== void 0 ? interfaceTierOf(source, name, opts.fromFile, {
|
|
6156
|
+
...opts.loadModule ? { loadModule: opts.loadModule } : {},
|
|
6157
|
+
...opts.autoBind !== void 0 ? { autoBind: opts.autoBind } : {}
|
|
6158
|
+
}) : void 0;
|
|
6159
|
+
const tierSrc = tier?.source;
|
|
6160
|
+
const isImplicitExport = tierSrc === "implicit";
|
|
5671
6161
|
const params = g.params;
|
|
5672
6162
|
const predsByName = /* @__PURE__ */ new Map();
|
|
5673
6163
|
if (g.entryReqs) {
|
|
@@ -5688,7 +6178,8 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
5688
6178
|
line: p.loc.end.line,
|
|
5689
6179
|
character: p.loc.end.column,
|
|
5690
6180
|
label: ` where ${text}`,
|
|
5691
|
-
kind: "parameter"
|
|
6181
|
+
kind: "parameter",
|
|
6182
|
+
...tierSrc ? { interfaceSource: tierSrc } : {}
|
|
5692
6183
|
});
|
|
5693
6184
|
}
|
|
5694
6185
|
}
|
|
@@ -5700,11 +6191,14 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
5700
6191
|
} catch {
|
|
5701
6192
|
label = `: ${formatShape(g.symbolic)}`;
|
|
5702
6193
|
}
|
|
6194
|
+
if (isImplicitExport) label += " \xB7 derived";
|
|
5703
6195
|
inlays.push({
|
|
5704
6196
|
line: bodyLoc.start.line,
|
|
5705
6197
|
character: Math.max(0, bodyLoc.start.column),
|
|
5706
6198
|
label: `${label} `,
|
|
5707
|
-
kind: "type"
|
|
6199
|
+
kind: "type",
|
|
6200
|
+
...tierSrc ? { interfaceSource: tierSrc } : {},
|
|
6201
|
+
...isImplicitExport ? { derived: true } : {}
|
|
5708
6202
|
});
|
|
5709
6203
|
}
|
|
5710
6204
|
}
|
|
@@ -5882,6 +6376,8 @@ function termIsValue(t, a) {
|
|
|
5882
6376
|
export {
|
|
5883
6377
|
$add,
|
|
5884
6378
|
$arr,
|
|
6379
|
+
$arrMutContainer,
|
|
6380
|
+
$arrRest,
|
|
5885
6381
|
$async,
|
|
5886
6382
|
$asyncReturn,
|
|
5887
6383
|
$await,
|
|
@@ -5893,6 +6389,7 @@ export {
|
|
|
5893
6389
|
$div,
|
|
5894
6390
|
$elems,
|
|
5895
6391
|
$eq,
|
|
6392
|
+
$eqLoose,
|
|
5896
6393
|
$fnVal,
|
|
5897
6394
|
$for,
|
|
5898
6395
|
$forIter,
|
|
@@ -5906,22 +6403,29 @@ export {
|
|
|
5906
6403
|
$idxSet,
|
|
5907
6404
|
$invoke,
|
|
5908
6405
|
$invokeSuper,
|
|
6406
|
+
$isForkExit,
|
|
5909
6407
|
$join,
|
|
5910
6408
|
$le,
|
|
5911
6409
|
$len,
|
|
5912
6410
|
$lit,
|
|
6411
|
+
$loopReturn,
|
|
5913
6412
|
$lt,
|
|
5914
6413
|
$mod,
|
|
5915
6414
|
$mul,
|
|
5916
6415
|
$ne,
|
|
6416
|
+
$neLoose,
|
|
5917
6417
|
$neg,
|
|
5918
6418
|
$new,
|
|
5919
6419
|
$not,
|
|
6420
|
+
$nullishTest,
|
|
5920
6421
|
$obj,
|
|
6422
|
+
$objRest,
|
|
5921
6423
|
$optionalGet,
|
|
5922
6424
|
$optionalInvoke,
|
|
5923
6425
|
$orDefault,
|
|
6426
|
+
$pushLoopExit,
|
|
5924
6427
|
$regex,
|
|
6428
|
+
$rethrowIfNudoReturn,
|
|
5925
6429
|
$set,
|
|
5926
6430
|
$setKey,
|
|
5927
6431
|
$spread,
|
|
@@ -5932,6 +6436,10 @@ export {
|
|
|
5932
6436
|
$thisGet,
|
|
5933
6437
|
$thisSet,
|
|
5934
6438
|
$throw,
|
|
6439
|
+
$tryCurrentMark,
|
|
6440
|
+
$tryMark,
|
|
6441
|
+
$tryPopMark,
|
|
6442
|
+
$tryTakeSince,
|
|
5935
6443
|
$typeof,
|
|
5936
6444
|
$while,
|
|
5937
6445
|
$whileSeq,
|
|
@@ -5939,6 +6447,7 @@ export {
|
|
|
5939
6447
|
DEFAULT_MAX_LOOP_ITERS,
|
|
5940
6448
|
MAX_CALL_DEPTH,
|
|
5941
6449
|
MAX_TOTAL_CALLS,
|
|
6450
|
+
NudoReturn,
|
|
5942
6451
|
NudoSidecarError,
|
|
5943
6452
|
NudoThrow,
|
|
5944
6453
|
SELF,
|
|
@@ -5955,6 +6464,7 @@ export {
|
|
|
5955
6464
|
analyzeFn,
|
|
5956
6465
|
analyzeFnFull,
|
|
5957
6466
|
and,
|
|
6467
|
+
any,
|
|
5958
6468
|
anyVar,
|
|
5959
6469
|
app,
|
|
5960
6470
|
applyAbsFn,
|
|
@@ -5964,6 +6474,7 @@ export {
|
|
|
5964
6474
|
asAbsVal,
|
|
5965
6475
|
attachFnImpl,
|
|
5966
6476
|
awaitAbs,
|
|
6477
|
+
beginCollectionFork,
|
|
5967
6478
|
beginDerivationSession,
|
|
5968
6479
|
betaOf,
|
|
5969
6480
|
bindImports,
|
|
@@ -5972,6 +6483,7 @@ export {
|
|
|
5972
6483
|
boolean,
|
|
5973
6484
|
buildArgsFromAssume,
|
|
5974
6485
|
callAbsMethod,
|
|
6486
|
+
callAtFunctionBoundary,
|
|
5975
6487
|
callFunction,
|
|
5976
6488
|
callFunctionFull,
|
|
5977
6489
|
callTranspiledExport,
|
|
@@ -5983,14 +6495,19 @@ export {
|
|
|
5983
6495
|
checkSource,
|
|
5984
6496
|
classFromMethods,
|
|
5985
6497
|
clearBClasses,
|
|
6498
|
+
clearCollectionTables,
|
|
5986
6499
|
cmp,
|
|
5987
6500
|
coerceAsyncReturn,
|
|
5988
6501
|
collectAbsExports,
|
|
6502
|
+
collectAbsFreeVars,
|
|
5989
6503
|
collectAbsInlays,
|
|
5990
6504
|
collectAbsNodeTypes,
|
|
6505
|
+
collectionElementJoin,
|
|
6506
|
+
collectionExactLen,
|
|
5991
6507
|
concatString,
|
|
5992
6508
|
confJoin,
|
|
5993
6509
|
constraintToEntryAbs,
|
|
6510
|
+
contractParamNameSet,
|
|
5994
6511
|
createEnvironment,
|
|
5995
6512
|
createHofCollectCtx,
|
|
5996
6513
|
createTemplateAbs,
|
|
@@ -6009,8 +6526,10 @@ export {
|
|
|
6009
6526
|
effectiveInterface,
|
|
6010
6527
|
emptyEnv,
|
|
6011
6528
|
emptyPhi,
|
|
6529
|
+
endCollectionFork,
|
|
6012
6530
|
endDerivationSession,
|
|
6013
6531
|
eq,
|
|
6532
|
+
errorBrandAbs,
|
|
6014
6533
|
evalArrayStatic,
|
|
6015
6534
|
evalBuiltinInstanceMethod,
|
|
6016
6535
|
evalBuiltinNew,
|
|
@@ -6047,11 +6566,15 @@ export {
|
|
|
6047
6566
|
fnConstraintToEntryReqs,
|
|
6048
6567
|
fnFingerprints,
|
|
6049
6568
|
fnOf,
|
|
6569
|
+
formalParamDisplayNames,
|
|
6570
|
+
formalParamsFromNodes,
|
|
6050
6571
|
formatAbs,
|
|
6051
6572
|
formatAbsMultiline,
|
|
6052
6573
|
formatCheckReport,
|
|
6053
6574
|
formatConstraint,
|
|
6054
6575
|
formatDiagnostics,
|
|
6576
|
+
formatEffectiveInterfaceDisplay,
|
|
6577
|
+
formatInterfaceTierLine,
|
|
6055
6578
|
formatShape,
|
|
6056
6579
|
formatShapeSlot,
|
|
6057
6580
|
formatTemplateNameViews,
|
|
@@ -6084,17 +6607,25 @@ export {
|
|
|
6084
6607
|
instantiateConstraint,
|
|
6085
6608
|
instantiateReturn,
|
|
6086
6609
|
interfaceDiagCount,
|
|
6610
|
+
interfaceSourceOf,
|
|
6611
|
+
interfaceTierOf,
|
|
6612
|
+
isArrMutator,
|
|
6087
6613
|
isDefinitelyFalse,
|
|
6088
6614
|
isDefinitelyTrue,
|
|
6615
|
+
isErrorCtorName,
|
|
6616
|
+
isEvalMissingSlotEnabled,
|
|
6089
6617
|
isExactLit,
|
|
6090
6618
|
isIntFlag,
|
|
6619
|
+
isMapAbs,
|
|
6091
6620
|
isNodeModulesPath,
|
|
6092
6621
|
isNudoConstraint,
|
|
6622
|
+
isNudoReturn,
|
|
6093
6623
|
isNudoThrow,
|
|
6094
6624
|
isNullishLitAbs,
|
|
6095
6625
|
isNumPrim,
|
|
6096
6626
|
isObj,
|
|
6097
6627
|
isRelFn,
|
|
6628
|
+
isSetAbs,
|
|
6098
6629
|
isStrPrim,
|
|
6099
6630
|
isTemplateLike,
|
|
6100
6631
|
joinAbs,
|
|
@@ -6116,16 +6647,29 @@ export {
|
|
|
6116
6647
|
literalMeetsConstraint,
|
|
6117
6648
|
loadModuleDepsFingerprint,
|
|
6118
6649
|
localNamedExports,
|
|
6650
|
+
locateContractParam,
|
|
6119
6651
|
lookupMethod,
|
|
6120
6652
|
lookupMethodWithOwner,
|
|
6121
6653
|
lookupSuperMethod,
|
|
6654
|
+
looseEqAbs,
|
|
6122
6655
|
lt,
|
|
6123
6656
|
ltNum,
|
|
6657
|
+
makeMapAbs,
|
|
6658
|
+
makeSetAbs,
|
|
6124
6659
|
makeSum,
|
|
6660
|
+
mapClearEntries,
|
|
6661
|
+
mapDeleteEntry,
|
|
6125
6662
|
mapElementFallback,
|
|
6663
|
+
mapEntriesAbs,
|
|
6664
|
+
mapGetEntry,
|
|
6665
|
+
mapHasEntry,
|
|
6666
|
+
mapSetEntry,
|
|
6667
|
+
mapSizeAbs,
|
|
6668
|
+
mapValuesAbs,
|
|
6126
6669
|
matchRelIdentLit,
|
|
6127
6670
|
maybeLeak,
|
|
6128
6671
|
mergeAdjacentFixedViews,
|
|
6672
|
+
mergeCollectionArms,
|
|
6129
6673
|
mock,
|
|
6130
6674
|
mod,
|
|
6131
6675
|
mul,
|
|
@@ -6136,9 +6680,11 @@ export {
|
|
|
6136
6680
|
normPath,
|
|
6137
6681
|
not,
|
|
6138
6682
|
notAbs,
|
|
6683
|
+
noteCollectionWrite,
|
|
6139
6684
|
noteDerivationAdd,
|
|
6140
6685
|
noteDerivationJoin,
|
|
6141
6686
|
noteMemberDispatchMiss,
|
|
6687
|
+
noteObjSlotMissing,
|
|
6142
6688
|
notePrimMemberMissing,
|
|
6143
6689
|
noteUnknownMemberMissing,
|
|
6144
6690
|
num,
|
|
@@ -6155,6 +6701,7 @@ export {
|
|
|
6155
6701
|
partial,
|
|
6156
6702
|
phiAnd,
|
|
6157
6703
|
pick,
|
|
6704
|
+
popCollectionArm,
|
|
6158
6705
|
popPhi,
|
|
6159
6706
|
predEquals,
|
|
6160
6707
|
predToString,
|
|
@@ -6164,7 +6711,10 @@ export {
|
|
|
6164
6711
|
projectFlatMapResult,
|
|
6165
6712
|
promoteParamShape,
|
|
6166
6713
|
ptypeof,
|
|
6714
|
+
pushCollectionArm,
|
|
6715
|
+
pushLoopExit,
|
|
6167
6716
|
pushPhi,
|
|
6717
|
+
pushThrowExit,
|
|
6168
6718
|
recordMemberDiag,
|
|
6169
6719
|
refineAbsForRelTrue,
|
|
6170
6720
|
refineDiagCount,
|
|
@@ -6172,6 +6722,7 @@ export {
|
|
|
6172
6722
|
registerBClass,
|
|
6173
6723
|
relationFingerprint,
|
|
6174
6724
|
relationFn,
|
|
6725
|
+
requiredFnArity,
|
|
6175
6726
|
resetAbsCallBudget,
|
|
6176
6727
|
resetCheckSourceMemo,
|
|
6177
6728
|
resetFnFpCache,
|
|
@@ -6183,18 +6734,27 @@ export {
|
|
|
6183
6734
|
resetPhi,
|
|
6184
6735
|
resolveDepPath,
|
|
6185
6736
|
runTranspiled,
|
|
6737
|
+
runWithEvalMissingSlot,
|
|
6738
|
+
runWithLoopExits,
|
|
6186
6739
|
serializeCheckJson,
|
|
6187
6740
|
setAbsAssignCollector,
|
|
6188
6741
|
setAbsCallCollector,
|
|
6189
6742
|
setAbsNodeCollector,
|
|
6190
6743
|
setAbsTruncationCollector,
|
|
6744
|
+
setAddEntry,
|
|
6191
6745
|
setApplyCallbackHost,
|
|
6192
6746
|
setBCallCollector,
|
|
6747
|
+
setClearEntries,
|
|
6748
|
+
setDeleteEntry,
|
|
6193
6749
|
setDerivation,
|
|
6194
6750
|
setDerivationCollector,
|
|
6751
|
+
setElementsAbs,
|
|
6752
|
+
setEvalMissingSlotEnabled,
|
|
6753
|
+
setHasEntry,
|
|
6195
6754
|
setInterfaceDiagCollector,
|
|
6196
6755
|
setMemberDiagCollector,
|
|
6197
6756
|
setRefineDiagCollector,
|
|
6757
|
+
setSizeAbs,
|
|
6198
6758
|
shape,
|
|
6199
6759
|
shapeOfTerm,
|
|
6200
6760
|
shapeOnlyFn,
|
|
@@ -6222,8 +6782,10 @@ export {
|
|
|
6222
6782
|
tagDerivationRoot,
|
|
6223
6783
|
takeInterfaceDiags,
|
|
6224
6784
|
takeInterfaceDiagsSince,
|
|
6785
|
+
takeLoopExits,
|
|
6225
6786
|
takeRefineDiags,
|
|
6226
6787
|
takeRefineDiagsSince,
|
|
6788
|
+
takeThrowExits,
|
|
6227
6789
|
templateMatchesValue,
|
|
6228
6790
|
templatePartsOf,
|
|
6229
6791
|
termDepth,
|