@aster-cloud/aster-lang-ts 1.0.37 → 1.1.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 (292) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +13 -7
  3. package/dist/scripts/aster.js +10 -5
  4. package/dist/scripts/aster.js.map +1 -1
  5. package/dist/scripts/core-ir-json.js +8 -3
  6. package/dist/scripts/core-ir-json.js.map +1 -1
  7. package/dist/scripts/emit-classfiles.js +3 -2
  8. package/dist/scripts/emit-classfiles.js.map +1 -1
  9. package/dist/scripts/emit-core.js +8 -5
  10. package/dist/scripts/emit-core.js.map +1 -1
  11. package/dist/scripts/generate-casefold.d.ts +2 -0
  12. package/dist/scripts/generate-casefold.d.ts.map +1 -0
  13. package/dist/scripts/generate-casefold.js +34 -0
  14. package/dist/scripts/generate-casefold.js.map +1 -0
  15. package/dist/scripts/golden.js +16 -16
  16. package/dist/scripts/golden.js.map +1 -1
  17. package/dist/scripts/perf-benchmark.js +1 -0
  18. package/dist/scripts/perf-benchmark.js.map +1 -1
  19. package/dist/scripts/profile-medium-project.js +1 -1
  20. package/dist/scripts/profile-medium-project.js.map +1 -1
  21. package/dist/scripts/repl.js +3 -8
  22. package/dist/scripts/repl.js.map +1 -1
  23. package/dist/scripts/typecheck-cli.js +10 -9
  24. package/dist/scripts/typecheck-cli.js.map +1 -1
  25. package/dist/scripts/update-eff-violation-expected.js +6 -6
  26. package/dist/scripts/update-eff-violation-expected.js.map +1 -1
  27. package/dist/scripts/verify-capabilities.js +3 -6
  28. package/dist/scripts/verify-capabilities.js.map +1 -1
  29. package/dist/src/ai/validator.d.ts +1 -1
  30. package/dist/src/ai/validator.d.ts.map +1 -1
  31. package/dist/src/ai/validator.js +12 -12
  32. package/dist/src/ai/validator.js.map +1 -1
  33. package/dist/src/ast/ast.d.ts +1 -0
  34. package/dist/src/ast/ast.d.ts.map +1 -1
  35. package/dist/src/ast/ast.js.map +1 -1
  36. package/dist/src/browser.d.ts +27 -10
  37. package/dist/src/browser.d.ts.map +1 -1
  38. package/dist/src/browser.js +42 -54
  39. package/dist/src/browser.js.map +1 -1
  40. package/dist/src/cli/policy-converter.js +5 -9
  41. package/dist/src/cli/policy-converter.js.map +1 -1
  42. package/dist/src/compile-pipeline.d.ts +48 -0
  43. package/dist/src/compile-pipeline.d.ts.map +1 -0
  44. package/dist/src/compile-pipeline.js +89 -0
  45. package/dist/src/compile-pipeline.js.map +1 -0
  46. package/dist/src/config/lexicons/diagnostic-messages.d.ts.map +1 -1
  47. package/dist/src/config/lexicons/diagnostic-messages.js +20 -0
  48. package/dist/src/config/lexicons/diagnostic-messages.js.map +1 -1
  49. package/dist/src/config/lexicons/identifiers/casefold-table.generated.d.ts +9 -0
  50. package/dist/src/config/lexicons/identifiers/casefold-table.generated.d.ts.map +1 -0
  51. package/dist/src/config/lexicons/identifiers/casefold-table.generated.js +1467 -0
  52. package/dist/src/config/lexicons/identifiers/casefold-table.generated.js.map +1 -0
  53. package/dist/src/config/lexicons/identifiers/casefold.d.ts +7 -0
  54. package/dist/src/config/lexicons/identifiers/casefold.d.ts.map +1 -0
  55. package/dist/src/config/lexicons/identifiers/casefold.js +37 -0
  56. package/dist/src/config/lexicons/identifiers/casefold.js.map +1 -0
  57. package/dist/src/config/lexicons/identifiers/domains/finance.loan.de-DE.d.ts.map +1 -1
  58. package/dist/src/config/lexicons/identifiers/domains/finance.loan.de-DE.js +8 -0
  59. package/dist/src/config/lexicons/identifiers/domains/finance.loan.de-DE.js.map +1 -1
  60. package/dist/src/config/lexicons/identifiers/domains/finance.loan.en-US.d.ts.map +1 -1
  61. package/dist/src/config/lexicons/identifiers/domains/finance.loan.en-US.js +8 -0
  62. package/dist/src/config/lexicons/identifiers/domains/finance.loan.en-US.js.map +1 -1
  63. package/dist/src/config/lexicons/identifiers/domains/finance.loan.zh-CN.d.ts.map +1 -1
  64. package/dist/src/config/lexicons/identifiers/domains/finance.loan.zh-CN.js +8 -0
  65. package/dist/src/config/lexicons/identifiers/domains/finance.loan.zh-CN.js.map +1 -1
  66. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.de-DE.d.ts.map +1 -1
  67. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.de-DE.js +6 -0
  68. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.de-DE.js.map +1 -1
  69. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.en-US.d.ts.map +1 -1
  70. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.en-US.js +6 -0
  71. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.en-US.js.map +1 -1
  72. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.zh-CN.d.ts.map +1 -1
  73. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.zh-CN.js +6 -0
  74. package/dist/src/config/lexicons/identifiers/domains/insurance.auto.zh-CN.js.map +1 -1
  75. package/dist/src/config/lexicons/identifiers/index.d.ts +7 -9
  76. package/dist/src/config/lexicons/identifiers/index.d.ts.map +1 -1
  77. package/dist/src/config/lexicons/identifiers/index.js +8 -9
  78. package/dist/src/config/lexicons/identifiers/index.js.map +1 -1
  79. package/dist/src/config/lexicons/identifiers/registry.d.ts +11 -5
  80. package/dist/src/config/lexicons/identifiers/registry.d.ts.map +1 -1
  81. package/dist/src/config/lexicons/identifiers/registry.js +20 -14
  82. package/dist/src/config/lexicons/identifiers/registry.js.map +1 -1
  83. package/dist/src/config/lexicons/identifiers/scopes.d.ts +52 -0
  84. package/dist/src/config/lexicons/identifiers/scopes.d.ts.map +1 -0
  85. package/dist/src/config/lexicons/identifiers/scopes.js +166 -0
  86. package/dist/src/config/lexicons/identifiers/scopes.js.map +1 -0
  87. package/dist/src/config/lexicons/identifiers/types.d.ts +15 -29
  88. package/dist/src/config/lexicons/identifiers/types.d.ts.map +1 -1
  89. package/dist/src/config/lexicons/identifiers/types.js +91 -101
  90. package/dist/src/config/lexicons/identifiers/types.js.map +1 -1
  91. package/dist/src/config/lexicons/lsp-ui-texts.d.ts +7 -0
  92. package/dist/src/config/lexicons/lsp-ui-texts.d.ts.map +1 -1
  93. package/dist/src/config/lexicons/lsp-ui-texts.js +12 -0
  94. package/dist/src/config/lexicons/lsp-ui-texts.js.map +1 -1
  95. package/dist/src/config/semantic.d.ts +5 -0
  96. package/dist/src/config/semantic.d.ts.map +1 -1
  97. package/dist/src/config/semantic.js +12 -0
  98. package/dist/src/config/semantic.js.map +1 -1
  99. package/dist/src/core/inferred_fields.d.ts +10 -0
  100. package/dist/src/core/inferred_fields.d.ts.map +1 -1
  101. package/dist/src/core/inferred_fields.js +9 -0
  102. package/dist/src/core/inferred_fields.js.map +1 -1
  103. package/dist/src/core/interpreter.d.ts.map +1 -1
  104. package/dist/src/core/interpreter.js +12 -10
  105. package/dist/src/core/interpreter.js.map +1 -1
  106. package/dist/src/core/resolution-mark.d.ts +28 -0
  107. package/dist/src/core/resolution-mark.d.ts.map +1 -0
  108. package/dist/src/core/resolution-mark.js +19 -0
  109. package/dist/src/core/resolution-mark.js.map +1 -0
  110. package/dist/src/core/resolve-typed-references.d.ts +36 -0
  111. package/dist/src/core/resolve-typed-references.d.ts.map +1 -0
  112. package/dist/src/core/resolve-typed-references.js +703 -0
  113. package/dist/src/core/resolve-typed-references.js.map +1 -0
  114. package/dist/src/diagnostics/error_codes.d.ts +11 -1
  115. package/dist/src/diagnostics/error_codes.d.ts.map +1 -1
  116. package/dist/src/diagnostics/error_codes.js +80 -0
  117. package/dist/src/diagnostics/error_codes.js.map +1 -1
  118. package/dist/src/frontend/canonicalizer.d.ts +8 -13
  119. package/dist/src/frontend/canonicalizer.d.ts.map +1 -1
  120. package/dist/src/frontend/canonicalizer.js +19 -48
  121. package/dist/src/frontend/canonicalizer.js.map +1 -1
  122. package/dist/src/frontend/resolution-choice.d.ts +34 -0
  123. package/dist/src/frontend/resolution-choice.d.ts.map +1 -0
  124. package/dist/src/frontend/resolution-choice.js +69 -0
  125. package/dist/src/frontend/resolution-choice.js.map +1 -0
  126. package/dist/src/frontend/resolution-context.d.ts +28 -0
  127. package/dist/src/frontend/resolution-context.d.ts.map +1 -0
  128. package/dist/src/frontend/resolution-context.js +7 -0
  129. package/dist/src/frontend/resolution-context.js.map +1 -0
  130. package/dist/src/frontend/resolve-declarations.d.ts +13 -0
  131. package/dist/src/frontend/resolve-declarations.d.ts.map +1 -0
  132. package/dist/src/frontend/resolve-declarations.js +611 -0
  133. package/dist/src/frontend/resolve-declarations.js.map +1 -0
  134. package/dist/src/frontend/resolve-policy-types.d.ts +54 -0
  135. package/dist/src/frontend/resolve-policy-types.d.ts.map +1 -0
  136. package/dist/src/frontend/resolve-policy-types.js +71 -0
  137. package/dist/src/frontend/resolve-policy-types.js.map +1 -0
  138. package/dist/src/index.d.ts +14 -7
  139. package/dist/src/index.d.ts.map +1 -1
  140. package/dist/src/index.js +14 -7
  141. package/dist/src/index.js.map +1 -1
  142. package/dist/src/lower_to_core.d.ts +2 -16
  143. package/dist/src/lower_to_core.d.ts.map +1 -1
  144. package/dist/src/lower_to_core.js +101 -44
  145. package/dist/src/lower_to_core.js.map +1 -1
  146. package/dist/src/lsp/canonicalize-options.d.ts +8 -11
  147. package/dist/src/lsp/canonicalize-options.d.ts.map +1 -1
  148. package/dist/src/lsp/canonicalize-options.js +8 -8
  149. package/dist/src/lsp/canonicalize-options.js.map +1 -1
  150. package/dist/src/lsp/completion.d.ts +32 -5
  151. package/dist/src/lsp/completion.d.ts.map +1 -1
  152. package/dist/src/lsp/completion.js +59 -0
  153. package/dist/src/lsp/completion.js.map +1 -1
  154. package/dist/src/lsp/diagnostics.d.ts +2 -0
  155. package/dist/src/lsp/diagnostics.d.ts.map +1 -1
  156. package/dist/src/lsp/diagnostics.js +77 -73
  157. package/dist/src/lsp/diagnostics.js.map +1 -1
  158. package/dist/src/lsp/navigation/hover.d.ts +12 -5
  159. package/dist/src/lsp/navigation/hover.d.ts.map +1 -1
  160. package/dist/src/lsp/navigation/hover.js +136 -90
  161. package/dist/src/lsp/navigation/hover.js.map +1 -1
  162. package/dist/src/lsp/parse-document.d.ts +3 -0
  163. package/dist/src/lsp/parse-document.d.ts.map +1 -1
  164. package/dist/src/lsp/parse-document.js +5 -17
  165. package/dist/src/lsp/parse-document.js.map +1 -1
  166. package/dist/src/lsp/resolution.d.ts +40 -0
  167. package/dist/src/lsp/resolution.d.ts.map +1 -0
  168. package/dist/src/lsp/resolution.js +179 -0
  169. package/dist/src/lsp/resolution.js.map +1 -0
  170. package/dist/src/lsp/server.js +3 -1
  171. package/dist/src/lsp/server.js.map +1 -1
  172. package/dist/src/lsp/source-positions.d.ts +2 -8
  173. package/dist/src/lsp/source-positions.d.ts.map +1 -1
  174. package/dist/src/lsp/source-positions.js +4 -16
  175. package/dist/src/lsp/source-positions.js.map +1 -1
  176. package/dist/src/mapping/pipeline.js +3 -2
  177. package/dist/src/mapping/pipeline.js.map +1 -1
  178. package/dist/src/mapping/review-queue.d.ts.map +1 -1
  179. package/dist/src/mapping/review-queue.js +3 -2
  180. package/dist/src/mapping/review-queue.js.map +1 -1
  181. package/dist/src/parser/context.d.ts +2 -0
  182. package/dist/src/parser/context.d.ts.map +1 -1
  183. package/dist/src/parser/context.js +1 -0
  184. package/dist/src/parser/context.js.map +1 -1
  185. package/dist/src/parser/decl-parser.d.ts.map +1 -1
  186. package/dist/src/parser/decl-parser.js +1 -0
  187. package/dist/src/parser/decl-parser.js.map +1 -1
  188. package/dist/src/parser/expr-stmt-parser.d.ts.map +1 -1
  189. package/dist/src/parser/expr-stmt-parser.js +2 -16
  190. package/dist/src/parser/expr-stmt-parser.js.map +1 -1
  191. package/dist/src/parser.d.ts.map +1 -1
  192. package/dist/src/parser.js +3 -1
  193. package/dist/src/parser.js.map +1 -1
  194. package/dist/src/typecheck/expression.d.ts.map +1 -1
  195. package/dist/src/typecheck/expression.js +13 -0
  196. package/dist/src/typecheck/expression.js.map +1 -1
  197. package/dist/src/typecheck/generics.d.ts +5 -0
  198. package/dist/src/typecheck/generics.d.ts.map +1 -1
  199. package/dist/src/typecheck/generics.js +15 -8
  200. package/dist/src/typecheck/generics.js.map +1 -1
  201. package/dist/src/types.d.ts +45 -13
  202. package/dist/src/types.d.ts.map +1 -1
  203. package/dist/src/types.js.map +1 -1
  204. package/dist/src/version.d.ts +17 -0
  205. package/dist/src/version.d.ts.map +1 -0
  206. package/dist/src/version.js +17 -0
  207. package/dist/src/version.js.map +1 -0
  208. package/dist/test/integration/builtin-enum-vocabulary.test.d.ts +2 -0
  209. package/dist/test/integration/builtin-enum-vocabulary.test.d.ts.map +1 -0
  210. package/dist/test/integration/builtin-enum-vocabulary.test.js +51 -0
  211. package/dist/test/integration/builtin-enum-vocabulary.test.js.map +1 -0
  212. package/dist/test/integration/lsp/lsp-rename-safety.test.js +0 -13
  213. package/dist/test/integration/lsp/lsp-rename-safety.test.js.map +1 -1
  214. package/dist/test/integration/name-resolution-entrypoints.test.d.ts +2 -0
  215. package/dist/test/integration/name-resolution-entrypoints.test.d.ts.map +1 -0
  216. package/dist/test/integration/name-resolution-entrypoints.test.js +109 -0
  217. package/dist/test/integration/name-resolution-entrypoints.test.js.map +1 -0
  218. package/dist/test/integration/vocabulary-resolution.test.d.ts +2 -0
  219. package/dist/test/integration/vocabulary-resolution.test.d.ts.map +1 -0
  220. package/dist/test/integration/vocabulary-resolution.test.js +291 -0
  221. package/dist/test/integration/vocabulary-resolution.test.js.map +1 -0
  222. package/dist/test/property/property.test.js +2 -1
  223. package/dist/test/property/property.test.js.map +1 -1
  224. package/dist/test/unit/canonicalizer/canonicalizer.test.js +7 -79
  225. package/dist/test/unit/canonicalizer/canonicalizer.test.js.map +1 -1
  226. package/dist/test/unit/config/lexicons/identifiers/identifier-mapping.test.js +134 -31
  227. package/dist/test/unit/config/lexicons/identifiers/identifier-mapping.test.js.map +1 -1
  228. package/dist/test/unit/config/lexicons/identifiers/literal-macro.test.js +16 -18
  229. package/dist/test/unit/config/lexicons/identifiers/literal-macro.test.js.map +1 -1
  230. package/dist/test/unit/core/resolve-typed-references.test.d.ts +2 -0
  231. package/dist/test/unit/core/resolve-typed-references.test.d.ts.map +1 -0
  232. package/dist/test/unit/core/resolve-typed-references.test.js +600 -0
  233. package/dist/test/unit/core/resolve-typed-references.test.js.map +1 -0
  234. package/dist/test/unit/diagnostics/resolution-codes.test.d.ts +6 -0
  235. package/dist/test/unit/diagnostics/resolution-codes.test.d.ts.map +1 -0
  236. package/dist/test/unit/diagnostics/resolution-codes.test.js +83 -0
  237. package/dist/test/unit/diagnostics/resolution-codes.test.js.map +1 -0
  238. package/dist/test/unit/formatter-corpus-roundtrip.test.js +9 -0
  239. package/dist/test/unit/formatter-corpus-roundtrip.test.js.map +1 -1
  240. package/dist/test/unit/frontend/resolve-declarations.test.d.ts +2 -0
  241. package/dist/test/unit/frontend/resolve-declarations.test.d.ts.map +1 -0
  242. package/dist/test/unit/frontend/resolve-declarations.test.js +400 -0
  243. package/dist/test/unit/frontend/resolve-declarations.test.js.map +1 -0
  244. package/dist/test/unit/identifiers/casefold.test.d.ts +2 -0
  245. package/dist/test/unit/identifiers/casefold.test.d.ts.map +1 -0
  246. package/dist/test/unit/identifiers/casefold.test.js +77 -0
  247. package/dist/test/unit/identifiers/casefold.test.js.map +1 -0
  248. package/dist/test/unit/identifiers/scopes.test.d.ts +2 -0
  249. package/dist/test/unit/identifiers/scopes.test.d.ts.map +1 -0
  250. package/dist/test/unit/identifiers/scopes.test.js +109 -0
  251. package/dist/test/unit/identifiers/scopes.test.js.map +1 -0
  252. package/dist/test/unit/lambda-capture-parity.test.js +12 -5
  253. package/dist/test/unit/lambda-capture-parity.test.js.map +1 -1
  254. package/dist/test/unit/lsp/lsp-locale-fixes.test.js +10 -11
  255. package/dist/test/unit/lsp/lsp-locale-fixes.test.js.map +1 -1
  256. package/dist/test/unit/lsp/resolution-completion.test.d.ts +2 -0
  257. package/dist/test/unit/lsp/resolution-completion.test.d.ts.map +1 -0
  258. package/dist/test/unit/lsp/resolution-completion.test.js +79 -0
  259. package/dist/test/unit/lsp/resolution-completion.test.js.map +1 -0
  260. package/dist/test/unit/lsp/resolution-diagnostics.test.d.ts +2 -0
  261. package/dist/test/unit/lsp/resolution-diagnostics.test.d.ts.map +1 -0
  262. package/dist/test/unit/lsp/resolution-diagnostics.test.js +88 -0
  263. package/dist/test/unit/lsp/resolution-diagnostics.test.js.map +1 -0
  264. package/dist/test/unit/lsp/resolution-fixture.d.ts +32 -0
  265. package/dist/test/unit/lsp/resolution-fixture.d.ts.map +1 -0
  266. package/dist/test/unit/lsp/resolution-fixture.js +69 -0
  267. package/dist/test/unit/lsp/resolution-fixture.js.map +1 -0
  268. package/dist/test/unit/lsp/resolution-hover.test.d.ts +2 -0
  269. package/dist/test/unit/lsp/resolution-hover.test.d.ts.map +1 -0
  270. package/dist/test/unit/lsp/resolution-hover.test.js +107 -0
  271. package/dist/test/unit/lsp/resolution-hover.test.js.map +1 -0
  272. package/dist/test/unit/lsp/tenant-vocabulary.test.js +21 -47
  273. package/dist/test/unit/lsp/tenant-vocabulary.test.js.map +1 -1
  274. package/dist/test/unit/parser/parser.test.js +22 -0
  275. package/dist/test/unit/parser/parser.test.js.map +1 -1
  276. package/dist/test/unit/public-api-checked-entries.test.d.ts +2 -0
  277. package/dist/test/unit/public-api-checked-entries.test.d.ts.map +1 -0
  278. package/dist/test/unit/public-api-checked-entries.test.js +28 -0
  279. package/dist/test/unit/public-api-checked-entries.test.js.map +1 -0
  280. package/dist/test/unit/typecheck/qualified-enum-member.test.d.ts +2 -0
  281. package/dist/test/unit/typecheck/qualified-enum-member.test.d.ts.map +1 -0
  282. package/dist/test/unit/typecheck/qualified-enum-member.test.js +73 -0
  283. package/dist/test/unit/typecheck/qualified-enum-member.test.js.map +1 -0
  284. package/dist/test/unit/version.test.d.ts +9 -0
  285. package/dist/test/unit/version.test.d.ts.map +1 -0
  286. package/dist/test/unit/version.test.js +34 -0
  287. package/dist/test/unit/version.test.js.map +1 -0
  288. package/package.json +1 -1
  289. package/dist/src/config/lexicons/identifiers/examples/canonicalizer-integration.d.ts +0 -47
  290. package/dist/src/config/lexicons/identifiers/examples/canonicalizer-integration.d.ts.map +0 -1
  291. package/dist/src/config/lexicons/identifiers/examples/canonicalizer-integration.js +0 -142
  292. package/dist/src/config/lexicons/identifiers/examples/canonicalizer-integration.js.map +0 -1
