@aster-cloud/aster-lang-ts 1.0.36 → 1.0.37

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 (63) hide show
  1. package/dist/scripts/generate-lexicons.js +17 -1
  2. package/dist/scripts/generate-lexicons.js.map +1 -1
  3. package/dist/scripts/verify-lexicon-sync.js +10 -0
  4. package/dist/scripts/verify-lexicon-sync.js.map +1 -1
  5. package/dist/src/config/lexicons/zh-CN.d.ts.map +1 -1
  6. package/dist/src/config/lexicons/zh-CN.js +1 -0
  7. package/dist/src/config/lexicons/zh-CN.js.map +1 -1
  8. package/dist/src/core/interpreter.js +25 -6
  9. package/dist/src/core/interpreter.js.map +1 -1
  10. package/dist/src/frontend/canonicalizer.js +2 -2
  11. package/dist/src/frontend/canonicalizer.js.map +1 -1
  12. package/dist/src/frontend/transformers.d.ts +11 -2
  13. package/dist/src/frontend/transformers.d.ts.map +1 -1
  14. package/dist/src/frontend/transformers.js +153 -10
  15. package/dist/src/frontend/transformers.js.map +1 -1
  16. package/dist/src/lsp/source-positions.d.ts +1 -1
  17. package/dist/src/lsp/source-positions.d.ts.map +1 -1
  18. package/dist/src/lsp/source-positions.js +21 -3
  19. package/dist/src/lsp/source-positions.js.map +1 -1
  20. package/dist/src/mapping/candidate-generator.d.ts +19 -9
  21. package/dist/src/mapping/candidate-generator.d.ts.map +1 -1
  22. package/dist/src/mapping/candidate-generator.js +79 -40
  23. package/dist/src/mapping/candidate-generator.js.map +1 -1
  24. package/dist/src/mapping/pipeline.d.ts +6 -0
  25. package/dist/src/mapping/pipeline.d.ts.map +1 -1
  26. package/dist/src/mapping/pipeline.js +67 -74
  27. package/dist/src/mapping/pipeline.js.map +1 -1
  28. package/dist/src/nodeid/node-id-map.d.ts +7 -0
  29. package/dist/src/nodeid/node-id-map.d.ts.map +1 -1
  30. package/dist/src/nodeid/node-id-map.js +23 -13
  31. package/dist/src/nodeid/node-id-map.js.map +1 -1
  32. package/dist/src/typecheck/expression.d.ts.map +1 -1
  33. package/dist/src/typecheck/expression.js +22 -1
  34. package/dist/src/typecheck/expression.js.map +1 -1
  35. package/dist/src/typecheck/statement.d.ts +10 -0
  36. package/dist/src/typecheck/statement.d.ts.map +1 -1
  37. package/dist/src/typecheck/statement.js +19 -5
  38. package/dist/src/typecheck/statement.js.map +1 -1
  39. package/dist/test/integration/compliance/compliance-smoke.test.js +16 -9
  40. package/dist/test/integration/compliance/compliance-smoke.test.js.map +1 -1
  41. package/dist/test/unit/allocation-budget.test.js +41 -0
  42. package/dist/test/unit/allocation-budget.test.js.map +1 -1
  43. package/dist/test/unit/canonicalizer/chinese-function-syntax.test.d.ts +2 -0
  44. package/dist/test/unit/canonicalizer/chinese-function-syntax.test.d.ts.map +1 -0
  45. package/dist/test/unit/canonicalizer/chinese-function-syntax.test.js +86 -0
  46. package/dist/test/unit/canonicalizer/chinese-function-syntax.test.js.map +1 -0
  47. package/dist/test/unit/canonicalizer/transformers.test.d.ts +2 -0
  48. package/dist/test/unit/canonicalizer/transformers.test.d.ts.map +1 -0
  49. package/dist/test/unit/canonicalizer/transformers.test.js +25 -0
  50. package/dist/test/unit/canonicalizer/transformers.test.js.map +1 -0
  51. package/dist/test/unit/lsp/parse-document.test.js +39 -0
  52. package/dist/test/unit/lsp/parse-document.test.js.map +1 -1
  53. package/dist/test/unit/mapping/candidate-generator.test.js +54 -1
  54. package/dist/test/unit/mapping/candidate-generator.test.js.map +1 -1
  55. package/dist/test/unit/mapping/pipeline.test.js +22 -1
  56. package/dist/test/unit/mapping/pipeline.test.js.map +1 -1
  57. package/dist/test/unit/typecheck/e104-block-scope-parity.test.d.ts +2 -0
  58. package/dist/test/unit/typecheck/e104-block-scope-parity.test.d.ts.map +1 -0
  59. package/dist/test/unit/typecheck/e104-block-scope-parity.test.js +82 -0
  60. package/dist/test/unit/typecheck/e104-block-scope-parity.test.js.map +1 -0
  61. package/dist/test/unit/typecheck/type-inference.test.js +22 -0
  62. package/dist/test/unit/typecheck/type-inference.test.js.map +1 -1
  63. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
