@nudojs/service 0.2.1 → 0.3.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/index.d.ts +502 -4
  3. package/dist/index.js +3017 -212
  4. package/package.json +5 -4
  5. package/src/__tests__/abs-bindings.test.ts +53 -0
  6. package/src/__tests__/abs-call-records.test.ts +33 -0
  7. package/src/__tests__/abs-calls.test.ts +59 -0
  8. package/src/__tests__/abs-module-cache.test.ts +121 -0
  9. package/src/__tests__/abs-modules-graph.test.ts +100 -0
  10. package/src/__tests__/abs-typevalue-diff.test.ts +111 -0
  11. package/src/__tests__/analyzer.test.ts +71 -3
  12. package/src/__tests__/bpath-arg-provenance.test.ts +104 -0
  13. package/src/__tests__/bpath-as.test.ts +54 -0
  14. package/src/__tests__/bpath-cache-key.test.ts +33 -0
  15. package/src/__tests__/bpath-calls.test.ts +55 -0
  16. package/src/__tests__/bpath-diagnostics.test.ts +78 -0
  17. package/src/__tests__/bpath-env-modules.test.ts +30 -0
  18. package/src/__tests__/bpath-env.test.ts +80 -0
  19. package/src/__tests__/bpath-hosted-skip.test.ts +71 -0
  20. package/src/__tests__/bpath-import-default-ns.test.ts +106 -0
  21. package/src/__tests__/bpath-method-dedupe.test.ts +65 -0
  22. package/src/__tests__/bpath-method-diag.test.ts +45 -0
  23. package/src/__tests__/bpath-module-diags.test.ts +101 -0
  24. package/src/__tests__/bpath-path-env.test.ts +46 -0
  25. package/src/__tests__/bpath-reexport.test.ts +131 -0
  26. package/src/__tests__/bpath-replace.test.ts +52 -0
  27. package/src/__tests__/bpath-require.test.ts +66 -0
  28. package/src/__tests__/bpath-run.test.ts +109 -0
  29. package/src/__tests__/cjs-require.test.ts +54 -0
  30. package/src/__tests__/diagnostics.test.ts +0 -30
  31. package/src/__tests__/fn-cache-evict.test.ts +56 -0
  32. package/src/__tests__/harvest-auto.test.ts +43 -0
  33. package/src/__tests__/harvest-node.test.ts +24 -0
  34. package/src/__tests__/harvest-package.test.ts +38 -0
  35. package/src/__tests__/harvest-to-abs.test.ts +46 -0
  36. package/src/__tests__/hover-intension.test.ts +39 -0
  37. package/src/__tests__/infer-json.test.ts +35 -0
  38. package/src/__tests__/integration.test.ts +89 -0
  39. package/src/__tests__/m3-intension.test.ts +28 -0
  40. package/src/__tests__/mock-seed-fingerprint.test.ts +64 -0
  41. package/src/__tests__/session-cache-evict.test.ts +90 -0
  42. package/src/__tests__/static-imports.test.ts +44 -0
  43. package/src/abs-modules-graph.ts +387 -0
  44. package/src/analysis-file-cache.ts +51 -0
  45. package/src/analyzer.ts +1416 -124
  46. package/src/bpath-diagnostics.ts +283 -0
  47. package/src/bpath-run.ts +409 -0
  48. package/src/case-emitter.ts +2 -0
  49. package/src/dts-generator.ts +3 -3
  50. package/src/env-to-abs.ts +57 -0
  51. package/src/fn-analysis-cache.ts +119 -0
  52. package/src/guard-generator.ts +8 -1
  53. package/src/harvest-auto.ts +86 -0
  54. package/src/harvest-node.ts +48 -0
  55. package/src/harvest-package.ts +204 -0
  56. package/src/harvest-to-abs.ts +129 -0
  57. package/src/index.ts +104 -1
  58. package/src/infer-json.ts +137 -0
  59. package/src/load-module.ts +34 -0
  60. package/src/mock-abs.ts +275 -0
  61. package/src/semantic-tokens.ts +216 -0
  62. package/src/session-cache.ts +50 -0
  63. package/src/static-imports.ts +241 -0
  64. package/src/target-path.ts +17 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @nudojs/service
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5786fa5: Promote the B-path (transpile + in-process Abs runtime) to the primary evaluation path for capable sources.
8
+
9
+ - Module graph now supports relative imports, bare-package harvest, default/namespace imports, re-exports, `export *`, require, cycle/depth/missing guards, and env modules (`path` / `node:path` etc.).
10
+ - Diagnostics, `@nudo:env` / mock injection, `call@` / `entry@` provenance, method-missing, unknown-recv, generators, classes, async/await, optional chaining, and destructuring run through B.
11
+ - When B hosts a file, `evaluateProgram` is skipped so TypeValue no longer double-reports.
12
+ - CLI `check` / `types` / `test` accept directories; check uses an Abs-only gate.
13
+ - LSP hover / `getTypeAtPosition` on capable files read the Abs node table; `*.nudo.js` edits evict L0 and recheck open parents.
14
+ - Public core surface now re-exports the algebra API (`Abs`, check, generalize, exec, bridge, `parseSource`, `stripTypes`).
15
+
16
+ - 5786fa5: Speed up repeated analysis with layered memos and tighter cache contracts.
17
+
18
+ - Shared parse/AST LRU, `generalizeFromAst` L0–L3 (instantiate, α-equivalence, dep fingerprint + LRU), Abs module cache, and session-wide memos with an incremental after-edit path.
19
+ - Host cache-eviction contract, AST/function-fingerprint memory caps, conservative call-scan depth cap, and fail-open truncated dependency fingerprints.
20
+ - Fix session-memo staleness and identity holes so after-edit results stay correct.
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies [5786fa5]
25
+ - Updated dependencies [5786fa5]
26
+ - Updated dependencies [5786fa5]
27
+ - Updated dependencies [5786fa5]
28
+ - @nudojs/core@0.3.0
29
+ - @nudojs/cli@0.3.0
30
+ - @nudojs/harvester@0.2.0
31
+ - @nudojs/parser@0.3.0
32
+
3
33
  ## 0.2.1
