test(aot): add trait private property write inherited test case

- Create new test file for trait method writing injected private property on child object
- Add trait PrivatePropertyWriter with private array property and items method
- Implement PropertyOwner class using the trait
- Create ChildPropertyOwner class extending PropertyOwner
- Add main function to test the inherited private property access
- Define expected output for the array dump result
pull/17/head
韩天峰 2 months ago
parent 0ad6285cfe
commit bc435f1dab
  1. 474
      docs/CORE_OOA_OOD_OOP_REFACTORING_PLAN.md

@ -0,0 +1,474 @@
# TypePHP 核心类 OOA / OOD / OOP 重构计划
## 1. 文档目的
本文档用于指导 `Translator`、`CompilerBase`、`Preprocessor` 的后续架构重构。实施时应逐阶段完成,不进行一次性重写。
当前基线:
| 类 | 行数 | 方法数 | 当前角色 |
|---|---:|---:|---|
| `Translator` | 3717 | 126 | CLI、项目配置、代码生成、构建协调 |
| `CompilerBase` | 3843 | 208 | 编译状态、AST 分派、Resolver、Emitter |
| `Preprocessor` | 973 | 25 | 声明收集、AST lowering、依赖和语义验证 |
当前继承结构:
```text
Translator
extends Preprocessor
extends CompilerBase
```
主要问题:
- 三个类形成继承式 God Object,高层流程可以访问全部底层可变状态。
- 大量 Trait 只完成了物理拆分,仍隐式依赖宿主的全部 `$this` 字段。
- 前端分析、名称解析、语义验证、代码生成和 native build 缺少明确边界。
- 数组、AST attribute 和 `string|false` 被用作模块间隐式协议。
- `resetFile()`、`resetClass()`、`resetFunction()` 等手工状态切换容易遗漏恢复。
## 2. 重构原则
1. 行为保持优先,架构重构和语义修改分开提交。
2. 先建立对象边界,再删除旧入口;迁移期允许新旧实现并存。
3. 优先使用组合、接口、不可变值对象;业务 Trait 仅作为过渡方案。
4. Handler Registry 使用节点类名直接索引,避免线性责任链造成编译性能下降。
5. 编译状态必须通过 Context 或 Session 显式传递。
6. Resolver 负责决策,Generator/Emitter 负责生成代码,两者不得混合。
7. 每个阶段必须具备独立 PHPUnit 和对应 PHPT 回归证据。
## 3. OOA:领域对象分析
### 3.1 编译会话域
负责一次编译生命周期的状态:
```text
CompilationSession
CompilerConfiguration
ScopeStack
ScopeFrame
FileContext
ClassContext
FunctionContext
```
### 3.2 前端分析域
负责 PHP 源码到已验证 AST/模型:
```text
SourceParser
FrontendPipeline
DeclarationCollector
DependencyAnalyzer
SemanticAnalyzer
AstLoweringPass
```
### 3.3 解析域
负责符号和语言语义决策:
```text
NameResolver
TypeResolver
MethodCallResolver
PropertyResolver
ConstantResolver
AccessPolicy
SymbolRepository
InheritanceGraph
```
### 3.4 代码生成域
负责 AST/实体模型到 C++:
```text
ExpressionCompiler
StatementCompiler
ClassCodeGenerator
FunctionCodeGenerator
WrapperGenerator
ExtensionModuleGenerator
```
### 3.5 构建域
负责生成文件到最终产物:
```text
SourcePipeline
NativeBuilder
ResourceCompiler
BuildModeStrategy
CompileOptions
LinkOptions
BuildResult
```
### 3.6 应用入口域
负责用户输入和顶层流程:
```text
CompilerApplication
CompileCommand
CompilerFacade
ProjectYamlLoader
CommandLineInput
```
## 4. OOD:目标架构
```text
CompilerApplication
└─ CompilerFacade
├─ ProjectLoader
├─ SourcePipeline
├─ FrontendPipeline
│ ├─ DeclarationCollector
│ ├─ AstLoweringPass[]
│ ├─ DependencyAnalyzer
│ └─ SemanticAnalyzer
├─ TranslationCodeGenerator
│ ├─ ExpressionCompiler
│ ├─ StatementCompiler
│ ├─ ClassCodeGenerator
│ └─ FunctionCodeGenerator
└─ NativeBuilder
```
### 4.1 Translator 的目标
`Translator` 最终作为 Facade/Coordinator,仅组织流程:
```php
final class Translator
{
public function translate(ProjectInput $input): BuildResult;
}
```
禁止继续承担:
- CLI 参数解析;
- AST 节点语义判断;
- 类、函数和 wrapper 的 C++ 模板拼接;
- shell 命令执行;
- 前处理器内部状态。
### 4.2 Preprocessor 的目标
`Preprocessor` 改为独立 Frontend Service,不再继承 `CompilerBase`
```php
final class Preprocessor
{
public function process(SourceUnit $source, CompilationSession $session): PreprocessResult;
}
```
使用 Pipeline 模式组织 Pass:
```text
ParseSourcePass
→ NameResolutionPass
→ PropertyHookLoweringPass
→ DeclarationCollectionPass
→ TraitExpansionPass
→ InheritanceValidationPass
→ TypeValidationPass
→ DependencyCollectionPass
```
### 4.3 CompilerBase 的目标
`CompilerBase` 最终被以下对象替代:
- `CompilationSession`:编译生命周期状态;
- `ExpressionCompiler`:表达式 Handler 分派;
- `StatementCompiler`:语句 Handler 分派;
- `CompilerServices`:Resolver 和 Generator 集合;
- `CodeGenerationContext`:生成期上下文。
完成迁移后删除 `CompilerBase`,或仅保留短期兼容 Facade。
## 5. 设计模式应用
### Facade
`CompilerFacade` 和最终的 `Translator` 提供稳定顶层入口,隐藏 Frontend、Generator、Builder 细节。
### Pipeline
`FrontendPipeline` 显式维护前处理 Pass 顺序,每个 Pass 可独立测试。
### Handler Registry
表达式和语句以 AST 类名进行 O(1) 分派:
```php
$handlers[Expr\MethodCall::class] = $methodCallHandler;
```
### Strategy
构建模式由以下策略实现:
- `BinaryBuildStrategy`
- `ExtensionBuildStrategy`
- `LibraryBuildStrategy`
- `EmbedBuildStrategy`
### Chain of Responsibility
方法解析顺序:
```text
DeclaredMethodResolver
→ ObjectExtensionMethodResolver
→ UniversalMethodResolver
→ MagicCallResolver
→ DynamicCallResolver
```
属性解析顺序:
```text
BackingSlotResolver
→ PropertyHookResolver
→ DeclaredPropertyResolver
→ NativePropertyResolver
→ DynamicPropertyResolver
```
### Repository
`SymbolRepository` 统一管理函数、类、接口、常量和继承关系;调用方不再自行处理 Repository key。
### State / Scope Stack
使用 `ScopeStack``ScopeGuard` 替代 reset 系列方法,确保异常、`Skip`、`Redo` 时恢复状态。
### Value Object / Result Object
逐步引入:
- `SourceUnit`
- `SourceLocation`
- `GeneratedExpression`
- `GeneratedStatement`
- `ResolvedCall`
- `ResolvedPropertyAccess`
- `PreprocessResult`
- `TranslationResult`
- `BuildResult`
## 6. OOP 渐进实施阶段
### 阶段 0:架构保护测试
任务:
- 建立表达式和语句节点覆盖清单;
- 增加 Frontend Pass 顺序测试;
- 增加 Scope 异常恢复测试;
- 增加 SymbolRepository 名称规范化测试;
- 固定 Property Hook、扩展方法、继承和异常测试集合;
- 对关键生成 C++ 建立快照或结构断言。
验收:
- PHPUnit 全量通过;
- 核心 PHPT 全部通过;
- 后续阶段可以识别 Handler 遗漏和求值顺序变化。
### 阶段 1:CompilationSession 与 ScopeStack
任务:
1. 新建 `CompilationSession`、`CompilerConfiguration`、`ScopeStack`。
2. 移入当前文件、namespace、class、method、function、PHP 版本和 phase 状态。
3. `CompilerBase` 旧属性先代理到 Session。
4. 将 reset 系列方法替换为 `enter/leave``try/finally`
5. 删除代理属性。
验收:
- `CompilerBase` 不再直接拥有作用域状态;
- 异常、`Skip`、`Redo` 不会污染下一作用域;
- ScopeStack 有独立单测。
### 阶段 2:Preprocessor Pipeline
任务:
1. 新建 `FrontendPass``FrontendPipeline`
2. 首先迁移 Property Hook lowering。
3. 迁移声明收集和 namespace/use 处理。
4. 迁移依赖收集与文件排序。
5. 迁移 Trait、继承、override 和接口实现验证。
6. 解除 `Preprocessor extends CompilerBase`
验收:
- 每个 Pass 有独立测试;
- Pass 顺序只有一处定义;
- `Preprocessor.php` 控制在 200~300 行。
### 阶段 3:ExpressionCompiler
任务:
1. 新建 `ExpressionHandlerRegistry``GeneratedExpression`
2. 按顺序迁移 scalar/const/variable、unary/binary/cast、array/assign。
3. 迁移 function/method/static call。
4. 迁移 property、nullsafe、isset/empty/ref。
5. 迁移 closure、generator、fiber、new、clone、instanceof。
6. 删除旧 `parseExpr()` 大型分派。
验收:
- 每种已支持 Expr 都有唯一 Handler;
- Handler 不依赖 `CompilerBase`
- Registry 启动时检查重复和遗漏;
- 求值顺序和副作用测试全部通过。
### 阶段 4:StatementCompiler
任务:
1. 新建 `StatementHandlerRegistry``GeneratedStatement`
2. 迁移 return/echo、条件、循环、异常控制流。
3. 迁移 global/static/namespace/declare。
4. 消除共享 `beforeStmtLines`、`afterStmtLines` 协议。
验收:
- Statement Handler 返回显式 Result;
- 控制流生成从 `CompilerBase` 移除;
- before/after 语句通过 Result 组合。
### 阶段 5:Resolver Chain
任务:
1. 建立 `MethodCallResolverChain`
2. 建立 `PropertyResolverChain`
3. 建立 `ConstantResolverChain`
4. 建立统一 `AccessPolicy`
5. 将 `MethodCallTrait`、`PropertyAccessTrait`、`UniversalMethodCall`、`MagicMethodDetector` 迁入 Resolver。
验收:
- 普通方法、扩展方法、`__call()` 优先级只有一处定义;
- backing slot、Property Hook 和普通属性优先级只有一处定义;
- `private(set)`、`protected(set)` 只由 AccessPolicy 判断;
- Resolver 不再返回 `string|false`
### 阶段 6:独立代码生成器
任务:
- 建立 `ClassCodeGenerator`
- 建立 `FunctionCodeGenerator`
- 建立 `WrapperGenerator`
- 建立 `ExtensionModuleGenerator`
- 将 `parseClass()`、`parseFunction()`、wrapper 和注册代码移出 `Translator`
验收:
- Generator 输入为 Entity/IR,输出为 `GeneratedFile`
- `Translator` 不再直接拼接具体 C++ 模板;
- 关键生成结果具备快照测试。
### 阶段 7:Translator Facade
任务:
1. 将 CLI 移到 `CompilerApplication` / `CompileCommand`
2. `Translator` 仅注入 ProjectLoader、Frontend、CodeGenerator、NativeBuilder。
3. 解除 `Translator extends Preprocessor`
4. 将公共入口收敛为 `translate(ProjectInput): BuildResult`
验收:
- `Translator` 不解析 CLI;
- 不直接访问 AST;
- 不直接执行 shell;
- 不依赖 Preprocessor 内部状态;
- 文件控制在 300~500 行。
### 阶段 8:删除 CompilerBase 继承体系
任务:
1. 清除剩余兼容代理和业务 Trait。
2. 将公共查询接口放入明确 Service/Context。
3. 删除 `Translator → Preprocessor → CompilerBase` 继承链。
4. 删除无调用的旧方法和字段。
验收:
- 核心组件仅通过接口和 DTO 协作;
- 无业务 Trait 隐式访问宿主全部状态;
- 不存在超过约 800 行的核心类;
- PHPUnit、核心 PHPT 和多 PHP 版本构建全部通过。
## 7. 每阶段执行模板
每个阶段都按照以下步骤实施:
1. 列出迁移方法、字段和调用方。
2. 先补保护测试。
3. 新建接口、DTO 和实现。
4. 旧入口改为委托新实现。
5. 批量迁移调用方。
6. 删除旧实现和代理字段。
7. 运行语法检查、PHPUnit 和对应 PHPT。
8. 检查 `git diff --check` 和未跟踪构建产物。
9. 更新本文档中的阶段状态和实际偏差。
## 8. 建议目录
```text
src/
├─ Application/
├─ Compiler/
│ └─ Scope/
├─ Frontend/
│ ├─ Pass/
│ └─ Result/
├─ CodeGeneration/
│ ├─ Expression/
│ └─ Statement/
├─ Resolver/
│ ├─ Call/
│ ├─ Property/
│ ├─ Constant/
│ └─ Access/
├─ Symbol/
├─ Build/
│ ├─ BuildMode/
│ └─ Options/
└─ Diagnostics/
```
## 9. 阶段状态
| 阶段 | 状态 |
|---|---|
| 0. 架构保护测试 | 待开始 |
| 1. CompilationSession / ScopeStack | 待开始 |
| 2. Preprocessor Pipeline | 待开始 |
| 3. ExpressionCompiler | 待开始 |
| 4. StatementCompiler | 待开始 |
| 5. Resolver Chain | 待开始 |
| 6. 独立代码生成器 | 待开始 |
| 7. Translator Facade | 待开始 |
| 8. 删除 CompilerBase 继承体系 | 待开始 |
实施过程中应持续更新此表,不允许仅根据文件行数宣布阶段完成。
Loading…
Cancel
Save