+ import { forEachIrNode } from '../nodeid/node-id-map.js';
1
2
  /**
2
3
  * 从「源码 + 带 origin 的节点」机械生成候选映射。
3
4
  *
4
5
  * <p>★本函数**不做任何猜测**:它只是把 `origin` 翻译成字符偏移并切片。
5
6
  * 切不出东西就跳过并记录,绝不编造。
6
7
  *
7
- * @param source 原始源码(与 canonical 逐行逐列对齐,见模块说明)
8
+ * @param source canonical 文本(origin 的行列以它为准);结果须再经 {@link relocateToSource}
8
9
  * @param nodes 带 origin 的节点(通常来自 Core IR 遍历)
9
10
  */
10
11
  export function generateCandidates(source, nodes) {
@@ -12,8 +13,8 @@ export function generateCandidates(source, nodes) {
12
13
  const candidates = [];
13
14
  const skipped = [];
14
15
  for (const node of nodes) {
15
- const start = toOffset(lineStarts, source.length, node.origin.start.line, node.origin.start.col);
16
- const end = toOffset(lineStarts, source.length, node.origin.end.line, node.origin.end.col);
16
+ const start = toOffset(lineStarts, source.length, node.origin.start.line, node.origin.start.col, false);
17
+ const end = toOffset(lineStarts, source.length, node.origin.end.line, node.origin.end.col, true);
17
18
  if (start === undefined || end === undefined) {
18
19
  skipped.push({ nodeId: node.nodeId, why: 'origin 的行列超出源码范围' });
19
20
  continue;
@@ -47,17 +48,82 @@ function computeLineStarts(source) {
47
48
  /**
48
49
  * 1-based 行列 → 字符偏移。越界返回 `undefined`(由调用方跳过并报告)。
49
50
  *
50
- * <p>★允许 `col` 指向行末之后一位(`end` 是开区间,可能正好落在行尾),
51
- * 但不允许越过整个源码长度。
51
+ * <p>★`end` 是开区间,允许正好落在行尾(`allowLineEnd`);`start` 必须指向该行的真实字符。
52
+ * 二者都不允许越过**该行**的行尾——否则切片会静默跨进下一行。
52
53
  */
53
- function toOffset(lineStarts, sourceLength, line, col) {
54
+ function toOffset(lineStarts, sourceLength, line, col, allowLineEnd) {
54
55
  if (!Number.isInteger(line) || !Number.isInteger(col) || line < 1 || col < 1) {
55
56
  return undefined;
56
57
  }
57
58
  if (line > lineStarts.length)
58
59
  return undefined;
59
- const offset = lineStarts[line - 1] + (col - 1);
60
- return offset > sourceLength ? undefined : offset;
60
+ const lineStart = lineStarts[line - 1];
61
+ const lineEnd = line < lineStarts.length ? lineStarts[line] - 1 : sourceLength;
62
+ const offset = lineStart + (col - 1);
63
+ return offset > lineEnd || (offset === lineEnd && !allowLineEnd) ? undefined : offset;
64
+ }
65
+ /**
66
+ * 把 canonical 坐标的候选重定位到原文坐标。
67
+ *
68
+ * <p>做法:候选起点所在行号在两边相同(canonicalize 保持行数)。数出候选文本在 canonical
69
+ * 该行内、起点之前出现了几次,再在原文同一行里取同序号的出现位置。字面量文本(数字、带引号的
70
+ * 字符串、布尔)不被 canonicalize 改写,所以序号一一对应。
71
+ *
72
+ * <p>★任何对不上的情况都跳过并报告:两边行数不同、该文本在两边同一行的出现次数不同
73
+ * (canonicalize 增删了同样的子串,如智能引号归一化后 `“x” plus "x"` 多出一个 `"x"`,
74
+ * 按序号配对会配错)、原文该行找不到该文本。宁可少一条候选,也不交出一条指错位置的。
75
+ */
76
+ export function relocateToSource(source, canonical, generated) {
77
+ const canStarts = computeLineStarts(canonical);
78
+ const srcStarts = computeLineStarts(source);
79
+ const skipped = [...generated.skipped];
80
+ if (canStarts.length !== srcStarts.length) {
81
+ for (const c of generated.candidates) {
82
+ skipped.push({ nodeId: c.nodeId, why: `原文与 canonical 行数不同(${srcStarts.length} ≠ ${canStarts.length}),无法定位原文位置` });
83
+ }
84
+ return { candidates: [], skipped };
85
+ }
86
+ const candidates = [];
87
+ for (const c of generated.candidates) {
88
+ const line = lineIndexOf(canStarts, c.span.start);
89
+ const canLineEnd = line + 1 < canStarts.length ? canStarts[line + 1] - 1 : canonical.length;
90
+ const lineEnd = line + 1 < srcStarts.length ? srcStarts[line + 1] - 1 : source.length;
91
+ const canCount = countOccurrences(canonical, c.text, canStarts[line], canLineEnd + 1);
92
+ const srcCount = countOccurrences(source, c.text, srcStarts[line], lineEnd + 1);
93
+ if (canCount !== srcCount) {
94
+ skipped.push({ nodeId: c.nodeId, why: `候选文本 ${JSON.stringify(c.text)} 在第 ${line + 1} 行的出现次数不同(原文 ${srcCount},canonical ${canCount}),无法唯一定位` });
95
+ continue;
96
+ }
97
+ const ordinal = countOccurrences(canonical, c.text, canStarts[line], c.span.start);
98
+ // 两边次数相等且候选自身就是 canonical 该行的第 ordinal 次出现,故原文必有第 ordinal 次。
99
+ const start = nthOccurrence(source, c.text, srcStarts[line], lineEnd, ordinal);
100
+ candidates.push({ ...c, span: { start, end: start + c.text.length } });
101
+ }
102
+ return { candidates, skipped };
103
+ }
104
+ /** 偏移所在的行(0-based)。 */
105
+ function lineIndexOf(lineStarts, offset) {
106
+ let line = 0;
107
+ while (line + 1 < lineStarts.length && lineStarts[line + 1] <= offset)
108
+ line++;
109
+ return line;
110
+ }
111
+ /** `text` 在 `[from, to)` 内起始的出现次数(允许重叠,与 {@link nthOccurrence} 同口径)。 */
112
+ function countOccurrences(s, text, from, to) {
113
+ let n = 0;
114
+ for (let i = s.indexOf(text, from); i !== -1 && i < to; i = s.indexOf(text, i + 1))
115
+ n++;
116
+ return n;
117
+ }
118
+ /** 起点落在 `[from, lineEnd]` 内的第 `ordinal` 次(0-based)出现;没有则为 `undefined`。 */
119
+ function nthOccurrence(s, text, from, lineEnd, ordinal) {
120
+ let n = 0;
121
+ for (let i = s.indexOf(text, from); i !== -1 && i <= lineEnd; i = s.indexOf(text, i + 1)) {
122
+ if (n === ordinal)
123
+ return i;
124
+ n++;
125
+ }
126
+ return undefined;
61
127
  }
62
128
  /**
63
129
  * 从 Core IR 里收集所有带 origin 的**字面量**节点。
@@ -68,39 +134,12 @@ function toOffset(lineStarts, sourceLength, line, col) {
68
134
  */
69
135
  export function collectLiteralNodes(ir) {
70
136
  const out = [];
71
- walk(ir, '$', out);
72
- return out;
73
- }
74
- function walk(node, path, out) {
75
- if (node === null || typeof node !== 'object' || Array.isArray(node))
76
- return;
77
- const obj = node;
78
- if (typeof obj.kind === 'string' && 'value' in obj && isOrigin(obj.origin)) {
79
- out.push({ nodeId: path, kind: obj.kind, origin: obj.origin });
80
- }
81
- for (const [field, value] of Object.entries(obj)) {
82
- if (field === 'origin')
83
- continue;
84
- if (Array.isArray(value)) {
85
- value.forEach((el, i) => walk(el, `${path}.${field}${segmentOf(el, i)}`, out));
86
- }
87
- else {
88
- walk(value, `${path}.${field}`, out);
137
+ forEachIrNode(ir, (node, nodeId) => {
138
+ if ('value' in node && isOrigin(node.origin)) {
139
+ out.push({ nodeId, kind: node.kind, origin: node.origin });
89
140
  }
90
- }
91
- }
92
- /** 与 `NodeIdMap.segmentOf` 同规则——路径必须与 nodeId 一致,否则两边对不上。 */
93
- function segmentOf(element, index) {
94
- if (element !== null && typeof element === 'object' && !Array.isArray(element)) {
95
- const el = element;
96
- // ★与 NodeIdMap 同规则:`_` 是占位符不是名字,必须退回下标,
97
- // 否则同一函数体里的多条裸表达式语句会塌成同一个 nodeId。
98
- if (typeof el.name === 'string' && el.name !== '_')
99
- return `{${el.name}}`;
100
- if (typeof el.path === 'string')
101
- return `{${el.path}}`;
102
- }
103
- return `[${index}]`;
141
+ });
142
+ return out;
104
143
  }
105
144
  function isOrigin(v) {
106
145
  if (v === null || typeof v !== 'object')
@@ -1 +1 @@
1
- {"version":3,"file":"candidate-generator.js","sourceRoot":"","sources":["../../../src/mapping/candidate-generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"candidate-generator.js","sourceRoot":"","sources":["../../../src/mapping/candidate-generator.ts"],"names":[],"mappings":"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"}
@@ -84,4 +84,10 @@ export interface BridgeResult {
84
84
  * ——编译不了时仍返回文档结构与数量实体,并在 diagnostics 里说明原因。
85
85
  */
86
86
  export declare function runSemanticBridge(source: string): BridgeResult;
87
+ /** 诊断前缀:两引擎一致,跨引擎语料按前缀断言(具体消息允许不同)。 */
88
+ export declare const BRIDGE_DIAGNOSTIC: {
89
+ readonly syntaxError: "源码有语法错误,无法编译成 Core IR,候选映射层已跳过:";
90
+ readonly compileFailed: "源码无法编译成 Core IR,候选映射层已跳过:";
91
+ readonly internalError: "候选映射层内部错误(不是源码问题):";
92
+ };
87
93
  //# sourceMappingURL=pipeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/mapping/pipeline.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAC/C,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,kBAAkB;AAClB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IAC1C,kBAAkB;IAClB,QAAQ,CAAC,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC;IACzC,gBAAgB;IAChB,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAgF9D"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/mapping/pipeline.ts"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,EAAiB,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAC/C,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,kBAAkB;AAClB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IAC1C,kBAAkB;IAClB,QAAQ,CAAC,UAAU,EAAE,SAAS,QAAQ,EAAE,CAAC;IACzC,gBAAgB;IAChB,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAsC9D;AAED,uCAAuC;AACvC,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC"}
@@ -2,10 +2,10 @@ import { canonicalize } from '../frontend/canonicalizer.js';
2
2
  import { lex } from '../frontend/lexer.js';
3
3
  import { parse } from '../parser.js';
4
4
  import { lowerModule } from '../lower_to_core.js';
5
- import { computeNodeIds } from '../nodeid/node-id-map.js';
5
+ import { computeNodeIds, forEachIrNode } from '../nodeid/node-id-map.js';
6
6
  import { parseSourceIr } from './source-ir.js';
7
7
  import { extractQuantities } from './quantity-ir.js';
8
- import { generateCandidates, collectLiteralNodes } from './candidate-generator.js';
8
+ import { generateCandidates, collectLiteralNodes, relocateToSource } from './candidate-generator.js';
9
9
  import { verifyMapping } from './mapping-ir.js';
10
10
  /**
11
11
  * 跑通「人类文档 → 结构化 → 抽取 → 候选 → 验证」全链路。
@@ -36,16 +36,64 @@ export function runSemanticBridge(source) {
36
36
  // ── 第 3 层:候选映射 + 验证(需要源码可编译)─────────────────
37
37
  // ★这一层**会失败**,且失败是常态(任意文字不是合法 Aster 源码)。
38
38
  // 失败时前两层的结果仍然有效——这正是分层降级的意义。
39
- let verified = [];
39
+ const verified = candidateLayer(source, diagnostics);
40
+ let v = 0, r = 0, j = 0;
41
+ for (const c of verified) {
42
+ if (c.result.verdict === 'VERIFIED')
43
+ v++;
44
+ else if (c.result.verdict === 'REVIEW_REQUIRED')
45
+ r++;
46
+ else
47
+ j++;
48
+ }
49
+ return {
50
+ sourceIr,
51
+ quantities,
52
+ verified,
53
+ summary: { verified: v, reviewRequired: r, rejected: j },
54
+ diagnostics,
55
+ };
56
+ }
57
+ /** 诊断前缀:两引擎一致,跨引擎语料按前缀断言(具体消息允许不同)。 */
58
+ export const BRIDGE_DIAGNOSTIC = {
59
+ syntaxError: '源码有语法错误,无法编译成 Core IR,候选映射层已跳过:',
60
+ compileFailed: '源码无法编译成 Core IR,候选映射层已跳过:',
61
+ internalError: '候选映射层内部错误(不是源码问题):',
62
+ };
63
+ /**
64
+ * 第 3 层:canonicalize → lex → parse → lower → 候选 → 重定位 → 验证。
65
+ *
66
+ * <p>失败分三类,各自如实报告:
67
+ * - 语法错误:解析器带错误恢复,照样会返回一棵残缺的树;在残缺树上生成的候选不可信,整层跳过。
68
+ * - 编译失败:lex / parse / lower 抛错,是源码本身的问题(任意文字本就编译不了)。
69
+ * - 内部错误:IR 已经得到之后的步骤抛错,是本链路的缺陷,不得伪装成「源码编译不了」。
70
+ */
71
+ function candidateLayer(source, diagnostics) {
72
+ const message = (e) => (e instanceof Error ? e.message || e.name : String(e));
73
+ let canonical;
74
+ let ir;
75
+ try {
76
+ canonical = canonicalize(source);
77
+ const parsed = parse(lex(canonical));
78
+ const syntaxErrors = parsed.diagnostics.filter(d => d.severity === 'error');
79
+ if (syntaxErrors.length > 0) {
80
+ const first = syntaxErrors[0];
81
+ diagnostics.push(`${BRIDGE_DIAGNOSTIC.syntaxError}L${first.span?.start.line ?? '?'}:${first.span?.start.col ?? '?'} ${first.message}`);
82
+ return [];
83
+ }
84
+ ir = lowerModule(parsed.ast);
85
+ }
86
+ catch (e) {
87
+ diagnostics.push(BRIDGE_DIAGNOSTIC.compileFailed + message(e));
88
+ return [];
89
+ }
40
90
  try {
41
- const canonical = canonicalize(source);
42
- const ir = lowerModule(parse(lex(canonical)).ast);
43
91
  const identities = computeNodeIds(ir);
44
92
  const nodes = collectLiteralNodes(ir);
45
93
  if (nodes.length === 0) {
46
94
  diagnostics.push('IR 里没有带 origin 的字面量节点——无候选可生成。');
47
95
  }
48
- const generated = generateCandidates(canonical, nodes);
96
+ const generated = relocateToSource(source, canonical, generateCandidates(canonical, nodes));
49
97
  for (const s of generated.skipped) {
50
98
  diagnostics.push(`跳过节点 ${s.nodeId}:${s.why}`);
51
99
  }
@@ -57,89 +105,34 @@ export function runSemanticBridge(source) {
57
105
  // 端到端 demo 一跑就暴露了(2 条候选全 REJECTED,而它们本该 VERIFIED)。
58
106
  // ★这也说明"接线"本身必须端到端验证——单看两侧模块的单测都是绿的。
59
107
  const byId = collectVerifiableNodes(ir);
60
- // identities 仅用于校验路径口径一致(两边都由同一套 segmentOf 规则生成)。
61
- for (const id of byId.keys()) {
62
- if (!identities.has(id)) {
63
- diagnostics.push(`节点 ${id} 不在 NodeIdMap 中——路径口径可能漂移。`);
64
- }
65
- }
66
- verified = generated.candidates.map(mapping => ({
108
+ return generated.candidates.map(mapping => ({
67
109
  mapping,
68
110
  result: verifyMapping(mapping, id => byId.get(id)),
69
111
  contentHash: identities.get(mapping.nodeId)?.contentHash,
70
112
  }));
71
113
  }
72
114
  catch (e) {
73
- // ★不把编译失败当成错误——"任意文字"本就编译不了。
74
- // 如实记录,让调用方知道第 3 层没跑,而不是以为跑了但没结果。
75
- diagnostics.push(`源码无法编译成 Core IR,候选映射层已跳过:`
76
- + `${e instanceof Error ? e.message : String(e)}`);
115
+ diagnostics.push(BRIDGE_DIAGNOSTIC.internalError + message(e));
116
+ return [];
77
117
  }
78
- let v = 0, r = 0, j = 0;
79
- for (const c of verified) {
80
- if (c.result.verdict === 'VERIFIED')
81
- v++;
82
- else if (c.result.verdict === 'REVIEW_REQUIRED')
83
- r++;
84
- else
85
- j++;
86
- }
87
- return {
88
- sourceIr,
89
- quantities,
90
- verified,
91
- summary: { verified: v, reviewRequired: r, rejected: j },
92
- diagnostics,
93
- };
94
118
  }
95
119
  /**
96
- * 按与 {@link collectLiteralNodes} **完全相同**的路径规则遍历 IR,
97
- * 产出 `nodeId → VerifiableNode`(带 `value`/`name`)。
120
+ * 按 nodeId 路径规则产出 `nodeId → VerifiableNode`(带 `value`/`name`)。
98
121
  *
99
122
  * <p>★为什么不复用 `computeNodeIds` 的返回值:`NodeIdentity` 只有
100
123
  * `{nodeId, contentHash, kind}`,**不含 value**。用它做 `resolve` 会让
101
- * `verifyMapping` 永远比不出值,把所有候选判成 REJECTED。
102
- *
103
- * <p>★路径规则必须与 `collectLiteralNodes` / `NodeIdMap` **三方一致**,
104
- * 否则候选的 nodeId 与这里的键对不上——那种错会表现为"节点不存在",
105
- * 极易被误读成 IR 有问题。
124
+ * `verifyMapping` 永远比不出值,把所有候选判成 REJECTED。路径规则与 nodeId 共用
125
+ * {@link forEachIrNode},不会漂移。
106
126
  */
107
127
  function collectVerifiableNodes(ir) {
108
128
  const out = new Map();
109
- walkVerifiable(ir, '$', out);
110
- return out;
111
- }
112
- function walkVerifiable(node, path, out) {
113
- if (node === null || typeof node !== 'object' || Array.isArray(node))
114
- return;
115
- const obj = node;
116
- if (typeof obj.kind === 'string') {
117
- out.set(path, {
118
- kind: obj.kind,
119
- ...(obj.value === undefined ? {} : { value: obj.value }),
120
- ...(typeof obj.name === 'string' ? { name: obj.name } : {}),
129
+ forEachIrNode(ir, (node, nodeId) => {
130
+ out.set(nodeId, {
131
+ kind: node.kind,
132
+ ...(node.value === undefined ? {} : { value: node.value }),
133
+ ...(typeof node.name === 'string' ? { name: node.name } : {}),
121
134
  });
122
- }
123
- for (const [field, value] of Object.entries(obj)) {
124
- if (field === 'origin')
125
- continue;
126
- if (Array.isArray(value)) {
127
- value.forEach((el, i) => walkVerifiable(el, `${path}.${field}${segmentOfPath(el, i)}`, out));
128
- }
129
- else {
130
- walkVerifiable(value, `${path}.${field}`, out);
131
- }
132
- }
133
- }
134
- /** 与 `collectLiteralNodes.segmentOf` / `NodeIdMap.segmentOf` 同规则(三方必须一致)。 */
135
- function segmentOfPath(element, index) {
136
- if (element !== null && typeof element === 'object' && !Array.isArray(element)) {
137
- const el = element;
138
- if (typeof el.name === 'string' && el.name !== '_')
139
- return `{${el.name}}`;
140
- if (typeof el.path === 'string')
141
- return `{${el.path}}`;
142
- }
143
- return `[${index}]`;
135
+ });
136
+ return out;
144
137
  }
145
138
  //# sourceMappingURL=pipeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/mapping/pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/mapping/pipeline.ts"],"names":[],"mappings":"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"}
@@ -66,4 +66,11 @@ export declare function canonicalHash(value: unknown): string;
66
66
  * @returns nodeId → NodeIdentity,按插入顺序(路径的深度优先序,确定)
67
67
  */
68
68
  export declare function computeNodeIds(ir: unknown): ReadonlyMap<string, NodeIdentity>;
69
+ /**
70
+ * 按 nodeId 的路径规则深度优先遍历 IR,对每个带 `kind` 的节点回调 `(节点, nodeId)`。
71
+ *
72
+ * <p>★候选生成、verifier 取值与本文件的 nodeId 必须用同一条路径规则,否则候选的 nodeId
73
+ * 与 resolve 的键对不上(表现为「节点不存在」)。各处一律走这个函数,不再各自复制遍历。
74
+ */
75
+ export declare function forEachIrNode(ir: unknown, visit: (node: Readonly<Record<string, unknown>>, nodeId: string) => void): void;
69
76
  //# sourceMappingURL=node-id-map.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-id-map.d.ts","sourceRoot":"","sources":["../../../src/nodeid/node-id-map.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,qDAAqD;AACrD,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAQlD,iBAAiB;AACjB,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA2DD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIpD;AAsCD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAI7E"}
1
+ {"version":3,"file":"node-id-map.d.ts","sourceRoot":"","sources":["../../../src/nodeid/node-id-map.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,qDAAqD;AACrD,eAAO,MAAM,eAAe,qBAAqB,CAAC;AAQlD,iBAAiB;AACjB,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA2DD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIpD;AAsCD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAY7E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GACvE,IAAI,CAEN"}
@@ -163,30 +163,40 @@ function segmentOf(element, index) {
163
163
  */
164
164
  export function computeNodeIds(ir) {
165
165
  const out = new Map();
166
- walk(ir, '$', out);
167
- return out;
168
- }
169
- function walk(node, path, out) {
170
- if (node === null || typeof node !== 'object' || Array.isArray(node))
171
- return;
172
- const obj = node;
173
166
  // 只有带 kind 的对象才是「IR 节点」;Field/Param 等无 kind 的结构体不单独发 ID,
174
167
  // 它们随宿主节点的 contentHash 一起变化(与 Java 侧口径一致)。
175
- if (typeof obj.kind === 'string') {
168
+ forEachIrNode(ir, (node, path) => {
176
169
  out.set(path, {
177
170
  nodeId: path,
178
- contentHash: canonicalHash(stripIdentityIrrelevant(obj)),
179
- kind: obj.kind,
171
+ contentHash: canonicalHash(stripIdentityIrrelevant(node)),
172
+ kind: node.kind,
180
173
  });
181
- }
174
+ });
175
+ return out;
176
+ }
177
+ /**
178
+ * 按 nodeId 的路径规则深度优先遍历 IR,对每个带 `kind` 的节点回调 `(节点, nodeId)`。
179
+ *
180
+ * <p>★候选生成、verifier 取值与本文件的 nodeId 必须用同一条路径规则,否则候选的 nodeId
181
+ * 与 resolve 的键对不上(表现为「节点不存在」)。各处一律走这个函数,不再各自复制遍历。
182
+ */
183
+ export function forEachIrNode(ir, visit) {
184
+ walk(ir, '$', visit);
185
+ }
186
+ function walk(node, path, visit) {
187
+ if (node === null || typeof node !== 'object' || Array.isArray(node))
188
+ return;
189
+ const obj = node;
190
+ if (typeof obj.kind === 'string')
191
+ visit(obj, path);
182
192
  for (const [field, value] of Object.entries(obj)) {
183
193
  if (isIdentityIrrelevant(field))
184
194
  continue;
185
195
  if (Array.isArray(value)) {
186
- value.forEach((el, i) => walk(el, `${path}.${field}${segmentOf(el, i)}`, out));
196
+ value.forEach((el, i) => walk(el, `${path}.${field}${segmentOf(el, i)}`, visit));
187
197
  }
188
198
  else {
189
- walk(value, `${path}.${field}`, out);
199
+ walk(value, `${path}.${field}`, visit);
190
200
  }
191
201
  }
192
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"node-id-map.js","sourceRoot":"","sources":["../../../src/nodeid/node-id-map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node-id-map.js","sourceRoot":"","sources":["../../../src/nodeid/node-id-map.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/typecheck/expression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAKL,YAAY,EAEb,MAAM,WAAW,CAAC;AAGnB,qBAAa,iBAAkB,SAAQ,kBAAkB,CAAC,sBAAsB,CAAC;IACxE,OAAO,UAAS;IAChB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAiB;IAEhC,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI;CAwb7F;AAqBD,wBAAgB,UAAU,CACxB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,IAAI,CAAC,UAAU,EACrB,WAAW,EAAE,iBAAiB,GAC7B,IAAI,CAAC,IAAI,CAIX;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,IAAI,CAAC,IAAI,EACjB,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EACrC,WAAW,EAAE,iBAAiB,GAC7B,IAAI,CAIN"}
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../../src/typecheck/expression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAKL,YAAY,EAEb,MAAM,WAAW,CAAC;AAGnB,qBAAa,iBAAkB,SAAQ,kBAAkB,CAAC,sBAAsB,CAAC;IACxE,OAAO,UAAS;IAChB,MAAM,EAAE,IAAI,CAAC,IAAI,CAAiB;IAEhC,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI;CA+c7F;AAqBD,wBAAgB,UAAU,CACxB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,IAAI,CAAC,UAAU,EACrB,WAAW,EAAE,iBAAiB,GAC7B,IAAI,CAAC,IAAI,CAIX;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,IAAI,CAAC,IAAI,EACjB,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EACrC,WAAW,EAAE,iBAAiB,GAC7B,IAAI,CAIN"}
@@ -1,6 +1,8 @@
1
1
  import { DefaultCoreVisitor } from '../core/visitor.js';
2
2
  import { TypeSystem } from './type_system.js';
3
3
  import { isFieldTypeInferred } from '../core/inferred_fields.js';
4
+ import { defineSymbol } from './context.js';
5
+ import { typecheckBlock } from './statement.js';
4
6
  import { formatType, isAssignable, isUnknown, normalizeType, originToSpan, unknownType, } from './pure.js';
5
7
  import { hasVerdictPrefix, isVerdictField, isVerdictType, verdictArity, VERDICT_TYPE_NAME } from './verdict_signatures.js';
6
8
  export class TypeOfExprVisitor extends DefaultCoreVisitor {
@@ -213,10 +215,29 @@ export class TypeOfExprVisitor extends DefaultCoreVisitor {
213
215
  }
214
216
  case 'Lambda': {
215
217
  const params = expression.params.map(param => normalizeType(param.type));
218
+ const ret = normalizeType(expression.retType);
219
+ symbols.enterScope('lambda');
220
+ try {
221
+ expression.params.forEach((param, index) => {
222
+ defineSymbol({ module, symbols, diagnostics }, param.name, params[index], 'param',
223
+ // 形参节点不带位置信息:用 lambda 自身的 origin 定位 E104。
224
+ originToSpan(expression.origin));
225
+ });
226
+ const bodyType = typecheckBlock(module, symbols, expression.body, diagnostics);
227
+ if (!isUnknown(bodyType) && !isUnknown(ret) && !isAssignable(ret, bodyType)) {
228
+ diagnostics.error("E003" /* ErrorCode.RETURN_TYPE_MISMATCH */, originToSpan(expression.origin), {
229
+ expected: formatType(ret),
230
+ actual: formatType(bodyType),
231
+ });
232
+ }
233
+ }
234
+ finally {
235
+ symbols.exitScope();
236
+ }
216
237
  const funcType = {
217
238
  kind: 'FuncType',
218
239
  params,
219
- ret: normalizeType(expression.ret),
240
+ ret,
220
241
  effectParams: [],
221
242
  declaredEffects: [],
222
243
  };