@nudojs/core 0.3.0 → 0.4.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 (123) hide show
  1. package/dist/chunk-N7E2A7IK.js +7216 -0
  2. package/dist/exec.d.ts +2 -0
  3. package/dist/exec.js +174 -0
  4. package/dist/index-DgyudAkw.d.ts +911 -0
  5. package/dist/index.d.ts +64 -710
  6. package/dist/index.js +3269 -8426
  7. package/package.json +18 -5
  8. package/CHANGELOG.md +0 -34
  9. package/src/__tests__/environment.test.ts +0 -48
  10. package/src/__tests__/fn-sig-impl.test.ts +0 -57
  11. package/src/__tests__/ops-refined.test.ts +0 -196
  12. package/src/__tests__/ops.test.ts +0 -84
  13. package/src/__tests__/type-value-phase2.test.ts +0 -117
  14. package/src/__tests__/type-value-phase3.test.ts +0 -94
  15. package/src/__tests__/type-value-refined.test.ts +0 -210
  16. package/src/__tests__/type-value.test.ts +0 -319
  17. package/src/algebra/__tests__/abs-native.test.ts +0 -176
  18. package/src/algebra/__tests__/arithmetic.test.ts +0 -170
  19. package/src/algebra/__tests__/ast-eval.test.ts +0 -154
  20. package/src/algebra/__tests__/bridge.test.ts +0 -160
  21. package/src/algebra/__tests__/call-budget.test.ts +0 -117
  22. package/src/algebra/__tests__/check-case-consistency.test.ts +0 -69
  23. package/src/algebra/__tests__/check-gold.test.ts +0 -290
  24. package/src/algebra/__tests__/check-json.test.ts +0 -57
  25. package/src/algebra/__tests__/check-mini-repo.test.ts +0 -49
  26. package/src/algebra/__tests__/check-real-commander.test.ts +0 -43
  27. package/src/algebra/__tests__/check-real-packages.test.ts +0 -165
  28. package/src/algebra/__tests__/check-recall-gold.test.ts +0 -1024
  29. package/src/algebra/__tests__/check-require-dep-memo.test.ts +0 -45
  30. package/src/algebra/__tests__/check-return-contract.test.ts +0 -90
  31. package/src/algebra/__tests__/check-shape-gold.test.ts +0 -303
  32. package/src/algebra/__tests__/check-source-memo.test.ts +0 -204
  33. package/src/algebra/__tests__/check.test.ts +0 -69
  34. package/src/algebra/__tests__/denote.test.ts +0 -77
  35. package/src/algebra/__tests__/diagnostics.test.ts +0 -64
  36. package/src/algebra/__tests__/differential.test.ts +0 -124
  37. package/src/algebra/__tests__/div-mod.test.ts +0 -38
  38. package/src/algebra/__tests__/example0.test.ts +0 -103
  39. package/src/algebra/__tests__/exec-analyze-throws.test.ts +0 -60
  40. package/src/algebra/__tests__/exec-async.test.ts +0 -46
  41. package/src/algebra/__tests__/exec-bpath.test.ts +0 -193
  42. package/src/algebra/__tests__/exec-class.test.ts +0 -56
  43. package/src/algebra/__tests__/exec-e2e.test.ts +0 -97
  44. package/src/algebra/__tests__/exec-generator.test.ts +0 -53
  45. package/src/algebra/__tests__/exec-inherit-default.test.ts +0 -111
  46. package/src/algebra/__tests__/exec-optional-nested.test.ts +0 -87
  47. package/src/algebra/__tests__/exec-rest.test.ts +0 -55
  48. package/src/algebra/__tests__/exec-spread-forof.test.ts +0 -85
  49. package/src/algebra/__tests__/exec-static-computed.test.ts +0 -61
  50. package/src/algebra/__tests__/exec-switch.test.ts +0 -74
  51. package/src/algebra/__tests__/exec-trycatch.test.ts +0 -71
  52. package/src/algebra/__tests__/fn-fp-memo.test.ts +0 -166
  53. package/src/algebra/__tests__/fn-fp-multidecl.test.ts +0 -49
  54. package/src/algebra/__tests__/format.test.ts +0 -34
  55. package/src/algebra/__tests__/generalize-memo.test.ts +0 -285
  56. package/src/algebra/__tests__/generalize.test.ts +0 -113
  57. package/src/algebra/__tests__/hash-source.test.ts +0 -19
  58. package/src/algebra/__tests__/hof.test.ts +0 -80
  59. package/src/algebra/__tests__/inlay.test.ts +0 -30
  60. package/src/algebra/__tests__/language.test.ts +0 -77
  61. package/src/algebra/__tests__/leq.test.ts +0 -109
  62. package/src/algebra/__tests__/load-deps-fp-memo.test.ts +0 -132
  63. package/src/algebra/__tests__/methods.test.ts +0 -37
  64. package/src/algebra/__tests__/node-types.test.ts +0 -26
  65. package/src/algebra/__tests__/nudo-constraints.ts +0 -46
  66. package/src/algebra/__tests__/objects.test.ts +0 -117
  67. package/src/algebra/__tests__/parse-source-cache.test.ts +0 -42
  68. package/src/algebra/__tests__/refine-import.test.ts +0 -109
  69. package/src/algebra/__tests__/stable-source-key-block.test.ts +0 -23
  70. package/src/algebra/__tests__/stable-source-key.test.ts +0 -31
  71. package/src/algebra/__tests__/surface.test.ts +0 -41
  72. package/src/algebra/__tests__/this-inherit.test.ts +0 -130
  73. package/src/algebra/abs-fn.ts +0 -49
  74. package/src/algebra/abs-modules.ts +0 -139
  75. package/src/algebra/abs.ts +0 -206
  76. package/src/algebra/arithmetic.ts +0 -691
  77. package/src/algebra/ast-eval.ts +0 -1763
  78. package/src/algebra/bridge.ts +0 -350
  79. package/src/algebra/builtins.ts +0 -373
  80. package/src/algebra/check-report.ts +0 -150
  81. package/src/algebra/check.ts +0 -1867
  82. package/src/algebra/constraint.ts +0 -304
  83. package/src/algebra/denote.ts +0 -166
  84. package/src/algebra/diagnostics.ts +0 -210
  85. package/src/algebra/exec/call.ts +0 -29
  86. package/src/algebra/exec/calls.ts +0 -96
  87. package/src/algebra/exec/class-registry.ts +0 -29
  88. package/src/algebra/exec/class.ts +0 -329
  89. package/src/algebra/exec/index.ts +0 -6
  90. package/src/algebra/exec/member-diag.ts +0 -141
  91. package/src/algebra/exec/run.ts +0 -341
  92. package/src/algebra/exec/runtime.ts +0 -583
  93. package/src/algebra/exec/transpile.ts +0 -993
  94. package/src/algebra/fn-fp.ts +0 -294
  95. package/src/algebra/format.ts +0 -91
  96. package/src/algebra/generalize.ts +0 -776
  97. package/src/algebra/hash-source.ts +0 -27
  98. package/src/algebra/index.ts +0 -34
  99. package/src/algebra/inlay.ts +0 -198
  100. package/src/algebra/language.ts +0 -289
  101. package/src/algebra/leak.ts +0 -68
  102. package/src/algebra/leq.ts +0 -301
  103. package/src/algebra/load-deps-fp.ts +0 -97
  104. package/src/algebra/methods.ts +0 -128
  105. package/src/algebra/objects.ts +0 -251
  106. package/src/algebra/parse-source.ts +0 -64
  107. package/src/algebra/phi.ts +0 -42
  108. package/src/algebra/pred.ts +0 -395
  109. package/src/algebra/refine.ts +0 -227
  110. package/src/algebra/stable-source-key.ts +0 -81
  111. package/src/algebra/surface.ts +0 -206
  112. package/src/algebra/template.ts +0 -143
  113. package/src/algebra/term.ts +0 -119
  114. package/src/environment.ts +0 -74
  115. package/src/index.ts +0 -73
  116. package/src/mock-helpers.ts +0 -166
  117. package/src/ops.ts +0 -191
  118. package/src/refinements/range.ts +0 -86
  119. package/src/refinements/template-predicates.ts +0 -11
  120. package/src/refinements/template.ts +0 -176
  121. package/src/strip-types.ts +0 -236
  122. package/src/type-value.ts +0 -513
  123. package/tsconfig.json +0 -8
