@nudojs/core 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RZOQL6PT.js → chunk-VVSVQKWF.js} +3595 -413
- package/dist/exec.d.ts +1 -1
- package/dist/exec.js +55 -1
- package/dist/{index-OfNo5qlN.d.ts → index-DxjxtxOJ.d.ts} +112 -18
- package/dist/index.d.ts +416 -238
- package/dist/index.js +943 -1357
- 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,15 +72,19 @@ import {
|
|
|
58
72
|
DEFAULT_MAX_LOOP_ITERS,
|
|
59
73
|
MAX_CALL_DEPTH,
|
|
60
74
|
MAX_TOTAL_CALLS,
|
|
75
|
+
NudoReturn,
|
|
61
76
|
NudoThrow,
|
|
77
|
+
abortDerivationSession,
|
|
62
78
|
abs,
|
|
63
79
|
absFunction,
|
|
80
|
+
absShapeKey,
|
|
64
81
|
absTemplateViews,
|
|
65
82
|
absToString,
|
|
66
83
|
add,
|
|
67
84
|
allFixedTextOfViews,
|
|
68
85
|
alphaOf,
|
|
69
86
|
analyzeFn,
|
|
87
|
+
analyzeFnFull,
|
|
70
88
|
and,
|
|
71
89
|
anyVar,
|
|
72
90
|
app,
|
|
@@ -76,20 +94,27 @@ import {
|
|
|
76
94
|
asAbsVal,
|
|
77
95
|
attachFnImpl,
|
|
78
96
|
awaitAbs,
|
|
97
|
+
beginCollectionFork,
|
|
98
|
+
beginDerivationSession,
|
|
79
99
|
betaOf,
|
|
80
100
|
bindImports,
|
|
81
101
|
bool,
|
|
82
102
|
boolLit,
|
|
83
103
|
callAbsMethod,
|
|
104
|
+
callAtFunctionBoundary,
|
|
84
105
|
callFunction,
|
|
106
|
+
callFunctionFull,
|
|
85
107
|
callTranspiledExport,
|
|
86
108
|
callTranspiledExportFull,
|
|
87
109
|
classFromMethods,
|
|
88
110
|
clearBClasses,
|
|
111
|
+
clearCollectionTables,
|
|
89
112
|
cmp,
|
|
90
113
|
coerceAsyncReturn,
|
|
91
114
|
collectAbsExports,
|
|
92
115
|
collectAbsNodeTypes,
|
|
116
|
+
collectionElementJoin,
|
|
117
|
+
collectionExactLen,
|
|
93
118
|
concatString,
|
|
94
119
|
confJoin,
|
|
95
120
|
createHofCollectCtx,
|
|
@@ -101,10 +126,14 @@ import {
|
|
|
101
126
|
defaultLeakBudget,
|
|
102
127
|
defineClass,
|
|
103
128
|
definitelyNotNullishShape,
|
|
129
|
+
derivationChain,
|
|
104
130
|
div,
|
|
105
131
|
emptyEnv,
|
|
106
132
|
emptyPhi,
|
|
133
|
+
endCollectionFork,
|
|
134
|
+
endDerivationSession,
|
|
107
135
|
eq,
|
|
136
|
+
errorBrandAbs,
|
|
108
137
|
evalArrayStatic,
|
|
109
138
|
evalBuiltinInstanceMethod,
|
|
110
139
|
evalBuiltinNew,
|
|
@@ -139,23 +168,31 @@ import {
|
|
|
139
168
|
getBClass,
|
|
140
169
|
getClass,
|
|
141
170
|
getClassChain,
|
|
171
|
+
getDerivation,
|
|
142
172
|
getFnImpl,
|
|
143
173
|
getParseSourceCacheSize,
|
|
144
174
|
getSlot,
|
|
145
175
|
gt,
|
|
146
176
|
gtNum,
|
|
177
|
+
hasDerivationSession,
|
|
147
178
|
implies,
|
|
148
179
|
instanceOf,
|
|
149
180
|
instantiateClass,
|
|
150
181
|
instantiateReturn,
|
|
182
|
+
isArrMutator,
|
|
151
183
|
isDefinitelyFalse,
|
|
152
184
|
isDefinitelyTrue,
|
|
185
|
+
isErrorCtorName,
|
|
186
|
+
isEvalMissingSlotEnabled,
|
|
153
187
|
isExactLit,
|
|
188
|
+
isMapAbs,
|
|
189
|
+
isNudoReturn,
|
|
154
190
|
isNudoThrow,
|
|
155
191
|
isNullishLitAbs,
|
|
156
192
|
isNumPrim,
|
|
157
193
|
isObj,
|
|
158
194
|
isRelFn,
|
|
195
|
+
isSetAbs,
|
|
159
196
|
isStrPrim,
|
|
160
197
|
isTemplateLike,
|
|
161
198
|
joinAbs,
|
|
@@ -174,13 +211,25 @@ import {
|
|
|
174
211
|
lookupMethod,
|
|
175
212
|
lookupMethodWithOwner,
|
|
176
213
|
lookupSuperMethod,
|
|
214
|
+
looseEqAbs,
|
|
177
215
|
lt,
|
|
178
216
|
ltNum,
|
|
217
|
+
makeMapAbs,
|
|
218
|
+
makeSetAbs,
|
|
179
219
|
makeSum,
|
|
220
|
+
mapClearEntries,
|
|
221
|
+
mapDeleteEntry,
|
|
180
222
|
mapElementFallback,
|
|
223
|
+
mapEntriesAbs,
|
|
224
|
+
mapGetEntry,
|
|
225
|
+
mapHasEntry,
|
|
226
|
+
mapSetEntry,
|
|
227
|
+
mapSizeAbs,
|
|
228
|
+
mapValuesAbs,
|
|
181
229
|
matchRelIdentLit,
|
|
182
230
|
maybeLeak,
|
|
183
231
|
mergeAdjacentFixedViews,
|
|
232
|
+
mergeCollectionArms,
|
|
184
233
|
mod,
|
|
185
234
|
mul,
|
|
186
235
|
namespaceNameOf,
|
|
@@ -189,7 +238,11 @@ import {
|
|
|
189
238
|
never,
|
|
190
239
|
not,
|
|
191
240
|
notAbs,
|
|
241
|
+
noteCollectionWrite,
|
|
242
|
+
noteDerivationAdd,
|
|
243
|
+
noteDerivationJoin,
|
|
192
244
|
noteMemberDispatchMiss,
|
|
245
|
+
noteObjSlotMissing,
|
|
193
246
|
notePrimMemberMissing,
|
|
194
247
|
noteUnknownMemberMissing,
|
|
195
248
|
num,
|
|
@@ -202,13 +255,18 @@ import {
|
|
|
202
255
|
pTrue,
|
|
203
256
|
parseSource,
|
|
204
257
|
phiAnd,
|
|
258
|
+
popCollectionArm,
|
|
205
259
|
predEquals,
|
|
206
260
|
predToString,
|
|
207
261
|
predVars,
|
|
208
262
|
projectBrand,
|
|
263
|
+
projectDerivationDsl,
|
|
209
264
|
projectFlatMapResult,
|
|
210
265
|
promoteParamShape,
|
|
211
266
|
ptypeof,
|
|
267
|
+
pushCollectionArm,
|
|
268
|
+
pushLoopExit,
|
|
269
|
+
pushThrowExit,
|
|
212
270
|
recordMemberDiag,
|
|
213
271
|
refineAbsForRelTrue,
|
|
214
272
|
registerBClass,
|
|
@@ -218,13 +276,24 @@ import {
|
|
|
218
276
|
resetLeakCounter,
|
|
219
277
|
resetParseSourceCache,
|
|
220
278
|
runTranspiled,
|
|
279
|
+
runWithEvalMissingSlot,
|
|
280
|
+
runWithLoopExits,
|
|
221
281
|
setAbsAssignCollector,
|
|
222
282
|
setAbsCallCollector,
|
|
223
283
|
setAbsNodeCollector,
|
|
224
284
|
setAbsTruncationCollector,
|
|
285
|
+
setAddEntry,
|
|
225
286
|
setApplyCallbackHost,
|
|
226
287
|
setBCallCollector,
|
|
288
|
+
setClearEntries,
|
|
289
|
+
setDeleteEntry,
|
|
290
|
+
setDerivation,
|
|
291
|
+
setDerivationCollector,
|
|
292
|
+
setElementsAbs,
|
|
293
|
+
setEvalMissingSlotEnabled,
|
|
294
|
+
setHasEntry,
|
|
227
295
|
setMemberDiagCollector,
|
|
296
|
+
setSizeAbs,
|
|
228
297
|
shapeOfTerm,
|
|
229
298
|
shapeOnlyFn,
|
|
230
299
|
shapeToString,
|
|
@@ -241,10 +310,14 @@ import {
|
|
|
241
310
|
substPredAbs,
|
|
242
311
|
superNameOf,
|
|
243
312
|
tagAbsOrigin,
|
|
313
|
+
tagDerivationRoot,
|
|
314
|
+
takeLoopExits,
|
|
315
|
+
takeThrowExits,
|
|
244
316
|
templateMatchesValue,
|
|
245
317
|
templatePartsOf,
|
|
246
318
|
termDepth,
|
|
247
319
|
termEquals,
|
|
320
|
+
termKey,
|
|
248
321
|
termNodes,
|
|
249
322
|
termToString,
|
|
250
323
|
transpile,
|
|
@@ -264,711 +337,7 @@ import {
|
|
|
264
337
|
withExecPhi,
|
|
265
338
|
withVar,
|
|
266
339
|
wrapPromise
|
|
267
|
-
} from "./chunk-
|
|
268
|
-
|
|
269
|
-
// src/refinements/template-predicates.ts
|
|
270
|
-
function isTemplate(tv) {
|
|
271
|
-
return tv.kind === "refined" && Array.isArray(tv.refinement.meta.parts);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// src/type-value.ts
|
|
275
|
-
function createUnion(...members) {
|
|
276
|
-
return simplifyUnion(members);
|
|
277
|
-
}
|
|
278
|
-
var T = {
|
|
279
|
-
literal: (value) => ({ kind: "literal", value }),
|
|
280
|
-
number: { kind: "primitive", type: "number" },
|
|
281
|
-
string: { kind: "primitive", type: "string" },
|
|
282
|
-
boolean: { kind: "primitive", type: "boolean" },
|
|
283
|
-
bigint: { kind: "primitive", type: "bigint" },
|
|
284
|
-
symbol: { kind: "primitive", type: "symbol" },
|
|
285
|
-
null: { kind: "literal", value: null },
|
|
286
|
-
undefined: { kind: "literal", value: void 0 },
|
|
287
|
-
unknown: { kind: "unknown" },
|
|
288
|
-
never: { kind: "never" },
|
|
289
|
-
object: (properties) => ({
|
|
290
|
-
kind: "object",
|
|
291
|
-
properties,
|
|
292
|
-
id: Symbol("object")
|
|
293
|
-
}),
|
|
294
|
-
array: (element) => ({ kind: "array", element }),
|
|
295
|
-
tuple: (elements) => ({ kind: "tuple", elements }),
|
|
296
|
-
promise: (value) => ({ kind: "promise", value }),
|
|
297
|
-
instanceOf: (className, properties = {}) => ({
|
|
298
|
-
kind: "instance",
|
|
299
|
-
className,
|
|
300
|
-
properties
|
|
301
|
-
}),
|
|
302
|
-
union: createUnion,
|
|
303
|
-
fn: (params, body, closure) => ({
|
|
304
|
-
kind: "function",
|
|
305
|
-
params,
|
|
306
|
-
body,
|
|
307
|
-
closure
|
|
308
|
-
}),
|
|
309
|
-
refine: (base, refinement) => ({
|
|
310
|
-
kind: "refined",
|
|
311
|
-
base,
|
|
312
|
-
refinement
|
|
313
|
-
}),
|
|
314
|
-
fnSig: (paramTypes, returnType, throwsType = { kind: "never" }, impl) => {
|
|
315
|
-
const dummy = {
|
|
316
|
-
kind: "function",
|
|
317
|
-
params: paramTypes.map((_p, i) => `_arg${i}`),
|
|
318
|
-
body: { type: "BlockStatement", body: [], directives: [] },
|
|
319
|
-
closure: null
|
|
320
|
-
};
|
|
321
|
-
dummy._signature = { paramTypes, returnType, throwsType, impl };
|
|
322
|
-
return dummy;
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
function typeValueEquals(a, b) {
|
|
326
|
-
if (a.kind !== b.kind) return false;
|
|
327
|
-
if (a.kind === "literal" && b.kind === "literal") return a.value === b.value;
|
|
328
|
-
if (a.kind === "primitive" && b.kind === "primitive") return a.type === b.type;
|
|
329
|
-
if (a.kind === "never" && b.kind === "never") return true;
|
|
330
|
-
if (a.kind === "unknown" && b.kind === "unknown") return true;
|
|
331
|
-
if (a.kind === "refined" && b.kind === "refined") {
|
|
332
|
-
return a.refinement.name === b.refinement.name && typeValueEquals(a.base, b.base);
|
|
333
|
-
}
|
|
334
|
-
if (a.kind === "promise" && b.kind === "promise") {
|
|
335
|
-
return typeValueEquals(a.value, b.value);
|
|
336
|
-
}
|
|
337
|
-
if (a.kind === "instance" && b.kind === "instance") {
|
|
338
|
-
return a.className === b.className;
|
|
339
|
-
}
|
|
340
|
-
if (a.kind === "union" && b.kind === "union") {
|
|
341
|
-
return a.members.length === b.members.length && a.members.every((m, i) => typeValueEquals(m, b.members[i]));
|
|
342
|
-
}
|
|
343
|
-
return a === b;
|
|
344
|
-
}
|
|
345
|
-
function simplifyUnion(members) {
|
|
346
|
-
if (members.length === 0) return T.never;
|
|
347
|
-
if (members.length === 1) return members[0].kind === "never" ? T.never : members[0];
|
|
348
|
-
if (members.length === 2) {
|
|
349
|
-
const a = members[0];
|
|
350
|
-
const b = members[1];
|
|
351
|
-
if (a.kind !== "union" && b.kind !== "union") {
|
|
352
|
-
if (a.kind === "never") return b.kind === "never" ? T.never : b;
|
|
353
|
-
if (b.kind === "never") return a;
|
|
354
|
-
if (typeValueEquals(a, b)) return a;
|
|
355
|
-
if (a.kind === "unknown" || b.kind === "unknown") return T.unknown;
|
|
356
|
-
const aBase = absorbablePrimitiveBase(a);
|
|
357
|
-
if (aBase !== void 0 && typeValueEquals(aBase, b)) return b;
|
|
358
|
-
const bBase = absorbablePrimitiveBase(b);
|
|
359
|
-
if (bBase !== void 0 && typeValueEquals(bBase, a)) return a;
|
|
360
|
-
return { kind: "union", members: [a, b] };
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
const flat = [];
|
|
364
|
-
for (const m of members) {
|
|
365
|
-
if (m.kind === "never") continue;
|
|
366
|
-
if (m.kind === "union") {
|
|
367
|
-
flat.push(...m.members);
|
|
368
|
-
} else {
|
|
369
|
-
flat.push(m);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
const deduped = [];
|
|
373
|
-
for (const m of flat) {
|
|
374
|
-
if (!deduped.some((d) => typeValueEquals(d, m))) {
|
|
375
|
-
deduped.push(m);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
const primitives = deduped.filter((m) => m.kind === "primitive");
|
|
379
|
-
const absorbed = primitives.length > 0 ? deduped.filter((m) => {
|
|
380
|
-
const base = absorbablePrimitiveBase(m);
|
|
381
|
-
return base === void 0 || !primitives.some((p) => typeValueEquals(p, base));
|
|
382
|
-
}) : deduped;
|
|
383
|
-
if (absorbed.length === 0) return T.never;
|
|
384
|
-
if (absorbed.length === 1) return absorbed[0];
|
|
385
|
-
if (absorbed.some((m) => m.kind === "unknown")) return T.unknown;
|
|
386
|
-
return { kind: "union", members: absorbed };
|
|
387
|
-
}
|
|
388
|
-
function absorbablePrimitiveBase(tv) {
|
|
389
|
-
if (tv.kind === "literal") {
|
|
390
|
-
const widened = widenLiteral(tv);
|
|
391
|
-
return widened.kind === "primitive" ? widened : void 0;
|
|
392
|
-
}
|
|
393
|
-
if (isTemplate(tv)) return T.string;
|
|
394
|
-
return void 0;
|
|
395
|
-
}
|
|
396
|
-
function widenLiteral(tv) {
|
|
397
|
-
if (tv.kind !== "literal") return tv;
|
|
398
|
-
const v2 = tv.value;
|
|
399
|
-
if (typeof v2 === "number") return T.number;
|
|
400
|
-
if (typeof v2 === "string") return T.string;
|
|
401
|
-
if (typeof v2 === "boolean") return T.boolean;
|
|
402
|
-
if (typeof v2 === "bigint") return T.bigint;
|
|
403
|
-
if (v2 === null) return T.null;
|
|
404
|
-
if (v2 === void 0) return T.undefined;
|
|
405
|
-
return T.unknown;
|
|
406
|
-
}
|
|
407
|
-
function collapseLiteralUnion(tv, maxLiterals) {
|
|
408
|
-
if (tv.kind !== "union") return tv;
|
|
409
|
-
if (tv.members.length <= maxLiterals) return tv;
|
|
410
|
-
const simplified = simplifyUnion(tv.members);
|
|
411
|
-
if (simplified.kind !== "union") return simplified;
|
|
412
|
-
if (!simplified.members.every((m) => m.kind === "literal")) return simplified;
|
|
413
|
-
const first = widenLiteral(simplified.members[0]);
|
|
414
|
-
if (!simplified.members.every((m) => typeValueEquals(widenLiteral(m), first))) return simplified;
|
|
415
|
-
return first;
|
|
416
|
-
}
|
|
417
|
-
function isSubtypeOf(a, b) {
|
|
418
|
-
if (b.kind === "unknown") return true;
|
|
419
|
-
if (a.kind === "never") return true;
|
|
420
|
-
if (typeValueEquals(a, b)) return true;
|
|
421
|
-
if (a.kind === "literal" && b.kind === "primitive") {
|
|
422
|
-
const v2 = a.value;
|
|
423
|
-
if (b.type === "number" && typeof v2 === "number") return true;
|
|
424
|
-
if (b.type === "string" && typeof v2 === "string") return true;
|
|
425
|
-
if (b.type === "boolean" && typeof v2 === "boolean") return true;
|
|
426
|
-
return false;
|
|
427
|
-
}
|
|
428
|
-
if (a.kind === "literal" && b.kind === "refined") {
|
|
429
|
-
if (!isSubtypeOf(a, b.base)) return false;
|
|
430
|
-
return b.refinement.check ? b.refinement.check(a.value) : false;
|
|
431
|
-
}
|
|
432
|
-
if (a.kind === "refined") {
|
|
433
|
-
if (b.kind === "refined" && a.refinement.name === b.refinement.name) {
|
|
434
|
-
return isSubtypeOf(a.base, b.base);
|
|
435
|
-
}
|
|
436
|
-
return isSubtypeOf(a.base, b);
|
|
437
|
-
}
|
|
438
|
-
if (a.kind === "object" && b.kind === "object") {
|
|
439
|
-
return Object.entries(b.properties).every(
|
|
440
|
-
([k, bv]) => k in a.properties && isSubtypeOf(a.properties[k], bv)
|
|
441
|
-
);
|
|
442
|
-
}
|
|
443
|
-
if (a.kind === "array" && b.kind === "array") {
|
|
444
|
-
return isSubtypeOf(a.element, b.element);
|
|
445
|
-
}
|
|
446
|
-
if (a.kind === "tuple" && b.kind === "tuple") {
|
|
447
|
-
return a.elements.length === b.elements.length && a.elements.every((el, i) => isSubtypeOf(el, b.elements[i]));
|
|
448
|
-
}
|
|
449
|
-
if (a.kind === "tuple" && b.kind === "array") {
|
|
450
|
-
return a.elements.every((el) => isSubtypeOf(el, b.element));
|
|
451
|
-
}
|
|
452
|
-
if (a.kind === "promise" && b.kind === "promise") {
|
|
453
|
-
return isSubtypeOf(a.value, b.value);
|
|
454
|
-
}
|
|
455
|
-
if (a.kind === "instance" && b.kind === "instance") {
|
|
456
|
-
return a.className === b.className || isErrorSubclass(a.className, b.className);
|
|
457
|
-
}
|
|
458
|
-
if (a.kind === "union") {
|
|
459
|
-
return a.members.every((m) => isSubtypeOf(m, b));
|
|
460
|
-
}
|
|
461
|
-
if (b.kind === "union") {
|
|
462
|
-
return b.members.some((m) => isSubtypeOf(a, m));
|
|
463
|
-
}
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
var errorHierarchy = {
|
|
467
|
-
TypeError: "Error",
|
|
468
|
-
SyntaxError: "Error",
|
|
469
|
-
RangeError: "Error",
|
|
470
|
-
ReferenceError: "Error",
|
|
471
|
-
URIError: "Error",
|
|
472
|
-
EvalError: "Error"
|
|
473
|
-
};
|
|
474
|
-
function isErrorSubclass(child, parent) {
|
|
475
|
-
if (child === parent) return true;
|
|
476
|
-
const sup = errorHierarchy[child];
|
|
477
|
-
return sup ? isErrorSubclass(sup, parent) : false;
|
|
478
|
-
}
|
|
479
|
-
function deepCloneTypeValue(tv, idMap) {
|
|
480
|
-
const map = idMap ?? /* @__PURE__ */ new Map();
|
|
481
|
-
if (tv.kind === "object") {
|
|
482
|
-
let newId = map.get(tv.id);
|
|
483
|
-
if (!newId) {
|
|
484
|
-
newId = Symbol("object");
|
|
485
|
-
map.set(tv.id, newId);
|
|
486
|
-
}
|
|
487
|
-
const newProps = {};
|
|
488
|
-
for (const [k, v2] of Object.entries(tv.properties)) {
|
|
489
|
-
newProps[k] = deepCloneTypeValue(v2, map);
|
|
490
|
-
}
|
|
491
|
-
return { kind: "object", properties: newProps, id: newId };
|
|
492
|
-
}
|
|
493
|
-
if (tv.kind === "array") {
|
|
494
|
-
return { kind: "array", element: deepCloneTypeValue(tv.element, map) };
|
|
495
|
-
}
|
|
496
|
-
if (tv.kind === "tuple") {
|
|
497
|
-
return { kind: "tuple", elements: tv.elements.map((e) => deepCloneTypeValue(e, map)) };
|
|
498
|
-
}
|
|
499
|
-
if (tv.kind === "promise") {
|
|
500
|
-
return { kind: "promise", value: deepCloneTypeValue(tv.value, map) };
|
|
501
|
-
}
|
|
502
|
-
if (tv.kind === "instance") {
|
|
503
|
-
const newProps = {};
|
|
504
|
-
for (const [k, v2] of Object.entries(tv.properties)) {
|
|
505
|
-
newProps[k] = deepCloneTypeValue(v2, map);
|
|
506
|
-
}
|
|
507
|
-
return { kind: "instance", className: tv.className, properties: newProps };
|
|
508
|
-
}
|
|
509
|
-
if (tv.kind === "refined") {
|
|
510
|
-
return { kind: "refined", base: deepCloneTypeValue(tv.base, map), refinement: tv.refinement };
|
|
511
|
-
}
|
|
512
|
-
if (tv.kind === "union") {
|
|
513
|
-
return simplifyUnion(tv.members.map((m) => deepCloneTypeValue(m, map)));
|
|
514
|
-
}
|
|
515
|
-
return tv;
|
|
516
|
-
}
|
|
517
|
-
function mergeObjectProperties(a, b) {
|
|
518
|
-
const allKeys = /* @__PURE__ */ new Set([...Object.keys(a.properties), ...Object.keys(b.properties)]);
|
|
519
|
-
const merged = {};
|
|
520
|
-
for (const k of allKeys) {
|
|
521
|
-
const av = a.properties[k];
|
|
522
|
-
const bv = b.properties[k];
|
|
523
|
-
if (av && bv) {
|
|
524
|
-
merged[k] = simplifyUnion([av, bv]);
|
|
525
|
-
} else {
|
|
526
|
-
merged[k] = av ?? bv;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
return { kind: "object", properties: merged, id: a.id };
|
|
530
|
-
}
|
|
531
|
-
function typeValueToString(tv) {
|
|
532
|
-
return typeValueToStringInner(tv, /* @__PURE__ */ new Set());
|
|
533
|
-
}
|
|
534
|
-
function typeValueToStringInner(tv, seen, depth = 0) {
|
|
535
|
-
if (depth > 48) return "\u2026";
|
|
536
|
-
const recur = (inner) => {
|
|
537
|
-
if (inner && typeof inner === "object") {
|
|
538
|
-
if (seen.has(inner)) return "\u2026";
|
|
539
|
-
seen.add(inner);
|
|
540
|
-
const out = typeValueToStringInner(inner, seen, depth + 1);
|
|
541
|
-
seen.delete(inner);
|
|
542
|
-
return out;
|
|
543
|
-
}
|
|
544
|
-
return typeValueToStringInner(inner, seen, depth + 1);
|
|
545
|
-
};
|
|
546
|
-
switch (tv.kind) {
|
|
547
|
-
case "literal": {
|
|
548
|
-
const v2 = tv.value;
|
|
549
|
-
if (v2 === null) return "null";
|
|
550
|
-
if (v2 === void 0) return "undefined";
|
|
551
|
-
if (typeof v2 === "string") return JSON.stringify(v2);
|
|
552
|
-
return String(v2);
|
|
553
|
-
}
|
|
554
|
-
case "primitive":
|
|
555
|
-
return tv.type;
|
|
556
|
-
case "refined":
|
|
557
|
-
return tv.refinement.name;
|
|
558
|
-
case "object": {
|
|
559
|
-
const entries = Object.entries(tv.properties);
|
|
560
|
-
if (entries.length === 0) return "{}";
|
|
561
|
-
const inner = entries.map(([k, v2]) => `${k}: ${recur(v2)}`).join(", ");
|
|
562
|
-
return `{ ${inner} }`;
|
|
563
|
-
}
|
|
564
|
-
case "array":
|
|
565
|
-
return `${recur(tv.element)}[]`;
|
|
566
|
-
case "tuple": {
|
|
567
|
-
const inner = tv.elements.map(recur).join(", ");
|
|
568
|
-
return `[${inner}]`;
|
|
569
|
-
}
|
|
570
|
-
case "function": {
|
|
571
|
-
const sig = getFnSig(tv);
|
|
572
|
-
if (sig) {
|
|
573
|
-
const params2 = sig.paramTypes.map((p, i) => `${tv.params[i]}: ${recur(p)}`).join(", ");
|
|
574
|
-
return `(${params2}) => ${recur(sig.returnType)}`;
|
|
575
|
-
}
|
|
576
|
-
const params = tv.params.join(", ");
|
|
577
|
-
return `(${params}) => ...`;
|
|
578
|
-
}
|
|
579
|
-
case "promise":
|
|
580
|
-
return `Promise<${recur(tv.value)}>`;
|
|
581
|
-
case "instance": {
|
|
582
|
-
const entries = Object.entries(tv.properties);
|
|
583
|
-
if (entries.length === 0) return tv.className;
|
|
584
|
-
const inner = entries.map(([k, v2]) => `${k}: ${recur(v2)}`).join(", ");
|
|
585
|
-
return `${tv.className} { ${inner} }`;
|
|
586
|
-
}
|
|
587
|
-
case "union": {
|
|
588
|
-
return tv.members.map(recur).join(" | ");
|
|
589
|
-
}
|
|
590
|
-
case "never":
|
|
591
|
-
return "never";
|
|
592
|
-
case "unknown":
|
|
593
|
-
return "unknown";
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
function narrowType(tv, predicate) {
|
|
597
|
-
if (tv.kind === "union") {
|
|
598
|
-
return simplifyUnion(tv.members.filter(predicate));
|
|
599
|
-
}
|
|
600
|
-
return predicate(tv) ? tv : T.never;
|
|
601
|
-
}
|
|
602
|
-
function subtractType(tv, predicate) {
|
|
603
|
-
return narrowType(tv, (m) => !predicate(m));
|
|
604
|
-
}
|
|
605
|
-
function getPrimitiveTypeOf(tv) {
|
|
606
|
-
if (tv.kind === "literal") {
|
|
607
|
-
const v2 = tv.value;
|
|
608
|
-
if (v2 === null) return "object";
|
|
609
|
-
return typeof v2;
|
|
610
|
-
}
|
|
611
|
-
if (tv.kind === "primitive") return tv.type;
|
|
612
|
-
if (tv.kind === "refined") return getPrimitiveTypeOf(tv.base);
|
|
613
|
-
if (tv.kind === "object") return "object";
|
|
614
|
-
if (tv.kind === "array" || tv.kind === "tuple") return "object";
|
|
615
|
-
if (tv.kind === "function") return "function";
|
|
616
|
-
if (tv.kind === "promise") return "object";
|
|
617
|
-
if (tv.kind === "instance") return "object";
|
|
618
|
-
return void 0;
|
|
619
|
-
}
|
|
620
|
-
function getRefinedBase(tv) {
|
|
621
|
-
return tv.kind === "refined" ? getRefinedBase(tv.base) : tv;
|
|
622
|
-
}
|
|
623
|
-
function isFnSig(tv) {
|
|
624
|
-
return tv.kind === "function" && "_signature" in tv;
|
|
625
|
-
}
|
|
626
|
-
function getFnSig(tv) {
|
|
627
|
-
if (tv.kind === "function" && "_signature" in tv) {
|
|
628
|
-
return tv._signature;
|
|
629
|
-
}
|
|
630
|
-
return void 0;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
// src/refinements/range.ts
|
|
634
|
-
function formatRangeName(meta) {
|
|
635
|
-
const parts = [];
|
|
636
|
-
if (meta.integer) parts.push("integer");
|
|
637
|
-
else parts.push("number");
|
|
638
|
-
const constraints = [];
|
|
639
|
-
if (meta.min != null) {
|
|
640
|
-
constraints.push(meta.minExclusive ? `> ${meta.min}` : `>= ${meta.min}`);
|
|
641
|
-
}
|
|
642
|
-
if (meta.max != null) {
|
|
643
|
-
constraints.push(meta.maxExclusive ? `< ${meta.max}` : `<= ${meta.max}`);
|
|
644
|
-
}
|
|
645
|
-
if (constraints.length > 0) parts.push(`(${constraints.join(", ")})`);
|
|
646
|
-
return parts.join(" ");
|
|
647
|
-
}
|
|
648
|
-
function createRangeRefinement(meta) {
|
|
649
|
-
return {
|
|
650
|
-
name: formatRangeName(meta),
|
|
651
|
-
meta: { ...meta },
|
|
652
|
-
check(value) {
|
|
653
|
-
if (typeof value !== "number") return false;
|
|
654
|
-
if (meta.integer && !Number.isInteger(value)) return false;
|
|
655
|
-
if (meta.min != null) {
|
|
656
|
-
if (meta.minExclusive ? value <= meta.min : value < meta.min) return false;
|
|
657
|
-
}
|
|
658
|
-
if (meta.max != null) {
|
|
659
|
-
if (meta.maxExclusive ? value >= meta.max : value > meta.max) return false;
|
|
660
|
-
}
|
|
661
|
-
return true;
|
|
662
|
-
},
|
|
663
|
-
ops: {
|
|
664
|
-
">="(self, other) {
|
|
665
|
-
const m = getRangeMeta(self);
|
|
666
|
-
if (!m || other.kind !== "literal" || typeof other.value !== "number") return void 0;
|
|
667
|
-
if (m.min != null) {
|
|
668
|
-
if (m.minExclusive && m.min >= other.value) return T.literal(true);
|
|
669
|
-
if (!m.minExclusive && m.min >= other.value) return T.literal(true);
|
|
670
|
-
}
|
|
671
|
-
if (m.max != null) {
|
|
672
|
-
if (m.maxExclusive && m.max <= other.value) return T.literal(false);
|
|
673
|
-
if (!m.maxExclusive && m.max < other.value) return T.literal(false);
|
|
674
|
-
}
|
|
675
|
-
return void 0;
|
|
676
|
-
},
|
|
677
|
-
">"(self, other) {
|
|
678
|
-
const m = getRangeMeta(self);
|
|
679
|
-
if (!m || other.kind !== "literal" || typeof other.value !== "number") return void 0;
|
|
680
|
-
if (m.min != null) {
|
|
681
|
-
if (m.minExclusive && m.min >= other.value) return T.literal(true);
|
|
682
|
-
if (!m.minExclusive && m.min > other.value) return T.literal(true);
|
|
683
|
-
}
|
|
684
|
-
if (m.max != null) {
|
|
685
|
-
if (m.max <= other.value) return T.literal(false);
|
|
686
|
-
}
|
|
687
|
-
return void 0;
|
|
688
|
-
},
|
|
689
|
-
"<="(self, other) {
|
|
690
|
-
const m = getRangeMeta(self);
|
|
691
|
-
if (!m || other.kind !== "literal" || typeof other.value !== "number") return void 0;
|
|
692
|
-
if (m.max != null) {
|
|
693
|
-
if (m.maxExclusive && m.max <= other.value) return T.literal(true);
|
|
694
|
-
if (!m.maxExclusive && m.max <= other.value) return T.literal(true);
|
|
695
|
-
}
|
|
696
|
-
if (m.min != null) {
|
|
697
|
-
if (m.minExclusive && m.min >= other.value) return T.literal(false);
|
|
698
|
-
if (!m.minExclusive && m.min > other.value) return T.literal(false);
|
|
699
|
-
}
|
|
700
|
-
return void 0;
|
|
701
|
-
},
|
|
702
|
-
"<"(self, other) {
|
|
703
|
-
const m = getRangeMeta(self);
|
|
704
|
-
if (!m || other.kind !== "literal" || typeof other.value !== "number") return void 0;
|
|
705
|
-
if (m.max != null) {
|
|
706
|
-
if (m.maxExclusive && m.max <= other.value) return T.literal(true);
|
|
707
|
-
if (!m.maxExclusive && m.max < other.value) return T.literal(true);
|
|
708
|
-
}
|
|
709
|
-
if (m.min != null) {
|
|
710
|
-
if (m.min >= other.value) return T.literal(false);
|
|
711
|
-
}
|
|
712
|
-
return void 0;
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
function createRange(meta) {
|
|
718
|
-
if (meta.min != null && meta.max != null && meta.min === meta.max && !meta.minExclusive && !meta.maxExclusive) {
|
|
719
|
-
return T.literal(meta.min);
|
|
720
|
-
}
|
|
721
|
-
return T.refine(T.number, createRangeRefinement(meta));
|
|
722
|
-
}
|
|
723
|
-
function isRange(tv) {
|
|
724
|
-
if (tv.kind !== "refined") return false;
|
|
725
|
-
const m = tv.refinement.meta;
|
|
726
|
-
return m.min !== void 0 || m.max !== void 0 || m.minExclusive !== void 0 || m.maxExclusive !== void 0 || m.integer !== void 0;
|
|
727
|
-
}
|
|
728
|
-
function getRangeMeta(tv) {
|
|
729
|
-
if (tv.kind !== "refined") return void 0;
|
|
730
|
-
const m = tv.refinement.meta;
|
|
731
|
-
if (m.min !== void 0 || m.max !== void 0 || m.minExclusive !== void 0 || m.maxExclusive !== void 0 || m.integer !== void 0) {
|
|
732
|
-
return m;
|
|
733
|
-
}
|
|
734
|
-
return void 0;
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
// src/refinements/template.ts
|
|
738
|
-
function tvTemplateViews(parts) {
|
|
739
|
-
return viewTemplateParts(
|
|
740
|
-
parts,
|
|
741
|
-
(p) => p.kind === "literal" && typeof p.value === "string" ? { fixed: p.value } : { render: typeValueToString(p) }
|
|
742
|
-
);
|
|
743
|
-
}
|
|
744
|
-
function formatTemplateName(parts) {
|
|
745
|
-
return formatTemplateNameViews(tvTemplateViews(parts));
|
|
746
|
-
}
|
|
747
|
-
function normalizeParts(parts) {
|
|
748
|
-
const merged = mergeAdjacentFixedViews(tvTemplateViews(parts), (text) => ({
|
|
749
|
-
fixed: text,
|
|
750
|
-
render: text,
|
|
751
|
-
part: T.literal(text)
|
|
752
|
-
}));
|
|
753
|
-
const out = [];
|
|
754
|
-
for (const { part: p } of merged) {
|
|
755
|
-
const last = out[out.length - 1];
|
|
756
|
-
if (last?.kind === "primitive" && last.type === "string" && p.kind === "primitive" && p.type === "string") {
|
|
757
|
-
} else {
|
|
758
|
-
out.push(p);
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
return out;
|
|
762
|
-
}
|
|
763
|
-
function createTemplateRefinement(parts) {
|
|
764
|
-
return {
|
|
765
|
-
name: formatTemplateName(parts),
|
|
766
|
-
meta: { parts },
|
|
767
|
-
check(value) {
|
|
768
|
-
if (typeof value !== "string") return false;
|
|
769
|
-
return templateMatchesValue(value, tvTemplateViews(parts));
|
|
770
|
-
},
|
|
771
|
-
ops: {
|
|
772
|
-
"+"(self, other) {
|
|
773
|
-
return concatTemplates(self, other);
|
|
774
|
-
}
|
|
775
|
-
},
|
|
776
|
-
methods: {
|
|
777
|
-
startsWith(_self, args) {
|
|
778
|
-
const arg = args[0];
|
|
779
|
-
if (arg?.kind !== "literal" || typeof arg.value !== "string") return void 0;
|
|
780
|
-
const parts2 = _self.refinement.meta.parts;
|
|
781
|
-
const d = decideStartsWith(knownPrefixOfViews(tvTemplateViews(parts2)), arg.value);
|
|
782
|
-
return d === "unknown" ? void 0 : T.literal(d);
|
|
783
|
-
},
|
|
784
|
-
endsWith(_self, args) {
|
|
785
|
-
const arg = args[0];
|
|
786
|
-
if (arg?.kind !== "literal" || typeof arg.value !== "string") return void 0;
|
|
787
|
-
const parts2 = _self.refinement.meta.parts;
|
|
788
|
-
const d = decideEndsWith(knownSuffixOfViews(tvTemplateViews(parts2)), arg.value);
|
|
789
|
-
return d === "unknown" ? void 0 : T.literal(d);
|
|
790
|
-
},
|
|
791
|
-
includes(_self, args) {
|
|
792
|
-
const arg = args[0];
|
|
793
|
-
if (arg?.kind !== "literal" || typeof arg.value !== "string") return void 0;
|
|
794
|
-
const parts2 = _self.refinement.meta.parts;
|
|
795
|
-
const d = decideIncludes(allFixedTextOfViews(tvTemplateViews(parts2)), arg.value);
|
|
796
|
-
return d === "unknown" ? void 0 : T.literal(d);
|
|
797
|
-
}
|
|
798
|
-
},
|
|
799
|
-
properties: {
|
|
800
|
-
length(_self) {
|
|
801
|
-
const parts2 = _self.refinement.meta.parts;
|
|
802
|
-
const hasAbstract = parts2.some((p) => p.kind !== "literal");
|
|
803
|
-
if (!hasAbstract) return void 0;
|
|
804
|
-
return createRange({ min: allFixedTextOfViews(tvTemplateViews(parts2)).length });
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
};
|
|
808
|
-
}
|
|
809
|
-
function createTemplate(parts) {
|
|
810
|
-
const normalized = normalizeParts(parts);
|
|
811
|
-
if (normalized.length === 1 && normalized[0].kind === "literal") {
|
|
812
|
-
return normalized[0];
|
|
813
|
-
}
|
|
814
|
-
if (normalized.length === 1 && normalized[0].kind === "primitive" && normalized[0].type === "string") {
|
|
815
|
-
return T.string;
|
|
816
|
-
}
|
|
817
|
-
return T.refine(T.string, createTemplateRefinement(normalized));
|
|
818
|
-
}
|
|
819
|
-
function getTemplateParts(tv) {
|
|
820
|
-
if (tv.kind === "refined" && Array.isArray(tv.refinement.meta.parts)) {
|
|
821
|
-
return tv.refinement.meta.parts;
|
|
822
|
-
}
|
|
823
|
-
return void 0;
|
|
824
|
-
}
|
|
825
|
-
function concatTemplates(left, right) {
|
|
826
|
-
const leftParts = getTemplateParts(left) ?? [left];
|
|
827
|
-
const rightParts = getTemplateParts(right) ?? [right];
|
|
828
|
-
return createTemplate([...leftParts, ...rightParts]);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
// src/ops.ts
|
|
832
|
-
function bothLiteral(l, r) {
|
|
833
|
-
if (l.kind === "literal" && r.kind === "literal") {
|
|
834
|
-
return { lv: l.value, rv: r.value };
|
|
835
|
-
}
|
|
836
|
-
return null;
|
|
837
|
-
}
|
|
838
|
-
function isNullishLiteral(tv) {
|
|
839
|
-
return tv.kind === "literal" && (tv.value === null || tv.value === void 0);
|
|
840
|
-
}
|
|
841
|
-
function definitelyNotNullish(tv) {
|
|
842
|
-
switch (tv.kind) {
|
|
843
|
-
case "literal":
|
|
844
|
-
return tv.value !== null && tv.value !== void 0;
|
|
845
|
-
case "primitive":
|
|
846
|
-
case "object":
|
|
847
|
-
case "array":
|
|
848
|
-
case "tuple":
|
|
849
|
-
case "function":
|
|
850
|
-
case "instance":
|
|
851
|
-
case "promise":
|
|
852
|
-
return true;
|
|
853
|
-
case "refined":
|
|
854
|
-
return definitelyNotNullish(tv.base);
|
|
855
|
-
case "union":
|
|
856
|
-
return tv.members.every(definitelyNotNullish);
|
|
857
|
-
default:
|
|
858
|
-
return false;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
var Ops = {
|
|
862
|
-
add(left, right) {
|
|
863
|
-
const lit3 = bothLiteral(left, right);
|
|
864
|
-
if (lit3) {
|
|
865
|
-
return T.literal(lit3.lv + lit3.rv);
|
|
866
|
-
}
|
|
867
|
-
const leftIsString = isSubtypeOf(left, T.string) || isTemplate(left);
|
|
868
|
-
const rightIsString = isSubtypeOf(right, T.string) || isTemplate(right);
|
|
869
|
-
if (leftIsString || rightIsString) {
|
|
870
|
-
const hasStructure = left.kind === "literal" && typeof left.value === "string" || right.kind === "literal" && typeof right.value === "string" || isTemplate(left) || isTemplate(right);
|
|
871
|
-
if (hasStructure) {
|
|
872
|
-
return concatTemplates(left, right);
|
|
873
|
-
}
|
|
874
|
-
return T.string;
|
|
875
|
-
}
|
|
876
|
-
if (isSubtypeOf(left, T.number) && isSubtypeOf(right, T.number)) {
|
|
877
|
-
return T.number;
|
|
878
|
-
}
|
|
879
|
-
return T.union(T.number, T.string);
|
|
880
|
-
},
|
|
881
|
-
strictEq(left, right) {
|
|
882
|
-
const lit3 = bothLiteral(left, right);
|
|
883
|
-
if (lit3) return T.literal(lit3.lv === lit3.rv);
|
|
884
|
-
if (isNullishLiteral(right) && definitelyNotNullish(left) || isNullishLiteral(left) && definitelyNotNullish(right)) {
|
|
885
|
-
return T.literal(false);
|
|
886
|
-
}
|
|
887
|
-
return T.boolean;
|
|
888
|
-
},
|
|
889
|
-
strictNeq(left, right) {
|
|
890
|
-
const lit3 = bothLiteral(left, right);
|
|
891
|
-
if (lit3) return T.literal(lit3.lv !== lit3.rv);
|
|
892
|
-
if (isNullishLiteral(right) && definitelyNotNullish(left) || isNullishLiteral(left) && definitelyNotNullish(right)) {
|
|
893
|
-
return T.literal(true);
|
|
894
|
-
}
|
|
895
|
-
return T.boolean;
|
|
896
|
-
},
|
|
897
|
-
gt(left, right) {
|
|
898
|
-
const lit3 = bothLiteral(left, right);
|
|
899
|
-
if (lit3) return T.literal(lit3.lv > lit3.rv);
|
|
900
|
-
return T.boolean;
|
|
901
|
-
},
|
|
902
|
-
lt(left, right) {
|
|
903
|
-
const lit3 = bothLiteral(left, right);
|
|
904
|
-
if (lit3) return T.literal(lit3.lv < lit3.rv);
|
|
905
|
-
return T.boolean;
|
|
906
|
-
},
|
|
907
|
-
gte(left, right) {
|
|
908
|
-
const lit3 = bothLiteral(left, right);
|
|
909
|
-
if (lit3) return T.literal(lit3.lv >= lit3.rv);
|
|
910
|
-
return T.boolean;
|
|
911
|
-
},
|
|
912
|
-
lte(left, right) {
|
|
913
|
-
const lit3 = bothLiteral(left, right);
|
|
914
|
-
if (lit3) return T.literal(lit3.lv <= lit3.rv);
|
|
915
|
-
return T.boolean;
|
|
916
|
-
},
|
|
917
|
-
not(operand) {
|
|
918
|
-
if (operand.kind === "literal") return T.literal(!operand.value);
|
|
919
|
-
return T.boolean;
|
|
920
|
-
}
|
|
921
|
-
};
|
|
922
|
-
var binaryOpMap = {
|
|
923
|
-
"+": Ops.add,
|
|
924
|
-
"===": Ops.strictEq,
|
|
925
|
-
"!==": Ops.strictNeq,
|
|
926
|
-
">": Ops.gt,
|
|
927
|
-
"<": Ops.lt,
|
|
928
|
-
">=": Ops.gte,
|
|
929
|
-
"<=": Ops.lte
|
|
930
|
-
};
|
|
931
|
-
function applyBinaryOp(op, left, right) {
|
|
932
|
-
const fn2 = binaryOpMap[op];
|
|
933
|
-
if (!fn2) return T.unknown;
|
|
934
|
-
return fn2(left, right);
|
|
935
|
-
}
|
|
936
|
-
function dispatchBinaryOp(op, left, right) {
|
|
937
|
-
if (left.kind === "refined" && left.refinement.ops?.[op]) {
|
|
938
|
-
const result = left.refinement.ops[op](left, right);
|
|
939
|
-
if (result !== void 0) return result;
|
|
940
|
-
}
|
|
941
|
-
if (right.kind === "refined" && right.refinement.ops?.[op]) {
|
|
942
|
-
const result = right.refinement.ops[op](right, left);
|
|
943
|
-
if (result !== void 0) return result;
|
|
944
|
-
}
|
|
945
|
-
const baseLeft = left.kind === "refined" ? left.base : left;
|
|
946
|
-
const baseRight = right.kind === "refined" ? right.base : right;
|
|
947
|
-
if (baseLeft !== left || baseRight !== right) {
|
|
948
|
-
return dispatchBinaryOp(op, baseLeft, baseRight);
|
|
949
|
-
}
|
|
950
|
-
return applyBinaryOp(op, left, right);
|
|
951
|
-
}
|
|
952
|
-
function dispatchMethod(receiver, name, args) {
|
|
953
|
-
if (receiver.kind === "refined" && receiver.refinement.methods?.[name]) {
|
|
954
|
-
const result = receiver.refinement.methods[name](receiver, args);
|
|
955
|
-
if (result !== void 0) return result;
|
|
956
|
-
}
|
|
957
|
-
if (receiver.kind === "refined") {
|
|
958
|
-
return dispatchMethod(receiver.base, name, args);
|
|
959
|
-
}
|
|
960
|
-
return void 0;
|
|
961
|
-
}
|
|
962
|
-
function dispatchProperty(receiver, name) {
|
|
963
|
-
if (receiver.kind === "refined" && receiver.refinement.properties?.[name]) {
|
|
964
|
-
const result = receiver.refinement.properties[name](receiver);
|
|
965
|
-
if (result !== void 0) return result;
|
|
966
|
-
}
|
|
967
|
-
if (receiver.kind === "refined") {
|
|
968
|
-
return dispatchProperty(receiver.base, name);
|
|
969
|
-
}
|
|
970
|
-
return void 0;
|
|
971
|
-
}
|
|
340
|
+
} from "./chunk-VVSVQKWF.js";
|
|
972
341
|
|
|
973
342
|
// src/environment.ts
|
|
974
343
|
function createEnvironment(parent, bindings = /* @__PURE__ */ new Map()) {
|
|
@@ -978,7 +347,7 @@ function createEnvironment(parent, bindings = /* @__PURE__ */ new Map()) {
|
|
|
978
347
|
const val = store.get(name);
|
|
979
348
|
if (val !== void 0) return val;
|
|
980
349
|
if (parent) return parent.lookup(name);
|
|
981
|
-
return
|
|
350
|
+
return unknown;
|
|
982
351
|
},
|
|
983
352
|
bind(name, value) {
|
|
984
353
|
store.set(name, value);
|
|
@@ -1041,7 +410,8 @@ stub.onSecondCall = function(value) {
|
|
|
1041
410
|
return { kind: "mock-helper", onSecondCallValue: value };
|
|
1042
411
|
};
|
|
1043
412
|
stub.withArgs = function(...args) {
|
|
1044
|
-
|
|
413
|
+
const unknownAbs = { shape: { k: "unknown" }, conf: "partial" };
|
|
414
|
+
return { kind: "mock-helper", withArgsCases: [{ args, returnValue: unknownAbs }] };
|
|
1045
415
|
};
|
|
1046
416
|
stub.callsFake = function(fn2) {
|
|
1047
417
|
return { kind: "mock-helper", callsFakeImpl: fn2 };
|
|
@@ -1055,57 +425,6 @@ spy.returns = function(value) {
|
|
|
1055
425
|
function mock() {
|
|
1056
426
|
return { kind: "mock-helper" };
|
|
1057
427
|
}
|
|
1058
|
-
function mockArgMatches(declared, actual) {
|
|
1059
|
-
if (actual === void 0) return false;
|
|
1060
|
-
if (typeValueEquals(declared, actual)) return true;
|
|
1061
|
-
if (declared.kind === "primitive" && actual.kind === "literal") {
|
|
1062
|
-
const t = typeof actual.value;
|
|
1063
|
-
return declared.type === "number" && t === "number" || declared.type === "string" && t === "string" || declared.type === "boolean" && t === "boolean" || declared.type === "bigint" && t === "bigint" || declared.type === "symbol" && t === "symbol";
|
|
1064
|
-
}
|
|
1065
|
-
return false;
|
|
1066
|
-
}
|
|
1067
|
-
function mockHelperToTypeValue(helper, env) {
|
|
1068
|
-
if (helper.callsFakeImpl) {
|
|
1069
|
-
if (helper.callsFakeImpl.kind === "function") {
|
|
1070
|
-
return helper.callsFakeImpl;
|
|
1071
|
-
}
|
|
1072
|
-
const plain = T.fn(["...args"], { type: "BlockStatement", body: [] }, env);
|
|
1073
|
-
plain._directReturn = helper.callsFakeImpl;
|
|
1074
|
-
return plain;
|
|
1075
|
-
}
|
|
1076
|
-
let defaultReturn;
|
|
1077
|
-
if (helper.resolvedValue) {
|
|
1078
|
-
defaultReturn = T.promise(helper.resolvedValue);
|
|
1079
|
-
} else if (helper.rejectedValue) {
|
|
1080
|
-
defaultReturn = T.never;
|
|
1081
|
-
} else if (helper.returnValue) {
|
|
1082
|
-
defaultReturn = helper.returnValue;
|
|
1083
|
-
} else if (helper.onFirstCallValue) {
|
|
1084
|
-
defaultReturn = helper.onFirstCallValue;
|
|
1085
|
-
} else {
|
|
1086
|
-
defaultReturn = T.unknown;
|
|
1087
|
-
}
|
|
1088
|
-
if (helper.withArgsCases?.length) {
|
|
1089
|
-
const cases = helper.withArgsCases;
|
|
1090
|
-
return T.fnSig(
|
|
1091
|
-
cases[0].args.map(() => T.unknown),
|
|
1092
|
-
T.union(...cases.map((c) => c.returnValue), defaultReturn),
|
|
1093
|
-
T.never,
|
|
1094
|
-
(args) => {
|
|
1095
|
-
for (const c of cases) {
|
|
1096
|
-
if (c.args.every((a, i) => mockArgMatches(a, args[i]))) {
|
|
1097
|
-
return c.returnValue;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
return defaultReturn;
|
|
1101
|
-
}
|
|
1102
|
-
);
|
|
1103
|
-
}
|
|
1104
|
-
const body = { type: "BlockStatement", body: [] };
|
|
1105
|
-
const fn2 = T.fn(["...args"], body, env);
|
|
1106
|
-
fn2._directReturn = defaultReturn;
|
|
1107
|
-
return fn2;
|
|
1108
|
-
}
|
|
1109
428
|
|
|
1110
429
|
// src/algebra/phi.ts
|
|
1111
430
|
var phiStack = [pTrue];
|
|
@@ -1147,6 +466,9 @@ function formatAbs(a, opts = {}) {
|
|
|
1147
466
|
parts.push(`where ${predToString(a.pred)}`);
|
|
1148
467
|
}
|
|
1149
468
|
parts.push(`#${a.conf}`);
|
|
469
|
+
if (a.pathNote) {
|
|
470
|
+
parts.push(a.pathNote);
|
|
471
|
+
}
|
|
1150
472
|
return parts.join(" ");
|
|
1151
473
|
}
|
|
1152
474
|
function formatShapeSlot(a) {
|
|
@@ -1163,8 +485,10 @@ function formatShape(a) {
|
|
|
1163
485
|
return "never";
|
|
1164
486
|
case "any":
|
|
1165
487
|
return "any";
|
|
1166
|
-
case "unknown":
|
|
488
|
+
case "unknown": {
|
|
489
|
+
if (a.term?.op === "lit" && a.term.value === void 0) return "undefined";
|
|
1167
490
|
return "unknown";
|
|
491
|
+
}
|
|
1168
492
|
case "prim": {
|
|
1169
493
|
const lv = litValue(a);
|
|
1170
494
|
if (typeof lv === "number" && !Number.isFinite(lv)) return String(lv);
|
|
@@ -1311,6 +635,9 @@ function string() {
|
|
|
1311
635
|
function boolean() {
|
|
1312
636
|
return makeBuilder("boolean", []);
|
|
1313
637
|
}
|
|
638
|
+
function any() {
|
|
639
|
+
return makeBuilder(void 0, []);
|
|
640
|
+
}
|
|
1314
641
|
function array(item) {
|
|
1315
642
|
if (!isConstraint(item))
|
|
1316
643
|
throw new Error("nudo: array(item) \u671F\u671B\u7EA6\u675F\u503C\uFF08number()/string()/\u2026\u6216\u5176\u7EC4\u5408\u5B50\uFF09");
|
|
@@ -1541,6 +868,46 @@ function constraintToEntryAbs(c, paramName) {
|
|
|
1541
868
|
}
|
|
1542
869
|
return constraintOnTermAbs(c, t);
|
|
1543
870
|
}
|
|
871
|
+
function memberLitValue(m) {
|
|
872
|
+
const leaves = [];
|
|
873
|
+
const visit = (p2) => {
|
|
874
|
+
if (p2.op === "and") {
|
|
875
|
+
p2.args.forEach(visit);
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
leaves.push(p2);
|
|
879
|
+
};
|
|
880
|
+
m.preds.forEach(visit);
|
|
881
|
+
if (leaves.length !== 1) return void 0;
|
|
882
|
+
const p = leaves[0];
|
|
883
|
+
if (p.op !== "eq") return void 0;
|
|
884
|
+
if (p.a.op === "var" && p.b.op === "lit") return p.b.value;
|
|
885
|
+
if (p.b.op === "var" && p.a.op === "lit") return p.a.value;
|
|
886
|
+
return void 0;
|
|
887
|
+
}
|
|
888
|
+
function samePrimLiteralUnionAbs(members, t) {
|
|
889
|
+
if (members.length === 0) return void 0;
|
|
890
|
+
const values = [];
|
|
891
|
+
let prim;
|
|
892
|
+
for (const m of members) {
|
|
893
|
+
const v2 = memberLitValue(m);
|
|
894
|
+
if (v2 === void 0) return void 0;
|
|
895
|
+
if (v2 === null) return void 0;
|
|
896
|
+
const mp = m.prim ?? (typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : "boolean");
|
|
897
|
+
if (prim === void 0) prim = mp;
|
|
898
|
+
else if (prim !== mp) return void 0;
|
|
899
|
+
values.push(v2);
|
|
900
|
+
}
|
|
901
|
+
if (prim === void 0) return void 0;
|
|
902
|
+
const uniq = [];
|
|
903
|
+
for (const v2 of values) {
|
|
904
|
+
if (!uniq.some((u) => Object.is(u, v2))) uniq.push(v2);
|
|
905
|
+
}
|
|
906
|
+
const disj = or(
|
|
907
|
+
...uniq.map((v2) => eq(t, lit(v2)))
|
|
908
|
+
);
|
|
909
|
+
return abs({ k: "prim", type: prim }, t, disj, "path");
|
|
910
|
+
}
|
|
1544
911
|
function constraintOnTermAbs(c, t) {
|
|
1545
912
|
if (c.fields) {
|
|
1546
913
|
const slots = {};
|
|
@@ -1553,6 +920,8 @@ function constraintOnTermAbs(c, t) {
|
|
|
1553
920
|
return abs({ k: "obj", slots }, t, void 0, "path");
|
|
1554
921
|
}
|
|
1555
922
|
if (c.members) {
|
|
923
|
+
const litUnion = samePrimLiteralUnionAbs(c.members, t);
|
|
924
|
+
if (litUnion) return litUnion;
|
|
1556
925
|
const joined = c.members.map((m) => constraintOnTermAbs(m, t)).reduce((a, b) => joinAbs(a, b));
|
|
1557
926
|
if (joined.shape.k === "prim" && joined.pred === void 0 && c.members.every((m) => m.prim === joined.shape.type)) {
|
|
1558
927
|
const type = joined.shape.type;
|
|
@@ -1735,12 +1104,13 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1735
1104
|
const keepTs = fromFile?.endsWith(".nudo.ts") === true;
|
|
1736
1105
|
const ast = parseSource(src, keepTs ? { keepTs: true } : void 0);
|
|
1737
1106
|
const cuts = [];
|
|
1738
|
-
const
|
|
1107
|
+
const exportPairs = [];
|
|
1739
1108
|
const imports = [];
|
|
1109
|
+
const DEFAULT_LOCAL = "__nudoDefault";
|
|
1740
1110
|
const badExport = (what) => {
|
|
1741
1111
|
collectDiag({
|
|
1742
1112
|
code: "nudo:interface-load",
|
|
1743
|
-
message: `sidecar ${what};
|
|
1113
|
+
message: `sidecar ${what}; recognized export forms are 'export const <name> = \u2026' and 'export default <constraint|fn>'`,
|
|
1744
1114
|
file: fromFile
|
|
1745
1115
|
});
|
|
1746
1116
|
};
|
|
@@ -1764,7 +1134,7 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1764
1134
|
if (decl.kind === "const") {
|
|
1765
1135
|
let simple = true;
|
|
1766
1136
|
for (const d of decl.declarations) {
|
|
1767
|
-
if (d.id.type === "Identifier")
|
|
1137
|
+
if (d.id.type === "Identifier") exportPairs.push({ key: d.id.name, expr: d.id.name });
|
|
1768
1138
|
else simple = false;
|
|
1769
1139
|
}
|
|
1770
1140
|
if (!simple) badExport("'export const' with destructuring pattern");
|
|
@@ -1788,15 +1158,40 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1788
1158
|
}
|
|
1789
1159
|
if (stmt.type === "ExportDefaultDeclaration") {
|
|
1790
1160
|
const decl = stmt.declaration;
|
|
1791
|
-
if ((decl
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1161
|
+
if (decl && (decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") && stmt.start != null && decl.start != null) {
|
|
1162
|
+
if (decl.id?.name) {
|
|
1163
|
+
exportPairs.push({ key: decl.id.name, expr: decl.id.name });
|
|
1164
|
+
exportPairs.push({ key: "default", expr: decl.id.name });
|
|
1165
|
+
} else {
|
|
1166
|
+
exportPairs.push({ key: "default", expr: DEFAULT_LOCAL });
|
|
1167
|
+
if (decl.start != null && decl.end != null) {
|
|
1168
|
+
const kind = decl.type === "FunctionDeclaration" ? "function" : "class";
|
|
1169
|
+
cuts.push({
|
|
1170
|
+
start: stmt.start,
|
|
1171
|
+
end: decl.start,
|
|
1172
|
+
text: `var ${DEFAULT_LOCAL} = `
|
|
1173
|
+
});
|
|
1174
|
+
void kind;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
if (decl.id?.name) {
|
|
1178
|
+
cuts.push({ start: stmt.start, end: decl.start, text: "" });
|
|
1799
1179
|
}
|
|
1180
|
+
continue;
|
|
1181
|
+
}
|
|
1182
|
+
if (decl && stmt.start != null && decl.start != null && decl.end != null) {
|
|
1183
|
+
exportPairs.push({ key: "default", expr: DEFAULT_LOCAL });
|
|
1184
|
+
cuts.push({
|
|
1185
|
+
start: stmt.start,
|
|
1186
|
+
end: decl.start,
|
|
1187
|
+
text: `var ${DEFAULT_LOCAL} = `
|
|
1188
|
+
});
|
|
1189
|
+
cuts.push({ start: decl.end, end: stmt.end ?? decl.end, text: ";" });
|
|
1190
|
+
continue;
|
|
1191
|
+
}
|
|
1192
|
+
badExport("'export default'");
|
|
1193
|
+
if (stmt.start != null && stmt.end != null) {
|
|
1194
|
+
cuts.push({ start: stmt.start, end: stmt.end, text: "" });
|
|
1800
1195
|
}
|
|
1801
1196
|
continue;
|
|
1802
1197
|
}
|
|
@@ -1816,20 +1211,21 @@ function rewriteSidecarSource(src, fromFile) {
|
|
|
1816
1211
|
const merged = [];
|
|
1817
1212
|
for (const c of cuts) {
|
|
1818
1213
|
const last = merged[merged.length - 1];
|
|
1819
|
-
if (last && c.start <= last.end) {
|
|
1214
|
+
if (last && c.start <= last.end && last.text === "" && c.text === "") {
|
|
1820
1215
|
last.end = Math.max(last.end, c.end);
|
|
1821
1216
|
} else {
|
|
1822
|
-
merged.push({ start: c.start, end: c.end });
|
|
1217
|
+
merged.push({ start: c.start, end: c.end, text: c.text });
|
|
1823
1218
|
}
|
|
1824
1219
|
}
|
|
1825
1220
|
let code = "";
|
|
1826
1221
|
let pos = 0;
|
|
1827
1222
|
for (const c of merged) {
|
|
1828
|
-
|
|
1223
|
+
if (c.start < pos) continue;
|
|
1224
|
+
code += src.slice(pos, c.start) + c.text;
|
|
1829
1225
|
pos = c.end;
|
|
1830
1226
|
}
|
|
1831
1227
|
code += src.slice(pos);
|
|
1832
|
-
return { code,
|
|
1228
|
+
return { code, exportPairs, imports };
|
|
1833
1229
|
}
|
|
1834
1230
|
var TS_STMT_CUT_TYPES = /* @__PURE__ */ new Set([
|
|
1835
1231
|
"TSInterfaceDeclaration",
|
|
@@ -1903,7 +1299,7 @@ function collectTsSyntaxCuts(node, src, cuts = []) {
|
|
|
1903
1299
|
}
|
|
1904
1300
|
function execSidecar(src, opts, chain, preloaded) {
|
|
1905
1301
|
const fromFile = opts?.fromFile;
|
|
1906
|
-
const { code,
|
|
1302
|
+
const { code, exportPairs, imports } = rewriteSidecarSource(src, fromFile);
|
|
1907
1303
|
const prologue = [];
|
|
1908
1304
|
const deps = {};
|
|
1909
1305
|
for (const imp of imports) {
|
|
@@ -2015,9 +1411,12 @@ function execSidecar(src, opts, chain, preloaded) {
|
|
|
2015
1411
|
for (const local of Object.keys(deps)) {
|
|
2016
1412
|
prologue.push(`var ${local} = __nudoDeps[${JSON.stringify(local)}];`);
|
|
2017
1413
|
}
|
|
1414
|
+
const returnObj = exportPairs.map(
|
|
1415
|
+
(p) => p.key === p.expr ? p.key : `${JSON.stringify(p.key)}: ${p.expr}`
|
|
1416
|
+
).join(", ");
|
|
2018
1417
|
const body = `${prologue.length > 0 ? `${prologue.join("\n")}
|
|
2019
1418
|
` : ""}${code}
|
|
2020
|
-
return { ${
|
|
1419
|
+
return { ${returnObj} };`;
|
|
2021
1420
|
const fn2 = new Function(
|
|
2022
1421
|
...Object.keys(sidecarInjects),
|
|
2023
1422
|
"__nudoInjects",
|
|
@@ -2269,28 +1668,134 @@ function localNamedExports(source) {
|
|
|
2269
1668
|
}
|
|
2270
1669
|
}
|
|
2271
1670
|
}
|
|
1671
|
+
const identName = (n) => {
|
|
1672
|
+
if (!n) return void 0;
|
|
1673
|
+
if (n.type === "Identifier" && typeof n.name === "string") return n.name;
|
|
1674
|
+
if (n.type === "Literal" && typeof n.value === "string") return n.value;
|
|
1675
|
+
return void 0;
|
|
1676
|
+
};
|
|
1677
|
+
const localClasses = /* @__PURE__ */ new Map();
|
|
2272
1678
|
for (const stmt of ast.program.body) {
|
|
2273
|
-
|
|
2274
|
-
if (
|
|
2275
|
-
const
|
|
2276
|
-
if (
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
1679
|
+
const s = stmt;
|
|
1680
|
+
if (s.type !== "ClassDeclaration") continue;
|
|
1681
|
+
const idName = identName(s.id);
|
|
1682
|
+
if (idName) localClasses.set(idName, s);
|
|
1683
|
+
}
|
|
1684
|
+
const addClassMethodKeys = (out2, decl) => {
|
|
1685
|
+
if (!decl || decl.type !== "ClassDeclaration") return;
|
|
1686
|
+
const idName = identName(decl.id);
|
|
1687
|
+
if (!idName) return;
|
|
1688
|
+
const body = decl.body?.body ?? [];
|
|
1689
|
+
for (const m of body) {
|
|
1690
|
+
const mem = m;
|
|
1691
|
+
const isMethod = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
1692
|
+
if (!isMethod) continue;
|
|
1693
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
1694
|
+
if (mem.static) continue;
|
|
1695
|
+
const keyName = identName(mem.key);
|
|
1696
|
+
if (keyName) out2.add(`${idName}.${keyName}`);
|
|
1697
|
+
}
|
|
1698
|
+
};
|
|
1699
|
+
const isExportsTarget = (n) => {
|
|
1700
|
+
if (!n) return false;
|
|
1701
|
+
if (n.type === "Identifier") return n.name === "exports";
|
|
1702
|
+
if (n.type === "MemberExpression") {
|
|
1703
|
+
return identName(n.object) === "module" && n.property !== void 0 ? identName(n.property) === "exports" : false;
|
|
1704
|
+
}
|
|
1705
|
+
return false;
|
|
1706
|
+
};
|
|
1707
|
+
const cjsPropName = (left) => {
|
|
1708
|
+
if (!left || left.type !== "MemberExpression") return void 0;
|
|
1709
|
+
if (left.computed === true) return void 0;
|
|
1710
|
+
const obj2 = left.object;
|
|
1711
|
+
if (!isExportsTarget(obj2)) return void 0;
|
|
1712
|
+
return identName(left.property);
|
|
1713
|
+
};
|
|
1714
|
+
for (const stmt of ast.program.body) {
|
|
1715
|
+
const s = stmt;
|
|
1716
|
+
if (s.type === "ExportNamedDeclaration") {
|
|
1717
|
+
if (s.source) continue;
|
|
1718
|
+
const d = s.declaration;
|
|
1719
|
+
if (!d) {
|
|
1720
|
+
const specs = s.specifiers ?? [];
|
|
1721
|
+
for (const spec of specs) {
|
|
1722
|
+
if (spec.type !== "ExportSpecifier") continue;
|
|
1723
|
+
const name = identName(spec.exported);
|
|
1724
|
+
if (!name) continue;
|
|
1725
|
+
const localName = identName(spec.local);
|
|
1726
|
+
if (name === "default") {
|
|
1727
|
+
out.add("default");
|
|
1728
|
+
if (localName && !importedLocalNames.has(localName)) out.add(localName);
|
|
1729
|
+
if (localName && !importedLocalNames.has(localName)) {
|
|
1730
|
+
addClassMethodKeys(out, localClasses.get(localName));
|
|
1731
|
+
}
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1734
|
+
if (localName && importedLocalNames.has(localName)) continue;
|
|
1735
|
+
out.add(name);
|
|
1736
|
+
if (localName) addClassMethodKeys(out, localClasses.get(localName));
|
|
1737
|
+
}
|
|
1738
|
+
continue;
|
|
1739
|
+
}
|
|
1740
|
+
if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
|
|
1741
|
+
const idName = identName(d.id);
|
|
1742
|
+
if (idName) out.add(idName);
|
|
1743
|
+
if (d.type === "ClassDeclaration" && idName) {
|
|
1744
|
+
addClassMethodKeys(out, d);
|
|
1745
|
+
}
|
|
1746
|
+
} else if (d.type === "VariableDeclaration") {
|
|
1747
|
+
const decls = d.declarations ?? [];
|
|
1748
|
+
for (const decl of decls) {
|
|
1749
|
+
const idName = identName(decl.id);
|
|
1750
|
+
if (idName) out.add(idName);
|
|
1751
|
+
}
|
|
2286
1752
|
}
|
|
2287
1753
|
continue;
|
|
2288
1754
|
}
|
|
2289
|
-
if (
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
if (
|
|
1755
|
+
if (s.type === "ExportDefaultDeclaration") {
|
|
1756
|
+
out.add("default");
|
|
1757
|
+
const d = s.declaration;
|
|
1758
|
+
if (d) {
|
|
1759
|
+
if ((d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") && d.id) {
|
|
1760
|
+
const idName = identName(d.id);
|
|
1761
|
+
if (idName) out.add(idName);
|
|
1762
|
+
if (d.type === "ClassDeclaration" && idName) {
|
|
1763
|
+
addClassMethodKeys(out, d);
|
|
1764
|
+
}
|
|
1765
|
+
} else if (d.type === "Identifier") {
|
|
1766
|
+
const n = identName(d);
|
|
1767
|
+
if (n && !importedLocalNames.has(n)) {
|
|
1768
|
+
out.add(n);
|
|
1769
|
+
addClassMethodKeys(out, localClasses.get(n));
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
continue;
|
|
1774
|
+
}
|
|
1775
|
+
if (s.type === "ExpressionStatement") {
|
|
1776
|
+
const expr = s.expression;
|
|
1777
|
+
if (!expr || expr.type !== "AssignmentExpression" || expr.operator !== "=") continue;
|
|
1778
|
+
const left = expr.left;
|
|
1779
|
+
const right = expr.right;
|
|
1780
|
+
if (!left || !right) continue;
|
|
1781
|
+
const prop = cjsPropName(left);
|
|
1782
|
+
if (prop && prop !== "default") out.add(prop);
|
|
1783
|
+
if (isExportsTarget(left)) {
|
|
1784
|
+
if (right.type === "ObjectExpression") {
|
|
1785
|
+
const props = right.properties ?? [];
|
|
1786
|
+
for (const p of props) {
|
|
1787
|
+
if (p.type !== "ObjectProperty" && p.type !== "Property") continue;
|
|
1788
|
+
const keyName = identName(p.key);
|
|
1789
|
+
if (keyName && keyName !== "default") out.add(keyName);
|
|
1790
|
+
else {
|
|
1791
|
+
const valName = identName(p.value);
|
|
1792
|
+
if (valName) out.add(valName);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
} else if (right.type === "Identifier") {
|
|
1796
|
+
const n = identName(right);
|
|
1797
|
+
if (n && !importedLocalNames.has(n)) out.add(n);
|
|
1798
|
+
}
|
|
2294
1799
|
}
|
|
2295
1800
|
}
|
|
2296
1801
|
}
|
|
@@ -2304,7 +1809,9 @@ function generatedExportNames(sidecarSrc) {
|
|
|
2304
1809
|
} catch {
|
|
2305
1810
|
return out;
|
|
2306
1811
|
}
|
|
2307
|
-
|
|
1812
|
+
const stmts = ast.program.body;
|
|
1813
|
+
for (let i = 0; i < stmts.length; i++) {
|
|
1814
|
+
const stmt = stmts[i];
|
|
2308
1815
|
if (stmt.type !== "ExportNamedDeclaration") continue;
|
|
2309
1816
|
if (stmt.source) continue;
|
|
2310
1817
|
const d = stmt.declaration;
|
|
@@ -2318,25 +1825,26 @@ function generatedExportNames(sidecarSrc) {
|
|
|
2318
1825
|
if (d.id) names.push(d.id.name);
|
|
2319
1826
|
}
|
|
2320
1827
|
if (names.length === 0) continue;
|
|
2321
|
-
if (
|
|
1828
|
+
if (regionHasGeneratedMarker(stmts, i, sidecarSrc)) {
|
|
2322
1829
|
for (const n of names) out.add(n);
|
|
2323
1830
|
}
|
|
2324
1831
|
}
|
|
2325
1832
|
return out;
|
|
2326
1833
|
}
|
|
2327
|
-
function
|
|
2328
|
-
const
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
if (
|
|
2334
|
-
|
|
2335
|
-
continue;
|
|
2336
|
-
}
|
|
1834
|
+
function regionHasGeneratedMarker(stmts, exportIdx, src) {
|
|
1835
|
+
const exportStart = stmts[exportIdx].start;
|
|
1836
|
+
if (exportStart == null) return false;
|
|
1837
|
+
let regionStart = 0;
|
|
1838
|
+
for (let j = exportIdx - 1; j >= 0; j--) {
|
|
1839
|
+
const prev = stmts[j];
|
|
1840
|
+
if (prev.type === "ImportDeclaration" || prev.type === "VariableDeclaration") continue;
|
|
1841
|
+
regionStart = prev.end ?? 0;
|
|
2337
1842
|
break;
|
|
2338
1843
|
}
|
|
2339
|
-
return
|
|
1844
|
+
return src.slice(regionStart, exportStart).split("\n").some((line) => {
|
|
1845
|
+
const t = line.trim();
|
|
1846
|
+
return (t.startsWith("//") || t.startsWith("/*") || t.startsWith("*")) && /@generated/.test(t);
|
|
1847
|
+
});
|
|
2340
1848
|
}
|
|
2341
1849
|
function sidecarAutoBindAllowed(sidecarPath, autoBind) {
|
|
2342
1850
|
if (isNodeModulesPath(sidecarPath)) return false;
|
|
@@ -2344,6 +1852,18 @@ function sidecarAutoBindAllowed(sidecarPath, autoBind) {
|
|
|
2344
1852
|
if (typeof autoBind === "function") return autoBind(sidecarPath) === true;
|
|
2345
1853
|
return false;
|
|
2346
1854
|
}
|
|
1855
|
+
function isDefaultExportLocal(source, localName) {
|
|
1856
|
+
const reList = new RegExp(
|
|
1857
|
+
`export\\s*\\{[^}]*\\b${localName}\\s+as\\s+default\\b[^}]*\\}`,
|
|
1858
|
+
"m"
|
|
1859
|
+
);
|
|
1860
|
+
const reDefaultFn = new RegExp(
|
|
1861
|
+
`export\\s+default\\s+(?:async\\s+)?function\\s+${localName}\\b`,
|
|
1862
|
+
"m"
|
|
1863
|
+
);
|
|
1864
|
+
const reDefaultId = new RegExp(`export\\s+default\\s+${localName}\\b`, "m");
|
|
1865
|
+
return reList.test(source) || reDefaultFn.test(source) || reDefaultId.test(source);
|
|
1866
|
+
}
|
|
2347
1867
|
function loadSidecarBinding(source, fnName, opts) {
|
|
2348
1868
|
const { loadModule, fromFile, autoBind } = opts;
|
|
2349
1869
|
if (!loadModule || !fromFile) return { ok: false };
|
|
@@ -2353,6 +1873,7 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
2353
1873
|
const spec = `./${sidecarPath.slice(sidecarPath.lastIndexOf("/") + 1)}`;
|
|
2354
1874
|
const sidecarSrc = loadModule(spec, fromFile);
|
|
2355
1875
|
if (sidecarSrc === void 0) return { ok: false };
|
|
1876
|
+
if (sidecarSrc === source) return { ok: false };
|
|
2356
1877
|
let exports;
|
|
2357
1878
|
try {
|
|
2358
1879
|
exports = execNudoModule(sidecarSrc, { loadModule, fromFile: sidecarPath });
|
|
@@ -2364,7 +1885,20 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
2364
1885
|
});
|
|
2365
1886
|
return { ok: false };
|
|
2366
1887
|
}
|
|
2367
|
-
|
|
1888
|
+
let binding = exports[fnName];
|
|
1889
|
+
if (binding === void 0 && exports.default !== void 0 && isDefaultExportLocal(source, fnName)) {
|
|
1890
|
+
binding = exports.default;
|
|
1891
|
+
}
|
|
1892
|
+
if (binding === void 0 && fnName.includes(".")) {
|
|
1893
|
+
const [cls, method] = fnName.split(".", 2);
|
|
1894
|
+
binding = exports[`${cls}_${method}`];
|
|
1895
|
+
if (binding === void 0) {
|
|
1896
|
+
const bag = exports[cls];
|
|
1897
|
+
if (bag && typeof bag === "object" && !isNudoConstraint(bag)) {
|
|
1898
|
+
binding = bag[method];
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
2368
1902
|
if (binding === void 0) return { ok: false };
|
|
2369
1903
|
if (!isNudoConstraint(binding)) {
|
|
2370
1904
|
collectDiag2({
|
|
@@ -2382,11 +1916,16 @@ function loadSidecarBinding(source, fnName, opts) {
|
|
|
2382
1916
|
});
|
|
2383
1917
|
return { ok: false };
|
|
2384
1918
|
}
|
|
1919
|
+
const generatedNames = generatedExportNames(sidecarSrc);
|
|
1920
|
+
const isGenerated = generatedNames.has(fnName) || (fnName.includes(".") ? (() => {
|
|
1921
|
+
const [cls, method] = fnName.split(".", 2);
|
|
1922
|
+
return generatedNames.has(`${cls}_${method}`) || generatedNames.has(cls);
|
|
1923
|
+
})() : false);
|
|
2385
1924
|
return {
|
|
2386
1925
|
ok: true,
|
|
2387
1926
|
sidecarPath,
|
|
2388
1927
|
constraint: binding,
|
|
2389
|
-
generated:
|
|
1928
|
+
generated: isGenerated
|
|
2390
1929
|
};
|
|
2391
1930
|
}
|
|
2392
1931
|
function boundsOf(c) {
|
|
@@ -2683,6 +2222,27 @@ function fmtConstraint(c) {
|
|
|
2683
2222
|
function formatConstraint(c) {
|
|
2684
2223
|
return fmtConstraint(c);
|
|
2685
2224
|
}
|
|
2225
|
+
function formatEffectiveInterfaceDisplay(eff) {
|
|
2226
|
+
const params = eff.params.map((p) => `${p.param}: ${formatConstraint(p.constraint)}`).join(", ");
|
|
2227
|
+
let s = `(${params})`;
|
|
2228
|
+
if (eff.returns) s += ` \u2192 ${formatConstraint(eff.returns.constraint)}`;
|
|
2229
|
+
return s;
|
|
2230
|
+
}
|
|
2231
|
+
function formatInterfaceTierLine(source) {
|
|
2232
|
+
return `\u25CF interface / ${source}`;
|
|
2233
|
+
}
|
|
2234
|
+
function interfaceTierOf(source, fnName, fromFile, opts = {}) {
|
|
2235
|
+
if (!localNamedExports(source).has(fnName)) return void 0;
|
|
2236
|
+
const eff = effectiveInterface(source, fnName, { fromFile, ...opts });
|
|
2237
|
+
const src = eff?.source ?? "implicit";
|
|
2238
|
+
if (eff && src !== "implicit") {
|
|
2239
|
+
return { source: src, display: formatEffectiveInterfaceDisplay(eff) };
|
|
2240
|
+
}
|
|
2241
|
+
return { source: src };
|
|
2242
|
+
}
|
|
2243
|
+
function interfaceSourceOf(source, fnName, fromFile, opts = {}) {
|
|
2244
|
+
return interfaceTierOf(source, fnName, fromFile, opts)?.source;
|
|
2245
|
+
}
|
|
2686
2246
|
|
|
2687
2247
|
// src/algebra/fn-fp.ts
|
|
2688
2248
|
var fnFpCache = /* @__PURE__ */ new Map();
|
|
@@ -2866,7 +2426,151 @@ function canSkipLiteralCallScan(source, file) {
|
|
|
2866
2426
|
for (const fp of fps.values()) {
|
|
2867
2427
|
if (fp.nRefs > 0) return false;
|
|
2868
2428
|
}
|
|
2869
|
-
return true;
|
|
2429
|
+
return true;
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
// src/algebra/param-surface.ts
|
|
2433
|
+
function collectPatternNames(p, top, nested, depth, propKey) {
|
|
2434
|
+
if (!p) return;
|
|
2435
|
+
if (p.type === "Identifier" && p.name) {
|
|
2436
|
+
if (depth === 0) top.push(p.name);
|
|
2437
|
+
else nested.push(p.name);
|
|
2438
|
+
return;
|
|
2439
|
+
}
|
|
2440
|
+
if (p.type === "AssignmentPattern") {
|
|
2441
|
+
collectPatternNames(p.left, top, nested, depth, propKey);
|
|
2442
|
+
return;
|
|
2443
|
+
}
|
|
2444
|
+
if (p.type === "RestElement") {
|
|
2445
|
+
collectPatternNames(p.argument, top, nested, depth, propKey);
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2448
|
+
if (p.type === "ObjectPattern") {
|
|
2449
|
+
for (const prop of p.properties ?? []) {
|
|
2450
|
+
if (prop.type === "RestElement" || prop.argument) {
|
|
2451
|
+
collectPatternNames(prop.argument, top, nested, depth, propKey);
|
|
2452
|
+
continue;
|
|
2453
|
+
}
|
|
2454
|
+
const keyName = prop.key?.type === "Identifier" && prop.key.name ? prop.key.name : prop.key && "value" in prop.key ? String(prop.key.value ?? "") : void 0;
|
|
2455
|
+
const v2 = prop.value ?? prop.key;
|
|
2456
|
+
if (!v2) continue;
|
|
2457
|
+
if (keyName && v2.type === "Identifier" && v2.name && keyName !== v2.name) {
|
|
2458
|
+
if (depth === 0) top.push(keyName);
|
|
2459
|
+
else nested.push(keyName);
|
|
2460
|
+
if (propKey && depth === 0) propKey[keyName] = keyName;
|
|
2461
|
+
}
|
|
2462
|
+
if (v2.type === "Identifier" && v2.name) {
|
|
2463
|
+
if (depth === 0) {
|
|
2464
|
+
top.push(v2.name);
|
|
2465
|
+
if (propKey && keyName) propKey[v2.name] = keyName;
|
|
2466
|
+
} else nested.push(v2.name);
|
|
2467
|
+
} else {
|
|
2468
|
+
collectPatternNames(v2, top, nested, depth + 1, propKey);
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
if (p.type === "ArrayPattern") {
|
|
2474
|
+
for (const el of p.elements ?? []) {
|
|
2475
|
+
if (!el) continue;
|
|
2476
|
+
if (el.type === "Identifier" && el.name) {
|
|
2477
|
+
if (depth === 0) top.push(el.name);
|
|
2478
|
+
else nested.push(el.name);
|
|
2479
|
+
} else {
|
|
2480
|
+
collectPatternNames(el, top, nested, depth + 1, propKey);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
function formalParamsFromNodes(params) {
|
|
2486
|
+
const list = params ?? [];
|
|
2487
|
+
return list.map((p, index) => {
|
|
2488
|
+
if (p?.type === "Identifier" && p.name) {
|
|
2489
|
+
return { kind: "id", name: p.name, index };
|
|
2490
|
+
}
|
|
2491
|
+
if (p?.type === "AssignmentPattern") {
|
|
2492
|
+
const left = p.left;
|
|
2493
|
+
if (left?.type === "Identifier" && left.name) {
|
|
2494
|
+
return { kind: "default", name: left.name, index };
|
|
2495
|
+
}
|
|
2496
|
+
const top2 = [];
|
|
2497
|
+
const nested2 = [];
|
|
2498
|
+
const propKey2 = {};
|
|
2499
|
+
if (left) collectPatternNames(left, top2, nested2, 0, propKey2);
|
|
2500
|
+
return {
|
|
2501
|
+
kind: "pattern",
|
|
2502
|
+
placeholder: `_p${index}`,
|
|
2503
|
+
bound: top2,
|
|
2504
|
+
propKey: propKey2,
|
|
2505
|
+
nested: nested2,
|
|
2506
|
+
index
|
|
2507
|
+
};
|
|
2508
|
+
}
|
|
2509
|
+
if (p?.type === "RestElement") {
|
|
2510
|
+
const arg = p.argument;
|
|
2511
|
+
const name = arg?.type === "Identifier" && arg.name ? arg.name : `arg${index}`;
|
|
2512
|
+
return { kind: "rest", name, display: `...${name}`, index };
|
|
2513
|
+
}
|
|
2514
|
+
const top = [];
|
|
2515
|
+
const nested = [];
|
|
2516
|
+
const propKey = {};
|
|
2517
|
+
if (p) collectPatternNames(p, top, nested, 0, propKey);
|
|
2518
|
+
return {
|
|
2519
|
+
kind: "pattern",
|
|
2520
|
+
placeholder: `_p${index}`,
|
|
2521
|
+
bound: top,
|
|
2522
|
+
propKey,
|
|
2523
|
+
nested,
|
|
2524
|
+
index
|
|
2525
|
+
};
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2528
|
+
function formalParamDisplayNames(formals) {
|
|
2529
|
+
return formals.map((f) => {
|
|
2530
|
+
switch (f.kind) {
|
|
2531
|
+
case "id":
|
|
2532
|
+
case "default":
|
|
2533
|
+
return f.name;
|
|
2534
|
+
case "rest":
|
|
2535
|
+
return f.display;
|
|
2536
|
+
case "pattern":
|
|
2537
|
+
return f.placeholder;
|
|
2538
|
+
}
|
|
2539
|
+
});
|
|
2540
|
+
}
|
|
2541
|
+
function contractParamNameSet(formals) {
|
|
2542
|
+
const out = /* @__PURE__ */ new Set();
|
|
2543
|
+
for (const f of formals) {
|
|
2544
|
+
if (f.kind === "id" || f.kind === "default") out.add(f.name);
|
|
2545
|
+
else if (f.kind === "rest") {
|
|
2546
|
+
out.add(f.name);
|
|
2547
|
+
out.add(f.display);
|
|
2548
|
+
} else if (f.kind === "pattern") {
|
|
2549
|
+
out.add(f.placeholder);
|
|
2550
|
+
out.add("_");
|
|
2551
|
+
for (const b of f.bound) out.add(b);
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
return out;
|
|
2555
|
+
}
|
|
2556
|
+
function locateContractParam(formals, contractName) {
|
|
2557
|
+
for (const f of formals) {
|
|
2558
|
+
if (f.kind === "id" || f.kind === "default") {
|
|
2559
|
+
if (f.name === contractName) return { index: f.index };
|
|
2560
|
+
} else if (f.kind === "rest") {
|
|
2561
|
+
if (f.name === contractName || f.display === contractName) {
|
|
2562
|
+
return { index: f.index, rest: true };
|
|
2563
|
+
}
|
|
2564
|
+
} else if (f.kind === "pattern") {
|
|
2565
|
+
if (f.placeholder === contractName || contractName === "_") {
|
|
2566
|
+
return { index: f.index };
|
|
2567
|
+
}
|
|
2568
|
+
if (f.bound.includes(contractName)) {
|
|
2569
|
+
return { index: f.index, field: f.propKey?.[contractName] ?? contractName };
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
return void 0;
|
|
2870
2574
|
}
|
|
2871
2575
|
|
|
2872
2576
|
// src/algebra/load-deps-fp.ts
|
|
@@ -2874,6 +2578,18 @@ var MAX_LOAD_DEP_NODES = 64;
|
|
|
2874
2578
|
function extractAllLoadSpecs(source) {
|
|
2875
2579
|
const specs = /* @__PURE__ */ new Set();
|
|
2876
2580
|
for (const imp of extractNudoImports(source)) specs.add(imp.spec);
|
|
2581
|
+
const isPathLikeSpec = (spec) => spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/") || /\.(ts|js|mjs|cjs|tsx|jsx)$/.test(spec);
|
|
2582
|
+
const envRe = /@nudo:env\s+([^\n*]+)/g;
|
|
2583
|
+
let envM;
|
|
2584
|
+
while (envM = envRe.exec(source)) {
|
|
2585
|
+
for (const part of envM[1].split(",")) {
|
|
2586
|
+
const spec = part.trim().replace(/^['"]|['"]$/g, "");
|
|
2587
|
+
if (spec && isPathLikeSpec(spec)) specs.add(spec);
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
const mockFromRe = /@nudo:mock-module\s+"[^"]+"\s+(?:\{[^}]*\}\s+)?from\s+["']([^"']+)["']/g;
|
|
2591
|
+
let mockM;
|
|
2592
|
+
while (mockM = mockFromRe.exec(source)) specs.add(mockM[1]);
|
|
2877
2593
|
const patterns = [
|
|
2878
2594
|
/\bfrom\s*['"]([^'"]+)['"]/g,
|
|
2879
2595
|
/\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
@@ -2893,6 +2609,7 @@ function sidecarSpecsOf(source) {
|
|
|
2893
2609
|
function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
2894
2610
|
const parts = [];
|
|
2895
2611
|
const paths = [];
|
|
2612
|
+
const contents = [];
|
|
2896
2613
|
const seen = /* @__PURE__ */ new Set();
|
|
2897
2614
|
const queue = extractAllLoadSpecs(source).map(
|
|
2898
2615
|
(spec) => ({ spec, from: fromFile })
|
|
@@ -2901,7 +2618,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2901
2618
|
let truncated = false;
|
|
2902
2619
|
const finish = () => {
|
|
2903
2620
|
parts.sort();
|
|
2904
|
-
return truncated ? { fp: `trunc:${parts.join(",")}`, paths, truncated: true } : { fp: parts.join(","), paths, truncated: false };
|
|
2621
|
+
return truncated ? { fp: `trunc:${parts.join(",")}`, paths, contents, truncated: true } : { fp: parts.join(","), paths, contents, truncated: false };
|
|
2905
2622
|
};
|
|
2906
2623
|
const absorbSidecarClosure = (entryFile) => {
|
|
2907
2624
|
const sidecarPath = sidecarPathOf(entryFile);
|
|
@@ -2917,6 +2634,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2917
2634
|
n++;
|
|
2918
2635
|
parts.push(`sidecar:${sidecarPath}=${hashSource(sidecarSrc)}`);
|
|
2919
2636
|
paths.push(sidecarPath);
|
|
2637
|
+
contents.push({ path: sidecarPath, content: sidecarSrc });
|
|
2920
2638
|
const sidecarQueue = sidecarSpecsOf(
|
|
2921
2639
|
sidecarSrc
|
|
2922
2640
|
).map((spec) => ({ spec, from: sidecarPath }));
|
|
@@ -2933,6 +2651,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2933
2651
|
const src = loadModule(cur.spec, cur.from);
|
|
2934
2652
|
parts.push(`sidecar:${path}=${src === void 0 ? "miss" : hashSource(src)}`);
|
|
2935
2653
|
paths.push(path);
|
|
2654
|
+
contents.push({ path, content: src ?? null });
|
|
2936
2655
|
if (src === void 0) continue;
|
|
2937
2656
|
for (const next of sidecarSpecsOf(src)) {
|
|
2938
2657
|
const nextPath = resolveDepPath(path, next);
|
|
@@ -2953,6 +2672,7 @@ function loadModuleDepsFingerprint(source, loadModule, fromFile) {
|
|
|
2953
2672
|
const src = loadModule(cur.spec, cur.from);
|
|
2954
2673
|
parts.push(`${path}=${src === void 0 ? "miss" : hashSource(src)}`);
|
|
2955
2674
|
paths.push(path);
|
|
2675
|
+
contents.push({ path, content: src ?? null });
|
|
2956
2676
|
if (src === void 0) continue;
|
|
2957
2677
|
for (const next of extractAllLoadSpecs(src)) {
|
|
2958
2678
|
const nextPath = resolveDepPath(path, next);
|
|
@@ -3017,14 +2737,14 @@ function loadModuleId(fn2) {
|
|
|
3017
2737
|
}
|
|
3018
2738
|
function refineDepsFingerprint(source, refine) {
|
|
3019
2739
|
if (!refine?.loadModule || !refine.fromFile) {
|
|
3020
|
-
return { fp: "-", paths: [], truncated: false };
|
|
2740
|
+
return { fp: "-", paths: [], contents: [], truncated: false };
|
|
3021
2741
|
}
|
|
3022
2742
|
return loadModuleDepsFingerprint(source, refine.loadModule, refine.fromFile);
|
|
3023
2743
|
}
|
|
3024
2744
|
function generalizeMemoKey(fnName, source, opts) {
|
|
3025
2745
|
const r = opts.refine;
|
|
3026
2746
|
const budget = opts.budget ?? defaultLeakBudget;
|
|
3027
|
-
const deps = opts.depsFp ?? (r ? refineDepsFingerprint(source, r) : { fp: "-", paths: [], truncated: false });
|
|
2747
|
+
const deps = opts.depsFp ?? (r ? refineDepsFingerprint(source, r) : { fp: "-", paths: [], contents: [], truncated: false });
|
|
3028
2748
|
const sc = opts.sidecarFp ?? (r?.loadModule && r.fromFile ? sidecarClosureFingerprint(r.fromFile, r) : void 0);
|
|
3029
2749
|
const scPath = sc !== void 0 && !sc.startsWith("trunc:") && r?.fromFile ? normPath(sidecarPathOf(r.fromFile)) : void 0;
|
|
3030
2750
|
const srcPart = generalizeSourceKeyPart(source, fnName, opts.file);
|
|
@@ -3074,14 +2794,14 @@ function generalizeMemoSet(key, value, depPaths) {
|
|
|
3074
2794
|
function isCacheableAbs(a) {
|
|
3075
2795
|
return a.conf === "exact" || a.conf === "path" || a.conf === "widened" || a.conf === "mock";
|
|
3076
2796
|
}
|
|
3077
|
-
function
|
|
2797
|
+
function termKey2(t, rename) {
|
|
3078
2798
|
switch (t.op) {
|
|
3079
2799
|
case "lit":
|
|
3080
2800
|
return `L:${typeof t.value}:${String(t.value)}`;
|
|
3081
2801
|
case "var":
|
|
3082
2802
|
return `V:${rename?.get(t.id) ?? t.id}`;
|
|
3083
2803
|
case "app":
|
|
3084
|
-
return `A:${t.fn}(${t.args.map((a) =>
|
|
2804
|
+
return `A:${t.fn}(${t.args.map((a) => termKey2(a, rename)).join(",")})`;
|
|
3085
2805
|
}
|
|
3086
2806
|
}
|
|
3087
2807
|
function predKey(p, rename) {
|
|
@@ -3096,7 +2816,7 @@ function predKey(p, rename) {
|
|
|
3096
2816
|
case "le":
|
|
3097
2817
|
case "gt":
|
|
3098
2818
|
case "ge":
|
|
3099
|
-
return `${p.op}(${
|
|
2819
|
+
return `${p.op}(${termKey2(p.a, rename)},${termKey2(p.b, rename)})`;
|
|
3100
2820
|
case "and":
|
|
3101
2821
|
case "or": {
|
|
3102
2822
|
const keys = p.args.map((a) => predKey(a, rename)).sort();
|
|
@@ -3105,7 +2825,7 @@ function predKey(p, rename) {
|
|
|
3105
2825
|
case "not":
|
|
3106
2826
|
return `not(${predKey(p.arg, rename)})`;
|
|
3107
2827
|
case "typeof":
|
|
3108
|
-
return `typeof(${
|
|
2828
|
+
return `typeof(${termKey2(p.t, rename)},${p.type})`;
|
|
3109
2829
|
}
|
|
3110
2830
|
}
|
|
3111
2831
|
function shapeKey(s, seen, rename) {
|
|
@@ -3150,7 +2870,7 @@ function shapeKey(s, seen, rename) {
|
|
|
3150
2870
|
function absKeyInner(a, seen, rename) {
|
|
3151
2871
|
if (seen.has(a)) return "cycle";
|
|
3152
2872
|
seen.add(a);
|
|
3153
|
-
const t = a.term ? `=${
|
|
2873
|
+
const t = a.term ? `=${termKey2(a.term, rename)}` : "";
|
|
3154
2874
|
const p = a.pred ? `@${predKey(a.pred, rename)}` : "";
|
|
3155
2875
|
return `${shapeKey(a.shape, seen, rename)}${t}${p}`;
|
|
3156
2876
|
}
|
|
@@ -3222,6 +2942,11 @@ function collectAbsVars(a, acc, seen) {
|
|
|
3222
2942
|
return;
|
|
3223
2943
|
}
|
|
3224
2944
|
}
|
|
2945
|
+
function collectAbsFreeVars(a) {
|
|
2946
|
+
const acc = /* @__PURE__ */ new Set();
|
|
2947
|
+
collectAbsVars(a, acc, /* @__PURE__ */ new Set());
|
|
2948
|
+
return acc;
|
|
2949
|
+
}
|
|
3225
2950
|
function renameTerm(t, map) {
|
|
3226
2951
|
if (t.op === "var") {
|
|
3227
2952
|
const to = map.get(t.id);
|
|
@@ -3338,6 +3063,7 @@ function alphaRenameResult(result, fromOrder, toOrder) {
|
|
|
3338
3063
|
function extractFn(source, fnName, fileAst) {
|
|
3339
3064
|
const file = fileAst ?? parseSource(source);
|
|
3340
3065
|
const env = emptyEnv();
|
|
3066
|
+
const formalsByName = /* @__PURE__ */ new Map();
|
|
3341
3067
|
for (const stmt of file.program.body) {
|
|
3342
3068
|
let decl = stmt;
|
|
3343
3069
|
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration) {
|
|
@@ -3347,30 +3073,53 @@ function extractFn(source, fnName, fileAst) {
|
|
|
3347
3073
|
decl = stmt.declaration;
|
|
3348
3074
|
}
|
|
3349
3075
|
if (decl.type === "FunctionDeclaration" && decl.id) {
|
|
3076
|
+
const formals = formalParamsFromNodes(decl.params);
|
|
3350
3077
|
env.fns.set(decl.id.name, {
|
|
3351
|
-
params:
|
|
3078
|
+
params: formalParamDisplayNames(formals),
|
|
3352
3079
|
body: decl.body,
|
|
3353
3080
|
async: decl.async === true
|
|
3354
3081
|
});
|
|
3082
|
+
formalsByName.set(decl.id.name, formals);
|
|
3083
|
+
}
|
|
3084
|
+
if (decl.type === "ClassDeclaration" && decl.id?.name) {
|
|
3085
|
+
const cname = decl.id.name;
|
|
3086
|
+
const body = decl.body?.body ?? [];
|
|
3087
|
+
for (const m of body) {
|
|
3088
|
+
const mem = m;
|
|
3089
|
+
const isMethod = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
3090
|
+
if (!isMethod || !mem.body) continue;
|
|
3091
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
3092
|
+
if (mem.static) continue;
|
|
3093
|
+
const keyName = mem.key?.type === "Identifier" ? mem.key.name : void 0;
|
|
3094
|
+
if (!keyName) continue;
|
|
3095
|
+
const fullName = `${cname}.${keyName}`;
|
|
3096
|
+
const formals = formalParamsFromNodes(mem.params ?? []);
|
|
3097
|
+
env.fns.set(fullName, {
|
|
3098
|
+
params: formalParamDisplayNames(formals),
|
|
3099
|
+
body: mem.body,
|
|
3100
|
+
async: mem.async === true
|
|
3101
|
+
});
|
|
3102
|
+
formalsByName.set(fullName, formals);
|
|
3103
|
+
}
|
|
3355
3104
|
}
|
|
3356
3105
|
if (decl.type === "VariableDeclaration") {
|
|
3357
3106
|
for (const d of decl.declarations) {
|
|
3358
3107
|
if (d.id.type === "Identifier" && d.init && (d.init.type === "ArrowFunctionExpression" || d.init.type === "FunctionExpression")) {
|
|
3359
3108
|
const init = d.init;
|
|
3109
|
+
const formals = formalParamsFromNodes(init.params);
|
|
3360
3110
|
env.fns.set(d.id.name, {
|
|
3361
|
-
params:
|
|
3362
|
-
(p) => p.type === "Identifier" ? p.name ?? "_" : "_"
|
|
3363
|
-
),
|
|
3111
|
+
params: formalParamDisplayNames(formals),
|
|
3364
3112
|
body: init.body,
|
|
3365
3113
|
async: init.async === true
|
|
3366
3114
|
});
|
|
3115
|
+
formalsByName.set(d.id.name, formals);
|
|
3367
3116
|
}
|
|
3368
3117
|
}
|
|
3369
3118
|
}
|
|
3370
3119
|
}
|
|
3371
3120
|
const fn2 = env.fns.get(fnName);
|
|
3372
3121
|
if (!fn2) return void 0;
|
|
3373
|
-
return { params: fn2.params, body: fn2.body, env };
|
|
3122
|
+
return { params: fn2.params, body: fn2.body, env, formals: formalsByName.get(fnName) ?? [] };
|
|
3374
3123
|
}
|
|
3375
3124
|
function generalizeFromAst(fnName, source, opts = {}) {
|
|
3376
3125
|
const { key, depPaths, truncated } = generalizeMemoKey(fnName, source, opts);
|
|
@@ -3389,7 +3138,7 @@ function generalizeFromAst(fnName, source, opts = {}) {
|
|
|
3389
3138
|
function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
3390
3139
|
const extracted = extractFn(source, fnName, opts.file);
|
|
3391
3140
|
if (!extracted) return void 0;
|
|
3392
|
-
const { params, body, env } = extracted;
|
|
3141
|
+
const { params, body, env, formals } = extracted;
|
|
3393
3142
|
const budget = opts.budget ?? defaultLeakBudget;
|
|
3394
3143
|
const label = opts.label ?? "A";
|
|
3395
3144
|
const typeParams = params.map((p, i) => ({
|
|
@@ -3505,6 +3254,7 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
|
|
|
3505
3254
|
entryShapes,
|
|
3506
3255
|
fnRels
|
|
3507
3256
|
),
|
|
3257
|
+
...formals.length > 0 ? { formals } : {},
|
|
3508
3258
|
...entryReqs ? { entryReqs } : {},
|
|
3509
3259
|
...fnRels ? { fnRels } : {},
|
|
3510
3260
|
...entryShapes ? { entryShapes } : {},
|
|
@@ -3530,9 +3280,8 @@ function formatPoly(name, params, typeParams, symbolic, entryReqs, entryShapes,
|
|
|
3530
3280
|
return `${p}: ${id}`;
|
|
3531
3281
|
}).join(", ");
|
|
3532
3282
|
const ret = formatShapeSlot(symbolic);
|
|
3533
|
-
const termPart = symbolic.term && symbolic.term.op !== "lit" ? ` = ${termToString(symbolic.term)}` : "";
|
|
3534
3283
|
const predPart = symbolic.pred && symbolic.pred.op !== "true" ? ` where ${predToString(symbolic.pred)}` : "";
|
|
3535
|
-
return `${name}: (${ps}) => ${ret}${
|
|
3284
|
+
return `${name}: (${ps}) => ${ret}${predPart}`;
|
|
3536
3285
|
}
|
|
3537
3286
|
function generalizeAll(source, opts = {}) {
|
|
3538
3287
|
const file = parseSource(source);
|
|
@@ -3849,7 +3598,7 @@ function boundsSatisfiable(bounds) {
|
|
|
3849
3598
|
loStrict = true;
|
|
3850
3599
|
}
|
|
3851
3600
|
} else if (b.op === "ge") {
|
|
3852
|
-
if (b.n > lo
|
|
3601
|
+
if (b.n > lo) {
|
|
3853
3602
|
lo = b.n;
|
|
3854
3603
|
loStrict = false;
|
|
3855
3604
|
}
|
|
@@ -3859,7 +3608,7 @@ function boundsSatisfiable(bounds) {
|
|
|
3859
3608
|
hiStrict = true;
|
|
3860
3609
|
}
|
|
3861
3610
|
} else if (b.op === "le") {
|
|
3862
|
-
if (b.n < hi
|
|
3611
|
+
if (b.n < hi) {
|
|
3863
3612
|
hi = b.n;
|
|
3864
3613
|
hiStrict = false;
|
|
3865
3614
|
}
|
|
@@ -4189,281 +3938,6 @@ function isLengthSelf(t) {
|
|
|
4189
3938
|
return t.op === "app" && t.fn === "length" && t.args.length === 1 && isSelfVar(t.args[0]);
|
|
4190
3939
|
}
|
|
4191
3940
|
|
|
4192
|
-
// src/algebra/bridge.ts
|
|
4193
|
-
var confByTv = /* @__PURE__ */ new WeakMap();
|
|
4194
|
-
function setTvConfidence(tv, conf) {
|
|
4195
|
-
if (tv && typeof tv === "object") confByTv.set(tv, conf);
|
|
4196
|
-
}
|
|
4197
|
-
function getTvConfidence(tv) {
|
|
4198
|
-
if (tv && typeof tv === "object") return confByTv.get(tv);
|
|
4199
|
-
return void 0;
|
|
4200
|
-
}
|
|
4201
|
-
function absToTypeValue(a) {
|
|
4202
|
-
let conf = a.conf;
|
|
4203
|
-
let result;
|
|
4204
|
-
switch (a.shape.k) {
|
|
4205
|
-
case "never":
|
|
4206
|
-
result = T.never;
|
|
4207
|
-
break;
|
|
4208
|
-
case "unknown":
|
|
4209
|
-
if (a.term?.op === "lit" && a.term.value === null) {
|
|
4210
|
-
result = T.literal(null);
|
|
4211
|
-
break;
|
|
4212
|
-
}
|
|
4213
|
-
result = T.unknown;
|
|
4214
|
-
break;
|
|
4215
|
-
case "any":
|
|
4216
|
-
result = T.unknown;
|
|
4217
|
-
break;
|
|
4218
|
-
case "prim": {
|
|
4219
|
-
const lv = litValue(a);
|
|
4220
|
-
if (lv !== void 0) {
|
|
4221
|
-
result = T.literal(lv);
|
|
4222
|
-
break;
|
|
4223
|
-
}
|
|
4224
|
-
if (isTemplateLike(a) && a.shape.k === "prim" && a.shape.type === "string") {
|
|
4225
|
-
const parts = templatePartsOf(a).map(absToTypeValue);
|
|
4226
|
-
result = createTemplate(parts);
|
|
4227
|
-
break;
|
|
4228
|
-
}
|
|
4229
|
-
const prim = primToT(a.shape.type);
|
|
4230
|
-
if (a.pred && a.pred.op !== "true") {
|
|
4231
|
-
const refined = tryEncodeRefined(prim, a);
|
|
4232
|
-
if (refined) {
|
|
4233
|
-
result = refined;
|
|
4234
|
-
} else {
|
|
4235
|
-
result = prim;
|
|
4236
|
-
conf = confJoin(conf, "widened");
|
|
4237
|
-
}
|
|
4238
|
-
} else {
|
|
4239
|
-
result = prim;
|
|
4240
|
-
if (a.term && a.term.op !== "lit") conf = confJoin(conf, "widened");
|
|
4241
|
-
}
|
|
4242
|
-
break;
|
|
4243
|
-
}
|
|
4244
|
-
case "obj": {
|
|
4245
|
-
const props = {};
|
|
4246
|
-
for (const [k, slot] of Object.entries(a.shape.slots)) {
|
|
4247
|
-
let v2 = absToTypeValue(slot.value);
|
|
4248
|
-
if (slot.optional) {
|
|
4249
|
-
v2 = T.union(v2, T.undefined);
|
|
4250
|
-
}
|
|
4251
|
-
props[k] = v2;
|
|
4252
|
-
}
|
|
4253
|
-
result = T.object(props);
|
|
4254
|
-
if (a.shape.open) conf = confJoin(conf, "widened");
|
|
4255
|
-
break;
|
|
4256
|
-
}
|
|
4257
|
-
case "arr":
|
|
4258
|
-
result = T.array(absToTypeValue(a.shape.element));
|
|
4259
|
-
break;
|
|
4260
|
-
case "tuple":
|
|
4261
|
-
result = T.tuple(a.shape.elements.map(absToTypeValue));
|
|
4262
|
-
break;
|
|
4263
|
-
case "fn": {
|
|
4264
|
-
const body = { type: "BlockStatement", body: [], directives: [] };
|
|
4265
|
-
result = T.fn(a.shape.params, body, null);
|
|
4266
|
-
break;
|
|
4267
|
-
}
|
|
4268
|
-
case "brand":
|
|
4269
|
-
result = T.instanceOf(a.shape.name, brandProps(a.shape.shape));
|
|
4270
|
-
break;
|
|
4271
|
-
case "eff":
|
|
4272
|
-
result = T.promise(absToTypeValue(a.shape.inner));
|
|
4273
|
-
break;
|
|
4274
|
-
case "sum":
|
|
4275
|
-
result = T.union(...a.shape.members.map(absToTypeValue));
|
|
4276
|
-
break;
|
|
4277
|
-
default:
|
|
4278
|
-
result = T.unknown;
|
|
4279
|
-
conf = confJoin(conf, "partial");
|
|
4280
|
-
}
|
|
4281
|
-
setTvConfidence(result, conf);
|
|
4282
|
-
return result;
|
|
4283
|
-
}
|
|
4284
|
-
function primToT(type) {
|
|
4285
|
-
switch (type) {
|
|
4286
|
-
case "number":
|
|
4287
|
-
return T.number;
|
|
4288
|
-
case "string":
|
|
4289
|
-
return T.string;
|
|
4290
|
-
case "boolean":
|
|
4291
|
-
return T.boolean;
|
|
4292
|
-
case "bigint":
|
|
4293
|
-
return T.bigint;
|
|
4294
|
-
case "symbol":
|
|
4295
|
-
return T.symbol;
|
|
4296
|
-
default:
|
|
4297
|
-
return T.unknown;
|
|
4298
|
-
}
|
|
4299
|
-
}
|
|
4300
|
-
function brandProps(shape2) {
|
|
4301
|
-
if (shape2.shape.k === "obj") {
|
|
4302
|
-
const out = {};
|
|
4303
|
-
for (const [k, slot] of Object.entries(shape2.shape.slots)) {
|
|
4304
|
-
out[k] = absToTypeValue(slot.value);
|
|
4305
|
-
}
|
|
4306
|
-
return out;
|
|
4307
|
-
}
|
|
4308
|
-
return {};
|
|
4309
|
-
}
|
|
4310
|
-
function tryEncodeRefined(base, a) {
|
|
4311
|
-
if (base.kind !== "primitive" || base.type !== "number") return void 0;
|
|
4312
|
-
const p = a.pred;
|
|
4313
|
-
if (!p) return void 0;
|
|
4314
|
-
if ((p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le") && p.b.op === "lit" && typeof p.b.value === "number") {
|
|
4315
|
-
const n = p.b.value;
|
|
4316
|
-
const op = p.op;
|
|
4317
|
-
const check = (value) => {
|
|
4318
|
-
if (typeof value !== "number") return false;
|
|
4319
|
-
switch (op) {
|
|
4320
|
-
case "gt":
|
|
4321
|
-
return value > n;
|
|
4322
|
-
case "ge":
|
|
4323
|
-
return value >= n;
|
|
4324
|
-
case "lt":
|
|
4325
|
-
return value < n;
|
|
4326
|
-
case "le":
|
|
4327
|
-
return value <= n;
|
|
4328
|
-
}
|
|
4329
|
-
};
|
|
4330
|
-
const opSym = op === "gt" ? ">" : op === "ge" ? ">=" : op === "lt" ? "<" : "<=";
|
|
4331
|
-
return T.refine(base, {
|
|
4332
|
-
name: `number (${opSym} ${n})`,
|
|
4333
|
-
meta: { op, n, pred: predToString(p) },
|
|
4334
|
-
check
|
|
4335
|
-
});
|
|
4336
|
-
}
|
|
4337
|
-
return void 0;
|
|
4338
|
-
}
|
|
4339
|
-
function typeValueToAbs(tv) {
|
|
4340
|
-
if (!tv) return abs({ k: "unknown" }, void 0, void 0, "partial");
|
|
4341
|
-
const confOr = (fallback) => getTvConfidence(tv) ?? fallback;
|
|
4342
|
-
switch (tv.kind) {
|
|
4343
|
-
case "never":
|
|
4344
|
-
return abs({ k: "never" }, void 0, void 0, confOr("exact"));
|
|
4345
|
-
case "unknown":
|
|
4346
|
-
return abs(
|
|
4347
|
-
{ k: "unknown" },
|
|
4348
|
-
void 0,
|
|
4349
|
-
void 0,
|
|
4350
|
-
confOr("partial")
|
|
4351
|
-
);
|
|
4352
|
-
case "literal":
|
|
4353
|
-
if (typeof tv.value === "bigint") {
|
|
4354
|
-
return abs(
|
|
4355
|
-
{ k: "prim", type: "bigint" },
|
|
4356
|
-
void 0,
|
|
4357
|
-
void 0,
|
|
4358
|
-
confOr("exact")
|
|
4359
|
-
);
|
|
4360
|
-
}
|
|
4361
|
-
return abs(
|
|
4362
|
-
shapeOfLit(tv.value),
|
|
4363
|
-
lit(tv.value),
|
|
4364
|
-
pTrue,
|
|
4365
|
-
confOr("exact")
|
|
4366
|
-
);
|
|
4367
|
-
case "primitive":
|
|
4368
|
-
return abs({ k: "prim", type: tv.type }, void 0, void 0, confOr("exact"));
|
|
4369
|
-
case "refined": {
|
|
4370
|
-
const tplParts = getTemplateParts(tv);
|
|
4371
|
-
if (tplParts) {
|
|
4372
|
-
return createTemplateAbs(tplParts.map(typeValueToAbs));
|
|
4373
|
-
}
|
|
4374
|
-
const base = typeValueToAbs(tv.base);
|
|
4375
|
-
const decoded = tryDecodeRefinedPred(tv, base.term);
|
|
4376
|
-
return abs(
|
|
4377
|
-
base.shape,
|
|
4378
|
-
base.term ?? (decoded ? v("_r") : void 0),
|
|
4379
|
-
decoded ?? base.pred,
|
|
4380
|
-
confOr(confJoin(base.conf, "path"))
|
|
4381
|
-
);
|
|
4382
|
-
}
|
|
4383
|
-
case "object": {
|
|
4384
|
-
const slots = {};
|
|
4385
|
-
for (const [k, v2] of Object.entries(tv.properties)) {
|
|
4386
|
-
slots[k] = { value: typeValueToAbs(v2) };
|
|
4387
|
-
}
|
|
4388
|
-
return abs({ k: "obj", slots }, void 0, void 0, confOr("exact"));
|
|
4389
|
-
}
|
|
4390
|
-
case "array":
|
|
4391
|
-
return abs(
|
|
4392
|
-
{ k: "arr", element: typeValueToAbs(tv.element) },
|
|
4393
|
-
void 0,
|
|
4394
|
-
void 0,
|
|
4395
|
-
confOr("exact")
|
|
4396
|
-
);
|
|
4397
|
-
case "tuple":
|
|
4398
|
-
return abs(
|
|
4399
|
-
{ k: "tuple", elements: tv.elements.map(typeValueToAbs) },
|
|
4400
|
-
void 0,
|
|
4401
|
-
void 0,
|
|
4402
|
-
confOr("exact")
|
|
4403
|
-
);
|
|
4404
|
-
case "function": {
|
|
4405
|
-
const params = tv.params ?? [];
|
|
4406
|
-
return abs({ k: "fn", params }, void 0, void 0, confOr("exact"));
|
|
4407
|
-
}
|
|
4408
|
-
case "promise":
|
|
4409
|
-
return abs(
|
|
4410
|
-
{ k: "eff", eff: "promise", inner: typeValueToAbs(tv.value) },
|
|
4411
|
-
void 0,
|
|
4412
|
-
void 0,
|
|
4413
|
-
confOr("exact")
|
|
4414
|
-
);
|
|
4415
|
-
case "instance": {
|
|
4416
|
-
const slots = {};
|
|
4417
|
-
for (const [k, v2] of Object.entries(tv.properties ?? {})) {
|
|
4418
|
-
slots[k] = { value: typeValueToAbs(v2) };
|
|
4419
|
-
}
|
|
4420
|
-
const inner = abs({ k: "obj", slots }, void 0, void 0, confOr("exact"));
|
|
4421
|
-
return abs(
|
|
4422
|
-
{ k: "brand", name: tv.className, shape: inner },
|
|
4423
|
-
void 0,
|
|
4424
|
-
void 0,
|
|
4425
|
-
confOr("exact")
|
|
4426
|
-
);
|
|
4427
|
-
}
|
|
4428
|
-
case "union":
|
|
4429
|
-
return abs(
|
|
4430
|
-
{ k: "sum", members: tv.members.map(typeValueToAbs) },
|
|
4431
|
-
void 0,
|
|
4432
|
-
void 0,
|
|
4433
|
-
confOr("path")
|
|
4434
|
-
);
|
|
4435
|
-
default:
|
|
4436
|
-
return abs({ k: "unknown" }, void 0, void 0, confOr("partial"));
|
|
4437
|
-
}
|
|
4438
|
-
}
|
|
4439
|
-
function tryDecodeRefinedPred(tv, term) {
|
|
4440
|
-
if (tv.kind !== "refined") return void 0;
|
|
4441
|
-
const meta = tv.refinement.meta;
|
|
4442
|
-
const op = meta?.op;
|
|
4443
|
-
const n = meta?.n;
|
|
4444
|
-
if (typeof n !== "number") return void 0;
|
|
4445
|
-
if (op !== "gt" && op !== "ge" && op !== "lt" && op !== "le") return void 0;
|
|
4446
|
-
const t = term ?? v("_r");
|
|
4447
|
-
const b = lit(n);
|
|
4448
|
-
switch (op) {
|
|
4449
|
-
case "gt":
|
|
4450
|
-
return gt(t, b);
|
|
4451
|
-
case "ge":
|
|
4452
|
-
return ge(t, b);
|
|
4453
|
-
case "lt":
|
|
4454
|
-
return lt(t, b);
|
|
4455
|
-
case "le":
|
|
4456
|
-
return le(t, b);
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
function shapeOfLit(v2) {
|
|
4460
|
-
if (typeof v2 === "number") return { k: "prim", type: "number" };
|
|
4461
|
-
if (typeof v2 === "string") return { k: "prim", type: "string" };
|
|
4462
|
-
if (typeof v2 === "boolean") return { k: "prim", type: "boolean" };
|
|
4463
|
-
if (typeof v2 === "bigint") return { k: "prim", type: "bigint" };
|
|
4464
|
-
return { k: "unknown" };
|
|
4465
|
-
}
|
|
4466
|
-
|
|
4467
3941
|
// src/algebra/scan.ts
|
|
4468
3942
|
function hofFnArgOk(src, tgt) {
|
|
4469
3943
|
if (src.shape.k !== "fn") return false;
|
|
@@ -4475,6 +3949,26 @@ function hofFnArgOk(src, tgt) {
|
|
|
4475
3949
|
function listTopFunctions(source, file) {
|
|
4476
3950
|
const f = file ?? parseSource(source);
|
|
4477
3951
|
const names = [];
|
|
3952
|
+
const localClasses = /* @__PURE__ */ new Map();
|
|
3953
|
+
for (const stmt of f.program.body) {
|
|
3954
|
+
if (stmt.type === "ClassDeclaration") {
|
|
3955
|
+
const cname = stmt.id?.name;
|
|
3956
|
+
if (cname) localClasses.set(cname, stmt);
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
const exportedClassNames = /* @__PURE__ */ new Set();
|
|
3960
|
+
const collectClassMethods = (cname, decl) => {
|
|
3961
|
+
const body = decl.body?.body ?? [];
|
|
3962
|
+
for (const m of body) {
|
|
3963
|
+
const mem = m;
|
|
3964
|
+
const isMethod = mem.type === "MethodDefinition" || mem.type === "ClassMethod" || mem.type === "TSDeclareMethod";
|
|
3965
|
+
if (!isMethod) continue;
|
|
3966
|
+
if (mem.kind && mem.kind !== "method") continue;
|
|
3967
|
+
if (mem.static) continue;
|
|
3968
|
+
const keyName = mem.key?.type === "Identifier" ? mem.key.name : void 0;
|
|
3969
|
+
if (keyName) names.push(`${cname}.${keyName}`);
|
|
3970
|
+
}
|
|
3971
|
+
};
|
|
4478
3972
|
for (const stmt of f.program.body) {
|
|
4479
3973
|
let decl = stmt;
|
|
4480
3974
|
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration) {
|
|
@@ -4491,121 +3985,48 @@ function listTopFunctions(source, file) {
|
|
|
4491
3985
|
}
|
|
4492
3986
|
}
|
|
4493
3987
|
}
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
return { shape: { k: "unknown" }, conf: "partial" };
|
|
4499
|
-
}
|
|
4500
|
-
function collectParamStructReqs(source, fnName, fileAst) {
|
|
4501
|
-
const reqs = /* @__PURE__ */ new Map();
|
|
4502
|
-
const extracted = extractFn(source, fnName, fileAst);
|
|
4503
|
-
if (!extracted) return reqs;
|
|
4504
|
-
const params = new Set(extracted.params);
|
|
4505
|
-
const body = extracted.body;
|
|
4506
|
-
const BUILTIN_METHODS = /* @__PURE__ */ new Set([
|
|
4507
|
-
"map",
|
|
4508
|
-
"filter",
|
|
4509
|
-
"reduce",
|
|
4510
|
-
"flatMap",
|
|
4511
|
-
"forEach",
|
|
4512
|
-
"some",
|
|
4513
|
-
"every",
|
|
4514
|
-
"find",
|
|
4515
|
-
"findIndex",
|
|
4516
|
-
"includes",
|
|
4517
|
-
"indexOf",
|
|
4518
|
-
"lastIndexOf",
|
|
4519
|
-
"join",
|
|
4520
|
-
"slice",
|
|
4521
|
-
"splice",
|
|
4522
|
-
"push",
|
|
4523
|
-
"pop",
|
|
4524
|
-
"shift",
|
|
4525
|
-
"unshift",
|
|
4526
|
-
"sort",
|
|
4527
|
-
"reverse",
|
|
4528
|
-
"concat",
|
|
4529
|
-
"at",
|
|
4530
|
-
"replace",
|
|
4531
|
-
"replaceAll",
|
|
4532
|
-
"split",
|
|
4533
|
-
"trim",
|
|
4534
|
-
"toLowerCase",
|
|
4535
|
-
"toUpperCase",
|
|
4536
|
-
"startsWith",
|
|
4537
|
-
"endsWith",
|
|
4538
|
-
"charAt",
|
|
4539
|
-
"charCodeAt",
|
|
4540
|
-
"padStart",
|
|
4541
|
-
"padEnd",
|
|
4542
|
-
"repeat",
|
|
4543
|
-
"toString",
|
|
4544
|
-
"valueOf",
|
|
4545
|
-
"substring",
|
|
4546
|
-
"match",
|
|
4547
|
-
"search",
|
|
4548
|
-
"hasOwnProperty",
|
|
4549
|
-
"keys",
|
|
4550
|
-
"values",
|
|
4551
|
-
"entries",
|
|
4552
|
-
"then",
|
|
4553
|
-
"catch",
|
|
4554
|
-
"finally"
|
|
4555
|
-
]);
|
|
4556
|
-
const visit = (n, isMethodCallee = false, guarded = false) => {
|
|
4557
|
-
if (!n || typeof n !== "object") return;
|
|
4558
|
-
const obj2 = n;
|
|
4559
|
-
if (obj2.type === "LogicalExpression") {
|
|
4560
|
-
visit(obj2.left, false, guarded);
|
|
4561
|
-
visit(obj2.right, false, true);
|
|
4562
|
-
return;
|
|
4563
|
-
}
|
|
4564
|
-
if (obj2.type === "ConditionalExpression") {
|
|
4565
|
-
visit(obj2.test, false, guarded);
|
|
4566
|
-
visit(obj2.consequent, false, true);
|
|
4567
|
-
visit(obj2.alternate, false, true);
|
|
4568
|
-
return;
|
|
4569
|
-
}
|
|
4570
|
-
if (obj2.type === "IfStatement") {
|
|
4571
|
-
visit(obj2.test, false, guarded);
|
|
4572
|
-
visit(obj2.consequent, false, true);
|
|
4573
|
-
visit(obj2.alternate, false, true);
|
|
4574
|
-
return;
|
|
3988
|
+
if (decl.type === "ClassDeclaration" && decl.id?.name && (stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration")) {
|
|
3989
|
+
const cname = decl.id.name;
|
|
3990
|
+
exportedClassNames.add(cname);
|
|
3991
|
+
collectClassMethods(cname, decl);
|
|
4575
3992
|
}
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
3993
|
+
}
|
|
3994
|
+
for (const stmt of f.program.body) {
|
|
3995
|
+
if (stmt.type === "ExportNamedDeclaration" && !stmt.declaration) {
|
|
3996
|
+
const specs = stmt.specifiers ?? [];
|
|
3997
|
+
for (const spec of specs) {
|
|
3998
|
+
const s = spec;
|
|
3999
|
+
if (s.type !== "ExportSpecifier") continue;
|
|
4000
|
+
const localName = s.local?.name;
|
|
4001
|
+
if (!localName || exportedClassNames.has(localName)) continue;
|
|
4002
|
+
const exportedName = s.exported?.name ?? s.exported?.value;
|
|
4003
|
+
const isDefault = exportedName === "default";
|
|
4004
|
+
if (!isDefault && exportedName !== localName) {
|
|
4586
4005
|
}
|
|
4587
|
-
|
|
4006
|
+
const decl = localClasses.get(localName);
|
|
4007
|
+
if (!decl) continue;
|
|
4008
|
+
exportedClassNames.add(localName);
|
|
4009
|
+
collectClassMethods(localName, decl);
|
|
4588
4010
|
}
|
|
4589
4011
|
}
|
|
4590
|
-
if (
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4012
|
+
if (stmt.type === "ExportDefaultDeclaration" && stmt.declaration) {
|
|
4013
|
+
const d = stmt.declaration;
|
|
4014
|
+
if (d.type === "Identifier") {
|
|
4015
|
+
const localName = d.name;
|
|
4016
|
+
if (!exportedClassNames.has(localName)) {
|
|
4017
|
+
const decl = localClasses.get(localName);
|
|
4018
|
+
if (decl) {
|
|
4019
|
+
exportedClassNames.add(localName);
|
|
4020
|
+
collectClassMethods(localName, decl);
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4597
4023
|
}
|
|
4598
|
-
return;
|
|
4599
|
-
}
|
|
4600
|
-
for (const key of Object.keys(obj2)) {
|
|
4601
|
-
if (key === "loc" || key === "start" || key === "end") continue;
|
|
4602
|
-
const val = obj2[key];
|
|
4603
|
-
if (Array.isArray(val)) val.forEach((v2) => visit(v2, isMethodCallee, guarded));
|
|
4604
|
-
else if (val && typeof val === "object") visit(val, isMethodCallee, guarded);
|
|
4605
4024
|
}
|
|
4606
|
-
}
|
|
4607
|
-
|
|
4608
|
-
|
|
4025
|
+
}
|
|
4026
|
+
return names;
|
|
4027
|
+
}
|
|
4028
|
+
function absUnknown() {
|
|
4029
|
+
return { shape: { k: "unknown" }, conf: "partial" };
|
|
4609
4030
|
}
|
|
4610
4031
|
function evalArgAbs(node, lookupVar) {
|
|
4611
4032
|
if (node.type === "Identifier" && typeof node.name === "string" && lookupVar) {
|
|
@@ -4978,14 +4399,37 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
4978
4399
|
eiCache.set(key, r);
|
|
4979
4400
|
return r;
|
|
4980
4401
|
};
|
|
4981
|
-
const
|
|
4402
|
+
const projectArgField = (arg, field) => {
|
|
4403
|
+
if (!arg) return void 0;
|
|
4404
|
+
if (arg.shape.k === "brand") {
|
|
4405
|
+
return projectArgField(arg.shape.shape, field);
|
|
4406
|
+
}
|
|
4407
|
+
if (arg.shape.k !== "obj") return void 0;
|
|
4408
|
+
return getSlot(arg.shape.slots, field)?.value;
|
|
4409
|
+
};
|
|
4410
|
+
const interfaceToIndexed = (ei, paramNames, formals) => {
|
|
4982
4411
|
const conflict = new Set(ei.conflict?.params ?? []);
|
|
4983
4412
|
const entries = [];
|
|
4984
4413
|
for (const { param, constraint } of ei.params) {
|
|
4985
|
-
if (conflict.has(param)) continue;
|
|
4414
|
+
if (!param || conflict.has(param)) continue;
|
|
4986
4415
|
const idx = paramNames.indexOf(param);
|
|
4987
4416
|
if (idx >= 0) {
|
|
4988
|
-
entries.push([
|
|
4417
|
+
entries.push([
|
|
4418
|
+
idx,
|
|
4419
|
+
{ param, pred: instantiateConstraint(constraint, param), constraint },
|
|
4420
|
+
void 0
|
|
4421
|
+
]);
|
|
4422
|
+
continue;
|
|
4423
|
+
}
|
|
4424
|
+
if (formals && formals.length > 0) {
|
|
4425
|
+
const hit = locateContractParam(formals, param);
|
|
4426
|
+
if (hit) {
|
|
4427
|
+
entries.push([
|
|
4428
|
+
hit.index,
|
|
4429
|
+
{ param, pred: instantiateConstraint(constraint, param), constraint },
|
|
4430
|
+
hit.field
|
|
4431
|
+
]);
|
|
4432
|
+
}
|
|
4989
4433
|
}
|
|
4990
4434
|
}
|
|
4991
4435
|
return entries;
|
|
@@ -5019,15 +4463,36 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5019
4463
|
return lv <= n;
|
|
5020
4464
|
};
|
|
5021
4465
|
const checkReqs = (displayName, reqs, paramNames, absArgs, argIndexOf, loc) => {
|
|
5022
|
-
for (const [idx, pred] of reqs) {
|
|
4466
|
+
for (const [idx, pred, field, contractParam] of reqs) {
|
|
5023
4467
|
const argIdx = argIndexOf(idx);
|
|
5024
4468
|
if (argIdx === void 0) continue;
|
|
5025
|
-
|
|
4469
|
+
let arg = absArgs[argIdx];
|
|
5026
4470
|
if (!arg) continue;
|
|
4471
|
+
const paramName = contractParam || paramNames[idx] || `arg${idx}`;
|
|
4472
|
+
if (field) {
|
|
4473
|
+
const projected = projectArgField(arg, field);
|
|
4474
|
+
if (!projected) {
|
|
4475
|
+
const k = arg.shape.k;
|
|
4476
|
+
if (k !== "unknown" && k !== "any") {
|
|
4477
|
+
out.push({
|
|
4478
|
+
severity: "error",
|
|
4479
|
+
code: "nudo:constraint-violated",
|
|
4480
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
4481
|
+
actual: formatAbs(arg),
|
|
4482
|
+
expected: `missing field ${field}`,
|
|
4483
|
+
suggestion: `\u8865\u5168\u5B57\u6BB5 ${field}`,
|
|
4484
|
+
fn: displayName,
|
|
4485
|
+
line: loc?.start.line,
|
|
4486
|
+
column: loc?.start.column
|
|
4487
|
+
});
|
|
4488
|
+
}
|
|
4489
|
+
continue;
|
|
4490
|
+
}
|
|
4491
|
+
arg = projected;
|
|
4492
|
+
}
|
|
5027
4493
|
const lv = litValue(arg);
|
|
5028
4494
|
const isStr = arg.shape.k === "prim" && arg.shape.type === "string";
|
|
5029
4495
|
const strLen = typeof lv === "string" ? lv.length : void 0;
|
|
5030
|
-
const paramName = paramNames[idx] ?? `arg${idx}`;
|
|
5031
4496
|
for (const p of flattenPred(pred)) {
|
|
5032
4497
|
if (p.op === "typeof") {
|
|
5033
4498
|
if (p.t.op !== "var") continue;
|
|
@@ -5104,14 +4569,13 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5104
4569
|
if (p.op === "lt") ok2 = strLen < n;
|
|
5105
4570
|
if (p.op === "le") ok2 = strLen <= n;
|
|
5106
4571
|
if (!ok2) {
|
|
5107
|
-
const paramName2 = paramNames[idx] ?? `arg${idx}`;
|
|
5108
4572
|
out.push({
|
|
5109
4573
|
severity: "error",
|
|
5110
4574
|
code: "nudo:constraint-violated",
|
|
5111
|
-
message: `${displayName}[${
|
|
4575
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
5112
4576
|
actual: formatAbs(arg),
|
|
5113
|
-
expected: `length(${
|
|
5114
|
-
suggestion: `\u6539\u7528\u6EE1\u8DB3\u957F\u5EA6 ${opSym} ${n} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${
|
|
4577
|
+
expected: `length(${paramName}) ${opSym} ${n}`,
|
|
4578
|
+
suggestion: `\u6539\u7528\u6EE1\u8DB3\u957F\u5EA6 ${opSym} ${n} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${paramName} \u7684\u524D\u7F6E`,
|
|
5115
4579
|
fn: displayName,
|
|
5116
4580
|
line: loc?.start.line,
|
|
5117
4581
|
column: loc?.start.column
|
|
@@ -5126,14 +4590,13 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5126
4590
|
if (p.op === "lt") ok = lv < n;
|
|
5127
4591
|
if (p.op === "le") ok = lv <= n;
|
|
5128
4592
|
if (!ok) {
|
|
5129
|
-
const paramName2 = paramNames[idx] ?? `arg${idx}`;
|
|
5130
4593
|
out.push({
|
|
5131
4594
|
severity: "error",
|
|
5132
4595
|
code: "nudo:constraint-violated",
|
|
5133
|
-
message: `${displayName}[${
|
|
4596
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
5134
4597
|
actual: formatAbs(arg),
|
|
5135
4598
|
expected: predToString(p),
|
|
5136
|
-
suggestion: `\u6539\u7528\u6EE1\u8DB3 ${predToString(p)} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${
|
|
4599
|
+
suggestion: `\u6539\u7528\u6EE1\u8DB3 ${predToString(p)} \u7684\u503C\uFF0C\u6216\u653E\u5BBD ${paramName} \u7684\u524D\u7F6E`,
|
|
5137
4600
|
fn: displayName,
|
|
5138
4601
|
line: loc?.start.line,
|
|
5139
4602
|
column: loc?.start.column
|
|
@@ -5315,14 +4778,35 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5315
4778
|
}
|
|
5316
4779
|
};
|
|
5317
4780
|
const checkShapeReqs = (displayName, reqs, paramNames, absArgs, argIndexOf, loc) => {
|
|
5318
|
-
for (const [idx, entry] of reqs) {
|
|
4781
|
+
for (const [idx, entry, field] of reqs) {
|
|
5319
4782
|
const c = entry.constraint;
|
|
5320
4783
|
if (!c.fields && !c.element && !isIntFlag(c) && !c.prim) continue;
|
|
5321
4784
|
const argIdx = argIndexOf(idx);
|
|
5322
4785
|
if (argIdx === void 0) continue;
|
|
5323
|
-
|
|
4786
|
+
let arg = absArgs[argIdx];
|
|
5324
4787
|
if (!arg) continue;
|
|
5325
4788
|
const paramName = entry.param || paramNames[idx] || `arg${idx}`;
|
|
4789
|
+
if (field) {
|
|
4790
|
+
const projected = projectArgField(arg, field);
|
|
4791
|
+
if (!projected) {
|
|
4792
|
+
const k = arg.shape.k;
|
|
4793
|
+
if (k !== "unknown" && k !== "any") {
|
|
4794
|
+
out.push({
|
|
4795
|
+
severity: "error",
|
|
4796
|
+
code: "nudo:constraint-violated",
|
|
4797
|
+
message: `${displayName}[${paramName}]: \u5B9E\u53C2 \u22AD \u524D\u7F6E`,
|
|
4798
|
+
actual: formatAbs(arg),
|
|
4799
|
+
expected: `missing field ${field}`,
|
|
4800
|
+
suggestion: `\u8865\u5168\u5B57\u6BB5 ${field}`,
|
|
4801
|
+
fn: displayName,
|
|
4802
|
+
line: loc?.start.line,
|
|
4803
|
+
column: loc?.start.column
|
|
4804
|
+
});
|
|
4805
|
+
}
|
|
4806
|
+
continue;
|
|
4807
|
+
}
|
|
4808
|
+
arg = projected;
|
|
4809
|
+
}
|
|
5326
4810
|
if (c.fields) {
|
|
5327
4811
|
checkShapeAgainstAbs(displayName, paramName, c, arg, paramName, loc);
|
|
5328
4812
|
}
|
|
@@ -5437,11 +4921,11 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5437
4921
|
};
|
|
5438
4922
|
const ownEi = effectiveInterfaceOf(fnName, source, optsR);
|
|
5439
4923
|
if (ownEi?.source === "handwritten") {
|
|
5440
|
-
const ownFull = interfaceToIndexed(ownEi, paramNames);
|
|
4924
|
+
const ownFull = interfaceToIndexed(ownEi, paramNames, g?.formals);
|
|
5441
4925
|
checkShapeReqs(fnName, ownFull, paramNames, absArgs, (i) => i, loc);
|
|
5442
4926
|
checkReqs(
|
|
5443
4927
|
fnName,
|
|
5444
|
-
ownFull.map(([i, e]) => [i, e.pred]),
|
|
4928
|
+
ownFull.map(([i, e, f]) => [i, e.pred, f, e.param]),
|
|
5445
4929
|
paramNames,
|
|
5446
4930
|
absArgs,
|
|
5447
4931
|
(i) => i,
|
|
@@ -5453,7 +4937,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5453
4937
|
const tg = generalizeFromAst(fwd.target, source, file ? { file } : {});
|
|
5454
4938
|
const tParams = tg?.params ?? [];
|
|
5455
4939
|
const tEi = effectiveInterfaceOf(fwd.target, source, optsR);
|
|
5456
|
-
const tFull = tEi?.source === "handwritten" ? interfaceToIndexed(tEi, tParams) : [];
|
|
4940
|
+
const tFull = tEi?.source === "handwritten" ? interfaceToIndexed(tEi, tParams, tg?.formals) : [];
|
|
5457
4941
|
if (tFull.length > 0) {
|
|
5458
4942
|
const wrapperArgOfTarget = /* @__PURE__ */ new Map();
|
|
5459
4943
|
fwd.map.forEach((wrapperIdx, targetIdx) => {
|
|
@@ -5463,7 +4947,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5463
4947
|
checkShapeReqs(`${fnName}\u2192${fwd.target}`, tFull, tParams, absArgs, mapArg, loc);
|
|
5464
4948
|
checkReqs(
|
|
5465
4949
|
`${fnName}\u2192${fwd.target}`,
|
|
5466
|
-
tFull.map(([i, e]) => [i, e.pred]),
|
|
4950
|
+
tFull.map(([i, e, f]) => [i, e.pred, f, e.param]),
|
|
5467
4951
|
tParams,
|
|
5468
4952
|
absArgs,
|
|
5469
4953
|
mapArg,
|
|
@@ -5489,7 +4973,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5489
4973
|
};
|
|
5490
4974
|
const ei = effectiveInterfaceOf(ext.fnName, ext.source, eiOpts);
|
|
5491
4975
|
if (ei?.source === "handwritten") {
|
|
5492
|
-
full = interfaceToIndexed(ei, paramNames);
|
|
4976
|
+
full = interfaceToIndexed(ei, paramNames, g?.formals);
|
|
5493
4977
|
}
|
|
5494
4978
|
} catch {
|
|
5495
4979
|
out.push({
|
|
@@ -5505,7 +4989,7 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5505
4989
|
checkShapeReqs(displayName, full, paramNames, absArgs, (i) => i, loc);
|
|
5506
4990
|
checkReqs(
|
|
5507
4991
|
displayName,
|
|
5508
|
-
full.map(([i, e]) => [i, e.pred]),
|
|
4992
|
+
full.map(([i, e, f]) => [i, e.pred, f, e.param]),
|
|
5509
4993
|
paramNames,
|
|
5510
4994
|
absArgs,
|
|
5511
4995
|
(i) => i,
|
|
@@ -5549,19 +5033,15 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5549
5033
|
}
|
|
5550
5034
|
}
|
|
5551
5035
|
};
|
|
5552
|
-
const checkArgStructures = (fnName, fnSource, args, loc, displayName,
|
|
5553
|
-
let structReqs;
|
|
5554
|
-
let paramNames;
|
|
5036
|
+
const checkArgStructures = (fnName, fnSource, args, loc, displayName, _interfaceFromFile) => {
|
|
5555
5037
|
let gFn;
|
|
5556
5038
|
try {
|
|
5557
5039
|
const sameFile = fnSource === source;
|
|
5558
|
-
structReqs = collectParamStructReqs(fnSource, fnName, sameFile ? file : void 0);
|
|
5559
5040
|
gFn = generalizeFromAst(
|
|
5560
5041
|
fnName,
|
|
5561
5042
|
fnSource,
|
|
5562
5043
|
sameFile && file ? { file } : {}
|
|
5563
5044
|
);
|
|
5564
|
-
paramNames = gFn?.params ?? [];
|
|
5565
5045
|
} catch (e) {
|
|
5566
5046
|
out.push({
|
|
5567
5047
|
severity: "warning",
|
|
@@ -5582,65 +5062,6 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
|
|
|
5582
5062
|
(n) => evalArgAbs(n, (x) => varAbs.get(x))
|
|
5583
5063
|
);
|
|
5584
5064
|
}
|
|
5585
|
-
if (structReqs.size === 0) return;
|
|
5586
|
-
let refinedParams;
|
|
5587
|
-
try {
|
|
5588
|
-
const sameFile = fnSource === source;
|
|
5589
|
-
const eiOpts = sameFile ? {
|
|
5590
|
-
loadModule: opts?.loadModule,
|
|
5591
|
-
fromFile: opts?.fromFile ?? "",
|
|
5592
|
-
...opts?.autoBind !== void 0 ? { autoBind: opts.autoBind } : {}
|
|
5593
|
-
} : {
|
|
5594
|
-
loadModule: opts?.loadModule,
|
|
5595
|
-
fromFile: interfaceFromFile ?? opts?.fromFile ?? "",
|
|
5596
|
-
...interfaceFromFile ? opts?.autoBind !== void 0 ? { autoBind: opts.autoBind } : {} : { autoBind: false }
|
|
5597
|
-
};
|
|
5598
|
-
const ei = effectiveInterfaceOf(fnName, fnSource, eiOpts);
|
|
5599
|
-
if (ei?.source === "handwritten" && ei.params.length > 0) {
|
|
5600
|
-
refinedParams = new Set(ei.params.map((p) => p.param));
|
|
5601
|
-
}
|
|
5602
|
-
} catch {
|
|
5603
|
-
out.push({
|
|
5604
|
-
severity: "warning",
|
|
5605
|
-
code: "nudo:no-signature",
|
|
5606
|
-
message: `${displayName ?? fnName}: handwritten interface load failed; falling back to body structure inference`,
|
|
5607
|
-
fn: displayName ?? fnName,
|
|
5608
|
-
line: loc?.start.line,
|
|
5609
|
-
column: loc?.start.column
|
|
5610
|
-
});
|
|
5611
|
-
}
|
|
5612
|
-
for (let i = 0; i < args.length; i++) {
|
|
5613
|
-
const pname = paramNames[i];
|
|
5614
|
-
if (!pname) continue;
|
|
5615
|
-
if (refinedParams?.has(pname)) continue;
|
|
5616
|
-
const keys = structReqs.get(pname);
|
|
5617
|
-
if (!keys || keys.size === 0) continue;
|
|
5618
|
-
const argNode = args[i];
|
|
5619
|
-
if (!argNode) continue;
|
|
5620
|
-
const absArg = evalArgAbs(argNode, (n) => varAbs.get(n));
|
|
5621
|
-
if (!absArg || absArg.shape.k === "unknown") continue;
|
|
5622
|
-
const isLeny = absArg.shape.k === "arr" || absArg.shape.k === "tuple" || absArg.shape.k === "prim" && absArg.shape.type === "string";
|
|
5623
|
-
const needKeys = isLeny ? [...keys].filter((k) => k !== "length") : [...keys];
|
|
5624
|
-
if (needKeys.length === 0) continue;
|
|
5625
|
-
const slots = {};
|
|
5626
|
-
for (const k of needKeys) slots[k] = { value: absUnknown() };
|
|
5627
|
-
const target = abs({ k: "obj", slots }, void 0, void 0, "exact");
|
|
5628
|
-
const leq = leqAbs(absArg, target);
|
|
5629
|
-
if (!leq.ok) {
|
|
5630
|
-
const name = displayName ?? fnName;
|
|
5631
|
-
out.push({
|
|
5632
|
-
severity: "error",
|
|
5633
|
-
code: "nudo:arg-structure",
|
|
5634
|
-
message: `${name}[${pname}]: \u5B9E\u53C2\u7ED3\u6784 \u22AD \u5F62\u53C2`,
|
|
5635
|
-
actual: formatAbs(absArg),
|
|
5636
|
-
expected: formatAbs(target),
|
|
5637
|
-
suggestion: leq.reason ?? `\u8865\u5168 ${pname} \u4E0A\u88AB\u8BBF\u95EE\u7684\u5B57\u6BB5`,
|
|
5638
|
-
fn: name,
|
|
5639
|
-
line: loc?.start.line,
|
|
5640
|
-
column: loc?.start.column
|
|
5641
|
-
});
|
|
5642
|
-
}
|
|
5643
|
-
}
|
|
5644
5065
|
};
|
|
5645
5066
|
const visit = (n) => {
|
|
5646
5067
|
if (!n || typeof n !== "object") return;
|
|
@@ -5670,9 +5091,13 @@ function evidenceToString(v2) {
|
|
|
5670
5091
|
return typeof v2 === "string" ? JSON.stringify(v2) : String(v2);
|
|
5671
5092
|
}
|
|
5672
5093
|
function checkInjectedDomainEvidence(fnName, source, records, opts) {
|
|
5673
|
-
const
|
|
5674
|
-
|
|
5675
|
-
|
|
5094
|
+
const isLeaked = (r) => {
|
|
5095
|
+
if (r.resultAbs && r.throwsAbs) {
|
|
5096
|
+
return r.resultAbs.shape.k === "never" && r.throwsAbs.shape.k === "never";
|
|
5097
|
+
}
|
|
5098
|
+
return false;
|
|
5099
|
+
};
|
|
5100
|
+
const usable = records.filter((r) => !isLeaked(r));
|
|
5676
5101
|
if (usable.length === 0) return [];
|
|
5677
5102
|
let ei;
|
|
5678
5103
|
try {
|
|
@@ -5701,15 +5126,9 @@ function checkInjectedDomainEvidence(fnName, source, records, opts) {
|
|
|
5701
5126
|
if (idx < 0) continue;
|
|
5702
5127
|
const failures = [];
|
|
5703
5128
|
for (const rec of usable) {
|
|
5704
|
-
const
|
|
5705
|
-
if (
|
|
5706
|
-
|
|
5707
|
-
if (typeof v2 !== "number" && typeof v2 !== "string" && typeof v2 !== "boolean") {
|
|
5708
|
-
continue;
|
|
5709
|
-
}
|
|
5710
|
-
const conf = getTvConfidence(arg);
|
|
5711
|
-
if (conf !== void 0 && conf !== "exact" && conf !== "path") continue;
|
|
5712
|
-
if (!literalMeetsConstraint(v2, constraint)) failures.push(v2);
|
|
5129
|
+
const lit3 = extractLiteralEvidence(rec, idx);
|
|
5130
|
+
if (lit3 === void 0) continue;
|
|
5131
|
+
if (!literalMeetsConstraint(lit3, constraint)) failures.push(lit3);
|
|
5713
5132
|
}
|
|
5714
5133
|
if (failures.length === 0) continue;
|
|
5715
5134
|
const shown = [...new Set(failures)].map(evidenceToString).join(", ");
|
|
@@ -5727,8 +5146,26 @@ function checkInjectedDomainEvidence(fnName, source, records, opts) {
|
|
|
5727
5146
|
}
|
|
5728
5147
|
return out;
|
|
5729
5148
|
}
|
|
5149
|
+
function extractLiteralEvidence(rec, idx) {
|
|
5150
|
+
const absArg = rec.argAbs?.[idx];
|
|
5151
|
+
if (!absArg) return void 0;
|
|
5152
|
+
if (absArg.conf !== "exact" && absArg.conf !== "path") return void 0;
|
|
5153
|
+
const lv = litValue(absArg);
|
|
5154
|
+
if (typeof lv === "number" || typeof lv === "string" || typeof lv === "boolean") {
|
|
5155
|
+
return lv;
|
|
5156
|
+
}
|
|
5157
|
+
return void 0;
|
|
5158
|
+
}
|
|
5730
5159
|
|
|
5731
5160
|
// src/algebra/check.ts
|
|
5161
|
+
function projectCaseArgField(arg, field) {
|
|
5162
|
+
if (!arg) return void 0;
|
|
5163
|
+
if (arg.shape.k === "brand") {
|
|
5164
|
+
return projectCaseArgField(arg.shape.shape, field);
|
|
5165
|
+
}
|
|
5166
|
+
if (arg.shape.k !== "obj") return void 0;
|
|
5167
|
+
return getSlot(arg.shape.slots, field)?.value;
|
|
5168
|
+
}
|
|
5732
5169
|
var checkReportMemo = /* @__PURE__ */ new Map();
|
|
5733
5170
|
var checkKeyDeps = /* @__PURE__ */ new Map();
|
|
5734
5171
|
var checkDepIndex = /* @__PURE__ */ new Map();
|
|
@@ -5752,7 +5189,7 @@ function loadModuleId2(fn2) {
|
|
|
5752
5189
|
}
|
|
5753
5190
|
function checkDepsFingerprint(source, opts) {
|
|
5754
5191
|
if (!opts.loadModule || !opts.fromFile) {
|
|
5755
|
-
return { fp: "-", paths: [], truncated: false };
|
|
5192
|
+
return { fp: "-", paths: [], contents: [], truncated: false };
|
|
5756
5193
|
}
|
|
5757
5194
|
return loadModuleDepsFingerprint(source, opts.loadModule, opts.fromFile);
|
|
5758
5195
|
}
|
|
@@ -5799,7 +5236,8 @@ function checkMemoKey(filePath, source, identityOpts, deps, sidecarFp) {
|
|
|
5799
5236
|
filePath,
|
|
5800
5237
|
`${loadModuleId2(identityOpts.loadModule)}:${identityOpts.fromFile ?? ""}`,
|
|
5801
5238
|
deps.fp,
|
|
5802
|
-
sidecarFp ?? "-"
|
|
5239
|
+
sidecarFp ?? "-",
|
|
5240
|
+
identityOpts.autoBind === false ? "ab0" : "ab1"
|
|
5803
5241
|
].join("|");
|
|
5804
5242
|
}
|
|
5805
5243
|
function checkMemoGet(key) {
|
|
@@ -5972,6 +5410,26 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
|
|
|
5972
5410
|
});
|
|
5973
5411
|
if (hasRefineDirective || (exportedNames?.has(name) ?? false)) {
|
|
5974
5412
|
const eff = effectiveInterfaceCached(name);
|
|
5413
|
+
if (eff?.source === "handwritten") {
|
|
5414
|
+
const contractNames = contractParamNameSet(g.formals ?? []);
|
|
5415
|
+
const formalDisplay = new Set(g.params);
|
|
5416
|
+
const conflictNames = new Set(eff.conflict?.params ?? []);
|
|
5417
|
+
const unknownParams = eff.params.map((p) => p.param).filter(
|
|
5418
|
+
(p) => p && !formalDisplay.has(p) && !contractNames.has(p) && !conflictNames.has(p)
|
|
5419
|
+
);
|
|
5420
|
+
if (unknownParams.length > 0) {
|
|
5421
|
+
const surface = [...contractNames].filter((n) => !n.startsWith("_p") && n !== "_").join(", ");
|
|
5422
|
+
issues.push({
|
|
5423
|
+
severity: "error",
|
|
5424
|
+
code: "nudo:interface-param-mismatch",
|
|
5425
|
+
message: `${name}: \u5951\u7EA6\u53C2\u6570\u540D\u4E0D\u5728\u5F62\u53C2\u8868\uFF08${unknownParams.join(", ")}\uFF09`,
|
|
5426
|
+
actual: unknownParams.join(", "),
|
|
5427
|
+
expected: surface || g.params.join(", ") || "(\u65E0\u53C2)",
|
|
5428
|
+
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"}`,
|
|
5429
|
+
fn: name
|
|
5430
|
+
});
|
|
5431
|
+
}
|
|
5432
|
+
}
|
|
5975
5433
|
if (eff?.conflict) {
|
|
5976
5434
|
if (eff.conflict.params.length > 0) {
|
|
5977
5435
|
issues.push({
|
|
@@ -6046,14 +5504,14 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
|
|
|
6046
5504
|
const varAbs = /* @__PURE__ */ new Map();
|
|
6047
5505
|
const callRecords = [];
|
|
6048
5506
|
setAbsAssignCollector((r) => records.push(r));
|
|
6049
|
-
setAbsCallCollector((r) => callRecords.push(r));
|
|
5507
|
+
const prevCallCollector = setAbsCallCollector((r) => callRecords.push(r));
|
|
6050
5508
|
try {
|
|
6051
5509
|
const { env } = evalProgramAbs(source, { file });
|
|
6052
5510
|
for (const [k, v2] of env.vars) varAbs.set(k, v2);
|
|
6053
5511
|
} catch {
|
|
6054
5512
|
} finally {
|
|
6055
5513
|
setAbsAssignCollector(null);
|
|
6056
|
-
setAbsCallCollector(
|
|
5514
|
+
setAbsCallCollector(prevCallCollector);
|
|
6057
5515
|
}
|
|
6058
5516
|
const callIssues = canSkipLiteralCallScan(source, file) ? [] : scanLiteralCalls(source, names, phi, {
|
|
6059
5517
|
loadModule: opts.loadModule,
|
|
@@ -6301,10 +5759,19 @@ function scanCaseInconsistency(source, knownFns, opts) {
|
|
|
6301
5759
|
});
|
|
6302
5760
|
if (!eff || eff.source !== "handwritten") return;
|
|
6303
5761
|
const conflictParams = new Set(eff.conflict?.params ?? []);
|
|
5762
|
+
const formals = g.formals ?? [];
|
|
6304
5763
|
const reqs = [];
|
|
6305
5764
|
for (const p of eff.params) {
|
|
6306
5765
|
if (conflictParams.has(p.param)) continue;
|
|
6307
|
-
|
|
5766
|
+
let idx = paramNames.indexOf(p.param);
|
|
5767
|
+
let field;
|
|
5768
|
+
if (idx < 0 && formals.length > 0) {
|
|
5769
|
+
const hit = locateContractParam(formals, p.param);
|
|
5770
|
+
if (hit) {
|
|
5771
|
+
idx = hit.index;
|
|
5772
|
+
field = hit.field;
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
6308
5775
|
if (idx < 0) continue;
|
|
6309
5776
|
reqs.push([
|
|
6310
5777
|
idx,
|
|
@@ -6312,15 +5779,40 @@ function scanCaseInconsistency(source, knownFns, opts) {
|
|
|
6312
5779
|
param: p.param,
|
|
6313
5780
|
pred: instantiateConstraint(p.constraint, p.param),
|
|
6314
5781
|
constraint: p.constraint
|
|
6315
|
-
}
|
|
5782
|
+
},
|
|
5783
|
+
field
|
|
6316
5784
|
]);
|
|
6317
5785
|
}
|
|
6318
5786
|
if (reqs.length === 0) return;
|
|
6319
5787
|
const absArgs = args.map((a) => parseLitArg(a) ?? absUnknown());
|
|
6320
|
-
for (const
|
|
5788
|
+
for (const req of reqs) {
|
|
5789
|
+
const idx = req[0];
|
|
5790
|
+
const entry = req[1];
|
|
5791
|
+
const field = req[2];
|
|
6321
5792
|
if (entry.constraint.fields) continue;
|
|
6322
|
-
|
|
5793
|
+
let arg = absArgs[idx];
|
|
6323
5794
|
if (!arg) continue;
|
|
5795
|
+
if (field) {
|
|
5796
|
+
const projected = projectCaseArgField(arg, field);
|
|
5797
|
+
if (!projected) {
|
|
5798
|
+
const k = arg.shape.k;
|
|
5799
|
+
if (k !== "unknown" && k !== "any") {
|
|
5800
|
+
const paramName = entry.param || paramNames[idx] || `arg${idx}`;
|
|
5801
|
+
out.push({
|
|
5802
|
+
severity: "error",
|
|
5803
|
+
code: "nudo:case-inconsistency",
|
|
5804
|
+
message: `${fnName} case "${caseName}": \u89C1\u8BC1 \u22AD \u5951\u7EA6`,
|
|
5805
|
+
actual: formatAbs(arg),
|
|
5806
|
+
expected: `missing field ${field}`,
|
|
5807
|
+
suggestion: `case \u5B9E\u53C2\u8865\u5168\u5B57\u6BB5 ${field}\uFF08\u5951\u7EA6\u4F4D ${paramName}\uFF09`,
|
|
5808
|
+
fn: fnName,
|
|
5809
|
+
line
|
|
5810
|
+
});
|
|
5811
|
+
}
|
|
5812
|
+
continue;
|
|
5813
|
+
}
|
|
5814
|
+
arg = projected;
|
|
5815
|
+
}
|
|
6324
5816
|
const lv = litValue(arg);
|
|
6325
5817
|
if (lv === void 0 || typeof lv !== "number" && typeof lv !== "string" && typeof lv !== "boolean") {
|
|
6326
5818
|
continue;
|
|
@@ -6619,8 +6111,12 @@ function formatReturnDisplay(g) {
|
|
|
6619
6111
|
}
|
|
6620
6112
|
return memberPath(abs2).text;
|
|
6621
6113
|
}
|
|
6622
|
-
function collectAbsInlays(source,
|
|
6114
|
+
function collectAbsInlays(source, opts) {
|
|
6623
6115
|
const inlays = [];
|
|
6116
|
+
const refineOpts = opts?.loadModule || opts?.fromFile ? {
|
|
6117
|
+
...opts.loadModule ? { loadModule: opts.loadModule } : {},
|
|
6118
|
+
...opts.fromFile ? { fromFile: opts.fromFile } : {}
|
|
6119
|
+
} : void 0;
|
|
6624
6120
|
for (const { name, node } of listFunctions(source)) {
|
|
6625
6121
|
let g;
|
|
6626
6122
|
try {
|
|
@@ -6629,6 +6125,12 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
6629
6125
|
continue;
|
|
6630
6126
|
}
|
|
6631
6127
|
if (!g) continue;
|
|
6128
|
+
const tier = opts?.fromFile !== void 0 ? interfaceTierOf(source, name, opts.fromFile, {
|
|
6129
|
+
...opts.loadModule ? { loadModule: opts.loadModule } : {},
|
|
6130
|
+
...opts.autoBind !== void 0 ? { autoBind: opts.autoBind } : {}
|
|
6131
|
+
}) : void 0;
|
|
6132
|
+
const tierSrc = tier?.source;
|
|
6133
|
+
const isImplicitExport = tierSrc === "implicit";
|
|
6632
6134
|
const params = g.params;
|
|
6633
6135
|
const predsByName = /* @__PURE__ */ new Map();
|
|
6634
6136
|
if (g.entryReqs) {
|
|
@@ -6649,7 +6151,8 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
6649
6151
|
line: p.loc.end.line,
|
|
6650
6152
|
character: p.loc.end.column,
|
|
6651
6153
|
label: ` where ${text}`,
|
|
6652
|
-
kind: "parameter"
|
|
6154
|
+
kind: "parameter",
|
|
6155
|
+
...tierSrc ? { interfaceSource: tierSrc } : {}
|
|
6653
6156
|
});
|
|
6654
6157
|
}
|
|
6655
6158
|
}
|
|
@@ -6661,11 +6164,14 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
6661
6164
|
} catch {
|
|
6662
6165
|
label = `: ${formatShape(g.symbolic)}`;
|
|
6663
6166
|
}
|
|
6167
|
+
if (isImplicitExport) label += " \xB7 derived";
|
|
6664
6168
|
inlays.push({
|
|
6665
6169
|
line: bodyLoc.start.line,
|
|
6666
6170
|
character: Math.max(0, bodyLoc.start.column),
|
|
6667
6171
|
label: `${label} `,
|
|
6668
|
-
kind: "type"
|
|
6172
|
+
kind: "type",
|
|
6173
|
+
...tierSrc ? { interfaceSource: tierSrc } : {},
|
|
6174
|
+
...isImplicitExport ? { derived: true } : {}
|
|
6669
6175
|
});
|
|
6670
6176
|
}
|
|
6671
6177
|
}
|
|
@@ -6676,7 +6182,7 @@ function collectAbsInlays(source, refineOpts) {
|
|
|
6676
6182
|
function denoteGuard(a, v2) {
|
|
6677
6183
|
const lv = litValue(a);
|
|
6678
6184
|
if (lv !== void 0 && (!a.pred || a.pred.op === "true")) {
|
|
6679
|
-
return
|
|
6185
|
+
return eqGuard(v2, lv);
|
|
6680
6186
|
}
|
|
6681
6187
|
const shape2 = denoteShape(a.shape, v2);
|
|
6682
6188
|
const pred = denotePred(a, v2);
|
|
@@ -6755,7 +6261,7 @@ function denotePred(a, v2) {
|
|
|
6755
6261
|
const p = a.pred;
|
|
6756
6262
|
if (!p || p.op === "true") {
|
|
6757
6263
|
const lv = litValue(a);
|
|
6758
|
-
if (lv !== void 0) return
|
|
6264
|
+
if (lv !== void 0) return eqGuard(v2, lv);
|
|
6759
6265
|
return "true";
|
|
6760
6266
|
}
|
|
6761
6267
|
return predAsJs(p, v2, a);
|
|
@@ -6784,15 +6290,15 @@ function predAsJs(p, v2, a) {
|
|
|
6784
6290
|
const leftIsValue = termIsValue(p.a, a);
|
|
6785
6291
|
const rightLit = litOfTerm(p.b);
|
|
6786
6292
|
if (leftIsValue && rightLit !== void 0) {
|
|
6787
|
-
return
|
|
6293
|
+
return cmpOp(v2, op, rightLit);
|
|
6788
6294
|
}
|
|
6789
6295
|
const leftLit = litOfTerm(p.a);
|
|
6790
6296
|
const rightIsValue = termIsValue(p.b, a);
|
|
6791
6297
|
if (rightIsValue && leftLit !== void 0) {
|
|
6792
|
-
return
|
|
6298
|
+
return cmpLitValue(leftLit, op, v2);
|
|
6793
6299
|
}
|
|
6794
6300
|
if (leftLit !== void 0 && rightLit !== void 0) {
|
|
6795
|
-
return `${
|
|
6301
|
+
return `${jsLit(leftLit)} ${op} ${jsLit(rightLit)}`;
|
|
6796
6302
|
}
|
|
6797
6303
|
return "true";
|
|
6798
6304
|
}
|
|
@@ -6803,6 +6309,35 @@ function predAsJs(p, v2, a) {
|
|
|
6803
6309
|
function litOfTerm(t) {
|
|
6804
6310
|
return t.op === "lit" ? t.value : void 0;
|
|
6805
6311
|
}
|
|
6312
|
+
function jsLit(v2) {
|
|
6313
|
+
if (v2 === void 0) return "undefined";
|
|
6314
|
+
if (v2 === null) return "null";
|
|
6315
|
+
if (typeof v2 === "number") {
|
|
6316
|
+
if (Number.isNaN(v2)) return "NaN";
|
|
6317
|
+
if (v2 === Infinity) return "Infinity";
|
|
6318
|
+
if (v2 === -Infinity) return "-Infinity";
|
|
6319
|
+
return String(v2);
|
|
6320
|
+
}
|
|
6321
|
+
return JSON.stringify(v2);
|
|
6322
|
+
}
|
|
6323
|
+
function eqGuard(v2, lv) {
|
|
6324
|
+
if (typeof lv === "number" && Number.isNaN(lv)) return `Number.isNaN(${v2})`;
|
|
6325
|
+
return `${v2} === ${jsLit(lv)}`;
|
|
6326
|
+
}
|
|
6327
|
+
function cmpOp(v2, op, lit3) {
|
|
6328
|
+
if (typeof lit3 === "number" && Number.isNaN(lit3)) {
|
|
6329
|
+
if (op === "===") return `Number.isNaN(${v2})`;
|
|
6330
|
+
if (op === "!==") return `!Number.isNaN(${v2})`;
|
|
6331
|
+
}
|
|
6332
|
+
return `${v2} ${op} ${jsLit(lit3)}`;
|
|
6333
|
+
}
|
|
6334
|
+
function cmpLitValue(lit3, op, v2) {
|
|
6335
|
+
if (typeof lit3 === "number" && Number.isNaN(lit3)) {
|
|
6336
|
+
if (op === "===") return `Number.isNaN(${v2})`;
|
|
6337
|
+
if (op === "!==") return `!Number.isNaN(${v2})`;
|
|
6338
|
+
}
|
|
6339
|
+
return `${jsLit(lit3)} ${op} ${v2}`;
|
|
6340
|
+
}
|
|
6806
6341
|
function termIsValue(t, a) {
|
|
6807
6342
|
if (t.op === "var") return true;
|
|
6808
6343
|
if (t.op === "lit") {
|
|
@@ -6814,6 +6349,8 @@ function termIsValue(t, a) {
|
|
|
6814
6349
|
export {
|
|
6815
6350
|
$add,
|
|
6816
6351
|
$arr,
|
|
6352
|
+
$arrMutContainer,
|
|
6353
|
+
$arrRest,
|
|
6817
6354
|
$async,
|
|
6818
6355
|
$asyncReturn,
|
|
6819
6356
|
$await,
|
|
@@ -6825,6 +6362,7 @@ export {
|
|
|
6825
6362
|
$div,
|
|
6826
6363
|
$elems,
|
|
6827
6364
|
$eq,
|
|
6365
|
+
$eqLoose,
|
|
6828
6366
|
$fnVal,
|
|
6829
6367
|
$for,
|
|
6830
6368
|
$forIter,
|
|
@@ -6838,22 +6376,29 @@ export {
|
|
|
6838
6376
|
$idxSet,
|
|
6839
6377
|
$invoke,
|
|
6840
6378
|
$invokeSuper,
|
|
6379
|
+
$isForkExit,
|
|
6841
6380
|
$join,
|
|
6842
6381
|
$le,
|
|
6843
6382
|
$len,
|
|
6844
6383
|
$lit,
|
|
6384
|
+
$loopReturn,
|
|
6845
6385
|
$lt,
|
|
6846
6386
|
$mod,
|
|
6847
6387
|
$mul,
|
|
6848
6388
|
$ne,
|
|
6389
|
+
$neLoose,
|
|
6849
6390
|
$neg,
|
|
6850
6391
|
$new,
|
|
6851
6392
|
$not,
|
|
6393
|
+
$nullishTest,
|
|
6852
6394
|
$obj,
|
|
6395
|
+
$objRest,
|
|
6853
6396
|
$optionalGet,
|
|
6854
6397
|
$optionalInvoke,
|
|
6855
6398
|
$orDefault,
|
|
6399
|
+
$pushLoopExit,
|
|
6856
6400
|
$regex,
|
|
6401
|
+
$rethrowIfNudoReturn,
|
|
6857
6402
|
$set,
|
|
6858
6403
|
$setKey,
|
|
6859
6404
|
$spread,
|
|
@@ -6864,6 +6409,10 @@ export {
|
|
|
6864
6409
|
$thisGet,
|
|
6865
6410
|
$thisSet,
|
|
6866
6411
|
$throw,
|
|
6412
|
+
$tryCurrentMark,
|
|
6413
|
+
$tryMark,
|
|
6414
|
+
$tryPopMark,
|
|
6415
|
+
$tryTakeSince,
|
|
6867
6416
|
$typeof,
|
|
6868
6417
|
$while,
|
|
6869
6418
|
$whileSeq,
|
|
@@ -6871,32 +6420,35 @@ export {
|
|
|
6871
6420
|
DEFAULT_MAX_LOOP_ITERS,
|
|
6872
6421
|
MAX_CALL_DEPTH,
|
|
6873
6422
|
MAX_TOTAL_CALLS,
|
|
6423
|
+
NudoReturn,
|
|
6874
6424
|
NudoSidecarError,
|
|
6875
6425
|
NudoThrow,
|
|
6876
|
-
Ops,
|
|
6877
6426
|
SELF,
|
|
6878
|
-
|
|
6427
|
+
abortDerivationSession,
|
|
6879
6428
|
abs,
|
|
6880
6429
|
absFunction,
|
|
6430
|
+
absShapeKey,
|
|
6881
6431
|
absTemplateViews,
|
|
6882
6432
|
absToConstraint,
|
|
6883
6433
|
absToString,
|
|
6884
|
-
absToTypeValue,
|
|
6885
6434
|
add,
|
|
6886
6435
|
allFixedTextOfViews,
|
|
6887
6436
|
alphaOf,
|
|
6888
6437
|
analyzeFn,
|
|
6438
|
+
analyzeFnFull,
|
|
6889
6439
|
and,
|
|
6440
|
+
any,
|
|
6890
6441
|
anyVar,
|
|
6891
6442
|
app,
|
|
6892
6443
|
applyAbsFn,
|
|
6893
|
-
applyBinaryOp,
|
|
6894
6444
|
applyCallbackAbs,
|
|
6895
6445
|
array,
|
|
6896
6446
|
asAbs,
|
|
6897
6447
|
asAbsVal,
|
|
6898
6448
|
attachFnImpl,
|
|
6899
6449
|
awaitAbs,
|
|
6450
|
+
beginCollectionFork,
|
|
6451
|
+
beginDerivationSession,
|
|
6900
6452
|
betaOf,
|
|
6901
6453
|
bindImports,
|
|
6902
6454
|
bool,
|
|
@@ -6904,7 +6456,9 @@ export {
|
|
|
6904
6456
|
boolean,
|
|
6905
6457
|
buildArgsFromAssume,
|
|
6906
6458
|
callAbsMethod,
|
|
6459
|
+
callAtFunctionBoundary,
|
|
6907
6460
|
callFunction,
|
|
6461
|
+
callFunctionFull,
|
|
6908
6462
|
callTranspiledExport,
|
|
6909
6463
|
callTranspiledExportFull,
|
|
6910
6464
|
canSkipLiteralCallScan,
|
|
@@ -6914,40 +6468,41 @@ export {
|
|
|
6914
6468
|
checkSource,
|
|
6915
6469
|
classFromMethods,
|
|
6916
6470
|
clearBClasses,
|
|
6471
|
+
clearCollectionTables,
|
|
6917
6472
|
cmp,
|
|
6918
6473
|
coerceAsyncReturn,
|
|
6919
|
-
collapseLiteralUnion,
|
|
6920
6474
|
collectAbsExports,
|
|
6475
|
+
collectAbsFreeVars,
|
|
6921
6476
|
collectAbsInlays,
|
|
6922
6477
|
collectAbsNodeTypes,
|
|
6478
|
+
collectionElementJoin,
|
|
6479
|
+
collectionExactLen,
|
|
6923
6480
|
concatString,
|
|
6924
|
-
concatTemplates,
|
|
6925
6481
|
confJoin,
|
|
6926
6482
|
constraintToEntryAbs,
|
|
6483
|
+
contractParamNameSet,
|
|
6927
6484
|
createEnvironment,
|
|
6928
6485
|
createHofCollectCtx,
|
|
6929
|
-
createRange,
|
|
6930
|
-
createTemplate,
|
|
6931
6486
|
createTemplateAbs,
|
|
6932
6487
|
currentExecPhi,
|
|
6933
6488
|
currentPhi,
|
|
6934
6489
|
decideEndsWith,
|
|
6935
6490
|
decideIncludes,
|
|
6936
6491
|
decideStartsWith,
|
|
6937
|
-
deepCloneTypeValue,
|
|
6938
6492
|
defaultLeakBudget,
|
|
6939
6493
|
defineClass,
|
|
6940
6494
|
definitelyNotNullishShape,
|
|
6941
6495
|
denoteGuard,
|
|
6496
|
+
derivationChain,
|
|
6942
6497
|
describePhi,
|
|
6943
|
-
dispatchBinaryOp,
|
|
6944
|
-
dispatchMethod,
|
|
6945
|
-
dispatchProperty,
|
|
6946
6498
|
div,
|
|
6947
6499
|
effectiveInterface,
|
|
6948
6500
|
emptyEnv,
|
|
6949
6501
|
emptyPhi,
|
|
6502
|
+
endCollectionFork,
|
|
6503
|
+
endDerivationSession,
|
|
6950
6504
|
eq,
|
|
6505
|
+
errorBrandAbs,
|
|
6951
6506
|
evalArrayStatic,
|
|
6952
6507
|
evalBuiltinInstanceMethod,
|
|
6953
6508
|
evalBuiltinNew,
|
|
@@ -6984,11 +6539,15 @@ export {
|
|
|
6984
6539
|
fnConstraintToEntryReqs,
|
|
6985
6540
|
fnFingerprints,
|
|
6986
6541
|
fnOf,
|
|
6542
|
+
formalParamDisplayNames,
|
|
6543
|
+
formalParamsFromNodes,
|
|
6987
6544
|
formatAbs,
|
|
6988
6545
|
formatAbsMultiline,
|
|
6989
6546
|
formatCheckReport,
|
|
6990
6547
|
formatConstraint,
|
|
6991
6548
|
formatDiagnostics,
|
|
6549
|
+
formatEffectiveInterfaceDisplay,
|
|
6550
|
+
formatInterfaceTierLine,
|
|
6992
6551
|
formatShape,
|
|
6993
6552
|
formatShapeSlot,
|
|
6994
6553
|
formatTemplateNameViews,
|
|
@@ -7004,20 +6563,16 @@ export {
|
|
|
7004
6563
|
getBClass,
|
|
7005
6564
|
getClass,
|
|
7006
6565
|
getClassChain,
|
|
6566
|
+
getDerivation,
|
|
7007
6567
|
getFnImpl,
|
|
7008
6568
|
getFnNameAndBodies,
|
|
7009
|
-
getFnSig,
|
|
7010
6569
|
getGeneralizeMemoSize,
|
|
7011
6570
|
getParseSourceCacheSize,
|
|
7012
|
-
getPrimitiveTypeOf,
|
|
7013
|
-
getRangeMeta,
|
|
7014
|
-
getRefinedBase,
|
|
7015
6571
|
getSlot,
|
|
7016
|
-
getTemplateParts,
|
|
7017
6572
|
getTerm,
|
|
7018
|
-
getTvConfidence,
|
|
7019
6573
|
gt,
|
|
7020
6574
|
gtNum,
|
|
6575
|
+
hasDerivationSession,
|
|
7021
6576
|
hashSource,
|
|
7022
6577
|
implies,
|
|
7023
6578
|
instanceOf,
|
|
@@ -7025,22 +6580,26 @@ export {
|
|
|
7025
6580
|
instantiateConstraint,
|
|
7026
6581
|
instantiateReturn,
|
|
7027
6582
|
interfaceDiagCount,
|
|
6583
|
+
interfaceSourceOf,
|
|
6584
|
+
interfaceTierOf,
|
|
6585
|
+
isArrMutator,
|
|
7028
6586
|
isDefinitelyFalse,
|
|
7029
6587
|
isDefinitelyTrue,
|
|
6588
|
+
isErrorCtorName,
|
|
6589
|
+
isEvalMissingSlotEnabled,
|
|
7030
6590
|
isExactLit,
|
|
7031
|
-
isFnSig,
|
|
7032
6591
|
isIntFlag,
|
|
6592
|
+
isMapAbs,
|
|
7033
6593
|
isNodeModulesPath,
|
|
7034
6594
|
isNudoConstraint,
|
|
6595
|
+
isNudoReturn,
|
|
7035
6596
|
isNudoThrow,
|
|
7036
6597
|
isNullishLitAbs,
|
|
7037
6598
|
isNumPrim,
|
|
7038
6599
|
isObj,
|
|
7039
|
-
isRange,
|
|
7040
6600
|
isRelFn,
|
|
6601
|
+
isSetAbs,
|
|
7041
6602
|
isStrPrim,
|
|
7042
|
-
isSubtypeOf,
|
|
7043
|
-
isTemplate,
|
|
7044
6603
|
isTemplateLike,
|
|
7045
6604
|
joinAbs,
|
|
7046
6605
|
joinFunctions,
|
|
@@ -7061,30 +6620,44 @@ export {
|
|
|
7061
6620
|
literalMeetsConstraint,
|
|
7062
6621
|
loadModuleDepsFingerprint,
|
|
7063
6622
|
localNamedExports,
|
|
6623
|
+
locateContractParam,
|
|
7064
6624
|
lookupMethod,
|
|
7065
6625
|
lookupMethodWithOwner,
|
|
7066
6626
|
lookupSuperMethod,
|
|
6627
|
+
looseEqAbs,
|
|
7067
6628
|
lt,
|
|
7068
6629
|
ltNum,
|
|
6630
|
+
makeMapAbs,
|
|
6631
|
+
makeSetAbs,
|
|
7069
6632
|
makeSum,
|
|
6633
|
+
mapClearEntries,
|
|
6634
|
+
mapDeleteEntry,
|
|
7070
6635
|
mapElementFallback,
|
|
6636
|
+
mapEntriesAbs,
|
|
6637
|
+
mapGetEntry,
|
|
6638
|
+
mapHasEntry,
|
|
6639
|
+
mapSetEntry,
|
|
6640
|
+
mapSizeAbs,
|
|
6641
|
+
mapValuesAbs,
|
|
7071
6642
|
matchRelIdentLit,
|
|
7072
6643
|
maybeLeak,
|
|
7073
6644
|
mergeAdjacentFixedViews,
|
|
7074
|
-
|
|
6645
|
+
mergeCollectionArms,
|
|
7075
6646
|
mock,
|
|
7076
|
-
mockHelperToTypeValue,
|
|
7077
6647
|
mod,
|
|
7078
6648
|
mul,
|
|
7079
6649
|
namespaceNameOf,
|
|
7080
|
-
narrowType,
|
|
7081
6650
|
ne,
|
|
7082
6651
|
negAbs,
|
|
7083
6652
|
never,
|
|
7084
6653
|
normPath,
|
|
7085
6654
|
not,
|
|
7086
6655
|
notAbs,
|
|
6656
|
+
noteCollectionWrite,
|
|
6657
|
+
noteDerivationAdd,
|
|
6658
|
+
noteDerivationJoin,
|
|
7087
6659
|
noteMemberDispatchMiss,
|
|
6660
|
+
noteObjSlotMissing,
|
|
7088
6661
|
notePrimMemberMissing,
|
|
7089
6662
|
noteUnknownMemberMissing,
|
|
7090
6663
|
num,
|
|
@@ -7101,15 +6674,20 @@ export {
|
|
|
7101
6674
|
partial,
|
|
7102
6675
|
phiAnd,
|
|
7103
6676
|
pick,
|
|
6677
|
+
popCollectionArm,
|
|
7104
6678
|
popPhi,
|
|
7105
6679
|
predEquals,
|
|
7106
6680
|
predToString,
|
|
7107
6681
|
predVars,
|
|
7108
6682
|
projectBrand,
|
|
6683
|
+
projectDerivationDsl,
|
|
7109
6684
|
projectFlatMapResult,
|
|
7110
6685
|
promoteParamShape,
|
|
7111
6686
|
ptypeof,
|
|
6687
|
+
pushCollectionArm,
|
|
6688
|
+
pushLoopExit,
|
|
7112
6689
|
pushPhi,
|
|
6690
|
+
pushThrowExit,
|
|
7113
6691
|
recordMemberDiag,
|
|
7114
6692
|
refineAbsForRelTrue,
|
|
7115
6693
|
refineDiagCount,
|
|
@@ -7128,17 +6706,27 @@ export {
|
|
|
7128
6706
|
resetPhi,
|
|
7129
6707
|
resolveDepPath,
|
|
7130
6708
|
runTranspiled,
|
|
6709
|
+
runWithEvalMissingSlot,
|
|
6710
|
+
runWithLoopExits,
|
|
7131
6711
|
serializeCheckJson,
|
|
7132
6712
|
setAbsAssignCollector,
|
|
7133
6713
|
setAbsCallCollector,
|
|
7134
6714
|
setAbsNodeCollector,
|
|
7135
6715
|
setAbsTruncationCollector,
|
|
6716
|
+
setAddEntry,
|
|
7136
6717
|
setApplyCallbackHost,
|
|
7137
6718
|
setBCallCollector,
|
|
6719
|
+
setClearEntries,
|
|
6720
|
+
setDeleteEntry,
|
|
6721
|
+
setDerivation,
|
|
6722
|
+
setDerivationCollector,
|
|
6723
|
+
setElementsAbs,
|
|
6724
|
+
setEvalMissingSlotEnabled,
|
|
6725
|
+
setHasEntry,
|
|
7138
6726
|
setInterfaceDiagCollector,
|
|
7139
6727
|
setMemberDiagCollector,
|
|
7140
6728
|
setRefineDiagCollector,
|
|
7141
|
-
|
|
6729
|
+
setSizeAbs,
|
|
7142
6730
|
shape,
|
|
7143
6731
|
shapeOfTerm,
|
|
7144
6732
|
shapeOnlyFn,
|
|
@@ -7147,7 +6735,6 @@ export {
|
|
|
7147
6735
|
sidecarPathOf,
|
|
7148
6736
|
sidecarSpecsOf,
|
|
7149
6737
|
simplifyTerm,
|
|
7150
|
-
simplifyUnion,
|
|
7151
6738
|
snapshotAbs,
|
|
7152
6739
|
spread,
|
|
7153
6740
|
spy,
|
|
@@ -7162,17 +6749,20 @@ export {
|
|
|
7162
6749
|
substAbs,
|
|
7163
6750
|
substPred,
|
|
7164
6751
|
substPredAbs,
|
|
7165
|
-
subtractType,
|
|
7166
6752
|
superNameOf,
|
|
7167
6753
|
tagAbsOrigin,
|
|
6754
|
+
tagDerivationRoot,
|
|
7168
6755
|
takeInterfaceDiags,
|
|
7169
6756
|
takeInterfaceDiagsSince,
|
|
6757
|
+
takeLoopExits,
|
|
7170
6758
|
takeRefineDiags,
|
|
7171
6759
|
takeRefineDiagsSince,
|
|
6760
|
+
takeThrowExits,
|
|
7172
6761
|
templateMatchesValue,
|
|
7173
6762
|
templatePartsOf,
|
|
7174
6763
|
termDepth,
|
|
7175
6764
|
termEquals,
|
|
6765
|
+
termKey,
|
|
7176
6766
|
termNodes,
|
|
7177
6767
|
termToString,
|
|
7178
6768
|
transpile,
|
|
@@ -7184,16 +6774,12 @@ export {
|
|
|
7184
6774
|
tryPromoteForOfIteratee,
|
|
7185
6775
|
tryPromoteHofCallback,
|
|
7186
6776
|
tryPromoteReceiverAsArr,
|
|
7187
|
-
typeValueEquals,
|
|
7188
|
-
typeValueToAbs,
|
|
7189
|
-
typeValueToString,
|
|
7190
6777
|
typeofAbs,
|
|
7191
6778
|
undefAbs,
|
|
7192
6779
|
union,
|
|
7193
6780
|
unknown,
|
|
7194
6781
|
v,
|
|
7195
6782
|
viewTemplateParts,
|
|
7196
|
-
widenLiteral,
|
|
7197
6783
|
withExecPhi,
|
|
7198
6784
|
withPhiConstraint,
|
|
7199
6785
|
withVar,
|