- 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 resultpull/17/head
parent
0ad6285cfe
commit
bc435f1dab
1 changed files with 474 additions and 0 deletions
@ -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…
Reference in new issue