# AST 转换(Lowering) 在 `doConvert()` 遍历 AST 时,`src/Transform/Visitor.php` 作为 `NodeVisitor` 挂载在遍历链上,对节点做**编译期改写(lowering)**——把 PHP 8.x 的高层语法(属性钩子、构造函数提升、getter、编译期属性等)降级为编译器能直接翻译的普通结构。 Sources: [src/Transform/Visitor.php](src/Transform/Visitor.php#L19-L36) · [src/Translator.php](src/Translator.php#L2462) ## 两个遍历钩子 `Visitor` 实现 `enterNode()` 与 `leaveNode()` 两阶段处理: - **enterNode**(进入节点前):校验 + 即时 lowering。依次调用 `CompileTimeAttribute::validateNode`、`FunctionAttributeLowering::lower`、`GetterLowering::validateTarget`、`PropertyMethodLowering::validateTarget`、`ConstructorLowering::validateTarget`。 - **leaveNode**(离开节点后):对函数/闭包做 `ParameterValidationLowering`;对类/属性做 `PropertyHookLowering`、`GetterLowering`、`PropertyMethodLowering`,把钩子属性、getter、提升属性改写成方法或标记。 Sources: [src/Transform/Visitor.php](src/Transform/Visitor.php#L28-L80) ## Lowering 算子清单 | 类 | 作用 | |---|---| | `CompileTimeAttribute` / `CompileTimeAttributeRegistry` | 识别并校验编译期属性(如 `Any`、`MustUse`) | | `FunctionAttributeLowering` | 处理函数上的编译期属性 | | `ConstructorLowering` | 处理构造函数提升参数 | | `GetterLowering` | `get` 钩子属性 → getter 方法 | | `PropertyHookLowering` | `get`/`set` 钩子属性 → 访问器方法 | | `PropertyMethodLowering` | 属性 ↔ 方法互转 | | `ParameterValidationLowering` | 参数类型校验,拒绝箭头函数误用 | | `PrinterLowering` / `ValidateLowering` | 打印/校验相关降级 | | `ArrayableLowering` / `NotEmptyLowering` / `NotNullLowering` | 特定表达式降级 | | `RuntimeAttributeFactoryLowering` | 运行时工厂属性(遍历链上独立挂载) | Sources: [src/Transform/](src/Transform/) · [src/Translator.php](src/Translator.php#L2467) ## 顺序意义 Lowering 必须早于 C++ 生成:例如属性钩子若不先降级成方法,后续 `genClassWrapper` 就无法生成对应的 C++ 访问逻辑。它处在 [解析器与 AST](parser) 之后、[代码生成](generator) 之前。 ## 相关阅读 - 编译期属性语义 → [编译期属性](compile-time-attributes) - 降级后如何发射 C++ → [生成器总览](generator) - 常量表达式校验 → [类型检查与兼容](type-check)