docs: 宏增加 open 校验——@JsonExportFields 仅允许标注 open class,否则编译期报错
- 遍历 ClassDecl.modifiers 检查 TokenKind.OPEN(参考 soulsoft Extensions.cj isOpen) - 非 open class / 非 class 声明 → throw MacroException 编译期报错 - 测试计划补充两条校验用例
This commit is contained in:
+33
-4
@@ -181,13 +181,40 @@ import std.collection.*
|
||||
|
||||
/// 标注在父类上:自动生成父类字段的 JSON 导出/导入静态方法
|
||||
public macro JsonExportFields(input: Tokens): Tokens {
|
||||
// 1. 解析输入的 ClassDecl
|
||||
// 2. 收集 public var 字段(跳过 @JsonIgnore)
|
||||
// 3. 生成 exportJsonFields / importJsonFields 两个静态方法
|
||||
// 4. 拼回原类声明 + 新方法,返回 Tokens
|
||||
// 1. 解析输入的 ClassDecl(非类声明 → 抛 MacroException)
|
||||
// 2. 校验 open:非 open class → 抛 MacroException(见 3.1.1)
|
||||
// 3. 收集 public var 字段(跳过 @JsonIgnore)
|
||||
// 4. 生成 exportJsonFields / importJsonFields 两个静态方法
|
||||
// 5. 拼回原类声明 + 新方法,返回 Tokens
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.1.1 open 校验(编译期报错)
|
||||
|
||||
`@JsonExportFields` 的语义是「暴露**父类**字段给子类继承链」——标注在**非 open** 类上没有意义(非 open 类不能被继承,不存在子类实例传入的场景)。因此宏在展开时校验:
|
||||
|
||||
```cangjie
|
||||
/// 遍历类声明的修饰符,检查是否含 open(参考 soulsoft Extensions.cj isOpen)
|
||||
func isOpenClass(decl: ClassDecl): Bool {
|
||||
for (m in decl.modifiers) {
|
||||
if (m.keyword.kind == TokenKind.OPEN) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// 宏展开入口内:
|
||||
if (!isOpenClass(decl)) {
|
||||
throw MacroException("@JsonExportFields 只能标注在 open class 上,"
|
||||
+ "因为非 open 类不能被继承,不存在子类场景。")
|
||||
}
|
||||
```
|
||||
|
||||
- 抛 `MacroException` → 编译期直接报错,错误信息定位到标注处,用户立即发现;
|
||||
- 顺带校验:标注在 **struct / interface / enum / func** 等非 class 声明上也抛错(`MacroCallExpr<ClassDecl>.parse` 失败即报);
|
||||
- 参考先例:soulsoft `Extensions.cj:75-82` 就是遍历 `modifiers` 判 `TokenKind.OPEN`;宏内报错用 `std.ast` 的 `MacroException`(`assertion_macro.cj` 同款用法)。
|
||||
|
||||
### 3.2 生成的目标代码
|
||||
|
||||
对如下父类:
|
||||
@@ -414,6 +441,8 @@ main() {
|
||||
| 父类字段 null | 导入时保持默认值 |
|
||||
| 与 @JsonPropertyName 组合 | 父类字段用注解名输出/匹配 |
|
||||
| 顶层序列化父类类型实例 | `Serialize(BaseUser 实例)` 直接可用 |
|
||||
| **宏校验:非 open 类标注报错** | 编译期报 `MacroException`(非 open class 标注 `@JsonExportFields` 编译失败) |
|
||||
| **宏校验:非 class 声明标注报错** | 对 struct/interface/enum 标注 `@JsonExportFields` 编译失败 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user