@nudojs/core 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -10504,6 +10504,10 @@ var _bForkBudgetLimit = MAX_B_TOTAL_FORKS;
|
|
|
10504
10504
|
var _bForkCount = 0;
|
|
10505
10505
|
var _bForkTruncNoted = false;
|
|
10506
10506
|
var FORK_TRUNCATION_LABEL = "#fork-budget";
|
|
10507
|
+
var HOST_EFFECT_LABEL_PREFIX = "#host-effect:";
|
|
10508
|
+
function noteHostEffectBlocked(name) {
|
|
10509
|
+
noteAbsTruncation(`${HOST_EFFECT_LABEL_PREFIX}${name}`);
|
|
10510
|
+
}
|
|
10507
10511
|
function noteBForkTruncation() {
|
|
10508
10512
|
noteAbsTruncation(FORK_TRUNCATION_LABEL);
|
|
10509
10513
|
}
|
|
@@ -12578,6 +12582,26 @@ var GLOBAL_FNS = /* @__PURE__ */ new Set([
|
|
|
12578
12582
|
"eval",
|
|
12579
12583
|
"Symbol"
|
|
12580
12584
|
]);
|
|
12585
|
+
var NEVER_EXEC_HOST_FN_NAMES = [
|
|
12586
|
+
"fetch",
|
|
12587
|
+
"XMLHttpRequest",
|
|
12588
|
+
"WebSocket",
|
|
12589
|
+
"EventSource",
|
|
12590
|
+
"setTimeout",
|
|
12591
|
+
"setInterval",
|
|
12592
|
+
"setImmediate",
|
|
12593
|
+
"queueMicrotask",
|
|
12594
|
+
"requestAnimationFrame",
|
|
12595
|
+
"requestIdleCallback"
|
|
12596
|
+
];
|
|
12597
|
+
function neverExecHostName(fn) {
|
|
12598
|
+
if (typeof fn !== "function") return null;
|
|
12599
|
+
const g = globalThis;
|
|
12600
|
+
for (const n of NEVER_EXEC_HOST_FN_NAMES) {
|
|
12601
|
+
if (fn === g[n]) return n;
|
|
12602
|
+
}
|
|
12603
|
+
return null;
|
|
12604
|
+
}
|
|
12581
12605
|
function noteBCallRecord(r) {
|
|
12582
12606
|
if (!bCallCollector) return;
|
|
12583
12607
|
try {
|
|
@@ -12659,8 +12683,12 @@ function $callNamed(name, fn, args, loc, argLocs) {
|
|
|
12659
12683
|
try {
|
|
12660
12684
|
if (typeof fn === "function") {
|
|
12661
12685
|
const g = GLOBAL_FNS.has(name) && fn === globalThis[name] ? evalGlobalFn(name, args) : void 0;
|
|
12686
|
+
const blockedHost = g === void 0 ? neverExecHostName(fn) : null;
|
|
12662
12687
|
if (g !== void 0) {
|
|
12663
12688
|
result = g;
|
|
12689
|
+
} else if (blockedHost !== null) {
|
|
12690
|
+
noteHostEffectBlocked(blockedHost);
|
|
12691
|
+
result = bTruncatedAbs();
|
|
12664
12692
|
} else {
|
|
12665
12693
|
const entered = bEnterCall(name, fn, args);
|
|
12666
12694
|
if (!entered.ok) {
|
|
@@ -12759,7 +12787,13 @@ function execRegexBrand(re, method, args) {
|
|
|
12759
12787
|
if (method === "toString") return strLit(`/${parts.pat}/${parts.flags}`);
|
|
12760
12788
|
const subject = args[0] ? litValue(args[0]) : void 0;
|
|
12761
12789
|
if (typeof subject !== "string") {
|
|
12762
|
-
|
|
12790
|
+
if (method === "test") {
|
|
12791
|
+
return abs({ k: "prim", type: "boolean" }, void 0, void 0, "partial");
|
|
12792
|
+
}
|
|
12793
|
+
const element = joinAbs(str(), undefAbs());
|
|
12794
|
+
const matchAbs = abs({ k: "arr", element }, void 0, void 0, "path");
|
|
12795
|
+
const nullAbs = abs({ k: "unknown" }, { op: "lit", value: null }, void 0, "exact");
|
|
12796
|
+
return joinAbs(nullAbs, matchAbs);
|
|
12763
12797
|
}
|
|
12764
12798
|
try {
|
|
12765
12799
|
return regexExecWithState(re, method, subject).result;
|
|
@@ -14936,6 +14970,8 @@ export {
|
|
|
14936
14970
|
exitCall,
|
|
14937
14971
|
MAX_B_TOTAL_FORKS,
|
|
14938
14972
|
FORK_TRUNCATION_LABEL,
|
|
14973
|
+
HOST_EFFECT_LABEL_PREFIX,
|
|
14974
|
+
noteHostEffectBlocked,
|
|
14939
14975
|
noteBForkTruncation,
|
|
14940
14976
|
setBForkBudgetLimit,
|
|
14941
14977
|
getBForkBudgetLimit,
|
package/dist/exec.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
takeRefineDiagsSince,
|
|
68
68
|
throwConstraintToKinds,
|
|
69
69
|
union
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-V2I7VXFZ.js";
|
|
71
71
|
import {
|
|
72
72
|
$add,
|
|
73
73
|
$arguments,
|
|
@@ -178,6 +178,7 @@ import {
|
|
|
178
178
|
$yield,
|
|
179
179
|
DEFAULT_MAX_LOOP_ITERS,
|
|
180
180
|
FORK_TRUNCATION_LABEL,
|
|
181
|
+
HOST_EFFECT_LABEL_PREFIX,
|
|
181
182
|
MAX_B_CALL_DEPTH,
|
|
182
183
|
MAX_B_TOTAL_CALLS,
|
|
183
184
|
NudoLoopSignal,
|
|
@@ -465,7 +466,7 @@ import {
|
|
|
465
466
|
v,
|
|
466
467
|
withExecPhi,
|
|
467
468
|
withVar
|
|
468
|
-
} from "./chunk-
|
|
469
|
+
} from "./chunk-CDH7QCGQ.js";
|
|
469
470
|
|
|
470
471
|
// src/environment.ts
|
|
471
472
|
function createEnvironment(parent, bindings = /* @__PURE__ */ new Map()) {
|
|
@@ -2101,6 +2102,17 @@ function checkSourceInner(filePath, source, file, phi, opts, issues, signatures,
|
|
|
2101
2102
|
});
|
|
2102
2103
|
continue;
|
|
2103
2104
|
}
|
|
2105
|
+
if (label.startsWith(HOST_EFFECT_LABEL_PREFIX)) {
|
|
2106
|
+
const hostName = label.slice(HOST_EFFECT_LABEL_PREFIX.length);
|
|
2107
|
+
issues.push({
|
|
2108
|
+
severity: "info",
|
|
2109
|
+
code: "nudo:host-effect-blocked",
|
|
2110
|
+
message: `Host function '${hostName}' is not executed during analysis (network/timer side effect); result widened to unknown#opaque`,
|
|
2111
|
+
suggestion: "optional: mock it with @nudo:mock / @nudo:env, or pass the value in from a call site",
|
|
2112
|
+
fn: hostName
|
|
2113
|
+
});
|
|
2114
|
+
continue;
|
|
2115
|
+
}
|
|
2104
2116
|
issues.push({
|
|
2105
2117
|
severity: "info",
|
|
2106
2118
|
code: "nudo:recursion-truncated",
|
|
@@ -2230,6 +2242,19 @@ function checkReturnConstraint(fnName, cName, constraint, ret) {
|
|
|
2230
2242
|
const out = [];
|
|
2231
2243
|
if (ret.shape.k === "unknown" && !ret.term) return out;
|
|
2232
2244
|
if (ret.shape.k === "any") return out;
|
|
2245
|
+
if (isNullishLitAbs(ret)) return out;
|
|
2246
|
+
if (ret.shape.k === "sum" && constraint.fields) {
|
|
2247
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2248
|
+
for (const m of ret.shape.members) {
|
|
2249
|
+
for (const issue of checkReturnConstraint(fnName, cName, constraint, m)) {
|
|
2250
|
+
const key = `${issue.message}\0${issue.actual ?? ""}\0${issue.expected ?? ""}`;
|
|
2251
|
+
if (seen.has(key)) continue;
|
|
2252
|
+
seen.add(key);
|
|
2253
|
+
out.push(issue);
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
return out;
|
|
2257
|
+
}
|
|
2233
2258
|
const push = (actual, expected, suggestion) => {
|
|
2234
2259
|
out.push({
|
|
2235
2260
|
severity: "error",
|
|
@@ -2398,6 +2423,11 @@ function actionsForIssue(i) {
|
|
|
2398
2423
|
label: "results widened to unknown \u2014 raise budget or narrow control flow"
|
|
2399
2424
|
}
|
|
2400
2425
|
];
|
|
2426
|
+
case "nudo:host-effect-blocked":
|
|
2427
|
+
return [
|
|
2428
|
+
{ kind: "mock", label: "pin the host API with @nudo:mock / @nudo:env" },
|
|
2429
|
+
{ kind: "info", label: "results widened to unknown \u2014 or feed the value in from a call site" }
|
|
2430
|
+
];
|
|
2401
2431
|
case "nudo:interface-drift":
|
|
2402
2432
|
return [
|
|
2403
2433
|
{
|
package/dist/internal.d.ts
CHANGED
|
@@ -65,6 +65,15 @@ declare const MAX_B_TOTAL_FORKS = 5000;
|
|
|
65
65
|
* 映射为 `nudo:fork-truncated`(warning)。
|
|
66
66
|
*/
|
|
67
67
|
declare const FORK_TRUNCATION_LABEL = "#fork-budget";
|
|
68
|
+
/**
|
|
69
|
+
* 宿主副作用未执行标签前缀:网络/定时器全局(fetch/setTimeout…)在分析期
|
|
70
|
+
* 不真实执行(Abs 实参喂原生实现会真发请求/真排定时器,且可能崩进程),
|
|
71
|
+
* fail-closed 为 unknown#opaque。专用前缀让 check 映射为
|
|
72
|
+
* `nudo:host-effect-blocked`,不复用「某函数被截断」文案。
|
|
73
|
+
*/
|
|
74
|
+
declare const HOST_EFFECT_LABEL_PREFIX = "#host-effect:";
|
|
75
|
+
/** 宿主副作用未执行观测(service/LSP 映射 nudo:host-effect-blocked;与调用截断同 collector 管道) */
|
|
76
|
+
declare function noteHostEffectBlocked(name: string): void;
|
|
68
77
|
/** fork 超限观测(service/LSP 映射 nudo:fork-truncated;与调用截断同 collector 管道) */
|
|
69
78
|
declare function noteBForkTruncation(): void;
|
|
70
79
|
/**
|
|
@@ -538,4 +547,4 @@ declare function runWithEvalMissingSlot<T>(enabled: boolean, body: () => T): T;
|
|
|
538
547
|
*/
|
|
539
548
|
declare function noteObjSlotMissing(recv: Abs | undefined, name: string, loc?: [number, number]): boolean;
|
|
540
549
|
|
|
541
|
-
export { type AbsBudgetStats, type AbsInlay, type ArgDerivation, type BMemberDiag, type ClassDef, type CollectAbsInlaysOpts, type DerivationNode, FORK_TRUNCATION_LABEL, type FnFp, type InjectedDomainEvidenceOpts, type InjectedDomainRecord, MAX_B_TOTAL_FORKS, MAX_CALL_DEPTH, MAX_TOTAL_CALLS, type MethodDef, OBJECT_PROTO_NAMES, type TemplateMeta, type TemplatePartDesc, type TemplatePartView, type TemplatePredicateDecision, abortDerivationSession, absTemplateViews, allFixedTextOfViews, anyMemberResult, awaitAbs, beginDerivationSession, bumpBForkBudget, callBudgetKey, canSkipLiteralCallScan, checkInjectedDomainEvidence, classChainNames, classFromMethods, coerceAsyncReturn, collectAbsInlays, concatString, createTemplateAbs, decideEndsWith, decideIncludes, decideStartsWith, defineClass, definitelyUncallableMember, denoteGuard, derivationChain, endDerivationSession, enterCall, exitCall, fixedLengthOfViews, fnFingerprints, formatTemplateNameViews, generalizeSourceKeyPart, getAbsCallBudgetStats, getAbsOrigin, getBForkBudgetLimit, getBForkCount, getClass, getClassChain, getDerivation, getFnNameAndBodies, hasDerivationSession, hashSource, instanceOf, instantiateClass, isEvalMissingSlotEnabled, isNullishAbs, isTemplateLike, knownPrefixOfViews, knownSuffixOfViews, listTopFunctions, lookupMethod, lookupMethodWithOwner, lookupSuperMethod, mergeAdjacentFixedViews, noteAbsTruncation, noteAnyMemberMayThrow, noteBForkTruncation, noteDerivationAdd, noteDerivationJoin, noteMemberDispatchMiss, noteNullishMemberThrows, noteObjSlotMissing, notePrimMemberMissing, noteUnknownMemberMissing, popCallLoc, projectBrand, projectDerivationDsl, pushCallLoc, recordMemberDiag, resetAbsCallBudget, resetBForkBudget, resetFnFpCache, resetHashSourceCache, runWithEvalMissingSlot, setAbsTruncationCollector, setBForkBudgetLimit, setDerivation, setDerivationCollector, setEvalMissingSlotEnabled, setMemberDiagCollector, stableAnalyzeKeySource, stableCallId, superNameOf, tagAbsOrigin, tagDerivationRoot, templateMatchesValue, templatePartsOf, termKey, truncatedAbs, viewTemplateParts, wrapPromise };
|
|
550
|
+
export { type AbsBudgetStats, type AbsInlay, type ArgDerivation, type BMemberDiag, type ClassDef, type CollectAbsInlaysOpts, type DerivationNode, FORK_TRUNCATION_LABEL, type FnFp, HOST_EFFECT_LABEL_PREFIX, type InjectedDomainEvidenceOpts, type InjectedDomainRecord, MAX_B_TOTAL_FORKS, MAX_CALL_DEPTH, MAX_TOTAL_CALLS, type MethodDef, OBJECT_PROTO_NAMES, type TemplateMeta, type TemplatePartDesc, type TemplatePartView, type TemplatePredicateDecision, abortDerivationSession, absTemplateViews, allFixedTextOfViews, anyMemberResult, awaitAbs, beginDerivationSession, bumpBForkBudget, callBudgetKey, canSkipLiteralCallScan, checkInjectedDomainEvidence, classChainNames, classFromMethods, coerceAsyncReturn, collectAbsInlays, concatString, createTemplateAbs, decideEndsWith, decideIncludes, decideStartsWith, defineClass, definitelyUncallableMember, denoteGuard, derivationChain, endDerivationSession, enterCall, exitCall, fixedLengthOfViews, fnFingerprints, formatTemplateNameViews, generalizeSourceKeyPart, getAbsCallBudgetStats, getAbsOrigin, getBForkBudgetLimit, getBForkCount, getClass, getClassChain, getDerivation, getFnNameAndBodies, hasDerivationSession, hashSource, instanceOf, instantiateClass, isEvalMissingSlotEnabled, isNullishAbs, isTemplateLike, knownPrefixOfViews, knownSuffixOfViews, listTopFunctions, lookupMethod, lookupMethodWithOwner, lookupSuperMethod, mergeAdjacentFixedViews, noteAbsTruncation, noteAnyMemberMayThrow, noteBForkTruncation, noteDerivationAdd, noteDerivationJoin, noteHostEffectBlocked, noteMemberDispatchMiss, noteNullishMemberThrows, noteObjSlotMissing, notePrimMemberMissing, noteUnknownMemberMissing, popCallLoc, projectBrand, projectDerivationDsl, pushCallLoc, recordMemberDiag, resetAbsCallBudget, resetBForkBudget, resetFnFpCache, resetHashSourceCache, runWithEvalMissingSlot, setAbsTruncationCollector, setBForkBudgetLimit, setDerivation, setDerivationCollector, setEvalMissingSlotEnabled, setMemberDiagCollector, stableAnalyzeKeySource, stableCallId, superNameOf, tagAbsOrigin, tagDerivationRoot, templateMatchesValue, templatePartsOf, termKey, truncatedAbs, viewTemplateParts, wrapPromise };
|
package/dist/internal.js
CHANGED
|
@@ -16,13 +16,14 @@ import {
|
|
|
16
16
|
resolveDepPath,
|
|
17
17
|
sidecarSpecsOf,
|
|
18
18
|
stableAnalyzeKeySource
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-V2I7VXFZ.js";
|
|
20
20
|
import {
|
|
21
21
|
$tryDigestSoft,
|
|
22
22
|
$tryMarkSoft,
|
|
23
23
|
$tryReleaseSoft,
|
|
24
24
|
ERROR_FAMILY,
|
|
25
25
|
FORK_TRUNCATION_LABEL,
|
|
26
|
+
HOST_EFFECT_LABEL_PREFIX,
|
|
26
27
|
MAX_B_TOTAL_FORKS,
|
|
27
28
|
MAX_CALL_DEPTH,
|
|
28
29
|
MAX_TOTAL_CALLS,
|
|
@@ -90,6 +91,7 @@ import {
|
|
|
90
91
|
noteBForkTruncation,
|
|
91
92
|
noteDerivationAdd,
|
|
92
93
|
noteDerivationJoin,
|
|
94
|
+
noteHostEffectBlocked,
|
|
93
95
|
noteMemberDispatchMiss,
|
|
94
96
|
noteNullishMemberThrows,
|
|
95
97
|
noteObjSlotMissing,
|
|
@@ -133,7 +135,7 @@ import {
|
|
|
133
135
|
truncatedAbs,
|
|
134
136
|
viewTemplateParts,
|
|
135
137
|
wrapPromise
|
|
136
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-CDH7QCGQ.js";
|
|
137
139
|
|
|
138
140
|
// src/algebra/inlay.ts
|
|
139
141
|
function listFunctions(source) {
|
|
@@ -458,6 +460,7 @@ export {
|
|
|
458
460
|
$tryReleaseSoft,
|
|
459
461
|
ERROR_FAMILY,
|
|
460
462
|
FORK_TRUNCATION_LABEL,
|
|
463
|
+
HOST_EFFECT_LABEL_PREFIX,
|
|
461
464
|
MAX_B_TOTAL_FORKS,
|
|
462
465
|
MAX_CALL_DEPTH,
|
|
463
466
|
MAX_TOTAL_CALLS,
|
|
@@ -535,6 +538,7 @@ export {
|
|
|
535
538
|
noteBForkTruncation,
|
|
536
539
|
noteDerivationAdd,
|
|
537
540
|
noteDerivationJoin,
|
|
541
|
+
noteHostEffectBlocked,
|
|
538
542
|
noteMemberDispatchMiss,
|
|
539
543
|
noteNullishMemberThrows,
|
|
540
544
|
noteObjSlotMissing,
|