@calcit/procs 0.12.15 → 0.12.17

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.
Binary file
@@ -0,0 +1,13 @@
1
+ ## 概要
2
+
3
+ 为 tuple-to-enum 自动改写实现预处理阶段支持。当函数参数 schema 标注为 enum 类型时,
4
+ 调用者传递的 untyped tuple `:: :tag payload` 自动改写为 `%:: Enum :tag payload`。
5
+
6
+ ## 知识点
7
+
8
+ - `CalcitTypeAnnotation::resolve_to_enum_with_ref()` 对应 struct 端已有的 `resolve_to_struct_with_ref()`
9
+ - `resolve_enum_from_program()` 通过 `lookup_runtime_ready_registered` + `lookup_def_code_registered` 两级缓存查找
10
+ - tuple 改写只替换 head proc (`NativeTuple` → `NativeEnumTupleNew`) 并插入 enum 引用,不对 tag/payload 做验证(由 `check_enum_tuple_construction` 兜底)
11
+ - JS codegen 需要 `Calcit::Import` 而非 `Calcit::Enum` 内联值,通过 TypeRef 路径判断走 SameFile 还是 NsReferDef
12
+ - map-to-record 改写验证 key 合法性,tuple-to-enum 改写不验证(差异源于 struct field 是封闭集合,enum tag 验证已有独立检查)
13
+ - Cirru tag-match 零载荷变体的 pattern 是 `(:ok)` 而非 `:ok`(后者在 pair 中被当作 body)
@@ -0,0 +1,40 @@
1
+ # TypeSlot + Enum 编译期安全增强
2
+
3
+ ## 概要
4
+
5
+ 让 `deftype-slot` / `bind-type` 机制真正实现编译期 enum variant 校验。此前 TypeSlot 绑定的 enum 在自动推导 (`:: → %::`) 路径上缺乏变体验证,导致拼写错误或不存在的 variant 无法在 `cr js` / `--check-only` 时报出。
6
+
7
+ ## 修改的文件
8
+
9
+ ### `src/calcit/type_annotation.rs`
10
+ - `resolve_to_enum_with_ref()`: 新增 `TypeSlot` 分支,通过 `resolve_type_slot()` 解析绑定类型后委托
11
+ - `matches_with_bindings()`: 双向 `Tuple/Enum` 匹配 — 原先只有 `(Tuple, Enum)` 方向,TypeSlot 解析后顺序会翻转,新增 `(Enum, Tuple)` 方向
12
+
13
+ ### `src/calcit.rs`
14
+ - 将 `resolve_type_slot` 加入 `pub use` 导出列表
15
+
16
+ ### `src/runner/preprocess.rs`
17
+ - `resolve_enum_value()`: 在 `as_struct()` 调用前增加 TypeSlot 解析(避免 `&CalcitStruct` 生命周期问题)
18
+ - 新增 `try_rewrite_local_fn_tuple_args_to_enum_tuples()`: 对本地函数调用(如回调 `d!`)也执行 tuple→enum 自动重写
19
+ - 主预处理 `Calcit::Local` 分支: 增加 local fn 调用的重写+类型检查(clone 避免借用冲突)
20
+ - `try_rewrite_single_tuple_to_enum_tuple()`: 增加变体验证 — 重写后立即检查 tag 是否是 enum 的合法 variant,不合法则发出警告
21
+
22
+ ### `src/bin/cr_tests/type_fail.rs`
23
+ - 新增 `type_fail_type_slot_enum_invalid_variant` 测试,验证 TypeSlot 绑定的 enum 在自动重写路径下能正确检测不存在的 variant
24
+
25
+ ### `calcit/type-fail/type-slot-enum-invalid-variant.cirru`
26
+ - 新增测试 fixture:声明 `defenum Action`、通过 TypeSlot 绑定、调用 `takes-action $ :: :nonexistent |hello`,期望产生 variant 不存在警告
27
+
28
+ ## 知识点
29
+
30
+ 1. **TypeSlot 解析链**: `TypeSlot(name) → resolve_type_slot(name) → CalcitTypeAnnotation (通常是 TypeRef)` → 再通过 `resolve_to_enum_with_ref()` 得到 enum 定义。这是一个两步间接过程。
31
+
32
+ 2. **`matches_with_bindings` 双向性**: TypeSlot 被解析后会调 `bound.matches_with_bindings(other, bindings)`,此时 self/other 顺序可能翻转。所有组合型匹配(如 Tuple/Enum)都需要双向 pattern。
33
+
34
+ 3. **`as_struct()` 返回引用**: `CalcitTypeAnnotation::as_struct()` 返回 `Option<&CalcitStruct>`,无法从临时解析结果中返回引用。修复方案是在调用点先解析 TypeSlot 再调 `as_struct()`。
35
+
36
+ 4. **自动重写的 `%::` 不经过 `preprocess_expr`**: `try_rewrite_single_tuple_to_enum_tuple` 构造的 `[NativeEnumTupleNew, ...]` 列表是在预处理完参数后生成的,不会经过 `check_proc_arg_types` 中的 `check_enum_tuple_construction`。因此变体验证必须在重写函数内部完成。
37
+
38
+ 5. **Local fn 调用缺少自动重写**: 原先只有 `CalcitFn` 调用走 `try_rewrite_tuple_args_to_enum_tuples`。`Calcit::Local` 调用(如回调参数 `d!`)需要单独处理。新函数接受 `CalcitFnTypeAnnotation` 而非 `CalcitFn`。
39
+
40
+ 6. **Lambda-in-map 的 EXPECTED_FN_TYPE 盲区**: `fn (e d!)` 在 hashmap 值(如 `:on-click`)中时,`d!` 不会获得 `EXPECTED_FN_TYPE` 注入的类型信息。目前通过显式 `%:: Op :variant` 写法绕过,属于已知架构限制。
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.12.15",
3
+ "version": "0.12.17",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.0.9",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calcit/procs",
3
- "version": "0.12.15",
3
+ "version": "0.12.17",
4
4
  "main": "./lib/calcit.procs.mjs",
5
5
  "devDependencies": {
6
6
  "@types/node": "^25.0.9",