4
34
 
5
35
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,7 +1,22 @@
1
- import { Node } from '@babel/types';
2
- import { TypeValue } from '@nudojs/core';
1
+ import { Node, File } from '@babel/types';
2
+ import { TypeValue, Abs, PolyFn, AbsModuleExports, AstEnv, Phi, BMemberDiag, BCallRecord, TranspiledCallResult } from '@nudojs/core';
3
+ export { AbsInlay, BMemberDiag, collectAbsInlays } from '@nudojs/core';
3
4
  import { CallRecord } from '@nudojs/cli/evaluator';
4
5
  export { CallRecord } from '@nudojs/cli/evaluator';
6
+ import { HarvestedEnv } from '@nudojs/harvester';
7
+ import { FunctionWithDirectives } from '@nudojs/parser';
8
+
9
+ /**
10
+ * Per-function FunctionAnalysis cache (body-edit: recompute only dirty fns).
11
+ * Cleared together with B-path / whole-file analysis caches.
12
+ */
13
+
14
+ declare function clearFnAnalysisCache(): void;
15
+ /**
16
+ * Dependency content changed: drop every per-fn entry for these entry files.
17
+ * Keys are `filePath\0...`, so a prefix scan is sound and cheap at LRU size.
18
+ */
19
+ declare function evictFnAnalysisCacheForFiles(files: string[]): number;
5
20
 