@@ -1,85 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- runTranspiled,
4
- callTranspiledExportFull,
5
- $lit,
6
- $obj,
7
- $arr,
8
- litValue,
9
- absToString,
10
- transpile,
11
- } from "@nudojs/core";
12
-
13
- describe("B-path spread", () => {
14
- it("object spread overwrites keys", () => {
15
- const src = `
16
- export function go() {
17
- const a = { x: 1, y: 2 };
18
- const b = { y: 9, z: 3 };
19
- const o = { ...a, ...b };
20
- return o.x + o.y + o.z;
21
- }
22
- `;
23
- const exports = runTranspiled(src, { mode: "analyze" });
24
- const r = callTranspiledExportFull(exports, "go", []);
25
- expect(litValue(r.result)).toBe(13); // 1+9+3
26
- });
27
-
28
- it("array spread concatenates", () => {
29
- const src = `
30
- export function go() {
31
- const a = [1, 2];
32
- const b = [3];
33
- const c = [...a, ...b];
34
- return c[0] + c[1] + c[2];
35
- }
36
- `;
37
- const exports = runTranspiled(src, { mode: "analyze" });
38
- const r = callTranspiledExportFull(exports, "go", []);
39
- expect(litValue(r.result)).toBe(6);
40
- });
41
-
42
- it("transpiles spread", () => {
43
- const out = transpile(`export function f(a, b) { return { ...a, z: 1 }; }`);
44
- expect(out).toContain("$spread(");
45
- });
46
- });
47
-
48
- describe("B-path for-of", () => {
49
- it("iterates tuple elements", () => {
50
- const src = `
51
- export function go() {
52
- const xs = [1, 2, 3];
53
- let sum = 0;
54
- for (const x of xs) {
55
- sum = sum + x;
56
- }
57
- return sum;
58
- }
59
- `;
60
- const exports = runTranspiled(src, { mode: "analyze" });
61
- const r = callTranspiledExportFull(exports, "go", []);
62
- expect(litValue(r.result)).toBe(6);
63
- });
64
-
65
- it("for-of with object destructure", () => {
66
- const src = `
67
- export function go() {
68
- const xs = [{ v: 1 }, { v: 2 }];
69
- let sum = 0;
70
- for (const { v } of xs) {
71
- sum = sum + v;
72
- }
73
- return sum;
74
- }
75
- `;
76
- const exports = runTranspiled(src, { mode: "analyze" });
77
- const r = callTranspiledExportFull(exports, "go", []);
78
- expect(litValue(r.result)).toBe(3);
79
- });
80
-
81
- it("transpiles for-of", () => {
82
- const out = transpile(`export function f(xs) { let t = 0; for (const x of xs) { t = t + x; } return t; }`);
83
- expect(out).toContain("$forOf(");
84
- });
85
- });
@@ -1,61 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- runTranspiled,
4
- callTranspiledExportFull,
5
- $lit,
6
- litValue,
7
- absToString,
8
- transpile,
9
- } from "@nudojs/core";
10
-
11
- describe("B-path class static members", () => {
12
- it("reads static fields and calls static methods", () => {
13
- const src = `
14
- class Point {
15
- static origin = 0;
16
- static make(n) { return n * 2; }
17
- constructor(x) { this.x = x; }
18
- get() { return this.x; }
19
- }
20
- export function go() {
21
- const p = new Point(Point.make(3));
22
- return p.get() + Point.origin;
23
- }
24
- `;
25
- const exports = runTranspiled(src, { mode: "analyze" });
26
- const r = callTranspiledExportFull(exports, "go", []);
27
- expect(litValue(r.result)).toBe(6); // make(3)=6 + origin=0
28
- });
29
-
30
- it("transpiles static to $class statics/staticMethods", () => {
31
- const out = transpile(`
32
- class C {
33
- static n = 1;
34
- static f() { return 2; }
35
- m() { return 3; }
36
- }
37
- `);
38
- expect(out).toContain("statics:");
39
- expect(out).toContain("staticMethods:");
40
- });
41
- });
42
-
43
- describe("B-path computed object properties", () => {
44
- it("{ [k]: v } uses $setKey", () => {
45
- const src = `
46
- export function go() {
47
- const k = "id";
48
- const o = { [k]: 7 };
49
- return o.id;
50
- }
51
- `;
52
- const exports = runTranspiled(src, { mode: "analyze" });
53
- const r = callTranspiledExportFull(exports, "go", []);
54
- expect(litValue(r.result)).toBe(7);
55
- });
56
-
57
- it("transpiles computed property", () => {
58
- const out = transpile(`export function f(k, v) { return { [k]: v }; }`);
59
- expect(out).toContain("$setKey(");
60
- });
61
- });
@@ -1,74 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- runTranspiled,
4
- callTranspiledExportFull,
5
- $lit,
6
- litValue,
7
- absToString,
8
- transpile,
9
- } from "@nudojs/core";
10
-
11
- describe("B-path switch", () => {
12
- it("selects matching case by concrete disc", () => {
13
- const src = `
14
- export function go(n) {
15
- switch (n) {
16
- case 1:
17
- return "one";
18
- case 2:
19
- return "two";
20
- default:
21
- return "other";
22
- }
23
- }
24
- `;
25
- const exports = runTranspiled(src, { mode: "analyze" });
26
- expect(litValue(callTranspiledExportFull(exports, "go", [$lit(1)]).result)).toBe("one");
27
- expect(litValue(callTranspiledExportFull(exports, "go", [$lit(2)]).result)).toBe("two");
28
- expect(litValue(callTranspiledExportFull(exports, "go", [$lit(9)]).result)).toBe("other");
29
- });
30
-
31
- it("handles fall-through", () => {
32
- const src = `
33
- export function go(n) {
34
- switch (n) {
35
- case 1:
36
- case 2:
37
- return "small";
38
- case 3:
39
- return "three";
40
- default:
41
- return "big";
42
- }
43
- }
44
- `;
45
- const exports = runTranspiled(src, { mode: "analyze" });
46
- expect(litValue(callTranspiledExportFull(exports, "go", [$lit(1)]).result)).toBe("small");
47
- expect(litValue(callTranspiledExportFull(exports, "go", [$lit(2)]).result)).toBe("small");
48
- expect(litValue(callTranspiledExportFull(exports, "go", [$lit(3)]).result)).toBe("three");
49
- });
50
-
51
- it("abstract disc joins branches", () => {
52
- const src = `
53
- export function go(n) {
54
- switch (n) {
55
- case 1:
56
- return 10;
57
- default:
58
- return 20;
59
- }
60
- }
61
- `;
62
- const exports = runTranspiled(src, { mode: "analyze" });
63
- const r = callTranspiledExportFull(exports, "go", [
64
- { shape: { k: "prim", type: "number" }, conf: "exact" },
65
- ]);
66
- // 抽象 number → join(10, 20) → number #path
67
- expect(absToString(r.result)).toContain("number");
68
- });
69
-
70
- it("transpiles switch to $switch", () => {
71
- const out = transpile(`export function f(n) { switch (n) { case 1: return 1; default: return 0; } }`);
72
- expect(out).toContain("$switch(");
73
- });
74
- });
@@ -1,71 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- runTranspiled,
4
- callTranspiledExportFull,
5
- $lit,
6
- litValue,
7
- absToString,
8
- transpile,
9
- } from "@nudojs/core";
10
-
11
- describe("B-path try/catch", () => {
12
- it("catches $throw and binds Abs value", () => {
13
- const src = `
14
- export function go(n) {
15
- try {
16
- if (n > 0) {
17
- return n;
18
- } else {
19
- throw "neg";
20
- }
21
- } catch (e) {
22
- return e;
23
- }
24
- }
25
- `;
26
- const exports = runTranspiled(src, { mode: "analyze" });
27
- const ok = callTranspiledExportFull(exports, "go", [$lit(3)]);
28
- expect(litValue(ok.result)).toBe(3);
29
- expect(ok.throws.shape.k).toBe("never");
30
-
31
- const bad = callTranspiledExportFull(exports, "go", [$lit(-1)]);
32
- expect(litValue(bad.result)).toBe("neg");
33
- });
34
-
35
- it("finally runs after catch", () => {
36
- const src = `
37
- export function go() {
38
- let t = 0;
39
- try {
40
- throw "x";
41
- } catch (e) {
42
- t = 1;
43
- } finally {
44
- t = t + 10;
45
- }
46
- return t;
47
- }
48
- `;
49
- const exports = runTranspiled(src, { mode: "analyze" });
50
- const r = callTranspiledExportFull(exports, "go", []);
51
- expect(litValue(r.result)).toBe(11);
52
- });
53
-
54
- it("uncaught throw still reports throws", () => {
55
- const src = `
56
- export function go() {
57
- throw "boom";
58
- }
59
- `;
60
- const exports = runTranspiled(src, { mode: "analyze" });
61
- const r = callTranspiledExportFull(exports, "go", []);
62
- expect(r.result.shape.k).toBe("never");
63
- expect(absToString(r.throws)).toContain("boom");
64
- });
65
-
66
- it("transpiles try/catch", () => {
67
- const out = transpile(`export function f() { try { return 1; } catch (e) { return 0; } }`);
68
- expect(out).toContain("try {");
69
- expect(out).toContain("$catchVal(");
70
- });
71
- });
@@ -1,166 +0,0 @@
1
- import { describe, it, expect, beforeEach } from "vitest";
2
- import {
3
- canSkipLiteralCallScan,
4
- generalizeFromAst,
5
- resetGeneralizeMemo,
6
- getGeneralizeMemoSize,
7
- parseSource,
8
- } from "../index.ts";
9
-
10
- const BASE = `
11
- function alpha(x) {
12
- return x + 1;
13
- }
14
- function beta(y) {
15
- return y * 2;
16
- }
17
- function gamma(z) {
18
- return alpha(z) + beta(z);
19
- }
20
- `;
21
-
22
- beforeEach(() => {
23
- resetGeneralizeMemo();
24
- });
25
-
26
- describe("per-function L0 fingerprints", () => {
27
- it("editing one independent function does not miss another", () => {
28
- const file0 = parseSource(BASE);
29
- const a0 = generalizeFromAst("alpha", BASE, { file: file0 });
30
- const b0 = generalizeFromAst("beta", BASE, { file: file0 });
31
- expect(a0).toBeDefined();
32
- expect(b0).toBeDefined();
33
-
34
- const edited = BASE.replace("return y * 2;", "return y * 3;");
35
- const file1 = parseSource(edited);
36
- // beta changed -> new PolyFn
37
- const b1 = generalizeFromAst("beta", edited, { file: file1 });
38
- expect(b1).toBeDefined();
39
- expect(b1).not.toBe(b0);
40
- // alpha unchanged and does not reference beta -> same instance
41
- const a1 = generalizeFromAst("alpha", edited, { file: file1 });
42
- expect(a1).toBe(a0);
43
- });
44
-
45
- it("caller misses when callee body changes", () => {
46
- const file0 = parseSource(BASE);
47
- const g0 = generalizeFromAst("gamma", BASE, { file: file0 });
48
- const a0 = generalizeFromAst("alpha", BASE, { file: file0 });
49
-
50
- const edited = BASE.replace("return x + 1;", "return x + 10;");
51
- const file1 = parseSource(edited);
52
- const a1 = generalizeFromAst("alpha", edited, { file: file1 });
53
- const g1 = generalizeFromAst("gamma", edited, { file: file1 });
54
- expect(a1).not.toBe(a0);
55
- expect(g1).not.toBe(g0);
56
- });
57
-
58
- it("top-level non-function context change misses all", () => {
59
- const src = `const K = 1;\nfunction alpha(x) { return x + K; }\nfunction beta(y) { return y; }\n`;
60
- const file0 = parseSource(src);
61
- const a0 = generalizeFromAst("alpha", src, { file: file0 });
62
- const b0 = generalizeFromAst("beta", src, { file: file0 });
63
-
64
- const edited = `const K = 2;\nfunction alpha(x) { return x + K; }\nfunction beta(y) { return y; }\n`;
65
- const file1 = parseSource(edited);
66
- const a1 = generalizeFromAst("alpha", edited, { file: file1 });
67
- const b1 = generalizeFromAst("beta", edited, { file: file1 });
68
- expect(a1).not.toBe(a0);
69
- expect(b1).not.toBe(b0);
70
- });
71
-
72
- it("without file AST falls back to whole-source key", () => {
73
- const a0 = generalizeFromAst("alpha", BASE);
74
- const edited = BASE.replace("return y * 2;", "return y * 3;");
75
- const a1 = generalizeFromAst("alpha", edited);
76
- // no file -> whole source hash, alpha misses too
77
- expect(a1).not.toBe(a0);
78
- });
79
-
80
- it("refine leading comments are part of own slice", () => {
81
- const src1 = `
82
- /**
83
- * @nudo:case "c" (1)
84
- */
85
- function f(x) { return x + 1; }
86
- `;
87
- const src2 = `
88
- /**
89
- * @nudo:case "c" (2)
90
- */
91
- function f(x) { return x + 1; }
92
- `;
93
- const g1 = generalizeFromAst("f", src1, { file: parseSource(src1) });
94
- const g2 = generalizeFromAst("f", src2, { file: parseSource(src2) });
95
- expect(g1).toBeDefined();
96
- expect(g2).toBeDefined();
97
- expect(g2).not.toBe(g1);
98
- });
99
-
100
- it("memo size grows with distinct fingerprints only", () => {
101
- const file = parseSource(BASE);
102
- generalizeFromAst("alpha", BASE, { file });
103
- generalizeFromAst("beta", BASE, { file });
104
- const n = getGeneralizeMemoSize();
105
- generalizeFromAst("alpha", BASE, { file });
106
- expect(getGeneralizeMemoSize()).toBe(n);
107
- });
108
-
109
- it("default-param sibling reference dirties caller L0", () => {
110
- const src1 = `
111
- function helper() { return 1; }
112
- function f(a = helper()) { return a; }
113
- `;
114
- const src2 = `
115
- function helper() { return 2; }
116
- function f(a = helper()) { return a; }
117
- `;
118
- const g1 = generalizeFromAst("f", src1, { file: parseSource(src1) });
119
- const g2 = generalizeFromAst("f", src2, { file: parseSource(src2) });
120
- expect(g1).toBeDefined();
121
- expect(g2).toBeDefined();
122
- expect(g2).not.toBe(g1);
123
- });
124
-
125
- it("multi-declarator leading refine comment is part of own slice", () => {
126
- const src1 = `
127
- const f = (x) => x,
128
- /**
129
- * @nudo:case "c" (1)
130
- */
131
- g = (y) => y + 1;
132
- `;
133
- const src2 = `
134
- const f = (x) => x,
135
- /**
136
- * @nudo:case "c" (2)
137
- */
138
- g = (y) => y + 1;
139
- `;
140
- const g1 = generalizeFromAst("g", src1, { file: parseSource(src1) });
141
- const g2 = generalizeFromAst("g", src2, { file: parseSource(src2) });
142
- expect(g1).toBeDefined();
143
- expect(g2).toBeDefined();
144
- expect(g2).not.toBe(g1);
145
- });
146
- });
147
-
148
- describe("canSkipLiteralCallScan depth cap", () => {
149
- it("does not skip when a call sits below the walk depth cap", () => {
150
- // 90 nested arrays push the CallExpression past hasAnyCallLike's depth>80
151
- // cut-off. Unexplored subtrees must be treated as "may contain a call".
152
- let nest = "f(-1)";
153
- for (let i = 0; i < 90; i++) nest = `[${nest}]`;
154
- const src = `const x = ${nest};\n`;
155
- const file = parseSource(src);
156
- expect(canSkipLiteralCallScan(src, file)).toBe(false);
157
- });
158
-
159
- it("still skips shallow call-free sources", () => {
160
- const src = `function id(x) { return x + 1; }\nconst y = id(2);\n`;
161
- // id(2) is a CallExpression — must NOT skip
162
- expect(canSkipLiteralCallScan(src, parseSource(src))).toBe(false);
163
- const pure = `const y = 1 + 2;\nfunction id(x) { return x + 1; }\n`;
164
- expect(canSkipLiteralCallScan(pure, parseSource(pure))).toBe(true);
165
- });
166
- });
@@ -1,49 +0,0 @@
1
- import { describe, it, expect, beforeEach } from "vitest";
2
- import {
3
- generalizeFromAst,
4
- resetGeneralizeMemo,
5
- parseSource,
6
- fnFingerprints,
7
- } from "../index.ts";
8
-
9
- const SRC = `const a = (x) => x, b = (x) => x + 1;
10
- function gamma(x) { return b(x); }
11
- `;
12
-
13
- beforeEach(() => {
14
- resetGeneralizeMemo();
15
- });
16
-
17
- describe("multi-declarator fingerprints", () => {
18
- it("indexes every function declarator", () => {
19
- const fps = fnFingerprints(SRC, parseSource(SRC));
20
- expect([...fps.keys()].sort()).toEqual(["a", "b", "gamma"]);
21
- });
22
-
23
- it("caller misses L0 when callee in same declarator statement changes", () => {
24
- const f0 = parseSource(SRC);
25
- const g0 = generalizeFromAst("gamma", SRC, { file: f0 });
26
- expect(g0).toBeDefined();
27
-
28
- const edited = SRC.replace("b = (x) => x + 1", "b = (x) => x + 10");
29
- const f1 = parseSource(edited);
30
- const g1 = generalizeFromAst("gamma", edited, { file: f1 });
31
- expect(g1).not.toBe(g0);
32
- });
33
-
34
- it("independent sibling in same statement does not dirty the other's callers", () => {
35
- const f0 = parseSource(SRC);
36
- const a0 = generalizeFromAst("a", SRC, { file: f0 });
37
- const g0 = generalizeFromAst("gamma", SRC, { file: f0 });
38
- expect(a0).toBeDefined();
39
- expect(g0).toBeDefined();
40
-
41
- // Only a changes; gamma calls b — a's own-slice must not drag gamma.
42
- const edited = SRC.replace("a = (x) => x", "a = (x) => x + 100");
43
- const f1 = parseSource(edited);
44
- const a1 = generalizeFromAst("a", edited, { file: f1 });
45
- const g1 = generalizeFromAst("gamma", edited, { file: f1 });
46
- expect(a1).not.toBe(a0);
47
- expect(g1).toBe(g0);
48
- });
49
- });
@@ -1,34 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { formatShape, formatAbs } from "../format.ts";
3
- import { abs, num } from "../abs.ts";
4
- import { v, lit } from "../term.ts";
5
- import { ge } from "../pred.ts";
6
-
7
- describe("formatShape brand/eff/fn", () => {
8
- it("brand shows class name", () => {
9
- const inner = abs(num().shape, undefined, undefined, "exact");
10
- const a = abs({ k: "brand", name: "Counter", shape: inner }, undefined, undefined, "exact");
11
- expect(formatShape(a)).toBe("Counter");
12
- });
13
-
14
- it("eff shows promise inner", () => {
15
- const inner = abs(num().shape, undefined, undefined, "exact");
16
- const a = abs({ k: "eff", eff: "promise", inner }, undefined, undefined, "exact");
17
- expect(formatShape(a)).toBe("promise<number>");
18
- });
19
-
20
- it("fn shows return shape when present", () => {
21
- const a = abs(
22
- { k: "fn", params: ["x"], returnType: abs(num().shape, undefined, undefined, "exact") },
23
- undefined,
24
- undefined,
25
- "exact",
26
- );
27
- expect(formatShape(a)).toBe("(x) => number");
28
- });
29
-
30
- it("formatAbs still includes pred", () => {
31
- const a = abs(num().shape, v("x"), ge(v("x"), lit(0)), "path");
32
- expect(formatAbs(a)).toContain("0");
33
- });
34
- });