@@ -0,0 +1,703 @@
1
+ /**
2
+ * @module core/resolve-typed-references
3
+ *
4
+ * 名称解析阶段 R2(ADR 0051 §4、§6.2):在 Core 上解析依赖类型的位置——
5
+ * (a) 点分路径 `x.f.g` 的字段段与 `Set` 目标(FIELD_REF);
6
+ * (b) 期望类型为枚举时的裸单段名(含期望枚举下用作成员的模式名);
7
+ * (c) 主语类型在 R1 未知的 PatternCtor。
8
+ * 另对 R1 未命中的无期望类型裸名报 E802。
9
+ *
10
+ * 只处理 lower 登记了 ResolutionMark 的位置。类型只来自 §4 的显式声明规则(参数 / lambda 参数、
11
+ * 构造 `X with …`、对源码函数的直接调用、已知类型的点分路径),其余一律未知;不调用类型检查器。
12
+ * 输入 Core 不被修改(标记只读),返回新的 Core 与诊断;同一输入重复运行结果相同。
13
+ */
14
+ import { foldKey, nfc } from '../config/lexicons/identifiers/casefold.js';
15
+ import { BUILTIN_AWAIT, BUILTIN_OPS } from '../config/semantic.js';
16
+ import { KEYWORD_CTORS, choose, chooseDecl, chooseVocab, formatCandidates } from '../frontend/resolution-choice.js';
17
+ import { DiagnosticBuilder } from '../typecheck/diagnostics.js';
18
+ import { BUILTIN_TYPE_NAMES } from '../typecheck/generics.js';
19
+ import { originToSpan } from '../typecheck/pure.js';
20
+ import { VERDICT_FIELDS, VERDICT_TYPE_NAME } from '../typecheck/verdict_signatures.js';
21
+ import { isFieldTypeInferred, isLambdaParamTypeInferred } from './inferred_fields.js';
22
+ import { resolutionMarkOf, withResolvedOrigin } from './resolution-mark.js';
23
+ /** 内置运算符、await 与关键词构造器的调用形式:不是待解析的名字。 */
24
+ function isBuiltinValue(name) {
25
+ return BUILTIN_OPS.has(name) || name === BUILTIN_AWAIT || KEYWORD_CTORS.has(name);
26
+ }
27
+ /**
28
+ * 动态值:未声明类型的字段(ADR 0040,如 Guard 的 context 映射)。其后的点分段是动态键,
29
+ * 原样保留、不解析。与“未知”(undefined,按全局候选回退)区分。
30
+ */
31
+ const DYNAMIC = 'dynamic';
32
+ function asType(t) {
33
+ return t === DYNAMIC ? undefined : t;
34
+ }
35
+ function declEntry(d, role) {
36
+ return { written: nfc(d.origin?.written ?? d.name), canonical: d.name, role };
37
+ }
38
+ function buildTables(m, ctx) {
39
+ const t = { datas: new Map(), enums: new Map(), funcs: new Map(), valueDecls: [], ctorDecls: [] };
40
+ for (const d of m.decls)
41
+ registerDecl(t, d);
42
+ const own = (name, role) => ({ written: name, canonical: name, role });
43
+ t.valueDecls.push(...ctx.imports.functions.map((f) => own(f, 'FUNC_REF')), ...ctx.imports.types.map((x) => own(x, 'TYPE')));
44
+ t.ctorDecls.push(...ctx.imports.types.filter((x) => !ctx.imports.enumMembers.has(x)).map((x) => own(x, 'TYPE')));
45
+ for (const [e, ms] of ctx.imports.enumMembers)
46
+ t.enums.set(e, ms);
47
+ for (const [s, fs] of ctx.imports.fields)
48
+ t.datas.set(s, new Map(fs.map((f) => [f, undefined])));
49
+ t.datas.set(VERDICT_TYPE_NAME, new Map([...VERDICT_FIELDS].map((f) => [f, undefined])));
50
+ return t;
51
+ }
52
+ function registerDecl(t, d) {
53
+ switch (d.kind) {
54
+ case 'Data':
55
+ t.datas.set(d.name, new Map(d.fields.map((f) => [f.name, f])));
56
+ t.valueDecls.push(declEntry(d, 'TYPE'));
57
+ t.ctorDecls.push(declEntry(d, 'TYPE'));
58
+ return;
59
+ case 'Enum':
60
+ t.enums.set(d.name, d.variants);
61
+ t.valueDecls.push(declEntry(d, 'TYPE'));
62
+ return;
63
+ case 'Func':
64
+ t.funcs.set(d.name, d);
65
+ t.valueDecls.push(declEntry(d, 'FUNC_REF'));
66
+ return;
67
+ case 'Import':
68
+ return;
69
+ default: {
70
+ const never = d;
71
+ throw new Error(`未处理的声明:${JSON.stringify(never)}`);
72
+ }
73
+ }
74
+ }
75
+ // ---- 词汇视图 ----
76
+ function vocabTypes(r) {
77
+ return r.scopes ? [{ map: r.scopes.types, role: 'TYPE' }] : [];
78
+ }
79
+ function vocabTypesAndFunctions(r) {
80
+ if (!r.scopes)
81
+ return [];
82
+ return [
83
+ { map: r.scopes.functions, role: 'FUNC_REF' },
84
+ { map: r.scopes.types, role: 'TYPE' },
85
+ ];
86
+ }
87
+ function scoped(r, pick, parent, role) {
88
+ if (!r.scopes)
89
+ return [];
90
+ const all = [...pick(r.scopes)].filter(([p]) => parent === undefined || p === parent);
91
+ return all.map(([, map]) => ({ map, role }));
92
+ }
93
+ /** 源码声明优先;未命中再查词汇(含规范名直写)。 */
94
+ function declThenVocab(decls, maps, written) {
95
+ const fromDecl = chooseDecl(decls, written);
96
+ return fromDecl.kind === 'miss' ? chooseVocab(maps, written) : fromDecl;
97
+ }
98
+ function entriesOf(names, role) {
99
+ return names.map((n) => ({ written: n, canonical: n, role }));
100
+ }
101
+ /** 枚举 e 的成员;e 缺省时为全部枚举的成员(主语类型未知的模式)。 */
102
+ function chooseMember(r, e, written) {
103
+ const enums = [...r.t.enums].filter(([name]) => e === undefined || name === e);
104
+ const decls = enums.flatMap(([, ms]) => entriesOf(ms, 'MEMBER_REF'));
105
+ return declThenVocab(decls, scoped(r, (s) => s.enumMembers, e, 'MEMBER_REF'), written);
106
+ }
107
+ /** Data S 的字段;S 缺省时为全部 Data 的字段(接收者类型未知)。 */
108
+ function chooseField(r, s, written) {
109
+ const datas = [...r.t.datas].filter(([name]) => s === undefined || name === s);
110
+ const decls = datas.flatMap(([, fs]) => entriesOf([...fs.keys()], 'FIELD_REF'));
111
+ return declThenVocab(decls, scoped(r, (x) => x.fields, s, 'FIELD_REF'), written);
112
+ }
113
+ function isEnum(r, name) {
114
+ return r.t.enums.has(name) || (r.scopes?.enumMembers.has(name) ?? false);
115
+ }
116
+ /** 已知类型名(TypeName);类型变量、容器与推断类型均视为未知。 */
117
+ function typeNameOf(t) {
118
+ return typeof t === 'object' && t.kind === 'TypeName' ? t.name : undefined;
119
+ }
120
+ function enumOf(r, t) {
121
+ const name = typeNameOf(t);
122
+ return name !== undefined && isEnum(r, name) ? name : undefined;
123
+ }
124
+ function dataOf(r, t) {
125
+ const name = typeNameOf(t);
126
+ return name !== undefined && r.t.datas.has(name) ? name : undefined;
127
+ }
128
+ /** 字段的静态类型:声明类型;未声明类型的字段为动态值;导入 Data 的字段未知。 */
129
+ function fieldType(r, s, field) {
130
+ const f = r.t.datas.get(s)?.get(field);
131
+ if (!f)
132
+ return undefined;
133
+ return isFieldTypeInferred(f) ? DYNAMIC : f.type;
134
+ }
135
+ /** 内置容器类型名:其元素类型才决定字段,自身不是可透传的不透明类型。 */
136
+ const CONTAINER_TYPE_NAMES = new Set(['Result', 'Option', 'List', 'Set', 'Workflow']);
137
+ /** 无字段结构、点分段只能是动态键的类型名:内置标量与 Map / Json / Any。 */
138
+ const OPAQUE_TYPE_NAMES = new Set([
139
+ ...[...BUILTIN_TYPE_NAMES].filter((n) => !CONTAINER_TYPE_NAMES.has(n)),
140
+ 'Map',
141
+ 'Json',
142
+ 'Any',
143
+ ]);
144
+ /**
145
+ * 不透明类型(白名单):动态值、类型变量、Map 及上述类型名。其后的点分段原样保留、不解析。
146
+ * 类型别名、Option / Maybe / List / TypeApp 等包装与未声明的类型名均不在其中,按未知处理。
147
+ */
148
+ function isOpaque(r, t) {
149
+ if (t === DYNAMIC)
150
+ return true;
151
+ if (t === undefined || dataOf(r, t) !== undefined)
152
+ return false;
153
+ if (t.kind === 'TypeVar' || t.kind === 'Map')
154
+ return true;
155
+ return t.kind === 'TypeName' && OPAQUE_TYPE_NAMES.has(t.name);
156
+ }
157
+ function child(f) {
158
+ return { ...f, scope: { parent: f.scope, locals: [] } };
159
+ }
160
+ function declare(f, name, type) {
161
+ f.scope.locals.push(type === undefined ? { name } : { name, type });
162
+ }
163
+ function visibleLocals(scope) {
164
+ const out = [];
165
+ for (let s = scope; s; s = s.parent)
166
+ out.push(...[...s.locals].reverse());
167
+ return out;
168
+ }
169
+ /** LOCAL(§6.2 第 1 步):精确命中最近声明,否则折叠唯一。 */
170
+ function findLocal(scope, written) {
171
+ const locals = visibleLocals(scope);
172
+ const w = nfc(written);
173
+ const exact = locals.find((l) => l.name === w);
174
+ const asEntry = (l) => ({ written: l.name, canonical: l.name, role: 'LOCAL' });
175
+ if (exact)
176
+ return { choice: { kind: 'hit', entry: asEntry(exact) }, local: exact };
177
+ const folded = locals.filter((l) => foldKey(l.name) === foldKey(w));
178
+ const choice = choose([], folded.map(asEntry));
179
+ return choice.kind === 'hit' ? { choice, local: folded.find((l) => l.name === choice.entry.canonical) } : { choice };
180
+ }
181
+ // ---- 静态类型(§4 类型来源表) ----
182
+ /** 规范名路径的类型:首段局部名的声明类型,逐段取字段声明类型;不产生诊断。 */
183
+ function pathType(r, scope, name) {
184
+ const [head, ...tail] = name.split('.');
185
+ let type = visibleLocals(scope).find((l) => l.name === head)?.type;
186
+ for (const seg of tail) {
187
+ if (isOpaque(r, type))
188
+ return DYNAMIC;
189
+ const s = dataOf(r, type);
190
+ type = s === undefined ? undefined : fieldType(r, s, seg);
191
+ }
192
+ return type;
193
+ }
194
+ /** 被调源码函数;同名局部名(如 lambda 绑定)遮蔽模块函数。 */
195
+ function calleeOf(r, scope, target) {
196
+ if (target.kind !== 'Name' || visibleLocals(scope).some((l) => l.name === target.name))
197
+ return undefined;
198
+ return r.t.funcs.get(target.name);
199
+ }
200
+ function declaredRet(f) {
201
+ return f && !f.retTypeInferred ? f.ret : undefined;
202
+ }
203
+ /** 已解析表达式的 R2 静态类型;表外的一切为未知。 */
204
+ function typeOf(r, scope, e) {
205
+ switch (e.kind) {
206
+ case 'Name':
207
+ return pathType(r, scope, e.name);
208
+ case 'Construct':
209
+ return { kind: 'TypeName', name: e.typeName };
210
+ case 'Call':
211
+ return declaredRet(calleeOf(r, scope, e.target));
212
+ default:
213
+ return undefined;
214
+ }
215
+ }
216
+ // ---- 诊断与改写 ----
217
+ function spanOf(node) {
218
+ return originToSpan(node.origin);
219
+ }
220
+ function report(r, code, at, written, role, cands = []) {
221
+ r.diags.error(code, at, { written, role, candidates: formatCandidates(cands) });
222
+ }
223
+ function warn(r, code, at, written, role, cands) {
224
+ r.diags.warning(code, at, { written, role, candidates: formatCandidates(cands) });
225
+ }
226
+ /** 写入规范名,并在 origin 上记录原写法与角色(written !== canonical 时)。 */
227
+ function renamed(node, patch, written, canonical, role) {
228
+ const origin = withResolvedOrigin(node.origin, written, canonical, role);
229
+ return origin ? { ...node, ...patch, origin } : { ...node, ...patch };
230
+ }
231
+ /** 只读标记:输入 Core 不被修改,同一 Core 上重复运行 R2 结果相同。 */
232
+ function consume(node) {
233
+ return resolutionMarkOf(node);
234
+ }
235
+ /** 仅在有观察者时才构造位置(含父名计算):编译路径零开销。 */
236
+ function observeSite(r, make) {
237
+ const onSite = r.observer?.onScopedSite;
238
+ if (onSite)
239
+ onSite(make());
240
+ }
241
+ function withParent(parent) {
242
+ return parent === undefined ? {} : { parent };
243
+ }
244
+ /** 写法本身即某个已声明字段的规范名(§6.2 第 5 步):接收者类型未知时直接接受,不告警。 */
245
+ function isCanonicalField(r, seg) {
246
+ const w = nfc(seg);
247
+ return [...r.t.datas.values()].some((fs) => fs.has(w));
248
+ }
249
+ /**
250
+ * 一个字段段:类型已知查 fields[S];未知时规范名直写直接接受,否则按全局唯一候选采用
251
+ * (写法与规范名不同时报 W801)。
252
+ */
253
+ function resolveSegment(r, type, seg, at) {
254
+ const s = dataOf(r, type);
255
+ if (s === undefined && isCanonicalField(r, seg))
256
+ return { name: nfc(seg), type: undefined };
257
+ const picked = chooseField(r, s, seg);
258
+ if (picked.kind === 'hit') {
259
+ if (s === undefined && picked.entry.canonical !== nfc(seg)) {
260
+ warn(r, "W801" /* ErrorCode.RESOLVED_WITHOUT_TYPE */, at, seg, 'FIELD_REF', [picked.entry]);
261
+ }
262
+ const canonical = picked.entry.canonical;
263
+ return { name: canonical, type: s === undefined ? undefined : fieldType(r, s, canonical) };
264
+ }
265
+ if (picked.kind === 'ambiguous')
266
+ report(r, "E805" /* ErrorCode.AMBIGUOUS_FIELD */, at, seg, 'FIELD_REF', picked.candidates);
267
+ else
268
+ report(r, "E801" /* ErrorCode.UNRESOLVED_FIELD */, at, seg, 'FIELD_REF');
269
+ return { name: nfc(seg), type: undefined };
270
+ }
271
+ /** 首段为局部名时解析整条路径;首段不是局部名(模块 / 类型限定名)返回 undefined。 */
272
+ function resolvePath(r, scope, written, at) {
273
+ const [head, ...tail] = written.split('.');
274
+ const local = findLocal(scope, head);
275
+ if (local.choice.kind === 'miss')
276
+ return undefined;
277
+ if (!local.local) {
278
+ report(r, "E804" /* ErrorCode.AMBIGUOUS_NAME */, at, head, 'LOCAL', local.choice.kind === 'ambiguous' ? local.choice.candidates : []);
279
+ return undefined;
280
+ }
281
+ const parts = [local.local.name];
282
+ let type = local.local.type;
283
+ for (const [i, seg] of tail.entries()) {
284
+ // 类型参数没有字段:其上的字段段一定无法解析(类型检查同样拒绝),不让原写法进入 IR
285
+ if (type !== DYNAMIC && type?.kind === 'TypeVar')
286
+ report(r, "E801" /* ErrorCode.UNRESOLVED_FIELD */, at, seg, 'FIELD_REF');
287
+ if (isOpaque(r, type))
288
+ return { name: [...parts, ...tail.slice(i)].join('.'), type: DYNAMIC };
289
+ const next = resolveSegment(r, type, seg, at);
290
+ const owner = type;
291
+ observeSite(r, () => ({
292
+ span: at, segment: { path: written, index: i + 1 }, written: seg, canonical: next.name, role: 'FIELD_REF', ...withParent(dataOf(r, owner)),
293
+ }));
294
+ parts.push(next.name);
295
+ type = next.type;
296
+ }
297
+ return { name: parts.join('.'), type };
298
+ }
299
+ // ---- 值位置名字 ----
300
+ /** §6.2 第 1、2、4、5 步(无期望类型)。 */
301
+ function chooseValue(r, scope, written) {
302
+ const local = findLocal(scope, written).choice;
303
+ if (local.kind !== 'miss')
304
+ return local;
305
+ return declThenVocab(r.t.valueDecls, vocabTypesAndFunctions(r), written);
306
+ }
307
+ /**
308
+ * 与期望枚举成员同写法的冲突层候选:模块函数 / 类型、词汇函数 / 类型,以及 R1 命中而 Core 中
309
+ * 不可见的声明(如类型别名)。其它枚举的成员不冲突——期望类型已经消歧。仅大小写不同的
310
+ * 函数同样冲突(ADR 0051 §14 第 1 条:`hoch` 与 `Hoch` 须写限定名)。
311
+ */
312
+ function otherLayers(r, written, current, mark) {
313
+ const found = [chooseDecl(r.t.valueDecls, written), chooseVocab(vocabTypesAndFunctions(r), written)].flatMap(choiceEntries);
314
+ const viaR1 = mark.r1Role === 'FUNC_REF' || mark.r1Role === 'TYPE';
315
+ return found.length === 0 && viaR1 ? [{ written, canonical: current, role: mark.r1Role }] : found;
316
+ }
317
+ function choiceEntries(c) {
318
+ if (c.kind === 'hit')
319
+ return [c.entry];
320
+ return c.kind === 'ambiguous' ? c.candidates : [];
321
+ }
322
+ /** R1 对同一写法的值位置规则已歧义(并已在同一位置报 E804):R2 不重复报告。 */
323
+ function reportedByR1(r, f, mark) {
324
+ return mark.r1Role === undefined && chooseValue(r, f.scope, mark.written).kind === 'ambiguous';
325
+ }
326
+ /**
327
+ * 期望枚举 E 下的裸名(§6.2 跨层裁决表)。成员未命中返回 undefined,交给无期望类型规则。
328
+ */
329
+ function resolveUnderEnum(r, f, n, mark, e) {
330
+ const member = chooseMember(r, e, mark.written);
331
+ const local = findLocal(f.scope, mark.written).choice;
332
+ const at = spanOf(n);
333
+ if (local.kind !== 'miss') {
334
+ // LOCAL 层先于成员:命中即取局部名,成员同时命中时提示遮蔽
335
+ if (local.kind === 'hit' && member.kind === 'hit')
336
+ warn(r, "W800" /* ErrorCode.SHADOWED_VOCABULARY */, at, mark.written, 'LOCAL', [member.entry]);
337
+ return member.kind === 'miss' ? undefined : n;
338
+ }
339
+ if (member.kind === 'miss')
340
+ return undefined;
341
+ if (member.kind === 'ambiguous') {
342
+ report(r, "E804" /* ErrorCode.AMBIGUOUS_NAME */, at, mark.written, 'MEMBER_REF', member.candidates);
343
+ return n;
344
+ }
345
+ const others = otherLayers(r, mark.written, n.name, mark);
346
+ if (others.length > 0) {
347
+ if (!reportedByR1(r, f, mark))
348
+ report(r, "E804" /* ErrorCode.AMBIGUOUS_NAME */, at, mark.written, 'MEMBER_REF', [member.entry, ...others]);
349
+ return n;
350
+ }
351
+ // 保持写法形态:裸名得裸成员规范名,使本地化源码与规范名拼写的同一程序产出相同 IR
352
+ const canonical = member.entry.canonical;
353
+ observeSite(r, () => ({ span: at, written: mark.written, canonical, role: 'MEMBER_REF', parent: e }));
354
+ return renamed(n, { name: canonical }, mark.written, canonical, 'MEMBER_REF');
355
+ }
356
+ /**
357
+ * 无期望类型:沿用 R1 结果;R1 未命中时按值位置规则(歧义已由 R1 报告)。仍未命中时,
358
+ * 写法恰为某一个源码 / 导入枚举成员的规范名则原样接受(多个枚举 → E804),否则 E802。
359
+ */
360
+ function resolveValue(r, f, n, mark, callee) {
361
+ if (mark.r1Role !== undefined || isBuiltinValue(n.name))
362
+ return n;
363
+ const picked = chooseValue(r, f.scope, mark.written);
364
+ if (picked.kind === 'hit')
365
+ return renamed(n, { name: picked.entry.canonical }, mark.written, picked.entry.canonical, picked.entry.role);
366
+ // UFCS 拆出的部分可能来自限定调用(`io.get(…)`),首段为命名空间时不报 E802
367
+ if (picked.kind === 'ambiguous' || mark.ufcs)
368
+ return n;
369
+ const owners = [...r.t.enums].filter(([, ms]) => ms.includes(nfc(mark.written)));
370
+ if (owners.length > 1) {
371
+ const cands = owners.map(([e]) => ({ written: mark.written, canonical: `${e}.${nfc(mark.written)}`, role: 'MEMBER_REF' }));
372
+ report(r, "E804" /* ErrorCode.AMBIGUOUS_NAME */, spanOf(n), mark.written, 'MEMBER_REF', cands);
373
+ }
374
+ // 调用目标全无候选时保留原写法,由类型检查的未定义函数诊断负责
375
+ if (owners.length === 0 && !callee)
376
+ report(r, "E802" /* ErrorCode.UNRESOLVED_NAME */, spanOf(n), mark.written, 'VALUE_REF');
377
+ return n;
378
+ }
379
+ function resolveName(r, f, n, expected, callee = false) {
380
+ const mark = consume(n);
381
+ if (!mark)
382
+ return n;
383
+ if (mark.written.includes('.')) {
384
+ const path = resolvePath(r, f.scope, mark.written, spanOf(n));
385
+ return path ? renamed(n, { name: path.name }, mark.written, path.name, 'FIELD_REF') : n;
386
+ }
387
+ const e = enumOf(r, expected);
388
+ const out = (e === undefined ? undefined : resolveUnderEnum(r, f, n, mark, e)) ?? resolveValue(r, f, n, mark, callee);
389
+ recordCapture(f, n.name, out.name);
390
+ return out;
391
+ }
392
+ /** 记录 lambda 体内裸名的改写,供改写捕获列表。 */
393
+ function recordCapture(f, before, after) {
394
+ for (const map of f.captures) {
395
+ const set = map.get(before) ?? new Set();
396
+ set.add(after);
397
+ map.set(before, set);
398
+ }
399
+ }
400
+ // ---- 表达式 ----
401
+ function resolveExpr(r, f, e, expected) {
402
+ const sub = (x) => resolveExpr(r, f, x);
403
+ switch (e.kind) {
404
+ case 'Name':
405
+ return observeTyped(r, f, resolveName(r, f, e, expected));
406
+ case 'Call':
407
+ return resolveCall(r, f, e);
408
+ case 'Construct':
409
+ return resolveConstruct(r, f, e);
410
+ case 'Ok':
411
+ case 'Err':
412
+ case 'Some':
413
+ case 'Await':
414
+ return { ...e, expr: sub(e.expr) };
415
+ case 'IfExpr':
416
+ return { ...e, cond: sub(e.cond), thenE: sub(e.thenE), elseE: sub(e.elseE) };
417
+ case 'ListLit':
418
+ return { ...e, elements: e.elements.map(sub) };
419
+ case 'Lambda':
420
+ return resolveLambda(r, f, e);
421
+ case 'Bool':
422
+ case 'Int':
423
+ case 'Long':
424
+ case 'Double':
425
+ case 'Decimal':
426
+ case 'String':
427
+ case 'Null':
428
+ case 'None':
429
+ return e;
430
+ default: {
431
+ const never = e;
432
+ throw new Error(`未处理的表达式节点:${JSON.stringify(never)}`);
433
+ }
434
+ }
435
+ }
436
+ /** 向观察者报告已解析名字的 §4 静态类型(不透明 / 动态视为未知)。 */
437
+ function observeTyped(r, f, n) {
438
+ const onTyped = r.observer?.onTypedName;
439
+ if (onTyped)
440
+ onTyped(n, asType(typeOf(r, f.scope, n)));
441
+ return n;
442
+ }
443
+ /**
444
+ * 未被 UFCS 拆分的点分调用目标(`Text.concat(…)`、`Action.equals(…)`)是限定调用,
445
+ * 首段为命名空间(§5 MODULE,不本地化),不按字段路径解析,原样保留。
446
+ */
447
+ function isQualifiedCall(target) {
448
+ return target.kind === 'Name' && target.name.includes('.');
449
+ }
450
+ /** 相等 / 不等比较(`equals to`、`not equal to`、`==`、`!=` 及其本地化关键词均降为这两个运算符)。 */
451
+ const EQUALITY_OPS = new Set(['==', '!=']);
452
+ function isEquality(target, args) {
453
+ return target.kind === 'Name' && EQUALITY_OPS.has(target.name) && args.length === 2;
454
+ }
455
+ /** 期望类型待定的比较操作数:带标记的单段裸名且不是局部名(局部名按 LOCAL 解析,与期望类型无关)。 */
456
+ function isBareOperand(f, e) {
457
+ const mark = e.kind === 'Name' ? resolutionMarkOf(e) : undefined;
458
+ return mark !== undefined && !mark.written.includes('.') && findLocal(f.scope, mark.written).choice.kind === 'miss';
459
+ }
460
+ /**
461
+ * 相等比较的期望类型来源(裁决 R49):先解析非裸名一侧,其 §4 静态类型为枚举 E 时,
462
+ * 另一侧裸名以 E 为期望类型(与 Return / 实参同一套 §6.2 跨层裁决)。两侧都是裸名时均无期望类型。
463
+ */
464
+ function resolveEquality(r, f, args) {
465
+ const bare = args.map((a) => isBareOperand(f, a));
466
+ const out = args.map((a, i) => (bare[i] ? a : resolveExpr(r, f, a)));
467
+ return out.map((a, i) => {
468
+ if (!bare[i])
469
+ return a;
470
+ const other = bare[1 - i] ? undefined : asType(typeOf(r, f.scope, out[1 - i]));
471
+ return resolveExpr(r, f, a, other);
472
+ });
473
+ }
474
+ /** 调用实参的期望类型取被调源码函数对应参数的声明类型;相等比较另见 resolveEquality。 */
475
+ function resolveCall(r, f, e) {
476
+ const target = isQualifiedCall(e.target)
477
+ ? e.target
478
+ : e.target.kind === 'Name'
479
+ ? resolveName(r, f, e.target, undefined, true)
480
+ : resolveExpr(r, f, e.target);
481
+ if (isEquality(target, e.args))
482
+ return { ...e, target, args: resolveEquality(r, f, e.args) };
483
+ const params = calleeOf(r, f.scope, target)?.params ?? [];
484
+ const expectedAt = (i) => {
485
+ const p = params[i];
486
+ return p && !p.typeInferred ? p.type : undefined;
487
+ };
488
+ return { ...e, target, args: e.args.map((a, i) => resolveExpr(r, f, a, expectedAt(i))) };
489
+ }
490
+ /** ConstructField 的期望类型取所构造 Data 的字段声明类型(字段名已由 R1 解析)。 */
491
+ function resolveConstruct(r, f, e) {
492
+ const fields = e.fields.map((cf) => ({ ...cf, expr: resolveExpr(r, f, cf.expr, asType(fieldType(r, e.typeName, cf.name))) }));
493
+ return { ...e, fields };
494
+ }
495
+ function resolveLambda(r, f, e) {
496
+ const renames = new Map();
497
+ const inner = { scope: { parent: f.scope, locals: [] }, ret: e.ret, captures: [...f.captures, renames] };
498
+ // 只有声明类型是类型来源(§4、裁决 R31):未标注类型的参数视为未知
499
+ for (const p of e.params)
500
+ declare(inner, p.name, isLambdaParamTypeInferred(p) ? undefined : p.type);
501
+ const body = resolveBlock(r, inner, e.body);
502
+ return e.captures ? { ...e, body, captures: rewriteCaptures(e.captures, renames) } : { ...e, body };
503
+ }
504
+ /** 捕获名随解析结果改写;解析为限定名(如枚举成员 `E.M`)的不再是自由变量。 */
505
+ function rewriteCaptures(captures, renames) {
506
+ const out = captures.flatMap((c) => [...(renames.get(c) ?? [c])]).filter((c) => !c.includes('.'));
507
+ return [...new Set(out)];
508
+ }
509
+ // ---- 语句 ----
510
+ function resolveBlock(r, f, b) {
511
+ const inner = child(f);
512
+ return { ...b, statements: b.statements.map((s) => resolveStmt(r, inner, s)) };
513
+ }
514
+ function resolveStmt(r, f, s) {
515
+ switch (s.kind) {
516
+ case 'Let': {
517
+ const expr = resolveExpr(r, f, s.expr);
518
+ declare(f, s.name, typeOf(r, f.scope, expr));
519
+ return { ...s, expr };
520
+ }
521
+ case 'Set':
522
+ return resolveSet(r, f, s);
523
+ case 'Return':
524
+ return { ...s, expr: resolveExpr(r, f, s.expr, f.ret) };
525
+ case 'If':
526
+ return { ...s, cond: resolveExpr(r, f, s.cond), thenBlock: resolveBlock(r, f, s.thenBlock), elseBlock: s.elseBlock ? resolveBlock(r, f, s.elseBlock) : null };
527
+ case 'Match':
528
+ return resolveMatch(r, f, s);
529
+ case 'Scope': {
530
+ const inner = child(f);
531
+ return { ...s, statements: s.statements.map((x) => resolveStmt(r, inner, x)) };
532
+ }
533
+ case 'Start': {
534
+ const expr = resolveExpr(r, f, s.expr);
535
+ declare(f, s.name);
536
+ return { ...s, expr };
537
+ }
538
+ case 'Wait':
539
+ return s;
540
+ case 'workflow':
541
+ return resolveWorkflow(r, f, s);
542
+ default: {
543
+ const never = s;
544
+ throw new Error(`未处理的语句节点:${JSON.stringify(never)}`);
545
+ }
546
+ }
547
+ }
548
+ /** Set 目标:单段为局部名(不解析);点分按路径解析,最后一段的声明类型作为右侧期望类型。 */
549
+ function resolveSet(r, f, s) {
550
+ const mark = consume(s);
551
+ const path = mark?.written.includes('.') ? resolvePath(r, f.scope, mark.written, spanOf(s)) : undefined;
552
+ const expr = resolveExpr(r, f, s.expr, asType(path?.type));
553
+ return path ? renamed(s, { name: path.name, expr }, mark.written, path.name, 'FIELD_REF') : { ...s, expr };
554
+ }
555
+ function resolveWorkflow(r, f, s) {
556
+ const steps = s.steps.map((step) => ({
557
+ ...step,
558
+ body: resolveBlock(r, f, step.body),
559
+ ...(step.compensate ? { compensate: resolveBlock(r, f, step.compensate) } : {}),
560
+ }));
561
+ return { ...s, steps };
562
+ }
563
+ function resolveMatch(r, f, s) {
564
+ const expr = resolveExpr(r, f, s.expr);
565
+ const subject = typeOf(r, f.scope, expr);
566
+ const cases = s.cases.map((c) => resolveCase(r, child(f), c, subject));
567
+ return { ...s, expr, cases };
568
+ }
569
+ function resolveCase(r, f, c, subject) {
570
+ const pattern = resolvePattern(r, f, c.pattern, subject);
571
+ const body = c.body.kind === 'Block' ? resolveBlock(r, f, c.body) : { ...c.body, expr: resolveExpr(r, f, c.body.expr, f.ret) };
572
+ return { ...c, pattern, body };
573
+ }
574
+ // ---- 模式 ----
575
+ function resolvePattern(r, f, p, subject) {
576
+ switch (p.kind) {
577
+ case 'PatName':
578
+ case 'PatternName':
579
+ return resolvePatName(r, f, p, subject);
580
+ case 'PatCtor':
581
+ case 'PatternCtor':
582
+ return resolvePatCtor(r, f, p, subject);
583
+ case 'PatNull':
584
+ case 'PatternNull':
585
+ case 'PatInt':
586
+ case 'PatternInt':
587
+ return p;
588
+ default: {
589
+ const never = p;
590
+ throw new Error(`未处理的模式节点:${JSON.stringify(never)}`);
591
+ }
592
+ }
593
+ }
594
+ /**
595
+ * 模式名:主语为枚举 E 时,命中 enumMembers[E] 即为成员(与其它层同时命中 → E804);
596
+ * 主语类型未知时,仅当写法精确等于某枚举成员才视为成员(唯一 → W801,多个 → E806);
597
+ * 其余为绑定名。模式名是声明而非引用,故不经过 LOCAL 层。
598
+ */
599
+ function resolvePatName(r, f, p, subject) {
600
+ const mark = consume(p);
601
+ const asMember = mark ? patNameMember(r, p, mark, subject) : undefined;
602
+ if (asMember)
603
+ return asMember;
604
+ declare(f, p.name);
605
+ return p;
606
+ }
607
+ function patNameMember(r, p, mark, subject) {
608
+ const e = enumOf(r, subject);
609
+ if (e !== undefined)
610
+ return patNameUnderEnum(r, p, mark, e);
611
+ if (typeNameOf(subject) !== undefined)
612
+ return undefined;
613
+ const member = choose(allMembers(r).filter((x) => x.written === nfc(mark.written) || x.canonical === nfc(mark.written)), []);
614
+ if (member.kind === 'miss')
615
+ return undefined;
616
+ if (member.kind === 'ambiguous') {
617
+ report(r, "E806" /* ErrorCode.AMBIGUOUS_PATTERN */, spanOf(p), mark.written, 'MEMBER_REF', member.candidates);
618
+ return p;
619
+ }
620
+ if (member.entry.canonical !== nfc(mark.written)) {
621
+ warn(r, "W801" /* ErrorCode.RESOLVED_WITHOUT_TYPE */, spanOf(p), mark.written, 'MEMBER_REF', [member.entry]);
622
+ }
623
+ return renamed(p, { name: member.entry.canonical }, mark.written, member.entry.canonical, 'MEMBER_REF');
624
+ }
625
+ function patNameUnderEnum(r, p, mark, e) {
626
+ const member = chooseMember(r, e, mark.written);
627
+ if (member.kind === 'miss')
628
+ return undefined;
629
+ const conflicts = member.kind === 'hit' ? otherLayers(r, mark.written, p.name, mark) : [];
630
+ if (member.kind === 'ambiguous' || conflicts.length > 0) {
631
+ report(r, "E804" /* ErrorCode.AMBIGUOUS_NAME */, spanOf(p), mark.written, 'MEMBER_REF', [...choiceEntries(member), ...conflicts]);
632
+ return p;
633
+ }
634
+ const canonical = member.entry.canonical;
635
+ observeSite(r, () => ({ span: spanOf(p), written: mark.written, canonical, role: 'MEMBER_REF', parent: e }));
636
+ return renamed(p, { name: canonical }, mark.written, canonical, 'MEMBER_REF');
637
+ }
638
+ /** 全部枚举成员候选:源码与导入(规范名)及词汇(原写法)。 */
639
+ function allMembers(r) {
640
+ const decls = [...r.t.enums].flatMap(([, ms]) => entriesOf(ms, 'MEMBER_REF'));
641
+ const vocab = scoped(r, (s) => s.enumMembers, undefined, 'MEMBER_REF').flatMap((m) => [...m.map.values()].flat().map((c) => ({ written: c.written, canonical: c.canonical, role: m.role })));
642
+ return [...decls, ...vocab];
643
+ }
644
+ function resolvePatCtor(r, f, p, subject) {
645
+ const mark = consume(p);
646
+ const args = p.args?.map((a) => resolvePattern(r, f, a, undefined));
647
+ for (const n of p.names)
648
+ declare(f, n);
649
+ const base = args ? { ...p, args } : { ...p };
650
+ return mark ? ctorResolution(r, base, mark, subject) : base;
651
+ }
652
+ /** 主语为枚举 → 成员(同 R1);为其它已知类型 → Data 构造器(同 R1);未知 → 全部成员与构造器中唯一(W801)。 */
653
+ function ctorRule(r, written, subject) {
654
+ const e = enumOf(r, subject);
655
+ if (e !== undefined) {
656
+ const choice = chooseMember(r, e, written);
657
+ return { choice, role: 'MEMBER_REF', typed: true, ambiguous: "E804" /* ErrorCode.AMBIGUOUS_NAME */, unresolved: "E803" /* ErrorCode.UNRESOLVED_PATTERN */ };
658
+ }
659
+ if (typeNameOf(subject) !== undefined) {
660
+ const choice = declThenVocab(r.t.ctorDecls, vocabTypes(r), written);
661
+ return { choice, role: 'TYPE', typed: true, ambiguous: "E804" /* ErrorCode.AMBIGUOUS_NAME */, unresolved: "E800" /* ErrorCode.UNRESOLVED_TYPE */ };
662
+ }
663
+ const members = [...r.t.enums].flatMap(([, ms]) => entriesOf(ms, 'MEMBER_REF'));
664
+ const maps = [...scoped(r, (s) => s.enumMembers, undefined, 'MEMBER_REF'), ...vocabTypes(r)];
665
+ const choice = declThenVocab([...members, ...r.t.ctorDecls], maps, written);
666
+ return { choice, role: 'TYPE', typed: false, ambiguous: "E806" /* ErrorCode.AMBIGUOUS_PATTERN */, unresolved: "E803" /* ErrorCode.UNRESOLVED_PATTERN */ };
667
+ }
668
+ function ctorResolution(r, p, mark, subject) {
669
+ const rule = ctorRule(r, mark.written, subject);
670
+ const at = spanOf(p);
671
+ if (rule.choice.kind === 'hit') {
672
+ const { canonical, role } = rule.choice.entry;
673
+ if (!rule.typed && canonical !== nfc(mark.written))
674
+ warn(r, "W801" /* ErrorCode.RESOLVED_WITHOUT_TYPE */, at, mark.written, role, [rule.choice.entry]);
675
+ observeSite(r, () => ({ span: at, written: mark.written, canonical, role, ...withParent(role === 'MEMBER_REF' ? enumOf(r, subject) : undefined) }));
676
+ return renamed(p, { typeName: canonical }, mark.written, canonical, role);
677
+ }
678
+ if (rule.choice.kind === 'ambiguous')
679
+ report(r, rule.ambiguous, at, mark.written, rule.role, rule.choice.candidates);
680
+ else
681
+ report(r, rule.unresolved, at, mark.written, rule.role);
682
+ return p;
683
+ }
684
+ // ---- 入口 ----
685
+ function resolveDecl(r, d) {
686
+ if (d.kind !== 'Func')
687
+ return d;
688
+ const f = { scope: { parent: undefined, locals: [] }, ret: declaredRet(d), captures: [] };
689
+ for (const p of d.params)
690
+ declare(f, p.name, p.typeInferred ? undefined : p.type);
691
+ return { ...d, body: resolveBlock(r, f, d.body) };
692
+ }
693
+ /**
694
+ * R2:解析依赖类型的名字位置。返回新的 Core(只含规范名,原写法记在 origin.written)与诊断
695
+ * (E801/E805 字段、E802 值名、E803/E806 模式、E804 期望枚举下的歧义、W800 遮蔽、W801 无类型采用)。
696
+ * 任一 error 时调用方不得发出 IR。observer 只读接收解析结果(LSP 用),不改变输出。
697
+ */
698
+ export function resolveTypedReferences(core, ctx, observer) {
699
+ const r = { scopes: ctx.scopes, t: buildTables(core, ctx), diags: new DiagnosticBuilder(), observer };
700
+ const decls = core.decls.map((d) => resolveDecl(r, d));
701
+ return { module: { ...core, decls }, diagnostics: r.diags.getDiagnostics() };
702
+ }
703
+ //# sourceMappingURL=resolve-typed-references.js.map