6
21
  type SourceLocation = {
7
22
  start: {
@@ -36,8 +51,26 @@ type CaseResult = {
36
51
  throws: TypeValue;
37
52
  throwLoc?: SourceLocation;
38
53
  source?: "directive" | "callsite";
54
+ /** `@nudo:case "name" (…) => expected` — presence means the case is a test assertion */
55
+ expected?: TypeValue;
39
56
  /** number of additional call sites folded into a symbolic case */
40
57
  aggregatedFrom?: number;
58
+ /**
59
+ * 内涵摘要(代数 generalize):无损 Abs + term/pred/conf。
60
+ * 仅在 entry@ / call@(Abs 路径)填充;外延 TypeValue 不变。
61
+ */
62
+ intension?: {
63
+ display?: string;
64
+ term?: string;
65
+ pred?: string;
66
+ conf?: string;
67
+ /** 无损 Abs 单行(formatAbs) */
68
+ abs?: string;
69
+ /** 无损 Abs 多行(formatAbsMultiline) */
70
+ absMultiline?: string;
71
+ };
72
+ /** 无损 Abs(denote/守卫用);仅 Abs 路径 case 填充 */
73
+ abs?: Abs;
41
74
  };
42
75
  type FunctionAnalysis = {
43
76
  name: string;
@@ -45,7 +78,6 @@ type FunctionAnalysis = {
45
78
  paramNames: string[];
46
79
  cases: CaseResult[];
47
80
  combined?: TypeValue;
48
- assertionErrors?: string[];
49
81
  entryOnly?: boolean;
50
82
  skipped?: boolean;
51
83
  /**
@@ -71,6 +103,12 @@ type AnalysisResult = {
71
103
  functions: FunctionAnalysis[];
72
104
  diagnostics: Diagnostic[];
73
105
  bindings: Map<string, BindingInfo>;
106
+ /**
107
+ * Node identity is from the analysis-time parse. A later re-parse of the
108
+ * same source returns a *different* File (new Nodes) if the AST LRU evicted
109
+ * the original — lookups must use the File that produced this result, not a
110
+ * freshly parsed one. getTypeAtPosition rebuilds its own map and is unaffected.
111
+ */
74
112
  nodeTypeMap: Map<Node, TypeValue>;
75
113
  caseHints: CaseHint[];
76
114
  /** functions imported from other modules, synthesized from cross-file call sites observed while analyzing this file */
@@ -129,6 +167,15 @@ declare function analyzeFileAsync(filePath: string, source: string, activeCases?
129
167
  * 依赖未 mock 的全局,收集不到就收集不到,不能拖垮主分析)。
130
168
  */
131
169
  declare function collectCallRecords(filePath: string, source: string): CallRecord[];
170
+ /**
171
+ * 整文件分析。同 (path, source, cases, external) 命中 memo → O(1)。
172
+ * 不再每次 clearBPathCache:B 路径按本文件 source 键控。
173
+ *
174
+ * 宿主契约:入口 source 未变但依赖模块内容变了时,必须调用
175
+ * `evictBPathCacheForFiles` / `evictAnalysisFileCacheForFiles` /
176
+ * `evictFnAnalysisCacheForFiles`(LSP 已接好)。非 LSP 宿主
177
+ * (CLI watch / vite-plugin)在 dep 变更时应 `clearBPathCache()` 或上述逐出。
178
+ */
132
179
  declare function analyzeFile(filePath: string, source: string, activeCases?: Map<string, number>, externalCallRecords?: CallRecord[]): AnalysisResult;
133
180
  type CaseInfo = {
134
181
  functionName: string;
@@ -146,8 +193,438 @@ declare function getCasesForFile(filePath: string, source: string): {
146
193
  /** Async entry to getTypeAtPosition with path-env preloading (see analyzeFileAsync). */
147
194
  declare function getTypeAtPositionAsync(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): Promise<TypeValue | null>;
148
195
  declare function getTypeAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): TypeValue | null;
196
+ type HoverInfo = {
197
+ /** 外延 TypeValue 展示(bridge 有损,仅兜底) */
198
+ typeText: string;
199
+ /** 内涵签名(代数 generalize) */
200
+ intension?: string;
201
+ /** 无损 Abs 单行展示(shape / term / pred / conf) */
202
+ abs?: string;
203
+ /** 无损 Abs 多行展示 */
204
+ absMultiline?: string;
205
+ };
206
+ /**
207
+ * LSP hover:优先无损 Abs(类型即计算本体),TypeValue 仅作外延对照。
208
+ * 节点表也是 Abs(collectAbsNodeTypes),不经 bridge。
209
+ */
210
+ declare function getHoverAtPosition(filePath: string, source: string, line: number, column: number, activeCases?: Map<string, number>): HoverInfo | null;
149
211
  declare function getCompletionsAtPosition(filePath: string, source: string, line: number, column: number): CompletionItem[];
150
212
 
213
+ /**
214
+ * `nudo infer --json` 稳定契约 v1(CI / Agent)。
215
+ *
216
+ * 字段只增不改语义:
217
+ * - ext_*:TypeValue 投影字符串(有损,兼容)
218
+ * - intension.abs*:无损 Abs 展示(主线)
219
+ */
220
+
221
+ type InferJsonCase = {
222
+ name: string;
223
+ /** TypeValue 投影(有损外延) */
224
+ args: string[];
225
+ result: string;
226
+ throws: string | null;
227
+ source: string | null;
228
+ aggregatedFrom?: number;
229
+ /** 无损内涵(Abs);无则省略 */
230
+ intension?: {
231
+ display?: string;
232
+ abs?: string;
233
+ absMultiline?: string;
234
+ term?: string;
235
+ pred?: string;
236
+ conf?: string;
237
+ };
238
+ };
239
+ type InferJsonFunction = {
240
+ name: string;
241
+ loc: SourceLocation;
242
+ entryOnly: boolean;
243
+ noDeclaration?: boolean;
244
+ cases: InferJsonCase[];
245
+ combined?: string;
246
+ };
247
+ type InferJson = {
248
+ version: 1;
249
+ file: string;
250
+ summary: {
251
+ functions: number;
252
+ externalFunctions: number;
253
+ cases: number;
254
+ diagnostics: number;
255
+ };
256
+ functions: InferJsonFunction[];
257
+ externalFunctions?: Array<{
258
+ name: string;
259
+ fromModule?: string;
260
+ cases: InferJsonCase[];
261
+ }>;
262
+ diagnostics: Array<{
263
+ range: SourceLocation;
264
+ severity: string;
265
+ message: string;
266
+ code?: string;
267
+ suggestions?: string[];
268
+ tags?: string[];
269
+ origin?: {
270
+ line: number;
271
+ column: number;
272
+ };
273
+ }>;
274
+ };
275
+ declare function serializeInferJson(result: AnalysisResult, file: string): InferJson;
276
+
277
+ /**
278
+ * nudo 推断目标文件判定(纯扩展名规则,路径无需存在)。
279
+ *
280
+ * 规则:.js / .mjs / .ts 可作为推断目标;其余扩展(.cjs/.tsx/.jsx/.mts/.d.ts…)
281
+ * 一律 false。两类显式排除:
282
+ * - .d.ts —— 类型声明文件(harvester 的输入),不是可求值的实现源码;
283
+ * - .tsx / .jsx —— JSX 构造的求值超出 nudo 推断器范围。
284
+ *
285
+ * 消费方:CLI 的 collectNudoFiles/watch 过滤/doctor 目录展开(.ts 放开后统一
286
+ * 走本函数,避免各处手写 endsWith 漂移),以及 LSP 的 isNudoFile(接线由
287
+ * LSP 侧负责)。
288
+ */
289
+ declare function isNudoTargetPath(path: string): boolean;
290
+
291
+ /**
292
+ * 相对/绝对 specifier → 模块源码。
293
+ * CLI / LSP / vite / check 共用同一扩展名表,避免门禁结果分叉。
294
+ */
295
+ type LoadModule = (spec: string, fromFile: string) => string | undefined;
296
+ /** 默认 loadModule:支持 .js/.mjs/.ts 与 index 入口 */
297
+ declare function defaultLoadModule(spec: string, fromFile: string): string | undefined;
298
+
299
+ /**
300
+ * Host 侧多文件解析(非代数层)。
301
+ *
302
+ * 分层:
303
+ * algebra = 纯抽象解释:吃 AST / source string,不碰 fs/path
304
+ * host = 读文件、解析相对 import/require、把 source 喂给代数
305
+ * Node/打包器 = 真正的模块加载与执行
306
+ *
307
+ * 引擎不做 bundler;这里只为「跨文件类型事实」做最薄的静态扫描。
308
+ */
309
+
310
+ type ModuleExports = {
311
+ path: string;
312
+ named: Map<string, string>;
313
+ defaultExport?: string;
314
+ source: string;
315
+ poly: Map<string, PolyFn>;
316
+ };
317
+ /** 从 AST 收集静态相对依赖(ESM import + CJS require) */
318
+ declare function collectDependencySpecs(ast: File): string[];
319
+ /** 分析单文件导出 + 内涵签名(source 由 host 提供) */
320
+ declare function analyzeExportsFromSource(filePath: string, source: string): ModuleExports;
321
+ /**
322
+ * 从入口文件沿静态相对 import/require 收集(仅类型事实,不是运行时加载器)。
323
+ * bare specifier(npm 包)跳过——交给 harvest / env。
324
+ */
325
+ declare function collectStaticImports(entryFile: string, maxDepth?: number): Map<string, ModuleExports>;
326
+
327
+ /**
328
+ * Host:从 npm 包 / @types 收集 .d.ts → harvestDts。
329
+ * 代数不碰 fs;这里只做「找到 dts 路径」这一层宿主职责。
330
+ */
331
+
332
+ /** 在 node_modules 中解析包根(含 @types/*) */
333
+ declare function resolvePackageRoot(pkg: string, fromDir?: string): string | undefined;
334
+ type PackageHarvest = {
335
+ pkg: string;
336
+ root: string;
337
+ dtsFiles: string[];
338
+ env: HarvestedEnv;
339
+ };
340
+ /**
341
+ * 从入口 .d.ts 沿 reference path / 相对 import 做 BFS 收集。
342
+ * 适合 @types 包(三斜线引用图);比整树 walk 更贴声明入口。
343
+ */
344
+ declare function collectDtsFromEntry(entry: string, maxFiles?: number): string[];
345
+ /** harvest 一个 npm 包(或 @types 包) */
346
+ declare function harvestPackage(pkg: string, fromDir?: string, maxFiles?: number): PackageHarvest | {
347
+ error: string;
348
+ };
349
+ /** harvest 结果 → 人类可读导出表 */
350
+ declare function formatHarvestSummary(h: PackageHarvest): string;
351
+ /** 取某个导出的 TypeValue 字符串 */
352
+ declare function lookupHarvested(h: PackageHarvest, moduleName: string, exportName: string): string | undefined;
353
+
354
+ /**
355
+ * harvest 自动化:源码裸 import → @types/package → env modules。
356
+ * 手动 `nudo harvest` 仍保留;这里是分析路径上的按需注入。
357
+ */
358
+
359
+ /** 裸说明符 → 包名(含 scope);相对/绝对/node: 内建返回 undefined */
360
+ declare function barePackageName(spec: string): string | undefined;
361
+ declare function collectBarePackages(source: string): string[];
362
+ declare function harvestPackageCached(pkg: string, fromDir: string): PackageHarvest | null;
363
+ declare function clearHarvestCache(): void;
364
+ /**
365
+ * 自动 harvest 源码中全部裸包(有 @types 或包内 dts 时)。
366
+ * 返回可注入 setEnvModules 的 modules 表;无包可 harvest 时为空对象。
367
+ */
368
+ declare function autoHarvestModules(source: string, fromDir: string): Record<string, Record<string, TypeValue>>;
369
+
370
+ /**
371
+ * Host:import 图(相对 + 裸包 harvest)→ Abs 导出表 → 注入入口。
372
+ * 读 fs / 解析路径 / harvest 在这里;core 只收 modules 表。
373
+ */
374
+
375
+ type AbsLoadModule = (spec: string, fromFile: string) => string | undefined;
376
+ /** 相对说明符 → 源码 */
377
+ declare function defaultAbsLoadModule(spec: string, fromFile: string): string | undefined;
378
+ /** 模块加载守卫:与 TypeValue loadModuleEnv 口径对齐,供 analyzer 映射诊断 */
379
+ type AbsModuleLoadIssue = {
380
+ kind: "cycle" | "depth" | "missing";
381
+ /** 诊断定位用标签(文件 basename 或 require/import 说明符) */
382
+ label: string;
383
+ reason: string;
384
+ };
385
+ type AbsModuleGraphResult = {
386
+ /** 入口 import 说明符 → 依赖导出表 */
387
+ modules: Record<string, AbsModuleExports>;
388
+ /** 绝对路径 → 导出表(含依赖;循环时占位为空) */
389
+ byPath: Map<string, AbsModuleExports>;
390
+ /** cycle / depth / missing(B 路径权威,避免 TypeValue 叠报) */
391
+ issues: AbsModuleLoadIssue[];
392
+ };
393
+ type AbsGraphOptions = {
394
+ loadModule?: AbsLoadModule;
395
+ seedVars?: Record<string, Abs>;
396
+ seedFns?: Record<string, {
397
+ params: string[];
398
+ body: Node;
399
+ async?: boolean;
400
+ }>;
401
+ maxDepth?: number;
402
+ };
403
+ /** 会话级依赖模块缓存条目:stat 指纹 + 导出 + 子树装载 issue。 */
404
+ type AbsModuleCacheEntry = {
405
+ mtimeMs: number;
406
+ size: number;
407
+ exports: AbsModuleExports;
408
+ /** 该模块子树首次求值时记录的 cycle/depth/missing;命中时重放。 */
409
+ issues: AbsModuleLoadIssue[];
410
+ };
411
+ declare function clearAbsModuleCache(): void;
412
+ declare function evictAbsModuleCacheFiles(paths: string[]): void;
413
+ /**
414
+ * 递归求值相对依赖 + 裸包 harvest,产出入口可用的 modules 表。
415
+ * 循环依赖:先放空表再回填(与 TypeValue 路径 partial 口径一致),
416
+ * 并记录 cycle/depth/missing 供诊断。
417
+ */
418
+ declare function evalAbsModuleGraph(entrySource: string, entryFile: string, opts?: AbsGraphOptions): AbsModuleGraphResult;
419
+ /** 便捷:入口求值 + 依赖 Abs 注入 */
420
+ declare function evalProgramAbsWithModules(source: string, entryFile: string, opts?: AbsGraphOptions & {
421
+ file?: unknown;
422
+ }): {
423
+ env: AstEnv;
424
+ last: Abs;
425
+ phi: Phi;
426
+ };
427
+ /**
428
+ * 收集顶层绑定名 → Abs(含相对 import / 裸包 harvest 注入)。
429
+ * 供 bindings / hover 从 Abs 投影,不必走 TypeValue evaluator。
430
+ */
431
+ declare function collectAbsBindingsFromGraph(source: string, filePath: string, opts?: AbsGraphOptions): Map<string, Abs>;
432
+
433
+ /**
434
+ * Harvest TypeValue 导出 → AbsModuleExports(供 Abs 模块图注入)。
435
+ * fnSig → absFunction + apply 直接返回声明返回类型(conf=mock)。
436
+ */
437
+
438
+ /** 单个 TypeValue 导出 → Abs(可调用) */
439
+ declare function harvestedValueToAbs(tv: TypeValue): Abs;
440
+ /**
441
+ * 把 harvest 的 modules/globals 合成 AbsModuleExports。
442
+ * 键同时登记:原始模块路径、包名、basename(path / @types/path)。
443
+ */
444
+ declare function harvestToAbsModules(pkg: string, fromDir: string): Record<string, AbsModuleExports>;
445
+ declare function packageHarvestToAbsModules(pkg: string, h: PackageHarvest): Record<string, AbsModuleExports>;
446
+ /** 裸说明符 → Abs 导出表(走 harvest 缓存) */
447
+ declare function bareSpecToAbsModules(spec: string, fromFile: string): AbsModuleExports | undefined;
448
+
449
+ /** @nudo:env → Abs 全局表(保留 fnSig impl) */
450
+ declare function collectEnvGlobals(envNames: string[]): Record<string, Abs>;
451
+ /** @nudo:env modules(path / node:path / fs…)→ AbsModuleExports */
452
+ declare function collectEnvModules(envNames: string[]): Record<string, AbsModuleExports>;
453
+ /** 收集 @nudo:replace + @nudo:as → transpile 注入表 */
454
+ declare function collectBPathReplacements(source: string): {
455
+ targets: Array<{
456
+ target: string;
457
+ varName: string;
458
+ stmtStart?: number;
459
+ stmtEnd?: number;
460
+ }>;
461
+ values: Record<string, Abs>;
462
+ asTargets: Array<{
463
+ varName: string;
464
+ stmtStart: number;
465
+ stmtEnd: number;
466
+ }>;
467
+ asValues: Record<string, Abs>;
468
+ };
469
+ /** 可走 transpile+exec:env 经 loadEnvs(内置 + 已 preload 的路径型) */
470
+ declare function isBPathCapable(source: string, envNames?: string[]): boolean;
471
+ type BPathRunResult = {
472
+ exports: Record<string, unknown>;
473
+ modules: Record<string, AbsModuleExports>;
474
+ /** 顶层执行期 method-missing */
475
+ memberDiags?: BMemberDiag[];
476
+ /** 模块图 cycle/depth/missing(B 权威) */
477
+ moduleIssues?: AbsModuleLoadIssue[];
478
+ /** Abs 求值递归截断的函数标签 */
479
+ truncatedFns?: string[];
480
+ /** 顶层 $callNamed 调用点(call@ 合成;不经 TypeValue collector) */
481
+ calls?: BCallRecord[];
482
+ };
483
+ declare function clearBPathCache(): void;
484
+ /** 依赖文件变更后:逐出以这些文件为入口的 B-path 缓存 */
485
+ declare function evictBPathCacheForFiles(files: string[]): number;
486
+ /** 模块图 + runTranspiled(默认 analyze 模式) */
487
+ declare function tryRunBPath(source: string, filePath: string, opts?: {
488
+ maxLoopIters?: number;
489
+ mode?: "exec" | "analyze";
490
+ envNames?: string[];
491
+ /** @nudo:mock → Abs,注入为全局绑定(防止顶层调用真 fetch 等) */
492
+ mocks?: Record<string, Abs>;
493
+ }): BPathRunResult | undefined;
494
+ /** B 路径求值具名导出(结果 + throws);opts.collectCalls 时附带调用点记录 */
495
+ declare function tryBPathCallFull(source: string, filePath: string, fnName: string, args: Abs[], opts?: {
496
+ collectCalls?: boolean;
497
+ collectMemberDiags?: boolean;
498
+ envNames?: string[];
499
+ mocks?: Record<string, Abs>;
500
+ }): (TranspiledCallResult & {
501
+ calls?: BCallRecord[];
502
+ memberDiags?: BMemberDiag[];
503
+ moduleIssues?: AbsModuleLoadIssue[];
504
+ truncatedFns?: string[];
505
+ }) | undefined;
506
+ /** B 路径求值具名导出(仅成功结果) */
507
+ declare function tryBPathCall(source: string, filePath: string, fnName: string, args: Abs[], opts?: {
508
+ envNames?: string[];
509
+ mocks?: Record<string, Abs>;
510
+ }): Abs | undefined;
511
+
512
+ declare function clearAnalysisFileCache(): void;
513
+ declare function getAnalysisFileCacheSize(): number;
514
+ /** 依赖变更后:按入口文件逐出 */
515
+ declare function evictAnalysisFileCacheForFiles(files: string[]): number;
516
+
517
+ /**
518
+ * 依赖内容变更后:按入口文件定向逐出 service 层缓存。
519
+ * 调用方应传「以这些文件为入口」的路径(脏集里的 dependents),
520
+ * 而不是变更的 dep 文件本身——dep 自己 source 变了会自然 miss。
521
+ */
522
+ declare function evictAnalysisCachesForFiles(files: string[]): void;
523
+ /**
524
+ * 清空全部会话级分析缓存(service + core)。
525
+ * 适用于:CLI watch 增量批前、vite buildStart / watchChange、测试隔离。
526
+ * 比定向逐出重,但保证无陈旧命中;单次 analyze 内部的 per-fn / generalize
527
+ * memo 不受影响(它们在同一轮里先写后读)。
528
+ */
529
+ declare function clearAnalysisSessionCaches(): void;
530
+ /** 比 clearAnalysisSessionCaches 更彻底:再丢 AST LRU(测试 / 进程复用场景) */
531
+ declare function resetAllAnalysisCaches(): void;
532
+
533
+ /**
534
+ * env TypeValue → Abs:保留 fnSig impl,使 Promise.resolve / URL 等
535
+ * 在 B 路径也能产出精确字面量。
536
+ */
537
+
538
+ declare function envValueToAbs(tv: TypeValue): Abs;
539
+
540
+ /**
541
+ * B 路径静态诊断(AST,不执行):
542
+ * - unreachable:同块 return/throw 之后的语句
543
+ * - builtin-unknown:未声明的全局调用(非 import / 局部 / $runtime)
544
+ */
545
+ type BPathLoc = {
546
+ start: {
547
+ line: number;
548
+ column: number;
549
+ };
550
+ end: {
551
+ line: number;
552
+ column: number;
553
+ };
554
+ };
555
+ type BPathUnreachable = {
556
+ range: BPathLoc;
557
+ };
558
+ type BPathBuiltinUnknown = {
559
+ name: string;
560
+ range: BPathLoc;
561
+ };
562
+ type BPathDiagnostics = {
563
+ unreachable: BPathUnreachable[];
564
+ builtinUnknown: BPathBuiltinUnknown[];
565
+ };
566
+ /**
567
+ * 静态收集 B 路径诊断。
568
+ * extraKnown:@nudo:mock / @nudo:env 已覆盖的全局名(B 注入后不再是裸原生
569
+ * 调用,不得误报 builtin-unknown——收集器只吃 AST,看不到指令)。
570
+ */
571
+ declare function collectBPathDiagnostics(source: string, extraKnown?: Iterable<string>): BPathDiagnostics;
572
+
573
+ /**
574
+ * 预置 Node API env:从 @types/node 的 .d.ts harvest。
575
+ * 与 packages/env 的手写 env 并行;此路径自动、可刷新。
576
+ */
577
+
578
+ type NodeEnvResult = {
579
+ ok: true;
580
+ env: HarvestedEnv;
581
+ root: string;
582
+ files: number;
583
+ } | {
584
+ ok: false;
585
+ error: string;
586
+ };
587
+ /** harvest @types/node(限制文件数 + 时间预算,避免拖垮启动) */
588
+ declare function harvestNodeTypes(fromDir?: string, maxFiles?: number, maxMs?: number): NodeEnvResult;
589
+ /** 把 harvest 结果压成「模块名 → 导出名列表」摘要,便于日志/测试 */
590
+ declare function summarizeNodeEnv(env: HarvestedEnv): {
591
+ modules: string[];
592
+ globals: string[];
593
+ symbolCount: number;
594
+ };
595
+
596
+ /**
597
+ * Semantic tokens 图例(tokenTypes 下标即 LSP 编码里的 tokenType 值)。
598
+ * 与 LSP server capabilities 里声明的 legend 必须逐字对齐——server.ts 直接
599
+ * 导入本常量注册,保证「提取端索引」与「客户端图例」单一来源。
600
+ * 顺序沿用 lsp 包原 legend(function/variable/parameter/property 在前),
601
+ * 末尾追加 method(对象字面量方法键),只追加不重排,客户端索引稳定。
602
+ */
603
+ declare const SEMANTIC_TOKEN_TYPES: readonly ["function", "variable", "parameter", "property", "type", "keyword", "string", "number", "comment", "decorator", "method"];
604
+ declare const SEMANTIC_TOKEN_MODIFIERS: readonly ["declaration", "readonly", "deprecated", "unreachable"];
605
+ type SemanticToken = {
606
+ line: number;
607
+ char: number;
608
+ length: number;
609
+ typeIndex: number;
610
+ modifierBitmask: number;
611
+ };
612
+ /** LSP 标准相对五元组编码:deltaLine/deltaStartChar/length/tokenType/tokenModifiers。 */
613
+ declare function encodeSemanticTokens(tokens: SemanticToken[]): number[];
614
+ /**
615
+ * 从源码提取 semantic tokens 并按 LSP 相对编码返回扁平 number[]。
616
+ *
617
+ * 上色范围(声明位优先,未解析的 token 一律不上色):
618
+ * - 顶层 const/let/var 声明的绑定名:推断为函数绑定 → function,否则 variable
619
+ * (函数体内部的声明不做 env 反查——外层同名绑定会串味,统一 variable);
620
+ * - 函数声明/函数表达式的名字 → function;所有函数的参数 → parameter;
621
+ * - 对象字面量的键:值为函数 → method,否则 property。
622
+ *
623
+ * 推断复用 evaluateProgram 的绑定分析(与补全/诊断同一求值链),不另建
624
+ * 符号体系;解析失败返回 [],求值中断则按已绑定的部分结果继续上色。
625
+ */
626
+ declare function buildSemanticTokens(filePath: string, source: string): number[];
627
+
151
628
  declare function typeValueToTSType(tv: TypeValue): string;
152
629
  /**
153
630
  * 为单个函数生成 .d.ts 声明行(JSDoc + 单一 widen 主签名)。
@@ -160,6 +637,8 @@ declare function generateDts(result: AnalysisResult): string;
160
637
  declare function typeValueToZodSchema(tv: TypeValue): string;
161
638
 
162
639
  declare function generateGuardFunction(name: string, tv: TypeValue): string;
640
+ /** Abs 指称守卫(设计 §2.7):比 TypeValue 投影多保留 pred */
641
+ declare function generateGuardFunctionFromAbs(name: string, abs: Abs): string;
163
642
 
164
643
  /** 单个 TypeValue → parseTypeValueExpr 可解析回去的表达式文本;不可表达返回 null */
165
644
  declare function serializeCaseArg(tv: TypeValue): string | null;
@@ -209,4 +688,23 @@ declare function insertGeneratedCaseDirectives(source: string, analysis: Analysi
209
688
  /** 行级 unified diff:`--- a/path` 头 + `@@` hunk + 上下文 3 行;相同返回 "" */
210
689
  declare function unifiedDiff(a: string, b: string, path: string): string;
211
690
 
212
- export { type AnalysisResult, type BindingInfo, type CaseHint, type CaseInfo, type CaseResult, type CompletionItem, type Diagnostic, type DiagnosticSeverity, type DiagnosticTag, type EmitResult, type EmitSkipReason, type FunctionAnalysis, type ModuleGraphCache, type ReferenceInfo, type SourceLocation, type SymbolInfo, type SymbolTable, analyzeFile, analyzeFileAsync, buildCaseDirective, buildModuleGraph, collectCallRecords, computeDirtySet, generateDts, generateFunctionDtsLines, generateGuardFunction, getCasesForFile, getCompletionsAtPosition, getTypeAtPosition, getTypeAtPositionAsync, insertGeneratedCaseDirectives, serializeCaseArg, stripGeneratedCaseDirectives, topoSortDirty, typeValueToTSType, typeValueToZodSchema, unifiedDiff };
691
+ /**
692
+ * @nudo:mock / sinon 指令 → Abs seed(供 evalProgramAbs)。
693
+ * host 层:依赖 parser 指令形态;core 只吃 seedVars/seedFns。
694
+ */
695
+
696
+ type AbsMockSeeds = {
697
+ seedVars: Record<string, Abs>;
698
+ seedFns: Record<string, {
699
+ params: string[];
700
+ body: Node;
701
+ async?: boolean;
702
+ fingerprint?: string;
703
+ }>;
704
+ };
705
+ /** 从函数上的 @nudo:mock 指令收集 Abs seed */
706
+ declare function mockDirectivesToAbsSeeds(functions: Array<{
707
+ directives: FunctionWithDirectives["directives"];
708
+ }>): AbsMockSeeds;
709
+
710
+ export { type AbsGraphOptions, type AbsMockSeeds, type AbsModuleCacheEntry, type AbsModuleGraphResult, type AbsModuleLoadIssue, type AnalysisResult, type BPathBuiltinUnknown, type BPathDiagnostics, type BPathRunResult, type BPathUnreachable, type BindingInfo, type CaseHint, type CaseInfo, type CaseResult, type CompletionItem, type Diagnostic, type DiagnosticSeverity, type DiagnosticTag, type EmitResult, type EmitSkipReason, type FunctionAnalysis, type HoverInfo, type InferJson, type InferJsonCase, type InferJsonFunction, type LoadModule, type ModuleExports, type ModuleGraphCache, type NodeEnvResult, type PackageHarvest, type ReferenceInfo, SEMANTIC_TOKEN_MODIFIERS, SEMANTIC_TOKEN_TYPES, type SemanticToken, type SourceLocation, type SymbolInfo, type SymbolTable, analyzeExportsFromSource, analyzeFile, analyzeFileAsync, autoHarvestModules, barePackageName, bareSpecToAbsModules, buildCaseDirective, buildModuleGraph, buildSemanticTokens, clearAbsModuleCache, clearAnalysisFileCache, clearAnalysisSessionCaches, clearBPathCache, clearFnAnalysisCache, clearHarvestCache, collectAbsBindingsFromGraph, collectBPathDiagnostics, collectBPathReplacements, collectBarePackages, collectCallRecords, collectDependencySpecs, collectDtsFromEntry, collectEnvGlobals, collectEnvModules, collectStaticImports, computeDirtySet, defaultAbsLoadModule, defaultLoadModule, encodeSemanticTokens, envValueToAbs, evalAbsModuleGraph, evalProgramAbsWithModules, evictAbsModuleCacheFiles, evictAnalysisCachesForFiles, evictAnalysisFileCacheForFiles, evictBPathCacheForFiles, evictFnAnalysisCacheForFiles, formatHarvestSummary, generateDts, generateFunctionDtsLines, generateGuardFunction, generateGuardFunctionFromAbs, getAnalysisFileCacheSize, getCasesForFile, getCompletionsAtPosition, getHoverAtPosition, getTypeAtPosition, getTypeAtPositionAsync, harvestNodeTypes, harvestPackage, harvestPackageCached, harvestToAbsModules, harvestedValueToAbs, insertGeneratedCaseDirectives, isBPathCapable, isNudoTargetPath, lookupHarvested, mockDirectivesToAbsSeeds, packageHarvestToAbsModules, resetAllAnalysisCaches, resolvePackageRoot, serializeCaseArg, serializeInferJson, stripGeneratedCaseDirectives, summarizeNodeEnv, topoSortDirty, tryBPathCall, tryBPathCallFull, tryRunBPath, typeValueToTSType, typeValueToZodSchema, unifiedDiff };