refactor(phase-a): remove Cranelift/JIT backend legacy code (~373 lines)
Phase A cleanup - Safe deletions with zero risk: ## Deleted Files (6 files, 373 lines total) 1. Cranelift/JIT Backend (321 lines): - src/runner/modes/cranelift.rs (45 lines) - src/runner/modes/aot.rs (55 lines) - src/runner/jit_direct.rs (152 lines) - src/tests/core13_smoke_jit.rs (42 lines) - src/tests/core13_smoke_jit_map.rs (27 lines) 2. Legacy MIR Builder (52 lines): - src/mir/builder/exprs_legacy.rs - Functionality inlined into exprs.rs (control flow constructs) ## Module Reference Cleanup - src/backend/mod.rs: Removed cranelift feature gate exports - src/runner/mod.rs: Removed jit_direct module reference - src/runner/modes/mod.rs: Removed aot module reference - src/mir/builder.rs: Removed exprs_legacy module ## Impact Analysis - Build: Success (cargo build --release) - Tests: All passing - Risk Level: None (feature already archived, code unused) - Related: Phase 15 JIT archival (archive/jit-cranelift/) ## BID Copilot Status - Already removed in previous cleanup - Not part of this commit Total Reduction: 373 lines (~0.4% of codebase) Next: Phase B - Dead code investigation Related: #phase-21.0-cleanup Part of: Legacy Code Cleanup Initiative
This commit is contained in:
395
docs/development/cleanup/CLEANUP_SUMMARY_2025-11-06.md
Normal file
395
docs/development/cleanup/CLEANUP_SUMMARY_2025-11-06.md
Normal file
@ -0,0 +1,395 @@
|
||||
# Hakorune コードベース重複・共通化調査 - 実行サマリー
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**調査実施**: Claude Code Agent
|
||||
|
||||
---
|
||||
|
||||
## クイックサマリー
|
||||
|
||||
### 主要発見
|
||||
- **重複パターン総数**: 260箇所以上
|
||||
- **削減可能行数**: 500-800行(全体の15-20%)
|
||||
- **即効対応可能**: Phase 1で270-380行削減(実装時間5-8時間)
|
||||
|
||||
### 優先度トップ3
|
||||
1. **Destination書き込み**: 49箇所 → ヘルパー関数化
|
||||
2. **引数検証**: 55箇所 → 統一検証関数
|
||||
3. **エラー生成**: 95箇所 → エラービルダー
|
||||
|
||||
---
|
||||
|
||||
## ドキュメント構成
|
||||
|
||||
### 1. 詳細分析レポート
|
||||
**ファイル**: [`DUPLICATION_ANALYSIS_REPORT.md`](./DUPLICATION_ANALYSIS_REPORT.md)
|
||||
|
||||
**内容**:
|
||||
- 9章構成の包括的レポート
|
||||
- 全重複パターンの詳細分析
|
||||
- 3段階のアクションプラン(Phase 1-3)
|
||||
- リスク評価と期待効果
|
||||
|
||||
**主要セクション**:
|
||||
1. MIR Interpreter Handlers の重複パターン(5種類)
|
||||
2. MIR Builder の重複パターン(PHI挿入など)
|
||||
3. 統合可能なモジュール(Box Handler群)
|
||||
4. 優先度付きアクションプラン
|
||||
5. 実装ガイドライン
|
||||
6. 期待される効果(定量・定性)
|
||||
7. リスク評価
|
||||
8. 追加調査項目
|
||||
9. 結論と推奨事項
|
||||
|
||||
### 2. Phase 1実装ガイド
|
||||
**ファイル**: [`PHASE1_IMPLEMENTATION_GUIDE.md`](./PHASE1_IMPLEMENTATION_GUIDE.md)
|
||||
|
||||
**内容**:
|
||||
- Step-by-Step実装手順
|
||||
- コード例(Before/After)
|
||||
- テスト戦略
|
||||
- トラブルシューティング
|
||||
|
||||
**実装項目**:
|
||||
1. `utils/register_ops.rs` - Destination書き込みヘルパー
|
||||
2. `utils/validation.rs` - 引数検証ヘルパー
|
||||
3. `utils/conversions.rs` - Receiver変換ヘルパー
|
||||
|
||||
---
|
||||
|
||||
## 数値で見る重複の実態
|
||||
|
||||
### パターン別重複数
|
||||
|
||||
| パターン | 箇所数 | 削減見込み行数 | 優先度 |
|
||||
|---------|--------|--------------|--------|
|
||||
| Destination書き込み | 49 | 150-200 | 最高 ⭐⭐⭐ |
|
||||
| 引数検証 | 55 | 100-150 | 高 ⭐⭐ |
|
||||
| エラー生成 | 95 | 200-300 | 最高 ⭐⭐⭐ |
|
||||
| Receiver変換 | 5 | 20-30 | 高 ⭐⭐ |
|
||||
| PHI挿入 | 13 | 50-100 | 中 ⭐ |
|
||||
| Box downcast | 57 | 将来検討 | 低 |
|
||||
| **合計** | **274** | **520-780** | - |
|
||||
|
||||
### ファイル別行数(上位10)
|
||||
|
||||
```
|
||||
907行 handlers/calls.rs ← 最大ファイル
|
||||
399行 handlers/boxes_object_fields.rs
|
||||
307行 handlers/boxes.rs
|
||||
298行 handlers/extern_provider.rs
|
||||
218行 handlers/externals.rs
|
||||
217行 handlers/boxes_plugin.rs
|
||||
208行 handlers/boxes_string.rs
|
||||
153行 handlers/boxes_instance.rs
|
||||
136行 handlers/arithmetic.rs
|
||||
134行 handlers/boxes_map.rs
|
||||
-------
|
||||
3,335行 handlers/ 合計
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## アクションプラン概要
|
||||
|
||||
### Phase 1: 即効対応(推奨: 即時実施)
|
||||
**目標**: 低リスク・高効果のヘルパー関数実装
|
||||
**期間**: 5-8時間
|
||||
**削減**: 270-380行
|
||||
|
||||
**実装項目**:
|
||||
1. Destination書き込みヘルパー
|
||||
```rust
|
||||
// Before (4行)
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::from_nyash_box(ret));
|
||||
}
|
||||
|
||||
// After (1行)
|
||||
this.write_box_result(dst, ret);
|
||||
```
|
||||
|
||||
2. 引数検証ヘルパー
|
||||
```rust
|
||||
// Before (3行)
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
|
||||
// After (1行)
|
||||
this.validate_args_exact("push", args, 1)?;
|
||||
```
|
||||
|
||||
3. Receiver変換ヘルパー
|
||||
```rust
|
||||
// Before (4行)
|
||||
let recv_box = match recv.clone() {
|
||||
VMValue::BoxRef(b) => b.share_box(),
|
||||
other => other.to_nyash_box(),
|
||||
};
|
||||
|
||||
// After (1行)
|
||||
let recv_box = this.convert_to_box(&recv);
|
||||
```
|
||||
|
||||
### Phase 2: 基盤整備(Phase 1完了後)
|
||||
**目標**: エラー処理とPHI挿入の統一
|
||||
**期間**: 5-7時間
|
||||
**削減**: 250-400行
|
||||
|
||||
**実装項目**:
|
||||
- エラー生成ヘルパー(95箇所)
|
||||
- PHI挿入ヘルパー(13箇所)
|
||||
|
||||
### Phase 3: 抜本改革(将来課題)
|
||||
**目標**: Box Handler群の統合
|
||||
**期間**: 1-2週間
|
||||
**削減**: 300-400行
|
||||
**リスク**: 中-高
|
||||
|
||||
**備考**: Phase 1-2の効果を見てから判断
|
||||
|
||||
---
|
||||
|
||||
## 期待される効果
|
||||
|
||||
### 定量的効果
|
||||
|
||||
| 指標 | 現状 | Phase 1後 | Phase 2後 | Phase 3後 |
|
||||
|-----|------|----------|----------|----------|
|
||||
| Handler総行数 | 3,335 | 2,965 (-11%) | 2,715 (-19%) | 2,415 (-28%) |
|
||||
| 重複パターン | 260箇所 | 109箇所 (-58%) | 46箇所 (-82%) | <20箇所 (-92%) |
|
||||
| 保守対象箇所 | 散在 | 3ヶ所集約 | 5ヶ所集約 | 統一API |
|
||||
|
||||
### 定性的効果
|
||||
|
||||
✅ **保守性向上**: ロジック変更が1箇所で完結
|
||||
✅ **可読性向上**: 意図が明確な関数名
|
||||
✅ **バグ削減**: 共通ロジックのバグ修正が全体に波及
|
||||
✅ **開発速度向上**: 新機能追加時のボイラープレート削減
|
||||
✅ **テスト容易性**: ユーティリティ関数の単体テストで広範囲カバー
|
||||
✅ **一貫性**: エラーメッセージの統一
|
||||
|
||||
---
|
||||
|
||||
## リスクと対策
|
||||
|
||||
### Phase 1リスク: 極めて低
|
||||
|
||||
| リスク | 確率 | 影響 | 対策 |
|
||||
|-------|------|------|------|
|
||||
| ヘルパー関数のバグ | 低 | 高 | 単体テスト、段階的移行 |
|
||||
| パフォーマンス劣化 | 極低 | 低 | インライン化、ベンチマーク |
|
||||
| 既存動作の変更 | 低 | 高 | 1ファイルずつ、回帰テスト |
|
||||
|
||||
### 推奨移行戦略
|
||||
|
||||
1. **テストファースト**: ユーティリティ関数のテストを先に書く
|
||||
2. **並行期間**: 新旧コードを共存させる
|
||||
3. **段階的移行**: 1ファイルずつ確実に
|
||||
4. **回帰テスト**: 各ファイル移行後にスモークテスト実行
|
||||
|
||||
---
|
||||
|
||||
## 実装の流れ(Phase 1)
|
||||
|
||||
### Week 1: インフラ構築(1-2時間)
|
||||
```
|
||||
1. utils/ ディレクトリ作成
|
||||
2. register_ops.rs, validation.rs, conversions.rs 実装
|
||||
3. ユニットテスト追加
|
||||
4. 全テスト確認
|
||||
```
|
||||
|
||||
### Week 1-2: Handler更新(3-5時間)
|
||||
```
|
||||
小さいファイルから順番に:
|
||||
1. boxes_array.rs (63行 → 50行)
|
||||
2. boxes_map.rs (134行 → 110行)
|
||||
3. boxes_string.rs (208行 → 170行)
|
||||
4. boxes_plugin.rs (217行 → 180行)
|
||||
5. boxes_instance.rs (153行 → 125行)
|
||||
6. boxes_object_fields.rs (399行 → 330行)
|
||||
7. boxes.rs (307行 → 250行)
|
||||
8. calls.rs (907行 → 750行)
|
||||
|
||||
各ファイル更新後:
|
||||
- コンパイル確認
|
||||
- テスト実行
|
||||
- コミット(小さなPR)
|
||||
```
|
||||
|
||||
### Week 2: 検証・ドキュメント(1時間)
|
||||
```
|
||||
1. 全ハンドラーで古いパターン検索
|
||||
2. スモークテスト実行
|
||||
3. ドキュメント更新
|
||||
4. Phase 2計画開始
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## コード例:Before/After
|
||||
|
||||
### Example 1: ArrayBox.push
|
||||
|
||||
**Before** (6行):
|
||||
```rust
|
||||
"push" => {
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
let val = this.reg_load(args[0])?.to_nyash_box();
|
||||
let _ = ab.push(val);
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::Void);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
**After** (4行, **33%削減**):
|
||||
```rust
|
||||
"push" => {
|
||||
this.validate_args_exact("push", args, 1)?;
|
||||
let val = this.reg_load(args[0])?.to_nyash_box();
|
||||
let _ = ab.push(val);
|
||||
this.write_void(dst);
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
### Example 2: StringBox.indexOf
|
||||
|
||||
**Before** (19行):
|
||||
```rust
|
||||
"indexOf" => {
|
||||
let (needle, from_index) = match args.len() {
|
||||
1 => {
|
||||
let n = this.reg_load(args[0])?.to_string();
|
||||
(n, 0)
|
||||
}
|
||||
2 => {
|
||||
let n = this.reg_load(args[0])?.to_string();
|
||||
let from = this.reg_load(args[1])?.as_integer().unwrap_or(0);
|
||||
(n, from.max(0) as usize)
|
||||
}
|
||||
_ => {
|
||||
return Err(VMError::InvalidInstruction(
|
||||
"indexOf expects 1 or 2 args (search [, fromIndex])".into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
// ... implementation
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::Integer(idx));
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
**After** (14行, **26%削減**):
|
||||
```rust
|
||||
"indexOf" => {
|
||||
this.validate_args_range("indexOf", args, 1, 2)?;
|
||||
|
||||
let needle = this.reg_load(args[0])?.to_string();
|
||||
let from_index = if args.len() >= 2 {
|
||||
this.reg_load(args[1])?.as_integer().unwrap_or(0).max(0) as usize
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
// ... implementation
|
||||
|
||||
this.write_integer(dst, idx);
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 推奨事項
|
||||
|
||||
### 🚀 即時実施推奨
|
||||
**Phase 1の実装**: 低リスク・高効果・短時間で完了可能
|
||||
|
||||
### 理由
|
||||
1. **投資対効果が極めて高い**: 5-8時間で270-380行削減
|
||||
2. **リスクが低い**: 既存パターンの単純な抽出
|
||||
3. **即効性がある**: 実装後すぐに効果が現れる
|
||||
4. **基盤になる**: Phase 2-3の土台
|
||||
|
||||
### 実施手順
|
||||
1. [`PHASE1_IMPLEMENTATION_GUIDE.md`](./PHASE1_IMPLEMENTATION_GUIDE.md) を読む
|
||||
2. Step 1-3でユーティリティ関数を実装(1-2時間)
|
||||
3. Step 6で1ファイルずつ更新(3-5時間)
|
||||
4. 完了後、効果測定とPhase 2計画
|
||||
|
||||
---
|
||||
|
||||
## 参考資料
|
||||
|
||||
### 調査で作成したドキュメント
|
||||
1. **詳細分析レポート**: [`DUPLICATION_ANALYSIS_REPORT.md`](./DUPLICATION_ANALYSIS_REPORT.md)
|
||||
- 全重複パターンの詳細分析
|
||||
- リスク評価と期待効果
|
||||
- 付録(ファイルサイズ一覧など)
|
||||
|
||||
2. **Phase 1実装ガイド**: [`PHASE1_IMPLEMENTATION_GUIDE.md`](./PHASE1_IMPLEMENTATION_GUIDE.md)
|
||||
- コピペで使えるコード例
|
||||
- トラブルシューティング
|
||||
- テスト戦略
|
||||
|
||||
3. **このサマリー**: [`CLEANUP_SUMMARY_2025-11-06.md`](./CLEANUP_SUMMARY_2025-11-06.md)
|
||||
- 全体像の把握
|
||||
- クイックリファレンス
|
||||
|
||||
### 調査実行コマンド
|
||||
```bash
|
||||
# 重複パターン確認
|
||||
grep -rn "if let Some(d) = dst { this.regs.insert" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "args.len()" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "match recv.clone()" src/backend/mir_interpreter/handlers/
|
||||
|
||||
# ファイルサイズ確認
|
||||
wc -l src/backend/mir_interpreter/handlers/*.rs | sort -rn
|
||||
|
||||
# Phase 1実装後の確認
|
||||
git diff --stat # 変更行数確認
|
||||
./tools/jit_smoke.sh # 回帰テスト
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Q&A
|
||||
|
||||
### Q1: なぜPhase 1を優先?
|
||||
**A**: 低リスク・高効果・短時間で、Phase 2-3の土台になるため。
|
||||
|
||||
### Q2: 既存テストは通る?
|
||||
**A**: はい。ヘルパー関数は既存ロジックの抽出なので、動作は同一です。
|
||||
|
||||
### Q3: パフォーマンスへの影響は?
|
||||
**A**: ほぼゼロ。コンパイラの最適化でインライン化されます。
|
||||
|
||||
### Q4: Phase 2-3はいつ実施?
|
||||
**A**: Phase 1完了後、効果を測定してから判断します。
|
||||
|
||||
### Q5: 他のメンバーへの影響は?
|
||||
**A**: 最小限。小さなPRに分割し、1ファイルずつレビューします。
|
||||
|
||||
---
|
||||
|
||||
## 次のステップ
|
||||
|
||||
1. ✅ **調査完了** - このドキュメント
|
||||
2. ⏭️ **Phase 1実装開始** - [`PHASE1_IMPLEMENTATION_GUIDE.md`](./PHASE1_IMPLEMENTATION_GUIDE.md) 参照
|
||||
3. ⏳ **Phase 2計画** - Phase 1完了後
|
||||
4. ⏳ **Phase 3検討** - Phase 1-2の効果測定後
|
||||
|
||||
---
|
||||
|
||||
**作成者**: Claude Code Agent
|
||||
**最終更新**: 2025-11-06
|
||||
**次回更新**: Phase 1完了時
|
||||
543
docs/development/cleanup/DUPLICATION_ANALYSIS_REPORT.md
Normal file
543
docs/development/cleanup/DUPLICATION_ANALYSIS_REPORT.md
Normal file
@ -0,0 +1,543 @@
|
||||
# Hakorune Rustコードベース 重複コード・共通化調査レポート
|
||||
|
||||
## 概要
|
||||
|
||||
このレポートは、Hakorune Rustコードベースにおける重複コード、共通化可能なパターンを特定し、DRY原則違反を解消するための調査結果をまとめたものです。
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**調査対象**: `/home/tomoaki/git/hakorune-selfhost/src/`
|
||||
|
||||
---
|
||||
|
||||
## エグゼクティブサマリー
|
||||
|
||||
### 主要な発見
|
||||
|
||||
- **重複パターン総数**: 5つの主要カテゴリで約260インスタンス
|
||||
- **最大削減見込み**: 推定500-800行(全体の約2-3%)
|
||||
- **優先度最高**: Handler内のBox操作パターン統一(49+55+95=199インスタンス)
|
||||
|
||||
### クイックメトリクス
|
||||
|
||||
| カテゴリ | 重複数 | 削減見込み行数 | 優先度 |
|
||||
|---------|--------|--------------|--------|
|
||||
| Receiver変換パターン | 5箇所 | 20-30行 | 高 |
|
||||
| Destination書き込み | 49箇所 | 150-200行 | 最高 |
|
||||
| 引数検証 | 55箇所 | 100-150行 | 高 |
|
||||
| エラー生成 | 95箇所 | 200-300行 | 最高 |
|
||||
| PHI挿入 | 13箇所 | 50-100行 | 中 |
|
||||
|
||||
---
|
||||
|
||||
## 1. MIR Interpreter Handlers の重複パターン
|
||||
|
||||
### 1.1 Receiver変換パターン(5箇所の完全重複)
|
||||
|
||||
**場所**:
|
||||
- `src/backend/mir_interpreter/handlers/boxes.rs:49-52`
|
||||
- `src/backend/mir_interpreter/handlers/boxes_array.rs:12-15`
|
||||
- `src/backend/mir_interpreter/handlers/boxes_map.rs:12-15`
|
||||
- `src/backend/mir_interpreter/handlers/boxes_plugin.rs:12-15`
|
||||
- `src/backend/mir_interpreter/handlers/boxes_instance.rs:14-17`
|
||||
|
||||
**重複コード**:
|
||||
```rust
|
||||
let recv_box: Box<dyn NyashBox> = match recv.clone() {
|
||||
VMValue::BoxRef(b) => b.share_box(),
|
||||
other => other.to_nyash_box(),
|
||||
};
|
||||
```
|
||||
|
||||
**共通化提案**:
|
||||
```rust
|
||||
// src/backend/mir_interpreter/utils/conversions.rs
|
||||
impl MirInterpreter {
|
||||
fn convert_to_box(&self, recv: &VMValue) -> Box<dyn NyashBox> {
|
||||
match recv.clone() {
|
||||
VMValue::BoxRef(b) => b.share_box(),
|
||||
other => other.to_nyash_box(),
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待効果**:
|
||||
- 削減行数: 約20行(4行 × 5箇所)
|
||||
- 保守性向上: 変換ロジックの一元管理
|
||||
- テスト容易性: 1箇所のテストで全体をカバー
|
||||
|
||||
**リスク**: 低 - 単純な抽出で破壊的変更なし
|
||||
|
||||
---
|
||||
|
||||
### 1.2 Destination Register書き込みパターン(49箇所)
|
||||
|
||||
**典型例**:
|
||||
```rust
|
||||
// パターン1: 単純な書き込み(最頻出)
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::from_nyash_box(ret));
|
||||
}
|
||||
|
||||
// パターン2: 直接値
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::Void);
|
||||
}
|
||||
|
||||
// パターン3: 変換後
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::Integer(idx));
|
||||
}
|
||||
```
|
||||
|
||||
**場所**: 全handlerファイルに散在(特に`boxes_*.rs`に集中)
|
||||
|
||||
**共通化提案**:
|
||||
```rust
|
||||
// src/backend/mir_interpreter/utils/register_ops.rs
|
||||
impl MirInterpreter {
|
||||
/// Write result to destination register if present
|
||||
fn write_result(&mut self, dst: Option<ValueId>, value: VMValue) {
|
||||
if let Some(d) = dst {
|
||||
self.regs.insert(d, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Write NyashBox result to destination register
|
||||
fn write_box_result(&mut self, dst: Option<ValueId>, boxed: Box<dyn NyashBox>) {
|
||||
self.write_result(dst, VMValue::from_nyash_box(boxed));
|
||||
}
|
||||
|
||||
/// Write void to destination register
|
||||
fn write_void(&mut self, dst: Option<ValueId>) {
|
||||
self.write_result(dst, VMValue::Void);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待効果**:
|
||||
- 削減行数: 約150-200行(3-4行 × 49箇所 → 1行呼び出し)
|
||||
- 可読性向上: 意図が明確になる(`write_box_result`の方が意味が伝わる)
|
||||
- エラー削減: 書き込み忘れを防止
|
||||
|
||||
**リスク**: 低 - 単純なヘルパー関数化
|
||||
|
||||
---
|
||||
|
||||
### 1.3 引数検証パターン(55箇所)
|
||||
|
||||
**典型例**:
|
||||
```rust
|
||||
// パターン1: 固定数検証
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
|
||||
// パターン2: 範囲検証
|
||||
if args.len() != 2 {
|
||||
return Err(VMError::InvalidInstruction("set expects 2 args".into()));
|
||||
}
|
||||
|
||||
// パターン3: 複数許容
|
||||
if args.len() < 1 || args.len() > 2 {
|
||||
return Err(VMError::InvalidInstruction("substring expects 1 or 2 args".into()));
|
||||
}
|
||||
```
|
||||
|
||||
**共通化提案**:
|
||||
```rust
|
||||
// src/backend/mir_interpreter/utils/validation.rs
|
||||
impl MirInterpreter {
|
||||
/// Validate exact argument count
|
||||
fn validate_args_exact(&self, method: &str, args: &[ValueId], expected: usize) -> Result<(), VMError> {
|
||||
if args.len() != expected {
|
||||
return Err(VMError::InvalidInstruction(
|
||||
format!("{} expects {} arg(s), got {}", method, expected, args.len())
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate argument count range
|
||||
fn validate_args_range(&self, method: &str, args: &[ValueId], min: usize, max: usize) -> Result<(), VMError> {
|
||||
let len = args.len();
|
||||
if len < min || len > max {
|
||||
return Err(VMError::InvalidInstruction(
|
||||
format!("{} expects {}-{} arg(s), got {}", method, min, max, len)
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**使用例**:
|
||||
```rust
|
||||
// Before
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
|
||||
// After
|
||||
self.validate_args_exact("push", args, 1)?;
|
||||
```
|
||||
|
||||
**期待効果**:
|
||||
- 削減行数: 約100-150行(2-3行 × 55箇所 → 1行呼び出し)
|
||||
- エラーメッセージ統一: 一貫した形式
|
||||
- 保守性向上: 検証ロジックの一元管理
|
||||
|
||||
**リスク**: 低 - 純粋な抽出、既存動作を変更しない
|
||||
|
||||
---
|
||||
|
||||
### 1.4 エラー生成パターン(95箇所)
|
||||
|
||||
**典型例**:
|
||||
```rust
|
||||
return Err(VMError::InvalidInstruction("some message".into()));
|
||||
return Err(VMError::InvalidInstruction(format!("message with {}", var)));
|
||||
```
|
||||
|
||||
**共通化提案**:
|
||||
```rust
|
||||
// src/backend/mir_interpreter/utils/errors.rs
|
||||
impl MirInterpreter {
|
||||
fn invalid_instruction<S: Into<String>>(&self, msg: S) -> VMError {
|
||||
VMError::InvalidInstruction(msg.into())
|
||||
}
|
||||
|
||||
fn method_not_found(&self, box_type: &str, method: &str) -> VMError {
|
||||
VMError::InvalidInstruction(
|
||||
format!("Method {} not found on {}", method, box_type)
|
||||
)
|
||||
}
|
||||
|
||||
fn arg_count_error(&self, method: &str, expected: usize, got: usize) -> VMError {
|
||||
VMError::InvalidInstruction(
|
||||
format!("{} expects {} arg(s), got {}", method, expected, got)
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待効果**:
|
||||
- 削減行数: 約200-300行(複雑な`format!`マクロが1行呼び出しに)
|
||||
- エラーメッセージ統一: 一貫した形式とタイポ防止
|
||||
- i18n対応準備: 将来の多言語化が容易
|
||||
|
||||
**リスク**: 低 - エラー生成ロジックの抽出のみ
|
||||
|
||||
---
|
||||
|
||||
## 2. MIR Builder の重複パターン
|
||||
|
||||
### 2.1 PHI挿入パターン(13箇所)
|
||||
|
||||
**場所**: `src/mir/builder/` 配下の複数ファイル
|
||||
- `exprs_peek.rs`: 2箇所
|
||||
- `if_form.rs`: 2箇所
|
||||
- `ops.rs`: 7箇所
|
||||
- `phi.rs`: 2箇所
|
||||
|
||||
**典型例**:
|
||||
```rust
|
||||
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) {
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(func, cur_bb, result_val, phi_inputs);
|
||||
} else {
|
||||
self.emit_instruction(MirInstruction::Phi { dst: result_val, inputs: phi_inputs })?;
|
||||
}
|
||||
```
|
||||
|
||||
**共通化提案**:
|
||||
```rust
|
||||
// src/mir/builder/utils/phi_helpers.rs
|
||||
impl MirBuilder {
|
||||
/// Insert PHI instruction at current block head or emit legacy format
|
||||
fn insert_phi(&mut self, dst: ValueId, inputs: Vec<(BasicBlockId, ValueId)>) -> Result<(), String> {
|
||||
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) {
|
||||
crate::mir::ssot::cf_common::insert_phi_at_head(func, cur_bb, dst, inputs);
|
||||
Ok(())
|
||||
} else {
|
||||
self.emit_instruction(MirInstruction::Phi { dst, inputs })
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待効果**:
|
||||
- 削減行数: 約50-100行(4-5行 × 13箇所 → 1行呼び出し)
|
||||
- 可読性向上: PHI挿入の意図が明確
|
||||
- 保守性向上: PHI挿入ロジックの一元管理
|
||||
|
||||
**リスク**: 低 - 既存パターンの単純な抽出
|
||||
|
||||
---
|
||||
|
||||
## 3. 統合可能な似たモジュール
|
||||
|
||||
### 3.1 Box Handler群の統合機会
|
||||
|
||||
**現状**:
|
||||
- `boxes_array.rs` (63行)
|
||||
- `boxes_map.rs` (134行)
|
||||
- `boxes_string.rs` (208行)
|
||||
- `boxes_plugin.rs` (217行)
|
||||
- `boxes_instance.rs` (153行)
|
||||
|
||||
**共通構造**:
|
||||
1. Receiver変換(全て同一)
|
||||
2. Box型ダウンキャスト
|
||||
3. Method名によるdispatch
|
||||
4. 引数検証
|
||||
5. Destination書き込み
|
||||
|
||||
**統合提案**:
|
||||
```rust
|
||||
// src/backend/mir_interpreter/handlers/box_dispatch.rs
|
||||
pub trait BoxMethodHandler {
|
||||
fn handle_method(&self, method: &str, args: &[ValueId], interp: &mut MirInterpreter)
|
||||
-> Result<Option<VMValue>, VMError>;
|
||||
}
|
||||
|
||||
impl MirInterpreter {
|
||||
fn dispatch_box_method<T: NyashBox + BoxMethodHandler>(
|
||||
&mut self,
|
||||
dst: Option<ValueId>,
|
||||
box_val: ValueId,
|
||||
method: &str,
|
||||
args: &[ValueId],
|
||||
) -> Result<bool, VMError> {
|
||||
let recv = self.reg_load(box_val)?;
|
||||
let recv_box = self.convert_to_box(&recv);
|
||||
|
||||
if let Some(handler) = recv_box.as_any().downcast_ref::<T>() {
|
||||
if let Some(result) = handler.handle_method(method, args, self)? {
|
||||
self.write_result(dst, result);
|
||||
} else {
|
||||
self.write_void(dst);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待効果**:
|
||||
- 削減行数: 約300-400行(共通部分の統一化)
|
||||
- 新Box型の追加が容易: Traitを実装するだけ
|
||||
- テスト容易性: Handler単位でのテストが可能
|
||||
|
||||
**リスク**: 中 - 大規模なリファクタリングが必要
|
||||
|
||||
---
|
||||
|
||||
## 4. 優先度付きアクションプラン
|
||||
|
||||
### Phase 1: 低リスク・高効果(即効性)
|
||||
|
||||
1. **Destination書き込みヘルパー** (優先度: 最高)
|
||||
- 実装時間: 2-3時間
|
||||
- 削減見込み: 150-200行
|
||||
- リスク: 低
|
||||
|
||||
2. **引数検証ヘルパー** (優先度: 高)
|
||||
- 実装時間: 2-3時間
|
||||
- 削減見込み: 100-150行
|
||||
- リスク: 低
|
||||
|
||||
3. **Receiver変換ヘルパー** (優先度: 高)
|
||||
- 実装時間: 1-2時間
|
||||
- 削減見込み: 20-30行
|
||||
- リスク: 低
|
||||
|
||||
### Phase 2: 中リスク・中効果(基盤整備)
|
||||
|
||||
4. **エラー生成ヘルパー** (優先度: 中)
|
||||
- 実装時間: 3-4時間
|
||||
- 削減見込み: 200-300行
|
||||
- リスク: 低
|
||||
|
||||
5. **PHI挿入ヘルパー** (優先度: 中)
|
||||
- 実装時間: 2-3時間
|
||||
- 削減見込み: 50-100行
|
||||
- リスク: 低
|
||||
|
||||
### Phase 3: 高リスク・高効果(抜本改革)
|
||||
|
||||
6. **Box Handler統合** (優先度: 低-中、将来課題)
|
||||
- 実装時間: 1-2週間
|
||||
- 削減見込み: 300-400行
|
||||
- リスク: 中-高
|
||||
- 備考: Phase 1-2完了後に検討
|
||||
|
||||
---
|
||||
|
||||
## 5. 実装ガイドライン
|
||||
|
||||
### 5.1 新規ユーティリティモジュール構成
|
||||
|
||||
```
|
||||
src/backend/mir_interpreter/
|
||||
├── handlers/
|
||||
│ ├── ... (existing files)
|
||||
│ └── mod.rs
|
||||
└── utils/ (新規)
|
||||
├── mod.rs
|
||||
├── conversions.rs (Phase 1: Receiver変換)
|
||||
├── register_ops.rs (Phase 1: Destination書き込み)
|
||||
├── validation.rs (Phase 1: 引数検証)
|
||||
├── errors.rs (Phase 2: エラー生成)
|
||||
└── phi_helpers.rs (Phase 2: PHI挿入, MIR Builder用)
|
||||
```
|
||||
|
||||
### 5.2 段階的移行戦略
|
||||
|
||||
1. **ユーティリティ関数実装**: 既存コードに影響を与えずに新機能を追加
|
||||
2. **並行期間**: 新旧両方のコードが共存
|
||||
3. **1ファイルずつ移行**: テストを都度実行して確認
|
||||
4. **完全移行後**: 旧パターンの削除
|
||||
|
||||
### 5.3 テスト戦略
|
||||
|
||||
```rust
|
||||
// 各ユーティリティ関数に対応するテストを追加
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_validate_args_exact() {
|
||||
// Exact match: OK
|
||||
// Too many: Error
|
||||
// Too few: Error
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_box_result() {
|
||||
// With destination: writes
|
||||
// Without destination: no-op
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 期待される全体効果
|
||||
|
||||
### 6.1 定量的効果
|
||||
|
||||
| 項目 | 現状 | Phase 1完了後 | Phase 2完了後 |
|
||||
|------|------|--------------|--------------|
|
||||
| Handler総行数 | 3,335行 | 2,965行 (-11%) | 2,715行 (-19%) |
|
||||
| 重複パターン数 | 260箇所 | 109箇所 (-58%) | 46箇所 (-82%) |
|
||||
| ユーティリティ関数数 | 0 | 3 | 5 |
|
||||
|
||||
### 6.2 定性的効果
|
||||
|
||||
- **保守性向上**: 変更が1箇所で完結
|
||||
- **可読性向上**: 意図が明確な関数名
|
||||
- **バグ削減**: 共通ロジックのバグ修正が全体に波及
|
||||
- **新機能追加の容易性**: 統一されたパターン
|
||||
- **テスト容易性**: ユーティリティ関数の単体テストで広範囲をカバー
|
||||
|
||||
---
|
||||
|
||||
## 7. リスク評価とミティゲーション
|
||||
|
||||
### 7.1 技術的リスク
|
||||
|
||||
| リスク | 確率 | 影響度 | 対策 |
|
||||
|-------|------|--------|------|
|
||||
| ユーティリティ関数のバグ | 低 | 高 | 単体テスト、段階的移行 |
|
||||
| パフォーマンス劣化 | 極低 | 低 | ベンチマーク測定 |
|
||||
| 既存動作の変更 | 低 | 高 | 回帰テスト、1ファイルずつ |
|
||||
|
||||
### 7.2 プロジェクト管理リスク
|
||||
|
||||
| リスク | 確率 | 影響度 | 対策 |
|
||||
|-------|------|--------|------|
|
||||
| 実装時間超過 | 中 | 中 | Phaseごとに区切る |
|
||||
| レビュー負荷 | 中 | 低 | 小さなPRに分割 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 追加調査項目(将来の改善機会)
|
||||
|
||||
### 8.1 MIR Builder内の重複
|
||||
|
||||
- `variable_map.insert`パターン(21箇所)
|
||||
- `current_block`アクセスパターン
|
||||
- エラーハンドリングの統一
|
||||
|
||||
### 8.2 型変換パターン
|
||||
|
||||
- `to_nyash_box()`(31箇所)
|
||||
- `from_nyash_box()`(33箇所)
|
||||
- 型変換ヘルパーの統一化可能性
|
||||
|
||||
### 8.3 Host Providers
|
||||
|
||||
- 現状3ファイルのみで大きな重複なし
|
||||
- 将来の拡張時に再評価
|
||||
|
||||
---
|
||||
|
||||
## 9. 結論と推奨事項
|
||||
|
||||
### 主要な推奨事項
|
||||
|
||||
1. **Phase 1を優先実施**: 低リスク・高効果で即効性がある
|
||||
- Destination書き込みヘルパー
|
||||
- 引数検証ヘルパー
|
||||
- Receiver変換ヘルパー
|
||||
|
||||
2. **段階的移行**: 一度に全てを変更せず、1ファイルずつ確実に
|
||||
|
||||
3. **テストファースト**: ユーティリティ関数のテストを先に書く
|
||||
|
||||
4. **Phase 3は慎重に**: Box Handler統合は効果が大きいが、Phase 1-2の完了を待つ
|
||||
|
||||
### 期待される最終成果
|
||||
|
||||
- **コード削減**: 500-800行(約15-20%削減)
|
||||
- **保守性向上**: 共通ロジックの一元管理
|
||||
- **バグ削減**: 統一されたパターンによるエラー低減
|
||||
- **開発速度向上**: 新機能追加時のボイラープレート削減
|
||||
|
||||
---
|
||||
|
||||
## 付録A: ファイルサイズ一覧
|
||||
|
||||
### Handler Files
|
||||
```
|
||||
907 src/backend/mir_interpreter/handlers/calls.rs
|
||||
399 src/backend/mir_interpreter/handlers/boxes_object_fields.rs
|
||||
307 src/backend/mir_interpreter/handlers/boxes.rs
|
||||
298 src/backend/mir_interpreter/handlers/extern_provider.rs
|
||||
218 src/backend/mir_interpreter/handlers/externals.rs
|
||||
217 src/backend/mir_interpreter/handlers/boxes_plugin.rs
|
||||
208 src/backend/mir_interpreter/handlers/boxes_string.rs
|
||||
153 src/backend/mir_interpreter/handlers/boxes_instance.rs
|
||||
136 src/backend/mir_interpreter/handlers/arithmetic.rs
|
||||
134 src/backend/mir_interpreter/handlers/boxes_map.rs
|
||||
107 src/backend/mir_interpreter/handlers/mod.rs
|
||||
89 src/backend/mir_interpreter/handlers/call_resolution.rs
|
||||
63 src/backend/mir_interpreter/handlers/boxes_array.rs
|
||||
47 src/backend/mir_interpreter/handlers/memory.rs
|
||||
31 src/backend/mir_interpreter/handlers/misc.rs
|
||||
21 src/backend/mir_interpreter/handlers/boxes_void_guards.rs
|
||||
3,335 合計
|
||||
```
|
||||
|
||||
### MIR Builder Files
|
||||
```
|
||||
6,885 行(54ファイル)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**レポート作成者**: Claude Code Agent
|
||||
**最終更新**: 2025-11-06
|
||||
**次回レビュー**: Phase 1実装完了後
|
||||
297
docs/development/cleanup/DUPLICATION_INDEX.md
Normal file
297
docs/development/cleanup/DUPLICATION_INDEX.md
Normal file
@ -0,0 +1,297 @@
|
||||
# コードベース重複・共通化調査 - インデックス
|
||||
|
||||
Hakorune Rustコードベースにおける重複コードの特定と、DRY原則に基づく改善計画のドキュメントハブです。
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**実施**: Claude Code Agent
|
||||
**調査種別**: 重複パターン分析・共通化機会の特定
|
||||
|
||||
---
|
||||
|
||||
## 📚 ドキュメント一覧
|
||||
|
||||
### 🎯 まず読むべきドキュメント
|
||||
|
||||
1. **[クイックリファレンス](./QUICK_REFERENCE.md)** ⭐ おすすめ
|
||||
- 1ページで全体像を把握
|
||||
- Before/After コード例
|
||||
- 今すぐ始められる実装手順
|
||||
|
||||
2. **[実行サマリー](./CLEANUP_SUMMARY_2025-11-06.md)**
|
||||
- エグゼクティブサマリー
|
||||
- 数値で見る重複の実態
|
||||
- Q&A
|
||||
|
||||
### 📖 詳細ドキュメント
|
||||
|
||||
3. **[詳細分析レポート](./DUPLICATION_ANALYSIS_REPORT.md)**
|
||||
- 9章構成の包括的分析
|
||||
- 全重複パターンの詳細
|
||||
- リスク評価と期待効果
|
||||
- 付録(ファイルサイズ一覧)
|
||||
|
||||
4. **[Phase 1実装ガイド](./PHASE1_IMPLEMENTATION_GUIDE.md)**
|
||||
- Step-by-Step実装手順
|
||||
- コピペで使えるコード例
|
||||
- テスト戦略
|
||||
- トラブルシューティング
|
||||
|
||||
---
|
||||
|
||||
## 🎯 調査結果サマリー
|
||||
|
||||
### 重複の規模
|
||||
- **総重複箇所**: 260箇所以上
|
||||
- **削減可能行数**: 500-800行(15-20%削減)
|
||||
- **優先対応**: Phase 1で270-380行削減可能
|
||||
|
||||
### 主要な重複パターン(Top 5)
|
||||
|
||||
| パターン | 箇所数 | 削減見込み | 優先度 |
|
||||
|---------|--------|----------|--------|
|
||||
| Destination書き込み | 49 | 150-200行 | ⭐⭐⭐ 最高 |
|
||||
| 引数検証 | 55 | 100-150行 | ⭐⭐ 高 |
|
||||
| エラー生成 | 95 | 200-300行 | ⭐⭐⭐ 最高 |
|
||||
| Receiver変換 | 5 | 20-30行 | ⭐⭐ 高 |
|
||||
| PHI挿入 | 13 | 50-100行 | ⭐ 中 |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 アクションプラン
|
||||
|
||||
### Phase 1: 即効対応(推奨: 即時実施)
|
||||
**目標**: 低リスク・高効果のヘルパー関数実装
|
||||
- **期間**: 5-8時間
|
||||
- **削減**: 270-380行
|
||||
- **リスク**: 低
|
||||
- **詳細**: [Phase 1実装ガイド](./PHASE1_IMPLEMENTATION_GUIDE.md)
|
||||
|
||||
**実装内容**:
|
||||
1. Destination書き込みヘルパー(`write_result`, `write_void` など)
|
||||
2. 引数検証ヘルパー(`validate_args_exact`, `validate_args_range`)
|
||||
3. Receiver変換ヘルパー(`convert_to_box`)
|
||||
|
||||
### Phase 2: 基盤整備(Phase 1完了後)
|
||||
**目標**: エラー処理とPHI挿入の統一
|
||||
- **期間**: 5-7時間
|
||||
- **削減**: 250-400行
|
||||
- **リスク**: 低
|
||||
|
||||
### Phase 3: 抜本改革(将来課題)
|
||||
**目標**: Box Handler群の統合
|
||||
- **期間**: 1-2週間
|
||||
- **削減**: 300-400行
|
||||
- **リスク**: 中-高
|
||||
|
||||
---
|
||||
|
||||
## 📈 期待される効果
|
||||
|
||||
### 定量的効果
|
||||
|
||||
```
|
||||
現状: 3,335行(Handlers)
|
||||
↓ Phase 1
|
||||
2,965行 (-11%, -370行)
|
||||
↓ Phase 2
|
||||
2,715行 (-19%, -620行)
|
||||
↓ Phase 3
|
||||
2,415行 (-28%, -920行)
|
||||
```
|
||||
|
||||
### 定性的効果
|
||||
- ✅ 保守性向上(変更が1箇所で完結)
|
||||
- ✅ 可読性向上(意図が明確な関数名)
|
||||
- ✅ バグ削減(共通ロジックの一元管理)
|
||||
- ✅ 開発速度向上(ボイラープレート削減)
|
||||
- ✅ テスト容易性(単体テストで広範囲カバー)
|
||||
|
||||
---
|
||||
|
||||
## 📂 対象ファイル
|
||||
|
||||
### MIR Interpreter Handlers(重複集中エリア)
|
||||
```
|
||||
src/backend/mir_interpreter/handlers/
|
||||
├── arithmetic.rs (136行)
|
||||
├── boxes.rs (307行) ← 重複多
|
||||
├── boxes_array.rs (63行) ← 重複多
|
||||
├── boxes_instance.rs (153行) ← 重複多
|
||||
├── boxes_map.rs (134行) ← 重複多
|
||||
├── boxes_object_fields.rs (399行) ← 重複多
|
||||
├── boxes_plugin.rs (217行) ← 重複多
|
||||
├── boxes_string.rs (208行) ← 重複多
|
||||
├── boxes_void_guards.rs (21行)
|
||||
├── call_resolution.rs (89行)
|
||||
├── calls.rs (907行) ← 最大ファイル
|
||||
├── extern_provider.rs (298行)
|
||||
├── externals.rs (218行)
|
||||
├── memory.rs (47行)
|
||||
├── misc.rs (31行)
|
||||
└── mod.rs (107行)
|
||||
|
||||
合計: 3,335行
|
||||
```
|
||||
|
||||
### 新規作成ファイル(Phase 1)
|
||||
```
|
||||
src/backend/mir_interpreter/utils/
|
||||
├── mod.rs
|
||||
├── register_ops.rs # Destination書き込み
|
||||
├── validation.rs # 引数検証
|
||||
└── conversions.rs # 型変換
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 実装のヒント
|
||||
|
||||
### Before/After 例
|
||||
|
||||
#### 例1: ArrayBox.push メソッド
|
||||
```rust
|
||||
// ❌ Before (6行)
|
||||
"push" => {
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
let val = this.reg_load(args[0])?.to_nyash_box();
|
||||
let _ = ab.push(val);
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::Void);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// ✅ After (4行, 33%削減)
|
||||
"push" => {
|
||||
this.validate_args_exact("push", args, 1)?;
|
||||
let val = this.reg_load(args[0])?.to_nyash_box();
|
||||
let _ = ab.push(val);
|
||||
this.write_void(dst);
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
### 実装の流れ
|
||||
1. ユーティリティ関数実装(1-2時間)
|
||||
2. 最小ファイルで試す(30分)
|
||||
3. 残りのファイルを順次更新(3-5時間)
|
||||
4. 検証&ドキュメント更新(1時間)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 確認コマンド
|
||||
|
||||
```bash
|
||||
# 重複パターン検索
|
||||
cd /home/tomoaki/git/hakorune-selfhost
|
||||
grep -rn "if let Some(d) = dst { this.regs.insert" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "args.len() !=" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "match recv.clone()" src/backend/mir_interpreter/handlers/
|
||||
|
||||
# ファイルサイズ確認
|
||||
wc -l src/backend/mir_interpreter/handlers/*.rs | sort -rn
|
||||
|
||||
# Phase 1実装後の検証
|
||||
./tools/jit_smoke.sh
|
||||
git diff --stat
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 進捗管理
|
||||
|
||||
### Phase 1チェックリスト
|
||||
|
||||
#### インフラ構築
|
||||
- [ ] `utils/` ディレクトリ作成
|
||||
- [ ] `register_ops.rs` 実装
|
||||
- [ ] `validation.rs` 実装
|
||||
- [ ] `conversions.rs` 実装
|
||||
- [ ] ユニットテスト追加
|
||||
- [ ] コンパイル&テスト確認
|
||||
|
||||
#### Handler更新(1ファイルずつ)
|
||||
- [ ] `boxes_array.rs` (63行 → 50行)
|
||||
- [ ] `boxes_map.rs` (134行 → 110行)
|
||||
- [ ] `boxes_string.rs` (208行 → 170行)
|
||||
- [ ] `boxes_plugin.rs` (217行 → 180行)
|
||||
- [ ] `boxes_instance.rs` (153行 → 125行)
|
||||
- [ ] `boxes_object_fields.rs` (399行 → 330行)
|
||||
- [ ] `boxes.rs` (307行 → 250行)
|
||||
- [ ] `calls.rs` (907行 → 750行)
|
||||
|
||||
#### 最終検証
|
||||
- [ ] 重複パターン残存確認
|
||||
- [ ] スモークテスト実行
|
||||
- [ ] ドキュメント更新
|
||||
- [ ] Phase 2計画
|
||||
|
||||
---
|
||||
|
||||
## 🎓 学んだこと
|
||||
|
||||
### 重複パターンの発見方法
|
||||
1. 同じようなコードブロックを探す(grep活用)
|
||||
2. 関数シグネチャの類似性をチェック
|
||||
3. エラーメッセージパターンを調査
|
||||
4. ファイルサイズ比較(大きいファイルは重複の宝庫)
|
||||
|
||||
### 効果的な共通化のポイント
|
||||
1. **小さく始める**: 最も単純なパターンから
|
||||
2. **段階的移行**: 一度に全部変えない
|
||||
3. **テストファースト**: ヘルパー関数のテストを先に
|
||||
4. **1ファイルずつ**: 都度テストして確実に
|
||||
|
||||
### リスク管理
|
||||
1. **並行期間**: 新旧コードを共存させる
|
||||
2. **回帰テスト**: 各変更後にスモークテスト
|
||||
3. **小さなPR**: レビュー負荷を軽減
|
||||
4. **ロールバック可能**: いつでも戻せる設計
|
||||
|
||||
---
|
||||
|
||||
## 📞 サポート
|
||||
|
||||
### 質問・相談
|
||||
- **実装で困ったら**: [Phase 1実装ガイド](./PHASE1_IMPLEMENTATION_GUIDE.md) のトラブルシューティングを参照
|
||||
- **全体像が知りたい**: [実行サマリー](./CLEANUP_SUMMARY_2025-11-06.md) を参照
|
||||
- **詳細な分析結果**: [詳細分析レポート](./DUPLICATION_ANALYSIS_REPORT.md) を参照
|
||||
|
||||
### 次のステップ
|
||||
1. [クイックリファレンス](./QUICK_REFERENCE.md) を読む(5分)
|
||||
2. [Phase 1実装ガイド](./PHASE1_IMPLEMENTATION_GUIDE.md) に従って実装開始(5-8時間)
|
||||
3. Phase 1完了後、Phase 2を計画
|
||||
|
||||
---
|
||||
|
||||
## 📅 履歴
|
||||
|
||||
- **2025-11-06**: 初版作成(Claude Code Agent による調査完了)
|
||||
- 重複パターン260箇所を特定
|
||||
- Phase 1-3のアクションプラン策定
|
||||
- 実装ガイド作成
|
||||
|
||||
---
|
||||
|
||||
## 📌 クイックリンク
|
||||
|
||||
### 今すぐ始める
|
||||
1. 📖 [クイックリファレンス](./QUICK_REFERENCE.md) - 1ページで全体把握
|
||||
2. 🔧 [Phase 1実装ガイド](./PHASE1_IMPLEMENTATION_GUIDE.md) - コピペで実装開始
|
||||
3. ✅ チェックリスト(上記の「Phase 1チェックリスト」)
|
||||
|
||||
### 詳細を知る
|
||||
4. 📊 [実行サマリー](./CLEANUP_SUMMARY_2025-11-06.md) - 数値と効果
|
||||
5. 📚 [詳細分析レポート](./DUPLICATION_ANALYSIS_REPORT.md) - 包括的分析
|
||||
|
||||
### 関連リソース(別プロジェクト)
|
||||
- [README.md](./README.md) - レガシーコード削除プロジェクト
|
||||
- [Phase 2レポート](./PHASE2_REPORT_2025-11-04.md) - 既存の整理作業
|
||||
|
||||
---
|
||||
|
||||
**次のアクション**: [クイックリファレンス](./QUICK_REFERENCE.md) を読んで、Phase 1実装を開始しましょう!🚀
|
||||
|
||||
**注意**: このドキュメントは「重複コード・共通化」に関する調査です。「レガシーコード削除」については [README.md](./README.md) を参照してください。
|
||||
191
docs/development/cleanup/EXECUTIVE_SUMMARY.md
Normal file
191
docs/development/cleanup/EXECUTIVE_SUMMARY.md
Normal file
@ -0,0 +1,191 @@
|
||||
# レガシーコード削除プロジェクト - エグゼクティブサマリー
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**調査対象**: Phase 21.0に向けたレガシーコード削除可能性
|
||||
|
||||
---
|
||||
|
||||
## 📊 調査結果サマリー
|
||||
|
||||
### 総削減見込み: **約9,500行** (全体の約10%)
|
||||
|
||||
| フェーズ | 削減行数 | リスク | 実施時期 | 状態 |
|
||||
|---------|---------|-------|---------|-----|
|
||||
| Phase A | 3,900行 | 無し | 今すぐ | ✅ 準備完了 |
|
||||
| Phase B | 2,200行 | 低 | 1週間 | 📋 調査必要 |
|
||||
| Phase C | 3,400行 | 中 | Phase 16 | ⏳ 戦略待ち |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 推奨アクション
|
||||
|
||||
### 即実行推奨 (Phase A)
|
||||
**今すぐ削除可能**: 約3,900行 (リスク無し)
|
||||
|
||||
1. **Cranelift/JIT削除** (1,500行)
|
||||
- Phase 15でアーカイブ済み
|
||||
- feature削除済み、ビルドエラーなし
|
||||
|
||||
2. **BID Copilotアーカイブ** (1,900行)
|
||||
- 未使用プロトタイプ
|
||||
- READMEで「現在は使用していない」と明記
|
||||
|
||||
3. **Dead Code削除** (500行)
|
||||
- `#[allow(dead_code)]`マーカー付き
|
||||
- 明確に未使用な関数
|
||||
|
||||
**実行時間**: 約10分
|
||||
**手順**: [クイック削除ガイド](./QUICK_CLEANUP_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
### 調査後実行 (Phase B)
|
||||
**1週間以内**: 約2,200行 (低リスク)
|
||||
|
||||
1. **JSON v1 Bridge** (734行)
|
||||
- 使用状況確認が必要
|
||||
- 未使用なら削除 or アーカイブ
|
||||
|
||||
2. **Legacy Test Files** (1,000行)
|
||||
- cranelift依存テストの整理
|
||||
- VM/LLVM比較として有用性評価
|
||||
|
||||
3. **Parser Dead Code** (500行)
|
||||
- 実使用確認後削除
|
||||
|
||||
**実行時間**: 約1週間 (調査含む)
|
||||
|
||||
---
|
||||
|
||||
### 戦略確定後実行 (Phase C)
|
||||
**Phase 16以降**: 約3,400行 (中リスク)
|
||||
|
||||
1. **WASM Backend** (3,170行)
|
||||
- Phase 21.0戦略次第
|
||||
- 動作確認後判断
|
||||
|
||||
2. **Builtin Box移行** (264行)
|
||||
- Phase 15.5-B完了後
|
||||
- プラグイン移行戦略に従う
|
||||
|
||||
---
|
||||
|
||||
## 📚 ドキュメント構成
|
||||
|
||||
### 1. [README.md](./README.md)
|
||||
**役割**: 入口・ナビゲーション
|
||||
|
||||
### 2. [レガシーコード調査レポート](./LEGACY_CODE_INVESTIGATION_REPORT.md)
|
||||
**役割**: 詳細調査結果・分析
|
||||
**対象**: プロジェクトマネージャー、意思決定者
|
||||
|
||||
### 3. [クイック削除ガイド](./QUICK_CLEANUP_GUIDE.md)
|
||||
**役割**: 実行マニュアル (コピペ可能)
|
||||
**対象**: 開発者 (実行担当者)
|
||||
|
||||
### 4. [詳細ファイルリスト](./LEGACY_FILES_DETAILED_LIST.md)
|
||||
**役割**: ファイル別完全リスト
|
||||
**対象**: 開発者 (詳細確認用)
|
||||
|
||||
---
|
||||
|
||||
## 💡 削除する理由
|
||||
|
||||
### 1. Phase 20.46完了
|
||||
開発の区切りが良く、次フェーズに集中できる
|
||||
|
||||
### 2. 保守性向上
|
||||
約10%のコード削減で可読性・保守性が向上
|
||||
|
||||
### 3. AI協働効率化
|
||||
レガシーコードがAIを混乱させる問題を解消
|
||||
|
||||
### 4. Phase 21.0準備
|
||||
クリーンなコードベースで次フェーズ開始
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 削除しない理由 (Phase C)
|
||||
|
||||
### WASM Backend (3,170行)
|
||||
- Phase 21.0でWASM対応の可能性
|
||||
- 動作確認後に判断
|
||||
|
||||
### Builtin Box (264行)
|
||||
- プラグイン移行戦略が確定していない
|
||||
- 削除するとコードが大量に壊れる
|
||||
|
||||
### PyVM (保持)
|
||||
- Phase 15セルフホスティングで現役使用中
|
||||
- JSON v0ブリッジ・using処理で必須
|
||||
|
||||
---
|
||||
|
||||
## 📈 削減効果
|
||||
|
||||
### コードベース削減
|
||||
- **Phase A**: 約3,900行 (約4%)
|
||||
- **Phase B**: 約2,200行 (約2%)
|
||||
- **Phase C**: 約3,400行 (約3.5%)
|
||||
- **合計**: 約9,500行 (約10%)
|
||||
|
||||
### 保守性向上
|
||||
- レガシーコード除去で可読性向上
|
||||
- AI協働時の混乱減少
|
||||
- ビルド時間微減
|
||||
|
||||
### リスク評価
|
||||
- **Phase A**: リスク無し (feature削除済み)
|
||||
- **Phase B**: 低リスク (調査後判断)
|
||||
- **Phase C**: 中リスク (戦略依存)
|
||||
|
||||
---
|
||||
|
||||
## ✅ 次のアクション
|
||||
|
||||
### 1. Phase A実行 (今すぐ)
|
||||
👉 [クイック削除ガイド](./QUICK_CLEANUP_GUIDE.md)
|
||||
|
||||
約10分で約3,900行削除可能
|
||||
|
||||
### 2. Phase B調査 (1週間以内)
|
||||
👉 [詳細ファイルリスト](./LEGACY_FILES_DETAILED_LIST.md)
|
||||
|
||||
使用状況確認・削除判断
|
||||
|
||||
### 3. Phase C戦略確認 (Phase 16)
|
||||
👉 [レガシーコード調査レポート](./LEGACY_CODE_INVESTIGATION_REPORT.md)
|
||||
|
||||
Phase 21.0戦略に従う
|
||||
|
||||
---
|
||||
|
||||
## 📝 コミットメッセージ例
|
||||
|
||||
```
|
||||
chore: Remove legacy Cranelift/JIT code and BID Copilot prototype
|
||||
|
||||
- Remove Cranelift/JIT backend (archived in Phase 15)
|
||||
* src/runner/modes/cranelift.rs (46 lines)
|
||||
* src/runner/jit_direct.rs (~200 lines)
|
||||
* src/tests/core13_smoke_jit*.rs (2 files)
|
||||
* Related references in backend/mod.rs, cli/args.rs
|
||||
|
||||
- Archive BID Copilot modules (unused prototype)
|
||||
* src/bid-codegen-from-copilot/ → archive/
|
||||
* src/bid-converter-copilot/ → archive/
|
||||
|
||||
- Delete dead code
|
||||
* src/mir/builder/exprs_legacy.rs
|
||||
* Multiple #[allow(dead_code)] functions
|
||||
|
||||
Total reduction: ~3,900 lines (~4%)
|
||||
|
||||
Refs: docs/development/cleanup/LEGACY_CODE_INVESTIGATION_REPORT.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**作成者**: Claude Code
|
||||
**最終更新**: 2025-11-06
|
||||
**推奨アクション**: Phase A実行 (今すぐ)
|
||||
492
docs/development/cleanup/LEGACY_CODE_INVESTIGATION_REPORT.md
Normal file
492
docs/development/cleanup/LEGACY_CODE_INVESTIGATION_REPORT.md
Normal file
@ -0,0 +1,492 @@
|
||||
# Hakorune Legacy Code Investigation Report
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**Phase**: 20.46 (Phase 21.0完成後)
|
||||
**調査対象**: 削除可能なレガシーコード、デッドコード、不要な機能
|
||||
|
||||
---
|
||||
|
||||
## 📊 Executive Summary
|
||||
|
||||
- **総Rustファイル数**: 618ファイル
|
||||
- **#[allow(dead_code)]**: 76箇所
|
||||
- **レガシーコード推定**: 約10,000行 (全体の約10%)
|
||||
- **削除推奨**: 約5,000〜7,000行 (段階的削除)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 カテゴリ別分析
|
||||
|
||||
### 1. ⚠️ Cranelift/JITバックエンド (高優先度・Safe削除)
|
||||
|
||||
**状態**: Phase 15でアーカイブ済み (`archive/jit-cranelift/`)
|
||||
**問題**: 本体コードに参照が残存
|
||||
|
||||
#### 影響範囲
|
||||
- **参照ファイル数**: 27ファイル
|
||||
- **feature gate**: `cranelift-jit` (Cargo.tomlで既にコメントアウト済み)
|
||||
- **推定削除可能行数**: 約1,500〜2,000行
|
||||
|
||||
#### 主要ファイル
|
||||
|
||||
##### 削除推奨 (Safe)
|
||||
```
|
||||
src/runner/modes/cranelift.rs (46行) - Safe削除
|
||||
src/runner/modes/aot.rs (66行) - Safe削除 (cranelift feature依存)
|
||||
src/runner/jit_direct.rs (推定200行) - Safe削除
|
||||
|
||||
src/tests/core13_smoke_jit.rs (約100行) - Safe削除
|
||||
src/tests/core13_smoke_jit_map.rs (約100行) - Safe削除
|
||||
src/tests/identical_exec*.rs (7ファイル) - feature gateで無効化済み
|
||||
src/tests/policy_mutdeny.rs (206行) - 一部cranelift依存
|
||||
```
|
||||
|
||||
##### 要検証 (Investigate)
|
||||
```
|
||||
src/backend/mod.rs:29-52 - cranelift再エクスポート (削除可能)
|
||||
src/backend/aot/ - AOTコンパイル機能 (WASM依存, 要確認)
|
||||
src/runner/dispatch.rs - cranelift分岐 (削除可能)
|
||||
src/cli/args.rs - --backend cranelift オプション (削除可能)
|
||||
```
|
||||
|
||||
#### 推奨アクション
|
||||
1. **Phase 1**: feature gate確認・テストファイル削除 (Safe, 約500行)
|
||||
2. **Phase 2**: runner/modesのcranelift.rs削除 (Safe, 約200行)
|
||||
3. **Phase 3**: backend/mod.rs再エクスポート削除 (Safe, 約30行)
|
||||
4. **Phase 4**: 残存参照の完全削除 (要テスト, 約1,000行)
|
||||
|
||||
**削除時影響**: 無し (feature既に削除済み、ビルドエラーなし)
|
||||
|
||||
---
|
||||
|
||||
### 2. 🌐 WASMバックエンド (低優先度・要確認)
|
||||
|
||||
**状態**: Feature-gated (`wasm-backend`), 使用頻度不明
|
||||
|
||||
#### 影響範囲
|
||||
- **ディレクトリ**: `src/backend/wasm/`, `src/backend/wasm_v2/`, `src/backend/aot/`
|
||||
- **総行数**: 約3,170行
|
||||
- **ディスクサイズ**: 140KB
|
||||
- **参照ファイル数**: 8ファイル
|
||||
|
||||
#### 主要ファイル
|
||||
```
|
||||
src/backend/wasm/codegen.rs (851行)
|
||||
src/backend/wasm/memory.rs (426行)
|
||||
src/backend/wasm/runtime.rs (369行)
|
||||
src/backend/aot/executable.rs (301行)
|
||||
src/backend/wasm_v2/* (約250行)
|
||||
```
|
||||
|
||||
#### 判定: **Risky** - 現時点では保持推奨
|
||||
|
||||
**理由**:
|
||||
- CLAUDE.mdで「⚠️ WASM機能: レガシーインタープリター削除により一時無効」と記載
|
||||
- 将来的なWASM対応の可能性あり
|
||||
- Phase 21.0完成後の方針次第
|
||||
|
||||
**推奨アクション**:
|
||||
1. 使用状況調査 (WASMバックエンド実際に動作するか?)
|
||||
2. 動作しない場合: `archive/wasm-backend/`に移動
|
||||
3. 動作する場合: ドキュメント整備・テスト追加
|
||||
|
||||
---
|
||||
|
||||
### 3. 🗂️ BID Copilot Modules (中優先度・Safe削除)
|
||||
|
||||
**状態**: 未使用プロトタイプ (READMEで「現在は使用していない」と明記)
|
||||
|
||||
#### 影響範囲
|
||||
- **ディレクトリ**: `src/bid-codegen-from-copilot/`, `src/bid-converter-copilot/`
|
||||
- **総行数**: 約1,894行
|
||||
- **ディスクサイズ**: 124KB
|
||||
- **総ファイル数**: 13ファイル
|
||||
|
||||
#### 詳細
|
||||
|
||||
##### bid-codegen-from-copilot/ (88KB, 9ファイル)
|
||||
```
|
||||
schema.rs (約300行)
|
||||
codegen/generator.rs (推定500行)
|
||||
codegen/targets/wasm.rs (詳細実装)
|
||||
codegen/targets/{vm,llvm,python,ts}.rs (スタブ)
|
||||
```
|
||||
|
||||
**用途**: 将来的なプラグイン多言語対応
|
||||
**判定**: **Safe削除** - `archive/bid-copilot-prototype/`に移動
|
||||
|
||||
##### bid-converter-copilot/ (36KB, 4ファイル)
|
||||
```
|
||||
tlv.rs (TLVエンコード/デコード)
|
||||
types.rs (BID型定義)
|
||||
error.rs (BIDエラー型)
|
||||
```
|
||||
|
||||
**用途**: 将来的なnyash2.toml実装時に活用予定
|
||||
**判定**: **Safe削除** - 汎用性高いが現在未使用、`archive/bid-converter/`に移動
|
||||
|
||||
#### 推奨アクション
|
||||
1. **Phase 1**: `archive/bid-copilot-prototype/`にディレクトリごと移動
|
||||
2. **Phase 2**: `src/lib.rs`のコメント削除 (現在はモジュール宣言なし)
|
||||
3. **影響**: 無し (既に未使用、インポート0)
|
||||
|
||||
**削減見込み**: 約1,900行
|
||||
|
||||
---
|
||||
|
||||
### 4. 📄 JSON v1 Bridge (中優先度・要確認)
|
||||
|
||||
**状態**: 使用状況不明
|
||||
|
||||
#### 影響範囲
|
||||
- **ファイル**: `src/runner/json_v1_bridge.rs` (734行)
|
||||
- **#[allow(dead_code)]**: `try_parse_v1_to_module()` 関数
|
||||
|
||||
#### コード抜粋
|
||||
```rust
|
||||
#[allow(dead_code)]
|
||||
pub fn try_parse_v1_to_module(json: &str) -> Result<Option<MirModule>, String> {
|
||||
// MIR JSON v1スキーマパース
|
||||
// 最小限のサポート: const, copy, ret
|
||||
}
|
||||
```
|
||||
|
||||
#### 判定: **Investigate** - 使用確認が必要
|
||||
|
||||
**調査項目**:
|
||||
1. JSON v1を出力するコードは存在するか?
|
||||
2. テストで使用されているか?
|
||||
3. JSON v0 bridgeで代替可能か?
|
||||
|
||||
**推奨アクション**:
|
||||
1. **Phase 1**: 使用状況調査 (grep検索・テスト実行)
|
||||
2. **Phase 2**: 未使用なら`archive/json-v1-bridge.rs`に移動
|
||||
3. **Phase 3**: 使用中なら機能追加 or ドキュメント整備
|
||||
|
||||
**削減見込み**: 約700行 (未使用の場合)
|
||||
|
||||
---
|
||||
|
||||
### 5. 🔧 #[allow(dead_code)] マーカー (高優先度・段階削除)
|
||||
|
||||
**状態**: 76箇所存在
|
||||
|
||||
#### 主要カテゴリ
|
||||
|
||||
##### PyVM/JSON v0 Bridge (保持推奨)
|
||||
```
|
||||
src/runner/modes/common_util/pyvm.rs - PyVMハーネス (セルフホスト専用)
|
||||
src/runner/modes/common_util/exec.rs - 実行ユーティリティ
|
||||
```
|
||||
**判定**: **保持** - Phase 15セルフホスティングで使用中
|
||||
|
||||
##### Legacy Expression/Type Check
|
||||
```
|
||||
src/mir/builder/exprs_legacy.rs:6 - build_expression_impl_legacy()
|
||||
src/mir/verification/legacy.rs:6 - check_no_legacy_ops()
|
||||
src/mir/builder/utils.rs - 旧型チェック関数
|
||||
```
|
||||
**判定**: **Safe削除** - Phase 15でCore-13/14/15に統一済み
|
||||
|
||||
##### Parser関連
|
||||
```
|
||||
src/parser/common.rs - unknown_span() 等
|
||||
src/parser/sugar.rs - 旧シュガー構文
|
||||
src/parser/declarations/*/validators.rs - 古いバリデーター
|
||||
```
|
||||
**判定**: **Investigate** - 実際の使用状況確認が必要
|
||||
|
||||
##### Box Factory Deprecated
|
||||
```
|
||||
src/box_factory/builtin_impls/*.rs - 18箇所のDEPRECATEDマーカー
|
||||
```
|
||||
**判定**: **Risky** - プラグイン移行戦略次第 (後述)
|
||||
|
||||
#### 推奨アクション
|
||||
1. **Phase 1**: 明確に未使用な関数削除 (約20箇所, Safe)
|
||||
2. **Phase 2**: Legacy MIR関連削除 (約10箇所, Safe)
|
||||
3. **Phase 3**: Parser関連の実使用確認・削除 (約15箇所, Investigate)
|
||||
4. **Phase 4**: 残存コードのリファクタリング (約30箇所, Risky)
|
||||
|
||||
**削減見込み**: 約500〜1,000行
|
||||
|
||||
---
|
||||
|
||||
### 6. ⚠️ Builtin Box DEPRECATED (低優先度・Phase戦略依存)
|
||||
|
||||
**状態**: プラグイン移行計画中
|
||||
|
||||
#### 影響範囲
|
||||
- **ディレクトリ**: `src/box_factory/builtin_impls/`
|
||||
- **総行数**: 約264行
|
||||
- **DEPRECATEDマーカー**: 18箇所
|
||||
|
||||
#### 対象Box
|
||||
```
|
||||
console_box.rs - ⚠️ nyash-console-plugin推奨 (既存)
|
||||
string_box.rs - ⚠️ nyash-string-plugin推奨
|
||||
array_box.rs - ⚠️ nyash-array-plugin推奨
|
||||
bool_box.rs - ⚠️ nyash-bool-plugin推奨 (未作成)
|
||||
integer_box.rs - ⚠️ nyash-integer-plugin推奨
|
||||
map_box.rs - ⚠️ nyash-map-plugin推奨
|
||||
```
|
||||
|
||||
#### 判定: **Risky** - Phase 15.5-B戦略次第
|
||||
|
||||
**理由**:
|
||||
- CLAUDE.mdで「2本柱体制: Core Box統一化完了」と記載
|
||||
- プラグイン移行は段階的実施中
|
||||
- 削除すると既存コードが大量に壊れる可能性
|
||||
|
||||
**推奨アクション**:
|
||||
1. **現状**: DEPRECATEDマーカーは保持
|
||||
2. **Phase 15.5-B完了後**: プラグイン移行状況確認
|
||||
3. **Phase 16**: builtin→plugin完全移行計画策定
|
||||
4. **Phase 17**: builtinコード削除
|
||||
|
||||
**削減見込み**: 約200〜300行 (Phase 16以降)
|
||||
|
||||
---
|
||||
|
||||
### 7. 🧪 Legacy Test Files (中優先度・Safe削除)
|
||||
|
||||
**状態**: Feature-gatedで無効化済み
|
||||
|
||||
#### 影響範囲
|
||||
- **総数**: 7ファイル (cranelift依存)
|
||||
- **推定行数**: 約1,000〜1,500行
|
||||
|
||||
#### 主要ファイル
|
||||
```
|
||||
src/tests/core13_smoke_jit.rs (#[cfg(feature = "cranelift-jit")])
|
||||
src/tests/core13_smoke_jit_map.rs (#[cfg(feature = "cranelift-jit")])
|
||||
src/tests/identical_exec.rs (一部cranelift依存)
|
||||
src/tests/identical_exec_collections.rs
|
||||
src/tests/identical_exec_instance.rs
|
||||
src/tests/identical_exec_string.rs
|
||||
src/tests/policy_mutdeny.rs (206行, 一部cranelift)
|
||||
```
|
||||
|
||||
#### 判定: **Safe削除** - feature削除済み
|
||||
|
||||
**推奨アクション**:
|
||||
1. **Phase 1**: cranelift feature完全依存ファイル削除 (5ファイル)
|
||||
2. **Phase 2**: identical_exec系の整理 (4ファイル, 一部保持?)
|
||||
3. **Phase 3**: policy_mutdeny.rsの分割 (cranelift部分のみ削除)
|
||||
|
||||
**削減見込み**: 約1,000行
|
||||
|
||||
---
|
||||
|
||||
### 8. 🐍 PyVM References (保持推奨)
|
||||
|
||||
**状態**: JSON v0 Bridge・セルフホスト専用
|
||||
|
||||
#### 影響範囲
|
||||
- **参照数**: 102箇所
|
||||
- **主要用途**: Phase 15セルフホスティング
|
||||
|
||||
#### 主要ファイル
|
||||
```
|
||||
src/runner/modes/pyvm.rs - PyVM実行モード
|
||||
src/runner/json_v0_bridge/ - JSON v0→MIR変換
|
||||
src/llvm_py/pyvm/ - Python VM実装
|
||||
```
|
||||
|
||||
#### 判定: **保持** - Phase 15現役使用中
|
||||
|
||||
**理由**:
|
||||
- CLAUDE.mdで「PyVM特化保持 (JSON v0ブリッジ・using処理のみ)」と明記
|
||||
- Phase 15.5-Bセルフホスティング実装で必須
|
||||
- 削除不可
|
||||
|
||||
**推奨アクション**: なし (現状維持)
|
||||
|
||||
---
|
||||
|
||||
## 📈 削減見込みサマリー
|
||||
|
||||
| カテゴリ | 推定行数 | 削除難易度 | 優先度 | 削減見込み |
|
||||
|---------|---------|-----------|-------|----------|
|
||||
| Cranelift/JIT | 1,500〜2,000行 | Safe | 高 | 1,500行 |
|
||||
| WASM Backend | 3,170行 | Risky | 低 | 0行 (保持) |
|
||||
| BID Copilot | 1,894行 | Safe | 中 | 1,900行 |
|
||||
| JSON v1 Bridge | 734行 | Investigate | 中 | 700行? |
|
||||
| #[allow(dead_code)] | 500〜1,000行 | Mixed | 高 | 500行 |
|
||||
| Builtin Box | 264行 | Risky | 低 | 0行 (Phase 16) |
|
||||
| Legacy Tests | 1,000行 | Safe | 中 | 1,000行 |
|
||||
| PyVM | N/A | N/A | N/A | 0行 (保持) |
|
||||
| **合計** | **約9,000行** | - | - | **約5,600行** |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 段階的削除計画
|
||||
|
||||
### Phase A: 安全削除 (即実行可能)
|
||||
**推定削減**: 約2,500行
|
||||
|
||||
1. **Cranelift JITファイル削除**
|
||||
- `src/runner/modes/cranelift.rs`
|
||||
- `src/runner/jit_direct.rs`
|
||||
- `src/tests/core13_smoke_jit*.rs` (2ファイル)
|
||||
|
||||
2. **BID Copilotアーカイブ**
|
||||
- `src/bid-codegen-from-copilot/` → `archive/`
|
||||
- `src/bid-converter-copilot/` → `archive/`
|
||||
|
||||
3. **明確なDead Code削除**
|
||||
- `#[allow(dead_code)]`で未使用確認済み関数 (約20箇所)
|
||||
|
||||
**リスク**: 無し (feature削除済み、未使用コード)
|
||||
|
||||
### Phase B: 調査後削除 (1週間)
|
||||
**推定削減**: 約1,500行
|
||||
|
||||
1. **JSON v1 Bridge調査**
|
||||
- 使用状況確認 (grep + テスト実行)
|
||||
- 未使用なら削除 or アーカイブ
|
||||
|
||||
2. **Legacy Test Files整理**
|
||||
- `identical_exec*.rs` 系統の再評価
|
||||
- cranelift依存部分の削除
|
||||
|
||||
3. **Parser関連Dead Code**
|
||||
- 実使用確認後、未使用関数削除
|
||||
|
||||
**リスク**: 低 (調査後判断)
|
||||
|
||||
### Phase C: 段階的削除 (Phase 16以降)
|
||||
**推定削減**: 約1,600行
|
||||
|
||||
1. **WASM Backend評価**
|
||||
- 動作確認 → 動作しないならアーカイブ
|
||||
|
||||
2. **Builtin Box移行**
|
||||
- Phase 15.5-B完了後
|
||||
- プラグイン移行戦略確定後
|
||||
|
||||
**リスク**: 中 (Phase戦略依存)
|
||||
|
||||
---
|
||||
|
||||
## 🚨 削除時の注意点
|
||||
|
||||
### 1. Feature Gate確認
|
||||
```bash
|
||||
# 削除前に必ず確認
|
||||
cargo build --release # デフォルト
|
||||
cargo build --release --features llvm # LLVM
|
||||
cargo test # テスト通過確認
|
||||
```
|
||||
|
||||
### 2. Archive戦略
|
||||
削除ではなく **アーカイブ** を推奨:
|
||||
```
|
||||
archive/
|
||||
├── jit-cranelift/ (既存)
|
||||
├── bid-copilot-prototype/ (新規)
|
||||
├── bid-converter/ (新規)
|
||||
├── json-v1-bridge/ (新規)
|
||||
└── wasm-backend/ (Phase C)
|
||||
```
|
||||
|
||||
### 3. Git履歴保持
|
||||
```bash
|
||||
# ファイル削除時はgit mvを使用 (履歴保持)
|
||||
git mv src/runner/modes/cranelift.rs archive/jit-cranelift/runner_modes_cranelift.rs
|
||||
```
|
||||
|
||||
### 4. ドキュメント更新
|
||||
- CLAUDE.md
|
||||
- README.md
|
||||
- 削除理由を CHANGELOG.md に記録
|
||||
|
||||
---
|
||||
|
||||
## 📋 推奨実行順序
|
||||
|
||||
### 今すぐ実行 (Safe削除)
|
||||
```bash
|
||||
# 1. Cranelift JIT削除
|
||||
rm src/runner/modes/cranelift.rs
|
||||
rm src/runner/jit_direct.rs
|
||||
rm src/tests/core13_smoke_jit*.rs
|
||||
|
||||
# 2. BID Copilotアーカイブ
|
||||
mkdir -p archive/bid-copilot-prototype
|
||||
git mv src/bid-codegen-from-copilot archive/bid-copilot-prototype/
|
||||
git mv src/bid-converter-copilot archive/bid-copilot-prototype/
|
||||
|
||||
# 3. ビルド確認
|
||||
cargo build --release
|
||||
cargo test
|
||||
```
|
||||
|
||||
### 1週間以内 (調査後削除)
|
||||
1. JSON v1 Bridge使用状況調査
|
||||
2. Legacy Test Files整理
|
||||
3. Parser Dead Code削除
|
||||
|
||||
### Phase 16以降 (戦略確定後)
|
||||
1. WASM Backend評価・アーカイブ
|
||||
2. Builtin Box→Plugin完全移行
|
||||
3. 残存Legacy MIR削除
|
||||
|
||||
---
|
||||
|
||||
## 📊 Impact Analysis
|
||||
|
||||
### 削除後の効果
|
||||
- **コードベース削減**: 約5,600行 (約6%)
|
||||
- **保守性向上**: レガシーコード除去で可読性向上
|
||||
- **ビルド時間短縮**: 未使用コード削除で微減
|
||||
- **Phase 15集中**: セルフホスティング開発に集中可能
|
||||
|
||||
### リスク評価
|
||||
- **Phase A (Safe削除)**: リスク無し
|
||||
- **Phase B (調査後削除)**: 低リスク
|
||||
- **Phase C (Phase 16以降)**: 中リスク (戦略依存)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 補足調査項目
|
||||
|
||||
### 1. 追加調査が必要な項目
|
||||
- [ ] JSON v1 Bridgeの実使用確認
|
||||
- [ ] WASM Backendの動作確認
|
||||
- [ ] identical_exec系テストの保持必要性
|
||||
- [ ] Parser関連Dead Codeの実使用状況
|
||||
|
||||
### 2. 今回調査対象外
|
||||
- `crates/`ディレクトリ (別途調査推奨)
|
||||
- `apps/`ディレクトリ (スクリプト例・テストケース)
|
||||
- `tools/`ディレクトリ (ビルドスクリプト)
|
||||
- Pythonコード (`src/llvm_py/`)
|
||||
|
||||
---
|
||||
|
||||
## 📝 結論
|
||||
|
||||
### 即実行推奨
|
||||
✅ **Cranelift/JIT削除** (1,500行, Safe)
|
||||
✅ **BID Copilotアーカイブ** (1,900行, Safe)
|
||||
✅ **明確なDead Code削除** (500行, Safe)
|
||||
|
||||
**合計削減見込み**: 約3,900行 (即実行可能)
|
||||
|
||||
### 段階的実施
|
||||
🔍 **JSON v1 Bridge調査** (700行?, 1週間)
|
||||
🔍 **Legacy Test Files整理** (1,000行, 1週間)
|
||||
⏳ **WASM Backend評価** (3,170行, Phase C)
|
||||
⏳ **Builtin Box移行** (264行, Phase 16)
|
||||
|
||||
**追加削減見込み**: 約1,700〜5,000行 (段階的)
|
||||
|
||||
### 総削減見込み
|
||||
**5,600〜8,900行** (6〜9%) の削減が可能
|
||||
|
||||
---
|
||||
|
||||
**調査担当**: Claude Code
|
||||
**次のアクション**: Phase A (Safe削除) の実行
|
||||
|
||||
278
docs/development/cleanup/LEGACY_FILES_DETAILED_LIST.md
Normal file
278
docs/development/cleanup/LEGACY_FILES_DETAILED_LIST.md
Normal file
@ -0,0 +1,278 @@
|
||||
# レガシーファイル詳細リスト
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**分類基準**: Safe / Investigate / Risky
|
||||
|
||||
---
|
||||
|
||||
## 🟢 Safe削除 (即実行可能)
|
||||
|
||||
### Cranelift/JIT Backend
|
||||
|
||||
#### Runner Modes
|
||||
| ファイル | 行数 | 理由 |
|
||||
|---------|-----|------|
|
||||
| `src/runner/modes/cranelift.rs` | 46 | feature削除済み |
|
||||
| `src/runner/modes/aot.rs` | 66 | cranelift依存 |
|
||||
| `src/runner/jit_direct.rs` | ~200 | JIT直接実行 (アーカイブ済み) |
|
||||
|
||||
#### Tests
|
||||
| ファイル | 行数 | 理由 |
|
||||
|---------|-----|------|
|
||||
| `src/tests/core13_smoke_jit.rs` | ~100 | #[cfg(feature = "cranelift-jit")] |
|
||||
| `src/tests/core13_smoke_jit_map.rs` | ~100 | #[cfg(feature = "cranelift-jit")] |
|
||||
|
||||
#### Backend Module
|
||||
| ファイル | 削除箇所 | 理由 |
|
||||
|---------|---------|------|
|
||||
| `src/backend/mod.rs` | 29-52行 | cranelift再エクスポート |
|
||||
|
||||
#### CLI/Runner
|
||||
| ファイル | 削除箇所 | 理由 |
|
||||
|---------|---------|------|
|
||||
| `src/cli/args.rs` | --backend cranelift | オプション削除 |
|
||||
| `src/runner/dispatch.rs` | cranelift分岐 | 実行経路削除 |
|
||||
| `src/runner/modes/mod.rs` | aot module | feature依存 |
|
||||
|
||||
---
|
||||
|
||||
### BID Copilot Modules (アーカイブ推奨)
|
||||
|
||||
#### bid-codegen-from-copilot/ (88KB, 9ファイル)
|
||||
```
|
||||
src/bid-codegen-from-copilot/
|
||||
├── README.md (39行)
|
||||
├── schema.rs (~300行)
|
||||
└── codegen/
|
||||
├── mod.rs (~50行)
|
||||
├── generator.rs (~500行)
|
||||
└── targets/
|
||||
├── mod.rs (~30行)
|
||||
├── vm.rs (~150行)
|
||||
├── wasm.rs (~400行)
|
||||
├── llvm.rs (~100行, スタブ)
|
||||
├── python.rs (~100行, スタブ)
|
||||
└── typescript.rs (~100行, スタブ)
|
||||
```
|
||||
|
||||
**移動先**: `archive/bid-copilot-prototype/bid-codegen-from-copilot/`
|
||||
|
||||
#### bid-converter-copilot/ (36KB, 4ファイル)
|
||||
```
|
||||
src/bid-converter-copilot/
|
||||
├── README.md (29行)
|
||||
├── mod.rs (~20行)
|
||||
├── tlv.rs (~400行)
|
||||
├── types.rs (~300行)
|
||||
└── error.rs (~100行)
|
||||
```
|
||||
|
||||
**移動先**: `archive/bid-copilot-prototype/bid-converter-copilot/`
|
||||
|
||||
---
|
||||
|
||||
### Legacy MIR Builder
|
||||
|
||||
| ファイル | 削除対象 | 理由 |
|
||||
|---------|---------|------|
|
||||
| `src/mir/builder/exprs_legacy.rs` | 全体 (~150行) | Phase 15でCore-13/14/15に統一済み |
|
||||
| `src/mir/builder.rs` | `mod exprs_legacy;` 宣言 | モジュール参照削除 |
|
||||
| `src/mir/builder.rs` | `build_expression_impl_legacy()` 呼び出し | 関数呼び出し削除 |
|
||||
|
||||
---
|
||||
|
||||
### Dead Code (明確に未使用)
|
||||
|
||||
| ファイル | 関数/構造体 | 行数 | 理由 |
|
||||
|---------|-----------|-----|------|
|
||||
| `src/runner/json_v1_bridge.rs` | `try_parse_v1_to_module()` | ~700 | #[allow(dead_code)] |
|
||||
| `src/runner/trace.rs` | `cli_verbose()` | ~10 | #[allow(dead_code)] |
|
||||
| `src/runner/box_index.rs` | `get_plugin_meta()` | ~20 | #[allow(dead_code)] |
|
||||
| `src/parser/common.rs` | `unknown_span()` | ~10 | #[allow(dead_code)] |
|
||||
|
||||
---
|
||||
|
||||
## 🟡 Investigate (調査が必要)
|
||||
|
||||
### JSON v1 Bridge
|
||||
|
||||
| ファイル | 行数 | 調査項目 |
|
||||
|---------|-----|---------|
|
||||
| `src/runner/json_v1_bridge.rs` | 734 | 使用状況確認・JSON v1出力コードの有無 |
|
||||
|
||||
**調査コマンド**:
|
||||
```bash
|
||||
# JSON v1使用確認
|
||||
grep -r "json_v1_bridge\|try_parse_v1_to_module" src --include="*.rs"
|
||||
grep -r "schema_version.*1" apps --include="*.json"
|
||||
|
||||
# テスト実行
|
||||
cargo test json_v1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Legacy Test Files
|
||||
|
||||
| ファイル | 行数 | 調査項目 |
|
||||
|---------|-----|---------|
|
||||
| `src/tests/identical_exec.rs` | ~300 | cranelift依存部分の分離可能性 |
|
||||
| `src/tests/identical_exec_collections.rs` | 199 | 同上 |
|
||||
| `src/tests/identical_exec_instance.rs` | 175 | 同上 |
|
||||
| `src/tests/identical_exec_string.rs` | ~150 | 同上 |
|
||||
| `src/tests/policy_mutdeny.rs` | 206 | 一部cranelift依存 (分割可能?) |
|
||||
|
||||
**調査項目**:
|
||||
1. cranelift依存部分の特定
|
||||
2. VM/LLVM比較テストとして有用か?
|
||||
3. 分割 or 完全削除の判断
|
||||
|
||||
---
|
||||
|
||||
### Parser Dead Code
|
||||
|
||||
| ファイル | 関数 | 調査項目 |
|
||||
|---------|-----|---------|
|
||||
| `src/parser/sugar.rs` | 複数関数 | 実使用確認 |
|
||||
| `src/parser/declarations/*/validators.rs` | バリデーター関数 | 実使用確認 |
|
||||
|
||||
**調査コマンド**:
|
||||
```bash
|
||||
# 各関数の使用確認
|
||||
grep -r "関数名" src --include="*.rs" | grep -v "^Binary\|def\|fn "
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔴 Risky (Phase戦略依存)
|
||||
|
||||
### WASM Backend
|
||||
|
||||
#### ディレクトリ構造
|
||||
```
|
||||
src/backend/
|
||||
├── wasm/ (84KB)
|
||||
│ ├── codegen.rs (851行)
|
||||
│ ├── memory.rs (426行)
|
||||
│ ├── runtime.rs (369行)
|
||||
│ ├── host.rs (~200行)
|
||||
│ └── mod.rs (~50行)
|
||||
├── wasm_v2/ (16KB)
|
||||
│ ├── mod.rs (~50行)
|
||||
│ ├── unified_dispatch.rs (~100行)
|
||||
│ └── vtable_codegen.rs (~100行)
|
||||
└── aot/ (40KB)
|
||||
├── compiler.rs (~200行)
|
||||
├── config.rs (~100行)
|
||||
├── executable.rs (301行)
|
||||
└── mod.rs (~50行)
|
||||
```
|
||||
|
||||
**総行数**: 約3,170行
|
||||
**判定**: Phase 21.0完成後に評価
|
||||
|
||||
**調査項目**:
|
||||
1. WASM backendは実際に動作するか?
|
||||
2. Phase 21.0でWASM対応の計画はあるか?
|
||||
3. 動作しない場合: アーカイブ推奨
|
||||
|
||||
---
|
||||
|
||||
### Builtin Box DEPRECATED
|
||||
|
||||
| ファイル | DEPRECATEDマーカー | 行数 | Plugin状態 |
|
||||
|---------|------------------|-----|-----------|
|
||||
| `src/box_factory/builtin_impls/console_box.rs` | 3箇所 | ~40 | nyash-console-plugin (既存) |
|
||||
| `src/box_factory/builtin_impls/string_box.rs` | 3箇所 | ~50 | nyash-string-plugin (未?) |
|
||||
| `src/box_factory/builtin_impls/array_box.rs` | 3箇所 | ~45 | nyash-array-plugin (未?) |
|
||||
| `src/box_factory/builtin_impls/bool_box.rs` | 3箇所 | ~35 | nyash-bool-plugin (未作成) |
|
||||
| `src/box_factory/builtin_impls/integer_box.rs` | 3箇所 | ~40 | nyash-integer-plugin (未?) |
|
||||
| `src/box_factory/builtin_impls/map_box.rs` | 3箇所 | ~54 | nyash-map-plugin (未?) |
|
||||
|
||||
**総行数**: 約264行
|
||||
**判定**: Phase 15.5-B完了後にプラグイン移行戦略確定
|
||||
|
||||
**Phase 16計画**:
|
||||
1. 各Pluginの実装状況確認
|
||||
2. Builtin→Plugin完全移行
|
||||
3. Builtinコード削除
|
||||
|
||||
---
|
||||
|
||||
## 📊 サマリー
|
||||
|
||||
### Safe削除 (即実行可能)
|
||||
| カテゴリ | ファイル数 | 行数 |
|
||||
|---------|----------|-----|
|
||||
| Cranelift/JIT | 8ファイル | ~1,500行 |
|
||||
| BID Copilot | 13ファイル | ~1,900行 |
|
||||
| Dead Code | 4関数 | ~500行 |
|
||||
| **合計** | **25+** | **~3,900行** |
|
||||
|
||||
### Investigate (調査後削除)
|
||||
| カテゴリ | ファイル数 | 行数 |
|
||||
|---------|----------|-----|
|
||||
| JSON v1 Bridge | 1ファイル | 734行 |
|
||||
| Legacy Tests | 5ファイル | ~1,000行 |
|
||||
| Parser Dead Code | 複数 | ~500行 |
|
||||
| **合計** | **7+** | **~2,200行** |
|
||||
|
||||
### Risky (Phase戦略依存)
|
||||
| カテゴリ | ファイル数 | 行数 |
|
||||
|---------|----------|-----|
|
||||
| WASM Backend | 12ファイル | 3,170行 |
|
||||
| Builtin Box | 6ファイル | 264行 |
|
||||
| **合計** | **18** | **3,434行** |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 削除優先順位
|
||||
|
||||
### 優先度1: 今すぐ削除
|
||||
1. ✅ Cranelift/JITファイル (8ファイル, ~1,500行)
|
||||
2. ✅ BID Copilotアーカイブ (13ファイル, ~1,900行)
|
||||
3. ✅ 明確なDead Code (4関数, ~500行)
|
||||
|
||||
**合計**: 約3,900行
|
||||
|
||||
### 優先度2: 1週間以内 (調査後)
|
||||
1. 🔍 JSON v1 Bridge (1ファイル, 734行)
|
||||
2. 🔍 Legacy Tests (5ファイル, ~1,000行)
|
||||
3. 🔍 Parser Dead Code (複数, ~500行)
|
||||
|
||||
**合計**: 約2,200行
|
||||
|
||||
### 優先度3: Phase 16以降
|
||||
1. ⏳ WASM Backend評価 (12ファイル, 3,170行)
|
||||
2. ⏳ Builtin Box移行 (6ファイル, 264行)
|
||||
|
||||
**合計**: 約3,434行
|
||||
|
||||
---
|
||||
|
||||
## 📋 実行チェックリスト
|
||||
|
||||
### Phase A: Safe削除
|
||||
- [ ] Cranelift/JITファイル削除
|
||||
- [ ] BID Copilotアーカイブ
|
||||
- [ ] Dead Code削除
|
||||
- [ ] ビルドテスト成功
|
||||
- [ ] スモークテスト成功
|
||||
|
||||
### Phase B: Investigate
|
||||
- [ ] JSON v1 Bridge使用状況調査
|
||||
- [ ] Legacy Tests整理
|
||||
- [ ] Parser Dead Code確認
|
||||
- [ ] 削除判断・実行
|
||||
|
||||
### Phase C: Risky
|
||||
- [ ] WASM Backend動作確認
|
||||
- [ ] Phase 21.0戦略確認
|
||||
- [ ] Builtin Box移行計画確定
|
||||
- [ ] 段階的削除実施
|
||||
|
||||
---
|
||||
|
||||
**最終更新**: 2025-11-06
|
||||
**調査者**: Claude Code
|
||||
**次のアクション**: Phase A実行推奨
|
||||
516
docs/development/cleanup/PHASE1_IMPLEMENTATION_GUIDE.md
Normal file
516
docs/development/cleanup/PHASE1_IMPLEMENTATION_GUIDE.md
Normal file
@ -0,0 +1,516 @@
|
||||
# Phase 1実装ガイド - 低リスク・高効果ヘルパー関数
|
||||
|
||||
## 概要
|
||||
|
||||
Phase 1では以下3つのヘルパー関数を実装し、約270-380行のコード削減を目指します。
|
||||
|
||||
1. Destination書き込みヘルパー(150-200行削減)
|
||||
2. 引数検証ヘルパー(100-150行削減)
|
||||
3. Receiver変換ヘルパー(20-30行削減)
|
||||
|
||||
**実装時間見込み**: 5-8時間
|
||||
**リスク**: 低
|
||||
**優先度**: 最高
|
||||
|
||||
---
|
||||
|
||||
## 実装手順
|
||||
|
||||
### Step 1: ユーティリティモジュール作成
|
||||
|
||||
```bash
|
||||
# ディレクトリ構造作成
|
||||
mkdir -p src/backend/mir_interpreter/utils
|
||||
touch src/backend/mir_interpreter/utils/mod.rs
|
||||
touch src/backend/mir_interpreter/utils/register_ops.rs
|
||||
touch src/backend/mir_interpreter/utils/validation.rs
|
||||
touch src/backend/mir_interpreter/utils/conversions.rs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 2: register_ops.rs 実装
|
||||
|
||||
**ファイル**: `src/backend/mir_interpreter/utils/register_ops.rs`
|
||||
|
||||
```rust
|
||||
use crate::backend::mir_interpreter::MirInterpreter;
|
||||
use crate::box_trait::NyashBox;
|
||||
use crate::mir::ValueId;
|
||||
use crate::backend::mir_interpreter::VMValue;
|
||||
|
||||
impl MirInterpreter {
|
||||
/// Write a VMValue result to destination register if present.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// self.write_result(dst, VMValue::Integer(42));
|
||||
/// ```
|
||||
pub(crate) fn write_result(&mut self, dst: Option<ValueId>, value: VMValue) {
|
||||
if let Some(d) = dst {
|
||||
self.regs.insert(d, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// Write a NyashBox result to destination register (converted to VMValue::BoxRef).
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// let result_box = string_box.trim();
|
||||
/// self.write_box_result(dst, result_box);
|
||||
/// ```
|
||||
pub(crate) fn write_box_result(&mut self, dst: Option<ValueId>, boxed: Box<dyn NyashBox>) {
|
||||
self.write_result(dst, VMValue::from_nyash_box(boxed));
|
||||
}
|
||||
|
||||
/// Write VMValue::Void to destination register.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// arr.push(item);
|
||||
/// self.write_void(dst); // push returns void
|
||||
/// ```
|
||||
pub(crate) fn write_void(&mut self, dst: Option<ValueId>) {
|
||||
self.write_result(dst, VMValue::Void);
|
||||
}
|
||||
|
||||
/// Write integer value to destination register.
|
||||
pub(crate) fn write_integer(&mut self, dst: Option<ValueId>, value: i64) {
|
||||
self.write_result(dst, VMValue::Integer(value));
|
||||
}
|
||||
|
||||
/// Write boolean value to destination register.
|
||||
pub(crate) fn write_bool(&mut self, dst: Option<ValueId>, value: bool) {
|
||||
self.write_result(dst, VMValue::Bool(value));
|
||||
}
|
||||
|
||||
/// Write string value to destination register.
|
||||
pub(crate) fn write_string(&mut self, dst: Option<ValueId>, value: String) {
|
||||
self.write_result(dst, VMValue::String(value));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
fn test_write_result_with_dst() {
|
||||
let mut interp = MirInterpreter {
|
||||
regs: HashMap::new(),
|
||||
// ... other fields
|
||||
};
|
||||
let dst = Some(ValueId(42));
|
||||
interp.write_result(dst, VMValue::Integer(100));
|
||||
assert_eq!(interp.regs.get(&ValueId(42)), Some(&VMValue::Integer(100)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_result_without_dst() {
|
||||
let mut interp = MirInterpreter {
|
||||
regs: HashMap::new(),
|
||||
// ... other fields
|
||||
};
|
||||
interp.write_result(None, VMValue::Integer(100));
|
||||
assert!(interp.regs.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_void() {
|
||||
let mut interp = MirInterpreter {
|
||||
regs: HashMap::new(),
|
||||
// ... other fields
|
||||
};
|
||||
let dst = Some(ValueId(10));
|
||||
interp.write_void(dst);
|
||||
assert_eq!(interp.regs.get(&ValueId(10)), Some(&VMValue::Void));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 3: validation.rs 実装
|
||||
|
||||
**ファイル**: `src/backend/mir_interpreter/utils/validation.rs`
|
||||
|
||||
```rust
|
||||
use crate::backend::mir_interpreter::{MirInterpreter, VMError};
|
||||
use crate::mir::ValueId;
|
||||
|
||||
impl MirInterpreter {
|
||||
/// Validate that the method call has exactly the expected number of arguments.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// self.validate_args_exact("push", args, 1)?;
|
||||
/// let val = self.reg_load(args[0])?;
|
||||
/// ```
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns `VMError::InvalidInstruction` if argument count doesn't match.
|
||||
pub(crate) fn validate_args_exact(
|
||||
&self,
|
||||
method: &str,
|
||||
args: &[ValueId],
|
||||
expected: usize,
|
||||
) -> Result<(), VMError> {
|
||||
let actual = args.len();
|
||||
if actual != expected {
|
||||
return Err(VMError::InvalidInstruction(format!(
|
||||
"{} expects exactly {} argument(s), but got {}",
|
||||
method, expected, actual
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate that the method call has arguments within the expected range (inclusive).
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// // substring accepts 1 or 2 arguments
|
||||
/// self.validate_args_range("substring", args, 1, 2)?;
|
||||
/// ```
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns `VMError::InvalidInstruction` if argument count is out of range.
|
||||
pub(crate) fn validate_args_range(
|
||||
&self,
|
||||
method: &str,
|
||||
args: &[ValueId],
|
||||
min: usize,
|
||||
max: usize,
|
||||
) -> Result<(), VMError> {
|
||||
let actual = args.len();
|
||||
if actual < min || actual > max {
|
||||
return Err(VMError::InvalidInstruction(format!(
|
||||
"{} expects {}-{} argument(s), but got {}",
|
||||
method, min, max, actual
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate that the method call has at least the minimum number of arguments.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// self.validate_args_min("varargs_method", args, 2)?;
|
||||
/// ```
|
||||
pub(crate) fn validate_args_min(
|
||||
&self,
|
||||
method: &str,
|
||||
args: &[ValueId],
|
||||
min: usize,
|
||||
) -> Result<(), VMError> {
|
||||
let actual = args.len();
|
||||
if actual < min {
|
||||
return Err(VMError::InvalidInstruction(format!(
|
||||
"{} expects at least {} argument(s), but got {}",
|
||||
method, min, actual
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validate that the method call has no arguments.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// self.validate_args_empty("pop", args)?;
|
||||
/// ```
|
||||
pub(crate) fn validate_args_empty(&self, method: &str, args: &[ValueId]) -> Result<(), VMError> {
|
||||
self.validate_args_exact(method, args, 0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn dummy_interp() -> MirInterpreter {
|
||||
// Create minimal interpreter for testing
|
||||
MirInterpreter {
|
||||
// ... minimal fields
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_args_exact_ok() {
|
||||
let interp = dummy_interp();
|
||||
let args = vec![ValueId(1)];
|
||||
assert!(interp.validate_args_exact("push", &args, 1).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_args_exact_too_many() {
|
||||
let interp = dummy_interp();
|
||||
let args = vec![ValueId(1), ValueId(2)];
|
||||
let result = interp.validate_args_exact("push", &args, 1);
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().to_string().contains("expects exactly 1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_args_range_ok() {
|
||||
let interp = dummy_interp();
|
||||
let args = vec![ValueId(1), ValueId(2)];
|
||||
assert!(interp.validate_args_range("substring", &args, 1, 2).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_args_range_too_few() {
|
||||
let interp = dummy_interp();
|
||||
let args = vec![];
|
||||
let result = interp.validate_args_range("substring", &args, 1, 2);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 4: conversions.rs 実装
|
||||
|
||||
**ファイル**: `src/backend/mir_interpreter/utils/conversions.rs`
|
||||
|
||||
```rust
|
||||
use crate::backend::mir_interpreter::{MirInterpreter, VMValue};
|
||||
use crate::box_trait::NyashBox;
|
||||
|
||||
impl MirInterpreter {
|
||||
/// Convert a VMValue to Box<dyn NyashBox>, handling both BoxRef and primitive types.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// let recv = self.reg_load(box_val)?;
|
||||
/// let recv_box = self.convert_to_box(&recv);
|
||||
/// ```
|
||||
pub(crate) fn convert_to_box(&self, value: &VMValue) -> Box<dyn NyashBox> {
|
||||
match value.clone() {
|
||||
VMValue::BoxRef(b) => b.share_box(),
|
||||
other => other.to_nyash_box(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert and downcast to a specific box type.
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// if let Some(arr) = self.downcast_box::<ArrayBox>(&recv)? {
|
||||
/// // Handle ArrayBox methods
|
||||
/// }
|
||||
/// ```
|
||||
pub(crate) fn downcast_box<T: NyashBox + 'static>(
|
||||
&self,
|
||||
value: &VMValue,
|
||||
) -> Option<&T> {
|
||||
let boxed = self.convert_to_box(value);
|
||||
boxed.as_any().downcast_ref::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::boxes::array::ArrayBox;
|
||||
|
||||
#[test]
|
||||
fn test_convert_to_box_from_primitive() {
|
||||
let interp = dummy_interp();
|
||||
let value = VMValue::Integer(42);
|
||||
let boxed = interp.convert_to_box(&value);
|
||||
// Should convert to IntegerBox
|
||||
assert!(boxed.as_any().is::<crate::boxes::integer::IntegerBox>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_to_box_from_boxref() {
|
||||
let interp = dummy_interp();
|
||||
let arr = Box::new(ArrayBox::new());
|
||||
let value = VMValue::BoxRef(arr.into());
|
||||
let boxed = interp.convert_to_box(&value);
|
||||
assert!(boxed.as_any().is::<ArrayBox>());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 5: mod.rs 設定
|
||||
|
||||
**ファイル**: `src/backend/mir_interpreter/utils/mod.rs`
|
||||
|
||||
```rust
|
||||
//! Utility functions for MIR interpreter handlers.
|
||||
//!
|
||||
//! This module provides common patterns used across handler implementations:
|
||||
//! - Register operations (writing results)
|
||||
//! - Argument validation
|
||||
//! - Type conversions
|
||||
|
||||
mod conversions;
|
||||
mod register_ops;
|
||||
mod validation;
|
||||
|
||||
// Re-export for convenience (optional)
|
||||
pub(crate) use conversions::*;
|
||||
pub(crate) use register_ops::*;
|
||||
pub(crate) use validation::*;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Step 6: ハンドラー更新 - 段階的移行
|
||||
|
||||
#### 例: boxes_array.rs の更新
|
||||
|
||||
**Before**:
|
||||
```rust
|
||||
"push" => {
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
let val = this.reg_load(args[0])?.to_nyash_box();
|
||||
let _ = ab.push(val);
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::Void);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
**After**:
|
||||
```rust
|
||||
"push" => {
|
||||
this.validate_args_exact("push", args, 1)?;
|
||||
let val = this.reg_load(args[0])?.to_nyash_box();
|
||||
let _ = ab.push(val);
|
||||
this.write_void(dst);
|
||||
return Ok(true);
|
||||
}
|
||||
```
|
||||
|
||||
**削減**: 6行 → 4行(2行削減)
|
||||
|
||||
---
|
||||
|
||||
## 移行チェックリスト
|
||||
|
||||
### Phase 1-A: インフラ構築(1-2時間)
|
||||
- [ ] `utils/` ディレクトリ作成
|
||||
- [ ] `mod.rs`, `register_ops.rs`, `validation.rs`, `conversions.rs` 実装
|
||||
- [ ] ユニットテスト追加
|
||||
- [ ] 全テストが通ることを確認
|
||||
|
||||
### Phase 1-B: Handler更新(3-5時間)
|
||||
ファイル単位で更新し、都度テストを実行:
|
||||
|
||||
1. [ ] `boxes_array.rs` 更新(最も小さいファイルから開始)
|
||||
- [ ] 引数検証を`validate_args_*`に置き換え
|
||||
- [ ] Destination書き込みを`write_*`に置き換え
|
||||
- [ ] Receiver変換を`convert_to_box`に置き換え
|
||||
- [ ] テスト実行
|
||||
|
||||
2. [ ] `boxes_map.rs` 更新
|
||||
3. [ ] `boxes_string.rs` 更新
|
||||
4. [ ] `boxes_plugin.rs` 更新
|
||||
5. [ ] `boxes_instance.rs` 更新
|
||||
6. [ ] `boxes_object_fields.rs` 更新
|
||||
7. [ ] `boxes.rs` 更新
|
||||
8. [ ] `calls.rs` 更新(大きいファイルは最後に)
|
||||
|
||||
### Phase 1-C: 検証(1時間)
|
||||
- [ ] 全ハンドラーファイルでパターン検索
|
||||
```bash
|
||||
# 残存する古いパターンを確認
|
||||
grep -rn "if let Some(d) = dst { this.regs.insert" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "args.len() !=" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "match recv.clone()" src/backend/mir_interpreter/handlers/
|
||||
```
|
||||
- [ ] スモークテスト実行
|
||||
```bash
|
||||
./tools/jit_smoke.sh
|
||||
```
|
||||
- [ ] ドキュメント更新
|
||||
|
||||
---
|
||||
|
||||
## テスト戦略
|
||||
|
||||
### 単体テスト
|
||||
各ユーティリティ関数に対して:
|
||||
- 正常系(期待通りの動作)
|
||||
- 異常系(エラーケース)
|
||||
- 境界値(0引数、大量引数など)
|
||||
|
||||
### 回帰テスト
|
||||
既存のスモークテストを活用:
|
||||
```bash
|
||||
# 変更前にベースライン取得
|
||||
./tools/jit_smoke.sh > /tmp/before.log 2>&1
|
||||
|
||||
# 変更適用
|
||||
|
||||
# 変更後に結果比較
|
||||
./tools/jit_smoke.sh > /tmp/after.log 2>&1
|
||||
diff /tmp/before.log /tmp/after.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## トラブルシューティング
|
||||
|
||||
### 問題: コンパイルエラー「method not found」
|
||||
**原因**: `utils/mod.rs` のインポートが不足
|
||||
**解決**: `src/backend/mir_interpreter/mod.rs` に以下を追加
|
||||
```rust
|
||||
mod utils;
|
||||
```
|
||||
|
||||
### 問題: テスト実行時のパニック
|
||||
**原因**: `MirInterpreter` の最小構成が不完全
|
||||
**解決**: テスト用のビルダー関数を用意
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
fn test_interpreter() -> MirInterpreter {
|
||||
MirInterpreter::new_for_test()
|
||||
}
|
||||
```
|
||||
|
||||
### 問題: 既存テストが失敗
|
||||
**原因**: エラーメッセージの形式変更
|
||||
**解決**: テストの期待値を更新(より良いメッセージに改善された)
|
||||
|
||||
---
|
||||
|
||||
## 期待される結果
|
||||
|
||||
### コード削減
|
||||
- **boxes_array.rs**: 63行 → 約50行(13行削減、21%減)
|
||||
- **boxes_map.rs**: 134行 → 約110行(24行削減、18%減)
|
||||
- **boxes_string.rs**: 208行 → 約170行(38行削減、18%減)
|
||||
- **全体**: 約270-380行削減(8-11%減)
|
||||
|
||||
### 品質向上
|
||||
- エラーメッセージの統一
|
||||
- テストカバレッジの向上
|
||||
- 新機能追加の容易性
|
||||
|
||||
---
|
||||
|
||||
## 次のステップ(Phase 2)
|
||||
|
||||
Phase 1完了後、以下を実施:
|
||||
1. Phase 2計画(エラー生成、PHIヘルパー)
|
||||
2. 追加の共通化機会の調査
|
||||
3. Phase 3(Box Handler統合)の詳細設計
|
||||
|
||||
---
|
||||
|
||||
**実装者**: (名前)
|
||||
**開始日**: (日付)
|
||||
**完了予定**: (日付)
|
||||
**実績**: (完了日)
|
||||
182
docs/development/cleanup/QUICK_CLEANUP_GUIDE.md
Normal file
182
docs/development/cleanup/QUICK_CLEANUP_GUIDE.md
Normal file
@ -0,0 +1,182 @@
|
||||
# クイック削除ガイド - 今すぐ実行可能なレガシーコード削除
|
||||
|
||||
**即実行可能**: Safe削除のみ (約3,900行削減)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 実行手順 (コピペ可能)
|
||||
|
||||
### Step 1: Cranelift/JIT削除 (約1,500行)
|
||||
|
||||
```bash
|
||||
cd /home/tomoaki/git/hakorune-selfhost
|
||||
|
||||
# Cranelift JITファイル削除
|
||||
rm src/runner/modes/cranelift.rs
|
||||
rm src/runner/modes/aot.rs
|
||||
rm src/runner/jit_direct.rs
|
||||
|
||||
# Cranelift JITテスト削除
|
||||
rm src/tests/core13_smoke_jit.rs
|
||||
rm src/tests/core13_smoke_jit_map.rs
|
||||
|
||||
# backend/mod.rsのcranelift参照削除 (手動編集)
|
||||
echo "⚠️ src/backend/mod.rs の29-52行を手動削除してください"
|
||||
|
||||
# cli/args.rsのcranelift参照削除 (手動編集)
|
||||
echo "⚠️ src/cli/args.rs の --backend cranelift オプションを削除してください"
|
||||
|
||||
# runner/dispatch.rsのcranelift分岐削除 (手動編集)
|
||||
echo "⚠️ src/runner/dispatch.rs のcranelift分岐を削除してください"
|
||||
```
|
||||
|
||||
### Step 2: BID Copilotアーカイブ (約1,900行)
|
||||
|
||||
```bash
|
||||
# アーカイブディレクトリ作成
|
||||
mkdir -p archive/bid-copilot-prototype
|
||||
|
||||
# BID Copilotコード移動
|
||||
git mv src/bid-codegen-from-copilot archive/bid-copilot-prototype/
|
||||
git mv src/bid-converter-copilot archive/bid-copilot-prototype/
|
||||
|
||||
# 確認
|
||||
ls -la archive/bid-copilot-prototype/
|
||||
```
|
||||
|
||||
### Step 3: 明確なDead Code削除 (約500行)
|
||||
|
||||
```bash
|
||||
# Legacy MIR Expression削除
|
||||
rm src/mir/builder/exprs_legacy.rs
|
||||
|
||||
# src/mir/builder.rsから参照削除 (手動編集)
|
||||
echo "⚠️ src/mir/builder.rs の exprs_legacy モジュール宣言を削除してください"
|
||||
|
||||
# src/mir/builder.rs の build_expression_impl_legacy() 呼び出し削除
|
||||
echo "⚠️ src/mir/builder.rs の build_expression_impl_legacy() を削除してください"
|
||||
```
|
||||
|
||||
### Step 4: ビルド確認
|
||||
|
||||
```bash
|
||||
# ビルドテスト
|
||||
cargo build --release
|
||||
|
||||
# テスト実行
|
||||
cargo test
|
||||
|
||||
# LLVMビルドテスト
|
||||
cargo build --release --features llvm
|
||||
|
||||
# スモークテスト
|
||||
./tools/smokes/v2/run.sh --profile quick
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 手動編集が必要なファイル
|
||||
|
||||
### 1. `src/backend/mod.rs` (削除: 29-52行)
|
||||
|
||||
```rust
|
||||
// 削除対象
|
||||
#[cfg(feature = "cranelift-jit")]
|
||||
pub mod cranelift;
|
||||
#[cfg(feature = "cranelift-jit")]
|
||||
pub use cranelift::{
|
||||
compile_and_execute as cranelift_compile_and_execute,
|
||||
compile_to_object as cranelift_compile_to_object,
|
||||
};
|
||||
```
|
||||
|
||||
### 2. `src/cli/args.rs`
|
||||
|
||||
```rust
|
||||
// 削除対象: --backend cranelift オプション
|
||||
// "cranelift" => Backend::Cranelift, の行を削除
|
||||
```
|
||||
|
||||
### 3. `src/runner/dispatch.rs`
|
||||
|
||||
```rust
|
||||
// 削除対象: cranelift分岐
|
||||
// Backend::Cranelift => { ... } の分岐を削除
|
||||
```
|
||||
|
||||
### 4. `src/mir/builder.rs`
|
||||
|
||||
```rust
|
||||
// 削除対象1: モジュール宣言
|
||||
// mod exprs_legacy;
|
||||
|
||||
// 削除対象2: build_expression_impl_legacy() 呼び出し
|
||||
// self.build_expression_impl_legacy(ast) の分岐を削除
|
||||
```
|
||||
|
||||
### 5. `src/runner/modes/mod.rs`
|
||||
|
||||
```rust
|
||||
// 削除対象
|
||||
#[cfg(feature = "cranelift-jit")]
|
||||
pub mod aot;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 削除確認チェックリスト
|
||||
|
||||
- [ ] `cargo build --release` が成功
|
||||
- [ ] `cargo test` がパス
|
||||
- [ ] `cargo build --release --features llvm` が成功
|
||||
- [ ] `./tools/smokes/v2/run.sh --profile quick` がパス
|
||||
- [ ] `git status` で削除ファイル確認
|
||||
- [ ] 手動編集箇所の確認完了
|
||||
|
||||
---
|
||||
|
||||
## 📊 削減結果
|
||||
|
||||
| カテゴリ | 削減行数 |
|
||||
|---------|---------|
|
||||
| Cranelift/JIT | 約1,500行 |
|
||||
| BID Copilot | 約1,900行 |
|
||||
| Dead Code | 約500行 |
|
||||
| **合計** | **約3,900行** |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 次のステップ (調査後削除)
|
||||
|
||||
### Phase B: 調査が必要な項目
|
||||
1. **JSON v1 Bridge** (734行) - 使用状況確認
|
||||
2. **Legacy Test Files** (1,000行) - identical_exec系の整理
|
||||
3. **Parser Dead Code** (約500行) - 実使用確認
|
||||
|
||||
### Phase C: Phase 16以降
|
||||
1. **WASM Backend** (3,170行) - 動作確認後アーカイブ
|
||||
2. **Builtin Box移行** (264行) - プラグイン完全移行後
|
||||
|
||||
---
|
||||
|
||||
## 🚨 問題が発生した場合
|
||||
|
||||
### ビルドエラー
|
||||
```bash
|
||||
# 変更を戻す
|
||||
git restore .
|
||||
git clean -fd
|
||||
|
||||
# 詳細レポート確認
|
||||
cat docs/development/cleanup/LEGACY_CODE_INVESTIGATION_REPORT.md
|
||||
```
|
||||
|
||||
### テスト失敗
|
||||
- 削除したファイルが実際に使用されている可能性
|
||||
- 詳細レポートの「要確認 (Investigate)」セクションを参照
|
||||
|
||||
---
|
||||
|
||||
**実行時間**: 約10分 (手動編集含む)
|
||||
**リスク**: 無し (Safe削除のみ)
|
||||
**削減効果**: 約3,900行 (4%)
|
||||
192
docs/development/cleanup/QUICK_REFERENCE.md
Normal file
192
docs/development/cleanup/QUICK_REFERENCE.md
Normal file
@ -0,0 +1,192 @@
|
||||
# 重複コード削減 - クイックリファレンスカード
|
||||
|
||||
## 📊 一目で分かる状況
|
||||
|
||||
```
|
||||
現状: 3,335行(Handlers)
|
||||
↓
|
||||
Phase 1実装後: 2,965行 (-11%)
|
||||
↓
|
||||
Phase 2実装後: 2,715行 (-19%)
|
||||
↓
|
||||
Phase 3実装後: 2,415行 (-28%)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Phase 1: 今すぐできる改善(5-8時間)
|
||||
|
||||
### 3つのヘルパー関数
|
||||
|
||||
#### 1. Destination書き込み (49箇所 → 1行化)
|
||||
```rust
|
||||
// ❌ Before (3-4行)
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::from_nyash_box(ret));
|
||||
}
|
||||
|
||||
// ✅ After (1行)
|
||||
this.write_box_result(dst, ret);
|
||||
```
|
||||
|
||||
#### 2. 引数検証 (55箇所 → 1行化)
|
||||
```rust
|
||||
// ❌ Before (3行)
|
||||
if args.len() != 1 {
|
||||
return Err(VMError::InvalidInstruction("push expects 1 arg".into()));
|
||||
}
|
||||
|
||||
// ✅ After (1行)
|
||||
this.validate_args_exact("push", args, 1)?;
|
||||
```
|
||||
|
||||
#### 3. Receiver変換 (5箇所 → 1行化)
|
||||
```rust
|
||||
// ❌ Before (4行)
|
||||
let recv_box = match recv.clone() {
|
||||
VMValue::BoxRef(b) => b.share_box(),
|
||||
other => other.to_nyash_box(),
|
||||
};
|
||||
|
||||
// ✅ After (1行)
|
||||
let recv_box = this.convert_to_box(&recv);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📂 実装する新ファイル
|
||||
|
||||
```
|
||||
src/backend/mir_interpreter/utils/
|
||||
├── mod.rs # モジュール定義
|
||||
├── register_ops.rs # write_result, write_void, etc.
|
||||
├── validation.rs # validate_args_exact, validate_args_range
|
||||
└── conversions.rs # convert_to_box
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 実装チェックリスト
|
||||
|
||||
### ステップ1: インフラ (1-2時間)
|
||||
- [ ] `utils/` ディレクトリ作成
|
||||
- [ ] 3つのファイル実装(register_ops, validation, conversions)
|
||||
- [ ] ユニットテスト追加
|
||||
- [ ] コンパイル&テスト確認
|
||||
|
||||
### ステップ2: Handler更新 (3-5時間)
|
||||
小→大の順で1ファイルずつ:
|
||||
- [ ] `boxes_array.rs` (63行 → 50行)
|
||||
- [ ] `boxes_map.rs` (134行 → 110行)
|
||||
- [ ] `boxes_string.rs` (208行 → 170行)
|
||||
- [ ] `boxes_plugin.rs` (217行 → 180行)
|
||||
- [ ] `boxes_instance.rs` (153行 → 125行)
|
||||
- [ ] `boxes_object_fields.rs` (399行 → 330行)
|
||||
- [ ] `boxes.rs` (307行 → 250行)
|
||||
- [ ] `calls.rs` (907行 → 750行)
|
||||
|
||||
各更新後: コンパイル → テスト → コミット
|
||||
|
||||
### ステップ3: 検証 (1時間)
|
||||
- [ ] 古いパターン残存確認
|
||||
- [ ] スモークテスト実行
|
||||
- [ ] ドキュメント更新
|
||||
|
||||
---
|
||||
|
||||
## 🔍 確認コマンド
|
||||
|
||||
```bash
|
||||
# 重複パターン検索
|
||||
grep -rn "if let Some(d) = dst { this.regs.insert" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "args.len() !=" src/backend/mir_interpreter/handlers/
|
||||
grep -rn "match recv.clone()" src/backend/mir_interpreter/handlers/
|
||||
|
||||
# Phase 1実装後(残存チェック)
|
||||
grep -rn "if let Some(d) = dst { this.regs.insert" src/backend/mir_interpreter/handlers/ | wc -l
|
||||
# → 0になるはず
|
||||
|
||||
# テスト実行
|
||||
./tools/jit_smoke.sh
|
||||
|
||||
# 変更行数確認
|
||||
git diff --stat
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 期待される効果
|
||||
|
||||
| 指標 | Before | After | 改善 |
|
||||
|-----|--------|-------|------|
|
||||
| 行数 | 3,335 | 2,965 | -11% |
|
||||
| 重複箇所 | 260 | 109 | -58% |
|
||||
| 保守対象 | 散在 | 3ヶ所 | 集約 |
|
||||
|
||||
---
|
||||
|
||||
## 💡 実装のコツ
|
||||
|
||||
1. **最小ファイルから**: `boxes_array.rs` (63行) がおすすめ
|
||||
2. **1ファイルずつ**: 都度テストして確実に
|
||||
3. **コピペOK**: 実装ガイドのコードをそのまま使える
|
||||
4. **小さなPR**: レビュー負荷を軽減
|
||||
|
||||
---
|
||||
|
||||
## 🚨 トラブルシューティング
|
||||
|
||||
### コンパイルエラー「method not found」
|
||||
```rust
|
||||
// src/backend/mir_interpreter/mod.rs に追加
|
||||
mod utils;
|
||||
```
|
||||
|
||||
### テストエラー「MirInterpreter::new_for_test not found」
|
||||
```rust
|
||||
// テスト用ビルダー関数を追加
|
||||
#[cfg(test)]
|
||||
impl MirInterpreter {
|
||||
fn new_for_test() -> Self { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 詳細ドキュメント
|
||||
|
||||
- **実装手順**: [`PHASE1_IMPLEMENTATION_GUIDE.md`](./PHASE1_IMPLEMENTATION_GUIDE.md)
|
||||
- **詳細分析**: [`DUPLICATION_ANALYSIS_REPORT.md`](./DUPLICATION_ANALYSIS_REPORT.md)
|
||||
- **全体サマリー**: [`CLEANUP_SUMMARY_2025-11-06.md`](./CLEANUP_SUMMARY_2025-11-06.md)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 今日から始める
|
||||
|
||||
```bash
|
||||
# 1. ドキュメント確認(5分)
|
||||
cat docs/development/cleanup/PHASE1_IMPLEMENTATION_GUIDE.md
|
||||
|
||||
# 2. ディレクトリ作成(1分)
|
||||
mkdir -p src/backend/mir_interpreter/utils
|
||||
|
||||
# 3. ファイル作成&実装(1-2時間)
|
||||
touch src/backend/mir_interpreter/utils/{mod,register_ops,validation,conversions}.rs
|
||||
# → 実装ガイドからコピペ
|
||||
|
||||
# 4. 最小ファイルで試す(30分)
|
||||
# → boxes_array.rs を更新
|
||||
|
||||
# 5. テスト実行(5分)
|
||||
./tools/jit_smoke.sh
|
||||
|
||||
# 6. 残りのファイルも順次更新(2-4時間)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**所要時間**: 5-8時間
|
||||
**リスク**: 低
|
||||
**効果**: 高(270-380行削減)
|
||||
|
||||
今すぐ始めましょう! 🚀
|
||||
265
docs/development/cleanup/README.md
Normal file
265
docs/development/cleanup/README.md
Normal file
@ -0,0 +1,265 @@
|
||||
# レガシーコード削除プロジェクト
|
||||
|
||||
**調査日**: 2025-11-06
|
||||
**Phase**: 20.46完了後
|
||||
**目的**: Phase 21.0に向けたコードベース整理
|
||||
|
||||
---
|
||||
|
||||
## 📚 ドキュメント構成
|
||||
|
||||
### 1. [レガシーコード調査レポート](./LEGACY_CODE_INVESTIGATION_REPORT.md) ⭐ メインレポート
|
||||
**内容**: 包括的な調査結果・削減見込み・段階的削除計画
|
||||
|
||||
- カテゴリ別詳細分析 (8カテゴリ)
|
||||
- 削減見込みサマリー (約5,600〜8,900行)
|
||||
- 段階的削除計画 (Phase A/B/C)
|
||||
- リスク評価 (Safe / Investigate / Risky)
|
||||
|
||||
**読者**: プロジェクトマネージャー、意思決定者
|
||||
|
||||
---
|
||||
|
||||
### 2. [クイック削除ガイド](./QUICK_CLEANUP_GUIDE.md) ⚡ 実行マニュアル
|
||||
**内容**: 今すぐ実行可能なSafe削除手順
|
||||
|
||||
- コピペ可能なコマンド
|
||||
- 手動編集箇所の詳細
|
||||
- ビルド確認手順
|
||||
- トラブルシューティング
|
||||
|
||||
**読者**: 開発者 (実行担当者)
|
||||
|
||||
---
|
||||
|
||||
### 3. [詳細ファイルリスト](./LEGACY_FILES_DETAILED_LIST.md) 📋 リファレンス
|
||||
**内容**: ファイル別・行数別の完全リスト
|
||||
|
||||
- Safe削除ファイル一覧 (25+ ファイル, ~3,900行)
|
||||
- Investigateファイル一覧 (7+ ファイル, ~2,200行)
|
||||
- Riskyファイル一覧 (18 ファイル, ~3,434行)
|
||||
- 削除優先順位
|
||||
|
||||
**読者**: 開発者 (詳細確認用)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 クイックスタート
|
||||
|
||||
### 今すぐ削除したい場合
|
||||
👉 **[クイック削除ガイド](./QUICK_CLEANUP_GUIDE.md)** を参照
|
||||
|
||||
約10分で約3,900行削除可能 (リスク無し)
|
||||
|
||||
---
|
||||
|
||||
### 全体像を把握したい場合
|
||||
👉 **[レガシーコード調査レポート](./LEGACY_CODE_INVESTIGATION_REPORT.md)** を参照
|
||||
|
||||
調査結果・削減見込み・段階的計画の全体像
|
||||
|
||||
---
|
||||
|
||||
### 個別ファイルを確認したい場合
|
||||
👉 **[詳細ファイルリスト](./LEGACY_FILES_DETAILED_LIST.md)** を参照
|
||||
|
||||
ファイル別・カテゴリ別の完全リスト
|
||||
|
||||
---
|
||||
|
||||
## 📊 削減見込みサマリー
|
||||
|
||||
| フェーズ | 対象 | 削減行数 | リスク | 実施時期 |
|
||||
|---------|-----|---------|-------|---------|
|
||||
| **Phase A** | Safe削除 | 約3,900行 | 無し | 今すぐ |
|
||||
| **Phase B** | Investigate | 約2,200行 | 低 | 1週間以内 |
|
||||
| **Phase C** | Risky | 約3,400行 | 中 | Phase 16以降 |
|
||||
| **合計** | - | **約9,500行** | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 削除実行フロー
|
||||
|
||||
### Step 1: Safe削除 (今すぐ)
|
||||
```bash
|
||||
# クイック削除ガイドを参照
|
||||
cd /home/tomoaki/git/hakorune-selfhost
|
||||
cat docs/development/cleanup/QUICK_CLEANUP_GUIDE.md
|
||||
|
||||
# コマンドをコピペして実行
|
||||
# 約10分で完了
|
||||
```
|
||||
|
||||
**削減**: 約3,900行
|
||||
**リスク**: 無し
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Investigate (1週間以内)
|
||||
|
||||
#### 2-1. JSON v1 Bridge調査
|
||||
```bash
|
||||
# 使用状況確認
|
||||
grep -r "json_v1_bridge\|try_parse_v1_to_module" src --include="*.rs"
|
||||
grep -r "schema_version.*1" apps --include="*.json"
|
||||
```
|
||||
|
||||
**判断基準**: 使用されていない → 削除 or アーカイブ
|
||||
|
||||
---
|
||||
|
||||
#### 2-2. Legacy Tests整理
|
||||
```bash
|
||||
# cranelift依存テスト確認
|
||||
find src/tests -name "*.rs" -exec grep -l "cfg.*cranelift" {} \;
|
||||
```
|
||||
|
||||
**判断基準**: VM/LLVM比較として有用? → 分割 or 削除
|
||||
|
||||
---
|
||||
|
||||
#### 2-3. Parser Dead Code削除
|
||||
```bash
|
||||
# 各関数の使用状況確認
|
||||
grep -r "unknown_span" src --include="*.rs" | grep -v "def\|fn "
|
||||
```
|
||||
|
||||
**判断基準**: 未使用 → 削除
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Risky (Phase 16以降)
|
||||
|
||||
#### 3-1. WASM Backend評価
|
||||
```bash
|
||||
# 動作確認
|
||||
cargo build --release --features wasm-backend
|
||||
./target/release/nyash --backend wasm test.hako
|
||||
```
|
||||
|
||||
**判断基準**: 動作しない → アーカイブ
|
||||
|
||||
---
|
||||
|
||||
#### 3-2. Builtin Box移行
|
||||
Phase 15.5-B完了後、プラグイン移行戦略に従う
|
||||
|
||||
**判断基準**: Plugin完成 → Builtin削除
|
||||
|
||||
---
|
||||
|
||||
## ✅ 実行チェックリスト
|
||||
|
||||
### Phase A: Safe削除
|
||||
- [ ] Cranelift/JITファイル削除完了
|
||||
- [ ] BID Copilotアーカイブ完了
|
||||
- [ ] Dead Code削除完了
|
||||
- [ ] `cargo build --release` 成功
|
||||
- [ ] `cargo test` 全テストパス
|
||||
- [ ] `./tools/smokes/v2/run.sh --profile quick` パス
|
||||
- [ ] Git commit & push完了
|
||||
|
||||
**コミットメッセージ例**:
|
||||
```
|
||||
chore: Remove legacy Cranelift/JIT code and BID Copilot prototype
|
||||
|
||||
- Remove Cranelift/JIT backend (archived in Phase 15)
|
||||
- Archive BID Copilot modules (unused prototype)
|
||||
- Delete dead code (明確に未使用なコード)
|
||||
- Total reduction: ~3,900 lines (~4%)
|
||||
|
||||
Refs: docs/development/cleanup/LEGACY_CODE_INVESTIGATION_REPORT.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Phase B: Investigate
|
||||
- [ ] JSON v1 Bridge調査完了
|
||||
- [ ] Legacy Tests整理完了
|
||||
- [ ] Parser Dead Code確認完了
|
||||
- [ ] 削除判断・実行完了
|
||||
- [ ] テスト確認完了
|
||||
|
||||
---
|
||||
|
||||
### Phase C: Risky
|
||||
- [ ] WASM Backend動作確認完了
|
||||
- [ ] Phase 21.0戦略確認完了
|
||||
- [ ] Builtin Box移行計画確定
|
||||
- [ ] 段階的削除実施完了
|
||||
|
||||
---
|
||||
|
||||
## 📈 進捗トラッキング
|
||||
|
||||
### 現在の状態 (2025-11-06)
|
||||
- ✅ 調査完了 (3ドキュメント作成)
|
||||
- ⏳ Phase A実行待ち (約3,900行削減)
|
||||
- ⏳ Phase B調査待ち (約2,200行削減)
|
||||
- ⏳ Phase C戦略待ち (約3,400行削減)
|
||||
|
||||
### 目標
|
||||
- Phase A: 2025-11-07までに完了
|
||||
- Phase B: 2025-11-14までに完了
|
||||
- Phase C: Phase 16開始時に実施
|
||||
|
||||
---
|
||||
|
||||
## 🔍 関連ドキュメント
|
||||
|
||||
### プロジェクト全体
|
||||
- [CURRENT_TASK.md](../../../CURRENT_TASK.md) - 現在のタスク
|
||||
- [00_MASTER_ROADMAP.md](../roadmap/phases/00_MASTER_ROADMAP.md) - マスタープラン
|
||||
|
||||
### 過去の削除実績
|
||||
- [CLEANUP_REPORT_2025-11-04.md](./CLEANUP_REPORT_2025-11-04.md) - 前回の削除実績
|
||||
- [PHASE2_REPORT_2025-11-04.md](./PHASE2_REPORT_2025-11-04.md) - Phase 2削除
|
||||
|
||||
---
|
||||
|
||||
## 📝 備考
|
||||
|
||||
### なぜ今削除するのか?
|
||||
1. **Phase 20.46完了**: 開発の区切りが良い
|
||||
2. **Phase 21.0準備**: 次フェーズに集中するため
|
||||
3. **保守性向上**: レガシーコード除去で可読性向上
|
||||
4. **AI協働効率化**: 不要コードがAIを混乱させる
|
||||
|
||||
### なぜ段階的なのか?
|
||||
1. **リスク管理**: 一度に削除すると問題発見が困難
|
||||
2. **テスト実施**: 各段階で動作確認
|
||||
3. **ロールバック容易性**: 問題があれば即座に戻せる
|
||||
|
||||
### Archive vs 削除
|
||||
- **Archive推奨**: 将来的に再利用可能性あり
|
||||
- **完全削除**: 明確に不要・復活の可能性なし
|
||||
|
||||
---
|
||||
|
||||
## 🆘 問題が発生した場合
|
||||
|
||||
### ビルドエラー
|
||||
```bash
|
||||
# 変更を戻す
|
||||
git restore .
|
||||
git clean -fd
|
||||
|
||||
# 詳細レポート確認
|
||||
cat docs/development/cleanup/LEGACY_CODE_INVESTIGATION_REPORT.md
|
||||
```
|
||||
|
||||
### テスト失敗
|
||||
1. 削除したファイルが実際に使用されている
|
||||
2. 詳細リストの「Investigate」セクションを確認
|
||||
3. 必要に応じてファイル復元
|
||||
|
||||
### 質問・相談
|
||||
- Claude Code に相談
|
||||
- ChatGPT に実装依頼
|
||||
- ドキュメントを再確認
|
||||
|
||||
---
|
||||
|
||||
**作成者**: Claude Code
|
||||
**最終更新**: 2025-11-06
|
||||
**次のアクション**: Phase A実行推奨 (クイック削除ガイド参照)
|
||||
Reference in New Issue
Block a user