docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)

This commit is contained in:
nyash-codex
2025-10-31 18:00:10 +09:00
parent 1d49e24bf0
commit 8fd3a2b509
433 changed files with 108935 additions and 0 deletions

View File

@ -0,0 +1,271 @@
# Phase 32 INDEX - Hakorune Static Analyzer MVP
**Phase番号**: 32
**名称**: Hakorune Static Analyzer - Dead Code Detector MVP
**状態**: 🟡 計画完了、実装準備中(構造改訂版)
**期間**: 2025-10-20 → 2025-10-27 (7日間)
**優先度**: HIGH ⭐⭐⭐⭐⭐
**Ring位置**: Ring-1Meta/自己ホスト)
---
## 📚 ドキュメント構成
| ファイル | 説明 | 状態 |
|---------|------|------|
| **README.md** | Phase概要・目標・アーキテクチャ改訂版 | ✅ 完成 |
| **PLAN.md** | 7日間詳細実装計画改訂版 | ✅ 完成 |
| **INDEX.md** | このファイル(ナビゲーション) | ✅ 完成 |
---
## 🎯 Phase 32 概要
### 目標
**HakoruneでHakoruneコードを解析する静的解析ツールデッドコード検出器の実装**
### スコープ
- ✅ MIR JSONからデッドコード検出
- ✅ Gate-C/AST Strict MIR前提の厳密解析
- ✅ テキストレポート出力(診断サマリ)
- ✅ 95%以上の精度目標
### 非スコープPhase 33以降
- ❌ 重複コード検出Phase 33
- ❌ 複雑度メトリクスPhase 34
- ❌ マルチファイル解析Phase 35
- ❌ JSON/DOT出力Phase 36
---
## 📋 実装計画サマリー
| Day | タスク | 成果物 | LOC |
|-----|--------|--------|-----|
| 1 | スケルトン作成 | driver/ast_scan/mir_scan/report + README | 180 |
| 2 | MIR走査基盤 | mir_scan_box.hako関数抽出 | 150 |
| 3 | 呼び出しグラフ構築 | mir_scan_box.hako拡張Graph | 250 |
| 4 | BFS到達可能性 | mir_scan_box.hako完成 | 300 |
| 5 | レポート生成 | report_box.hako完成 | 120 |
| 6 | スモークテスト整備 | 3本happy/happy/負例) | 180 |
| 7 | セルフホスト解析 | ドキュメント + 実用化 | 50 |
| **Total** | | | **1,230** |
---
## 🏗️ 成果物の場所
### 実装ファイル(改訂版)
```
selfhost/analyzer/
├── hako_module.toml # exports 最小selfhost.analyzer.*
├── boxes/
│ ├── driver_box.hako # 入口: 入力→走査→レポート
│ ├── ast_scan_box.hako # AST Strict前提の走査
│ ├── mir_scan_box.hako # Gate-C Strict MIR JSONの走査
│ └── report_box.hako # 集計と文字列整形、出力
├── README.md # 責務/入出力/ENV/非対象
└── smokes/
├── analyzer_ast_strict_ok_vm.sh
├── analyzer_mir_gatec_ok_vm.sh
└── analyzer_bad_mir_fail_vm.sh # 負例・診断固定
```
### ドキュメント
```
docs/private/roadmap/phases/phase-32/
├── README.md # 本Phase概要改訂版
├── PLAN.md # 実装計画(改訂版)
└── INDEX.md # このファイル
```
### 設計ドキュメント(既存)
```
docs/development/proposals/
├── analyzer-mvp-summary.md # MVPサマリー
├── hakorune-static-analyzer-feasibility.md # 実現可能性調査
├── analyzer-implementation-guide.md # 実装ガイドSSOT要約をselfhost/analyzer/README.mdに
└── dead-code-detection/
├── call-graph-algorithm-detailed-design.md
└── call-graph-visualization.md
```
---
## 🔗 関連Phase
### 前提Phase
- **Phase 12.7**: continue実装 ✅
- **Phase 15**: Everything is Box ✅
- **Phase 20**: Hakorune VM実装 ✅
- **Phase 31**: Gate-C/AST Strict確立 ✅
### 後続Phase予定
- **Phase 33**: 重複コード検出1週間
- **Phase 34**: 複雑度メトリクス1週間
- **Phase 35**: マルチファイル解析2週間
- **Phase 36**: 可視化・出力2週間
---
## 📊 進捗状況
### 完了チェックリスト
**設計フェーズ**
- [x] 実現可能性調査Task 8
- [x] アルゴリズム設計Task 9
- [x] 重複検出設計Task 10
- [x] Phase 32 計画作成
- [x] 構造改訂selfhost/analyzer/ 配置確定)
**実装フェーズ** 🟡
- [ ] Day 1: スケルトン作成
- [ ] Day 2: MIR走査基盤
- [ ] Day 3: 呼び出しグラフ
- [ ] Day 4: BFS到達可能性
- [ ] Day 5: レポート生成
- [ ] Day 6: スモークテスト
- [ ] Day 7: セルフホスト解析
**検証フェーズ**
- [ ] 精度95%以上確認
- [ ] 処理速度5秒以内確認
- [ ] セルフホストコード実用化
---
## 🎓 学習リソース
### selfhost/shared から再利用
1. **BoxHelpers** - JSON解析パターン
2. **MirSchema** - MIR構造定義
3. **JsonEmit** - MapBox→JSON文字列変換
### Rustコードベース参考箇所
1. **src/mir/optimizer.rs** - デッドコード検出パターン
2. **src/mir/verification.rs** - Callee型のパース
3. **src/mir/builder/** - MIR構築パターン
### 既存Hakoruneコード
1. **apps/selfhost-compiler/builder/rewrite/known.hako** - continueの実例
2. **selfhost/shared/json/** - JSON処理パターン
3. **selfhost/hakorune-vm/** - MapBox/ArrayBox実践例
---
## 🚀 クイックスタート
### 今すぐ始めるDay 1
```bash
# 1. ディレクトリ作成
mkdir -p selfhost/analyzer/{boxes,smokes}
# 2. hako_module.toml作成
cat > selfhost/analyzer/hako_module.toml << 'EOF'
[package]
name = "selfhost.analyzer"
version = "0.1.0"
[exports]
driver = "boxes/driver_box.hako"
ast_scan = "boxes/ast_scan_box.hako"
mir_scan = "boxes/mir_scan_box.hako"
report = "boxes/report_box.hako"
[dependencies]
BoxHelpers = "selfhost.shared.box_helpers"
MirSchema = "selfhost.shared.mir.schema"
JsonEmit = "selfhost.shared.json.emit"
EOF
# 3. DriverBox スケルトン作成
cat > selfhost/analyzer/boxes/driver_box.hako << 'EOF'
using selfhost.analyzer.mir_scan as MirScanBox
using selfhost.analyzer.report as ReportBox
static box DriverBox {
birth() {
# 空のbirth
}
run_from_string(input, kind) {
return "[DriverBox] Not implemented yet"
}
run_from_box(input, kind) {
local result
result = new MapBox()
return result
}
}
EOF
# 4. 残りのBoxスケルトンも同様に作成
# PLAN.md Day 1参照
```
---
## 💡 重要な設計判断
### ✅ 決定事項
1. **配置**: selfhost/analyzer/Ring-1: Meta/自己ホスト) - apps/toolsではない
2. **責務分離**: driver/ast_scan/mir_scan/report - 単一Boxではない
3. **依存**: selfhost/shared のみ - 外部I/Oなし
4. **Gate-C/AST Strict**: 既定ON - 厳密型保証
5. **Fail-Fast**: フォールバック禁止 - Silent failure なし
6. **テスト先行**: ドキュメント→スモーク→実装
### ⚠️ 制約事項
1. **外部I/Oなし** - 入力は文字列/MapBoxのみ
2. **プラグイン化なし** - 当面VM経由のみ
3. **CLI化なし** - Phase 32では実装せず将来tools/に追加可能)
---
## 📈 成功メトリクス
| メトリクス | 目標値 | 測定方法 |
|-----------|--------|------------|
| **精度** | >95% | セルフホストコード手動検証 |
| **再現率** | >90% | 既知デッドコード検出率 |
| **処理速度** | <5秒 | 1,000行ファイル解析 |
| **LOC** | ~1,230行 | 実装コード総量 |
| **テスト** | 3件以上 | スモークテストhappy/happy/負例 |
---
## 🏆 期待される成果
### 技術的成果
1. 95%精度のデッドコード検出器
2. cargo-udepsの15倍精度25% 95%
3. セルフホスト開発の加速
### 戦略的成果
1. 論文ネタPLDI SRC / ICSE Demo
2. Everything is Box のショーケース
3. コミュニティ貢献
---
## 📞 サポート
### 質問・相談
- **設計相談**: `docs/development/proposals/` 参照
- **実装相談**: README.md のアーキテクチャセクション
- **バグ報告**: PLAN.md のリスク & 対策セクション
### 関連ドキュメント
- [Phase 32 README](./README.md) - 概要アーキテクチャ改訂版
- [Phase 32 PLAN](./PLAN.md) - 7日間実装計画改訂版
- [MVPサマリー](../../development/proposals/analyzer-mvp-summary.md)
- [アルゴリズム設計](../../development/proposals/dead-code-detection/call-graph-algorithm-detailed-design.md)
- [実装ガイド](../../development/proposals/analyzer-implementation-guide.md)
---
**最終更新**: 2025-10-19構造改訂版
**次回レビュー**: 2025-10-20 (Day 1完了時)

View File

@ -0,0 +1,787 @@
# Phase 32: Hakorune Static Analyzer - 実装計画(改訂版)
**期間**: 2025-10-20 → 2025-10-27 (7日間)
**配置**: selfhost/analyzer/Ring-1: Meta/自己ホスト)
**構造**: 責務分離driver/ast_scan/mir_scan/report
---
## Day 1: スケルトン作成 + README (2025-10-20)
### 🎯 目標
- ディレクトリ構造作成
- 4つのBoxスケルトン
- hako_module.toml設定
- README.md責務/入出力/ENV
### タスク
#### ディレクトリ作成 (10分)
```bash
mkdir -p selfhost/analyzer/{boxes,smokes}
```
#### hako_module.toml作成 (20分)
```toml
# selfhost/analyzer/hako_module.toml
[package]
name = "selfhost.analyzer"
version = "0.1.0"
[exports]
driver = "boxes/driver_box.hako"
ast_scan = "boxes/ast_scan_box.hako"
mir_scan = "boxes/mir_scan_box.hako"
report = "boxes/report_box.hako"
[dependencies]
BoxHelpers = "selfhost.shared.box_helpers"
MirSchema = "selfhost.shared.mir.schema"
JsonEmit = "selfhost.shared.json.emit"
```
#### driver_box.hako スケルトン (30分)
```hako
# selfhost/analyzer/boxes/driver_box.hako
using selfhost.analyzer.mir_scan as MirScanBox
using selfhost.analyzer.report as ReportBox
static box DriverBox {
birth() {
# 空のbirthstatic boxなので状態なし
}
# 文字列入力→文字列出力
run_from_string(input, kind) {
# TODO: Day 2-3で実装
return "[DriverBox] Not implemented yet"
}
# MapBox入力→MapBox出力
run_from_box(input, kind) {
# TODO: Day 2-3で実装
local result
result = new MapBox()
return result
}
}
```
#### mir_scan_box.hako スケルトン (30分)
```hako
# selfhost/analyzer/boxes/mir_scan_box.hako
using selfhost.shared.box_helpers as BoxHelpers
using selfhost.shared.mir.schema as MirSchema
static box MirScanBox {
birth() {
# 空のbirth
}
# MIR JSON → 関数リスト抽出
extract_functions(mir_json) {
# TODO: Day 2で実装
local result
result = new ArrayBox()
return result
}
# 呼び出しグラフ構築
build_call_graph(mir_json) {
# TODO: Day 3で実装
local result
result = new MapBox()
return result
}
# BFS到達可能性分析
find_dead_code(call_graph, entry_points) {
# TODO: Day 4で実装
local result
result = new ArrayBox()
return result
}
}
```
#### report_box.hako スケルトン (20分)
```hako
# selfhost/analyzer/boxes/report_box.hako
static box ReportBox {
birth() {
# 空のbirth
}
# 診断サマリ文字列生成
generate_text_report(dead_functions, all_functions) {
# TODO: Day 5で実装
return "[ReportBox] Analysis complete"
}
# MapBox診断生成
generate_map_report(dead_functions, reachable_functions) {
# TODO: Day 5で実装
local result
result = new MapBox()
return result
}
}
```
#### ast_scan_box.hako スケルトン (10分)
```hako
# selfhost/analyzer/boxes/ast_scan_box.hako
static box AstScanBox {
birth() {
# 空のbirth
}
# AST走査Phase 32外、将来実装
scan(ast_json) {
return "[AstScanBox] Not implemented in Phase 32"
}
}
```
#### README.md作成 (40分)
```markdown
# selfhost/analyzer - Hakorune Static Analyzer
## 責務
HakoruneでHakoruneコードを解析する静的解析ツールPhase 32: デッドコード検出MVP
## 入出力
### 入力
- MIR JSON文字列Gate-C Strict前提
- またはMapBoxMIR構造
### 出力
- テキストレポート(診断サマリ)
- またはMapBox構造化診断
## ENV変数
```bash
# 追加チェックON
NYASH_ANALYZER_STRICT=1
# 将来の切替(既定=mir
HAKO_ANALYZER_ENTRY=ast|mir
# Gate-C/AST Strict既定ON
NYASH_GATE_C_STRICT=1
NYASH_AST_STRICT=1
```
## 非対象
- 外部I/Oファイル読み書き
- プラグイン化当面VM経由のみ
- CLI将来tools/に追加可能)
## 使用例
```hako
using selfhost.analyzer.driver as DriverBox
local mir_json = "{ ... }" // MIR JSON文字列
local result = DriverBox.run_from_string(mir_json, "mir")
print(result)
```
```
### 成果物
- ✅ selfhost/analyzer/hako_module.toml: 20行
- ✅ driver_box.hako: 30行
- ✅ mir_scan_box.hako: 40行
- ✅ report_box.hako: 25行
- ✅ ast_scan_box.hako: 15行
- ✅ README.md: 50行
- **合計**: 180行
### 完了基準
- [ ] 全ファイル作成完了
- [ ] hako_module.toml が正しく読み込まれる
- [ ] スケルトンBoxがインポート可能
---
## Day 2: MIR走査基盤関数抽出 (2025-10-21)
### 🎯 目標
- extract_functions 実装
- MIR JSON → 関数リスト変換
- 基本的な走査パターン確立
### タスク
#### extract_functions 実装 (2時間)
```hako
# selfhost/analyzer/boxes/mir_scan_box.hako
extract_functions(mir_json) {
local functions_key
functions_key = "functions"
local has_key
has_key = mir_json.has(functions_key)
if has_key == 0 {
print("[MirScanBox] ERROR: Missing 'functions' key")
return null
}
local functions_array
functions_array = mir_json.get(functions_key)
local result
result = new ArrayBox()
local i
i = 0
loop(i < functions_array.size()) {
local func
func = functions_array.get(i)
local name
name = me.extract_function_name(func)
if name != null {
result.push(name)
}
i = i + 1
}
return result
}
extract_function_name(func_obj) {
local name_key
name_key = "name"
local has_name
has_name = func_obj.has(name_key)
if has_name == 0 {
return null
}
local name
name = func_obj.get(name_key)
local arity_key
arity_key = "arity"
local arity
arity = func_obj.get(arity_key)
# "Main.main/0" 形式
local slash
slash = "/"
local arity_str
arity_str = arity.to_string()
local qualified
qualified = name.concat(slash)
qualified = qualified.concat(arity_str)
return qualified
}
```
#### テストケース作成 (1時間)
- 簡単なMIR JSON2関数
- 関数リスト抽出確認
### 成果物
- ✅ mir_scan_box.hako拡張: 100行
- ✅ テストケース: 50行
- **合計**: 150行
### 完了基準
- [ ] extract_functions が動作
- [ ] 実際のMIR JSONから関数リスト取得可能
---
## Day 3: 呼び出しグラフ構築 (2025-10-22)
### 🎯 目標
- build_call_graph 実装
- mir_call命令から呼び出し先抽出
- caller → [callees] マップ生成
### タスク
#### build_call_graph 実装 (3時間)
- 各関数のinstructionsをスキャン
- mir_call命令のcalleeを抽出
- MapBoxcaller → ArrayBox<callee>)構築
#### Callee型パース実装 (1時間)
```hako
parse_callee(callee_obj) {
# "function:Main.helper/1"
# "extern:env.console.log"
# "constructor:ArrayBox"
local callee_type
callee_type = callee_obj.get("type")
if callee_type == "ModuleFunction" {
local module
module = callee_obj.get("module")
local func
func = callee_obj.get("function")
local arity
arity = callee_obj.get("arity")
local dot
dot = "."
local slash
slash = "/"
local result
result = module.concat(dot)
result = result.concat(func)
result = result.concat(slash)
local arity_str
arity_str = arity.to_string()
result = result.concat(arity_str)
return result
}
# TODO: Constructor/Extern対応
return null
}
```
### 成果物
- ✅ mir_scan_box.hako拡張: 150行
- ✅ テストケース: 100行
- **合計**: 250行
### 完了基準
- [ ] build_call_graph が動作
- [ ] 実際のMIR JSONから呼び出しグラフ生成可能
---
## Day 4: BFS到達可能性分析 (2025-10-23)
### 🎯 目標
- find_dead_code 実装
- BFS幅優先探索アルゴリズム
- デッドコード検出
### タスク
#### find_dead_code 実装 (2時間)
```hako
find_dead_code(call_graph, entry_points) {
local reachable
reachable = me.mark_reachable(call_graph, entry_points)
local all_funcs
all_funcs = call_graph.keys()
local dead
dead = new ArrayBox()
local i
i = 0
loop(i < all_funcs.size()) {
local func
func = all_funcs.get(i)
local is_reachable
is_reachable = reachable.has(func)
if is_reachable == 0 {
dead.push(func)
}
i = i + 1
}
return dead
}
mark_reachable(graph, entry_points) {
local visited
visited = new MapBox() # Set代わり
local queue
queue = new ArrayBox() # 簡易キュー
# エントリポイント追加
local i
i = 0
loop(i < entry_points.size()) {
local entry
entry = entry_points.get(i)
queue.push(entry)
i = i + 1
}
# BFS
loop(queue.size() > 0) {
local current
current = queue.get(0)
# 簡易shift先頭削除の代わりに新しいArrayBoxを作る
local new_queue
new_queue = new ArrayBox()
local j
j = 1
loop(j < queue.size()) {
local item
item = queue.get(j)
new_queue.push(item)
j = j + 1
}
queue = new_queue
local already_visited
already_visited = visited.has(current)
if already_visited == 1 {
continue # ✅ Phase 12.7で実装済み
}
visited.set(current, 1)
local callees
callees = graph.get(current)
if callees != null {
local ci
ci = 0
loop(ci < callees.size()) {
local callee
callee = callees.get(ci)
local callee_visited
callee_visited = visited.has(callee)
if callee_visited == 0 {
queue.push(callee)
}
ci = ci + 1
}
}
}
return visited
}
```
### 成果物
- ✅ mir_scan_box.hako完成: 200行
- ✅ テストケース: 100行
- **合計**: 300行
### 完了基準
- [ ] find_dead_code が動作
- [ ] BFS正確性確認既知デッドコード検出
---
## Day 5: レポート生成 (2025-10-24)
### 🎯 目標
- generate_text_report 実装
- generate_map_report 実装
- 人間可読・機械可読両対応
### タスク
#### generate_text_report 実装 (1.5時間)
```hako
generate_text_report(dead_functions, all_functions) {
local header
header = "Hakorune Dead Code Analyzer\n"
local separator
separator = "=============================\n"
local result
result = header.concat(separator)
local all_count
all_count = all_functions.size()
local all_str
all_str = all_count.to_string()
local all_line
all_line = "Functions found: "
all_line = all_line.concat(all_str)
all_line = all_line.concat("\n")
result = result.concat(all_line)
local dead_count
dead_count = dead_functions.size()
local dead_str
dead_str = dead_count.to_string()
local dead_line
dead_line = "Dead functions: "
dead_line = dead_line.concat(dead_str)
dead_line = dead_line.concat("\n")
result = result.concat(dead_line)
# 個別リスト表示
local i
i = 0
loop(i < dead_functions.size()) {
local func
func = dead_functions.get(i)
local prefix
prefix = " [DEAD] "
local line
line = prefix.concat(func)
line = line.concat("\n")
result = result.concat(line)
i = i + 1
}
return result
}
```
#### generate_map_report 実装 (1時間)
```hako
generate_map_report(dead_functions, reachable_functions) {
local result
result = new MapBox()
result.set("dead_functions", dead_functions)
result.set("reachable_functions", reachable_functions)
local dead_count
dead_count = dead_functions.size()
result.set("dead_count", dead_count)
local reachable_count
reachable_count = reachable_functions.size()
result.set("reachable_count", reachable_count)
return result
}
```
### 成果物
- ✅ report_box.hako完成: 120行
- **合計**: 120行
### 完了基準
- [ ] レポートが見やすい
- [ ] 統計情報が正確
---
## Day 6: スモークテスト整備 (2025-10-25)
### 🎯 目標
- 3本のスモークテスト作成
- happy path 2本 + 負例1本
- quick-lite/quick/integrationプロファイル対応
### タスク
#### happy path スモーク1 (1時間)
```bash
# selfhost/analyzer/smokes/analyzer_mir_gatec_ok_vm.sh
#!/bin/bash
set -euo pipefail
# Gate-C MIR JSON入力正常系
MIR_JSON='{"functions":[{"name":"Main.main","arity":0,"blocks":[]}]}'
RESULT=$(NYASH_GATE_C_STRICT=1 ./target/release/hakorune -c "
using selfhost.analyzer.driver as DriverBox
local mir = \"$MIR_JSON\"
local result = DriverBox.run_from_string(mir, \"mir\")
print(result)
")
if echo "$RESULT" | grep -q "Functions found: 1"; then
echo "✅ PASS: analyzer_mir_gatec_ok_vm"
exit 0
else
echo "❌ FAIL: Expected 'Functions found: 1'"
exit 1
fi
```
#### 負例スモーク (1時間)
```bash
# selfhost/analyzer/smokes/analyzer_bad_mir_fail_vm.sh
#!/bin/bash
set -euo pipefail
# 不正MIR: 余剰キー/型不一致
BAD_MIR='{"functions":[], "extra_key": "should fail"}'
set +e
RESULT=$(NYASH_GATE_C_STRICT=1 ./target/release/hakorune -c "
using selfhost.analyzer.driver as DriverBox
local mir = \"$BAD_MIR\"
local result = DriverBox.run_from_string(mir, \"mir\")
print(result)
" 2>&1)
EXIT_CODE=$?
set -e
if [ $EXIT_CODE -ne 0 ]; then
echo "✅ PASS: analyzer_bad_mir_fail_vm (expected failure)"
exit 0
else
echo "❌ FAIL: Should have failed on bad MIR"
exit 1
fi
```
#### プロファイル統合 (1時間)
- quick-lite: 負例のみ
- quick: 全3本
- integration: セルフホスト解析追加
### 成果物
- ✅ スモークテスト3本: 150行
- ✅ プロファイル設定: 30行
- **合計**: 180行
### 完了基準
- [ ] 全スモークテストPASS
- [ ] quick-liteで負例Fail-Fast確認
---
## Day 7: セルフホスト解析 + ドキュメント (2025-10-26)
### 🎯 目標
- セルフホストコードでの実用検証
- 精度95%以上確認
- ドキュメント整備
### タスク
#### セルフホスト解析 (2時間)
```bash
# selfhost/compiler/builder/rewrite/known.hako を解析
NYASH_GATE_C_STRICT=1 ./target/release/hakorune --emit-mir-json /tmp/known.json \
apps/selfhost-compiler/builder/rewrite/known.hako
# Analyzerで解析
./target/release/hakorune -c "
using selfhost.analyzer.driver as DriverBox
# /tmp/known.json の内容を読み込み(簡易版)
local result = DriverBox.run_from_string(mir_json, \"mir\")
print(result)
"
```
#### ドキュメント整備 (1時間)
- Phase 32 README.md 更新(実装完了マーク)
- PLAN.md 実績LOC記録
#### 精度検証 (30分)
- 手動でデッドコード候補確認
- 偽陽性/偽陰性チェック
### 成果物
- ✅ 実用検証レポート: 50行
- ✅ ドキュメント更新
- **合計**: 50行
### 完了基準
- [ ] セルフホストコードで95%以上の精度
- [ ] ドキュメント完備
- [ ] 1,000行ファイルを5秒以内で解析
---
## 📊 進捗トラッキング
| Day | 計画LOC | 実績LOC | 状態 | 備考 |
|-----|--------|--------|------|------|
| Day 1 | 180 | - | 🟡 | スケルトン + README |
| Day 2 | 150 | - | 🟡 | MIR走査基盤 |
| Day 3 | 250 | - | 🟡 | 呼び出しグラフ |
| Day 4 | 300 | - | 🟡 | BFS到達可能性 |
| Day 5 | 120 | - | 🟡 | レポート生成 |
| Day 6 | 180 | - | 🟡 | スモークテスト |
| Day 7 | 50 | - | 🟡 | セルフホスト解析 |
| **Total** | **1,230** | **-** | | |
---
## 🎯 成功基準(最終確認)
- [ ] **精度**: >95%(セルフホストコードで手動検証)
- [ ] **再現率**: >90%(既知デッドコード検出)
- [ ] **処理速度**: <5秒1,000行ファイル
- [ ] **使いやすさ**: 1コマンドで実行可能
- [ ] **テストカバレッジ**: 3件のスモークテスト全PASS
---
## 🚨 リスク & 対策
### リスク1: selfhost/shared依存の複雑さ
- **対策**: Day 1でimport確認早期検証
- **バックアップ**: 簡易JSON解析を自前実装
### リスク2: BFS パフォーマンス
- **対策**: ArrayBox簡易キュー小規模グラフで十分
- **バックアップ**: 将来QueueBox追加可能
### リスク3: セルフホスト解析で想定外の問題
- **対策**: Day 7に余裕を持たせる
- **バックアップ**: 簡単な例で先に検証
---
**作成日**: 2025-10-19
**改訂日**: 2025-10-19構造改訂版
**開始予定**: 2025-10-20
**完了予定**: 2025-10-27

View File

@ -0,0 +1,303 @@
# Phase 32: Hakorune Static Analyzer - Dead Code Detector MVP
**Status**: 計画完了、実装準備中(構造改訂版)
**期間**: 1週間7日、2025-10-20 → 2025-10-27
**担当**: Claude + ChatGPT協調
**優先度**: HIGH ⭐⭐⭐⭐⭐
**Ring位置**: Ring-1Meta/自己ホスト)
---
## 🎯 目標
**HakoruneでHakoruneコードを解析する静的解析ツールの実装**
### Phase 32 スコープMVP
- ✅ MIR JSONからデッドコード到達不可能関数を検出
- ✅ Gate-C/AST Strict MIR前提の厳密解析
- ✅ テキストレポート出力(診断サマリ)
- ✅ 95%以上の精度目標
### Phase 32外Phase 33以降
- ❌ 重複コード検出Phase 33
- ❌ 複雑度メトリクスPhase 34
- ❌ マルチファイル解析Phase 35
- ❌ JSON/DOT出力Phase 36
---
## 💡 革命的な理由
### 15倍の精度改善
- **cargo-udeps**: 25%精度75%誤検出)
- **Hakorune Analyzer**: 95%精度5%誤検出)
### なぜこんなに精度が高いのか?
1. **完璧な呼び出しグラフ**
- グローバル変数なしすべてBox
- 明示的関数呼び出しのみ
- 動的ディスパッチも型情報で追跡可能
2. **ネイティブMIRアクセス**
- Rust: 外部ツールでAST推論不正確
- Hakorune: Gate-C Strict MIR JSONで完全な呼び出し情報
3. **Box理論の恩恵**
- すべてBoxで統一
- 拡張が簡単新しいBoxを追加するだけ
- 型安全
---
## 🏗️ アーキテクチャ設計(改訂版)
### 配置理由: selfhost/ 配下
**Three Rings の Ring-1Meta/自己ホスト)に属する開発ツール**
- 将来のコンパイラと密に連携する前提
- selfhost/shared の BoxHelpers/MirSchema/Gate-C Strict を直に再利用
- 独立箱として将来 CLI 化しやすい
### ファイル構造(責務分離)
```
selfhost/analyzer/
├── hako_module.toml # exports 最小selfhost.analyzer.*
├── boxes/
│ ├── driver_box.hako # 入口: 入力→走査→レポート
│ ├── ast_scan_box.hako # AST Strict前提の走査
│ ├── mir_scan_box.hako # Gate-C Strict MIR JSONの走査
│ └── report_box.hako # 集計と文字列整形、出力
├── README.md # 責務/入出力/ENV/非対象
└── smokes/
├── analyzer_ast_strict_ok_vm.sh
├── analyzer_mir_gatec_ok_vm.sh
└── analyzer_bad_mir_fail_vm.sh # 負例・診断固定
```
### データフロー
```
.hako file
↓ (hakorune --emit-mir-json + Gate-C Strict)
MIR JSON (厳密型保証)
↓ driver_box.hako
├→ ast_scan_box.hako (AST走査)
└→ mir_scan_box.hako (MIR走査)
↓ selfhost/shared/MirSchema
↓ BoxHelpers (JSON解析)
↓ 到達可能性分析BFS
["unused_helper/1", "deprecated_func/0"]
↓ report_box.hako
Text Report + MapBox診断
```
---
## 📦 依存とガードFail-Fast
### 依存関係
-**selfhost/shared のみ**BoxHelpers, MirSchema, JsonEmit
-**外部I/Oなし**(入力は文字列/MapBox
- ✅ **Gate-C/AST Strict を既定ON**で実行
### 環境変数dev限定
```bash
# 追加チェックON
NYASH_ANALYZER_STRICT=1
# 将来の切替(既定=mir
HAKO_ANALYZER_ENTRY=ast|mir
# Gate-C/AST Strictスモークテストで既定ON
NYASH_GATE_C_STRICT=1
NYASH_AST_STRICT=1
```
### Fail-Fast 原則
- 不正なMIR JSON → 即座にエラー
- 余剰キー/型不一致 → 診断固定(負例テスト)
- フォールバック禁止Silent failure なし)
---
## 🔧 公開インターフェース(最小)
### DriverBox API
```hako
static box DriverBox {
# 文字列入力→文字列出力
run_from_string(input: StringBox, kind: StringBox) -> StringBox
# MapBox入力→MapBox出力
run_from_box(input: MapBox, kind: StringBox) -> MapBox
}
```
**kind引数**:
- `"ast"` - AST走査将来実装
- `"mir"` - MIR JSON走査Phase 32実装
**返り値**:
- 文字列: 診断サマリ(テキストレポート)
- MapBox: 構造化診断dead_functions, reachable_functions等
---
## 📋 実装計画(改訂版)
| Day | タスク | 成果物 | LOC | 状態 |
|-----|--------|--------|-----|------|
| **Day 1** | スケルトン作成 | driver/ast_scan/mir_scan/report + README | 150 | 🟡 準備中 |
| **Day 2** | MIR走査基盤 | mir_scan_box.hako関数抽出 | 200 | 🟡 計画中 |
| **Day 3** | 呼び出しグラフ構築 | mir_scan_box.hako拡張Graph | 250 | 🟡 計画中 |
| **Day 4** | BFS到達可能性分析 | mir_scan_box.hako完成 | 200 | 🟡 計画中 |
| **Day 5** | レポート生成 | report_box.hako完成 | 150 | 🟡 計画中 |
| **Day 6** | スモークテスト整備 | 3本happy/happy/負例) | 100 | 🟡 計画中 |
| **Day 7** | セルフホスト解析 + ドキュメント | 実用化 | 50 | 🟡 計画中 |
| **Total** | | | **1,100** | |
---
## 🧪 テスト戦略(ドキュメント・テスト先行)
### スモークテスト構成
**happy path 2本**:
```bash
# AST Strict入力将来
selfhost/analyzer/smokes/analyzer_ast_strict_ok_vm.sh
# Gate-C MIR JSON入力Phase 32
selfhost/analyzer/smokes/analyzer_mir_gatec_ok_vm.sh
```
**負例1本診断文言固定**:
```bash
# 不正MIR: 余剰キー/型不一致
selfhost/analyzer/smokes/analyzer_bad_mir_fail_vm.sh
```
### quick-lite → quick → integration 段階追加
- **quick-lite**: 負例のみ診断Fail-Fast確認
- **quick**: happy path 2本追加
- **integration**: セルフホストコード解析(実用検証)
---
## 🎓 参考実装(学習元)
### selfhost/shared から再利用
1. **BoxHelpers** - JSON解析パターン
2. **MirSchema** - MIR構造定義
3. **JsonEmit** - MapBox→JSON文字列変換
### Rustコードベースから学ぶ
1. **src/mir/optimizer.rs** (`diagnose_unlowered_type_ops`)
- デッドコード検出の基本パターン
2. **src/mir/verification.rs**
- 呼び出し検証ロジック
- Callee型のパース
---
## 📈 Phase 33以降の展望
### Phase 33: 重複コード検出1週間
- MIR正規化レジスタ・定数・演算子
- 構造ハッシュ化
- 4種類の重複完全一致/変数名/構造/部分)
### Phase 34: 複雑度メトリクス1週間
- サイクロマティック複雑度
- 認知的複雑度
- 行数・関数数統計
### Phase 35: マルチファイル解析2週間
- プロジェクト全体解析
- モジュール間依存グラフ
- 到達可能性の階層分析
### Phase 36: 可視化・出力2週間
- JSON出力機械可読
- DOT出力Graphviz
- HTML/Markdown レポート
**合計**: 7週間で完全な静的解析ツールキット完成
---
## 🏆 期待される成果
### 技術的成果
1. **95%精度のデッドコード検出器**
2. **セルフホスト開発の加速**(不要コード削除)
3. **Everything is Box のショーケース**
### 戦略的成果
1. **論文ネタ**: "70日でセルフホスト + 静的解析ツール"
2. **採用材料**: Hakorune の品質保証能力
3. **コミュニティ貢献**: 他言語でも応用可能なパターン
### 学術的価値
- **PLDI SRC**: "Bootstrapping Static Analysis"
- **ICSE Demo**: 実動デモ
- **比較研究**: cargo-udeps vs Hakorune (15倍精度)
---
## 🚀 導入ステップ(短期)
### Step 1: スケルトン作成Day 1
```bash
mkdir -p selfhost/analyzer/{boxes,smokes}
touch selfhost/analyzer/hako_module.toml
touch selfhost/analyzer/README.md
touch selfhost/analyzer/boxes/{driver_box,ast_scan_box,mir_scan_box,report_box}.hako
```
### Step 2: Gate-C/AST Strict happy pathDay 2-3
- MIR JSON入力の基本走査
- 関数リスト抽出
- スモーク2本
### Step 3: 負例スモークDay 4
- 不正MIR: 余剰キー/型不一致
- 診断文言固定
### Step 4: CURRENT_TASK.md 登録
- Phase 32 トラックとして追加
---
## 📚 関連ドキュメント
- **設計書**: `docs/development/proposals/analyzer-mvp-summary.md`
- **アルゴリズム**: `docs/development/proposals/dead-code-detection/call-graph-algorithm-detailed-design.md`
- **重複検出**: `docs/development/proposals/ideas/refactoring/mir-duplicate-detection-algorithm.md`
- **実現可能性**: `docs/development/proposals/hakorune-static-analyzer-feasibility.md`
- **実装ガイド**: `docs/development/proposals/analyzer-implementation-guide.md`SSOT要約を selfhost/analyzer/README.md に配置)
---
## ✅ 決定事項
1. **配置**: selfhost/analyzer/Ring-1: Meta/自己ホスト) ✅
2. **責務分離**: driver/ast_scan/mir_scan/report ✅
3. **依存**: selfhost/shared のみ ✅
4. **Gate-C/AST Strict**: 既定ON ✅
5. **Fail-Fast**: フォールバック禁止 ✅
6. **テスト先行**: ドキュメント→スモーク→実装 ✅
---
**作成日**: 2025-10-19
**改訂日**: 2025-10-19構造改訂版
**次回レビュー**: 2025-10-20 (Day 1完了時)
**最終更新**: 2025-10-19