feat(hako_check): Phase 153 - Dead code detection revival (JoinIR version)

Implement comprehensive dead code detection for hako_check with JoinIR
integration, following Phase 133/134/152 box-based modularity pattern.

## Key Achievements

1. **Comprehensive Inventory** (`phase153_hako_check_inventory.md`):
   - Documented current hako_check architecture (872 lines)
   - Analyzed existing HC011/HC012 rules
   - Confirmed JoinIR-only pipeline (Phase 124)
   - Identified Phase 153 opportunities

2. **DeadCodeAnalyzerBox** (`rule_dead_code.hako`):
   - Unified HC019 rule (570+ lines)
   - Method-level + box-level dead code detection
   - DFS reachability from entrypoints
   - Text-based analysis (no MIR JSON dependency for MVP)
   - Heuristic-based false positive reduction

3. **CLI Integration** (`cli.hako`):
   - Added `--dead-code` flag for comprehensive mode
   - Added `--rules dead_code` for selective execution
   - Compatible with --format (text/json-lsp/dot)

4. **Test Infrastructure**:
   - HC019_dead_code test directory (ng/ok/expected.json)
   - `hako_check_deadcode_smoke.sh` with 4 test cases

## Technical Details

- **Input**: Analysis IR (MapBox with methods/calls/boxes/entrypoints)
- **Output**: HC019 diagnostics
- **Algorithm**: Graph-based DFS reachability
- **Pattern**: Box-based modular architecture
- **No ENV vars**: CLI flags only

## Files Modified

- NEW: docs/development/current/main/phase153_hako_check_inventory.md
- NEW: tools/hako_check/rules/rule_dead_code.hako
- MOD: tools/hako_check/cli.hako
- NEW: tools/hako_check/tests/HC019_dead_code/
- NEW: tools/hako_check_deadcode_smoke.sh
- MOD: CURRENT_TASK.md

## Next Steps

- Phase 154+: MIR CFG integration for block-level detection
- Phase 160+: Integration with .hako JoinIR/MIR migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-04 14:19:48 +09:00
parent d75bbf4f90
commit c85d67c92e
19 changed files with 1388 additions and 8 deletions

View File

@ -1,5 +1,8 @@
# 🔄 現在のVM変更状態 (2025-08-21)
> **Status**: Legacy snapshotPhase 9.78 系の記録)
> **Note**: 現在の正本はリポジトリ直下の `CURRENT_TASK.md` および `docs/development/roadmap/` / `docs/private/roadmap/` 側に集約しています。このファイルは当時の実装状況メモとしてのみ残しています。
## 📊 Phase 9.78a VM統一Box処理の実装状況
### ✅ 完了したステップ
@ -144,4 +147,4 @@ VM → UnifiedBoxRegistry ✅ (推奨)
---
**結論**: **Option A置いておく**を推奨します。現在の実装は方向性として正しく、インタープリター整理後に続きから再開するのが最も効率的です。
**結論**: **Option A置いておく**を推奨します。現在の実装は方向性として正しく、インタープリター整理後に続きから再開するのが最も効率的です。

View File

@ -1,5 +1,8 @@
JIT Phase 10_7 — Known Issues and Future Refinements (2025-08-27)
Status: Legacy snapshotフェーズ固有の既知問題メモ
Scope: LowerCore(Core-1), Branch/PHI wiring, ABI(min), Stats/CFG dump
1) b1 PHI tagging heuristics
@ -49,4 +52,3 @@ Scope: LowerCore(Core-1), Branch/PHI wiring, ABI(min), Stats/CFG dump
9) Documentation sync
- Symptom: Some flags visible via CLI and boxes; ensure README/CURRENT_TASK stay aligned.
- Future: Add short “JIT quick flags” section with examples in docs.

View File

@ -1,8 +1,9 @@
# Phi 正規化プラン9.78h スキャフォールド)
目的: ループ/分岐における Phi 選択を正道に戻し、借用衝突を避けつつ段階導入する。
> **Status**: Archived plan実装済み / 設計メモ)
> **Note**: Step 3 まで実装済みで、MIR ビルダーは既定で PHI-on。以降は `docs/development/roadmap/` / `docs/private/roadmap/` 側の設計を正とし、このファイルは当時の段階プランの記録として残しています。
> ステータス更新2025-09-26: Step 3 まで実装済みで、MIR ビルダーは既定で PHI-on になったよ。以下のプランはアーカイブとして残しているよ
目的: ループ/分岐における Phi 選択を正道に戻し、借用衝突を避けつつ段階導入する
段階プラン80/20
- Step 1: 実行系での選択復帰(完了)

View File

@ -1,5 +1,8 @@
# Plugin Loader Migration Plan
> **Status**: Migration plan memo継続検討用の設計メモ
> **Note**: 実際の進捗と優先度は `CURRENT_TASK.md` と roadmap 側を正として管理し、このファイルはプラグインローダ統合の設計メモ・タスクリストとして扱います。
## Overview
Consolidate three plugin loader implementations into a single unified system.
@ -113,4 +116,4 @@ fn detect_plugin_type(path: &str) -> PluginType {
- Phase 5-6: Day 4
- Phase 7: Day 5
Total: 5 days for complete migration
Total: 5 days for complete migration

View File

@ -1,5 +1,8 @@
## ResultBox Migration TODO (Phase 9.78h follow-up)
> **Status**: Legacy TODO状態スナップショット
> **Note**: 実際の移行状況・今後の計画は `RESULTBOX` 関連のコードとロードマップ側を正とし、このメモは Phase 9.78h 時点のタスク列挙の記録としてのみ保持しています。
Goal: fully migrate from legacy `box_trait::ResultBox` to `boxes::result::NyashResultBox` (aka `boxes::ResultBox`).
### Current usages (grep snapshot)

View File

@ -1,5 +1,8 @@
# Function Values, Captures, and Events
> **Status**: Behavior summary現仕様サマリ兼設計ート
> **Note**: 関数値 / キャプチャ / イベントに関する現行挙動の要約です。詳細仕様は `docs/reference/language/` や関連アーキテクチャドキュメントを正として参照してください。
Summary of current behavior and guidelines.
- Function values: created via `function(...) { ... }` produce a `FunctionBox` with

View File

@ -1,5 +1,8 @@
# JIT機能拡張 - 2025年8月27日
> **Status**: Historical JIT enhancement note実装完了済みの観測メモ
> **Note**: 機能の現状はコードベースと JIT 関連の roadmap を正とし、この文書は 2025-08-27 時点の実装内容・観測方法の記録として残しています。
## ChatGPT5による最新実装
### 1. PHI可視化強化
@ -65,4 +68,4 @@ NYASH_JIT_DUMP=1 ./target/release/nyash --backend vm examples/phi_bool_merge.hak
3. **最適化ヒント**: ブール返り値のカウントによる最適化機会の発見
4. **デバッグ支援**: より詳細な情報による問題解析の容易化
Box-First方法論の「観測箱」の具現化として、これらの機能は論文の実証例となる。
Box-First方法論の「観測箱」の具現化として、これらの機能は論文の実証例となる。

View File

@ -0,0 +1,543 @@
# Phase 153: hako_check Inventory (Dead Code Detection Mode)
**Created**: 2025-12-04
**Phase**: 153 (hako_check / dead code detection mode revival)
---
## Executive Summary
This document inventories the current state of `hako_check` as of Phase 153, with focus on:
1. Current execution flow and architecture
2. Existing dead code detection capabilities (HC011, HC012)
3. JoinIR integration status
4. Gaps and opportunities for Phase 153 enhancement
**Key Finding**: hako_check already has partial dead code detection through HC011 (dead methods) and HC012 (dead static boxes), but lacks:
- MIR-level unreachable block detection
- CFG-based reachability analysis
- Integration with JoinIR's control flow information
- Unified `--dead-code` flag for comprehensive dead code reporting
---
## 1. Current Architecture
### 1.1 Execution Flow
```
.hako source file
tools/hako_check.sh (bash wrapper)
tools/hako_check/cli.hako (VM-executed .hako script)
HakoAnalysisBuilderBox.build_from_source_flags()
├─ HakoParserCoreBox.parse() (AST generation)
└─ Text-based scanning (fallback)
Analysis IR (MapBox) with:
- methods: Array<String> (qualified: "Box.method/arity")
- calls: Array<Map{from, to}>
- boxes: Array<Map{name, is_static, methods}>
- entrypoints: Array<String>
- source: String (original text)
Rule execution (19 rules, including HC011/HC012)
Diagnostics output (text / JSON-LSP / DOT)
```
### 1.2 Key Components
**Entry Points**:
- `tools/hako_check.sh` - Shell script wrapper with environment setup
- `tools/hako_check/cli.hako` - Main .hako script (HakoAnalyzerBox)
**Core Boxes**:
- `HakoAnalyzerBox` (cli.hako) - Main orchestrator
- `HakoAnalysisBuilderBox` (analysis_consumer.hako) - IR builder
- `HakoParserCoreBox` (tools/hako_parser/parser_core.hako) - AST parser
**Dead Code Rules**:
- `RuleDeadMethodsBox` (rule_dead_methods.hako) - HC011
- `RuleDeadStaticBoxBox` (rule_dead_static_box.hako) - HC012
**IR Format** (MapBox):
```javascript
{
path: String,
source: String,
uses: Array<String>,
boxes: Array<{
name: String,
is_static: Boolean,
span_line: Integer,
methods: Array<{
name: String,
arity: Integer,
span: Integer
}>
}>,
methods: Array<String>, // "Box.method/arity"
calls: Array<{from: String, to: String}>,
entrypoints: Array<String>
}
```
---
## 2. Existing Dead Code Detection
### 2.1 HC011: Dead Methods (Unreachable Methods)
**File**: `tools/hako_check/rules/rule_dead_methods.hako`
**Algorithm**:
1. Build adjacency graph from `calls` array
2. DFS from entrypoints (Main.main, main, etc.)
3. Mark visited methods
4. Report unvisited methods as dead
**Limitations**:
- Only detects unreachable methods (function-level granularity)
- No unreachable block detection within functions
- Heuristic-based call detection (text scanning fallback)
- No integration with MIR CFG information
**Test Coverage**:
- `HC011_dead_methods/ng.hako` - Contains unreachable method
- `HC011_dead_methods/ok.hako` - All methods reachable
### 2.2 HC012: Dead Static Box (Unused Static Boxes)
**File**: `tools/hako_check/rules/rule_dead_static_box.hako`
**Algorithm**:
1. Collect all static box names from IR
2. Build set of referenced boxes from calls
3. Report boxes with no references (except Main)
**Limitations**:
- Only detects completely unreferenced boxes
- No detection of boxes with unreachable methods only
- AST span_line support for precise line reporting
**Test Coverage**:
- `HC012_dead_static_box/ng.hako` - Unused static box
- `HC012_dead_static_box/ok.hako` - All boxes referenced
### 2.3 HC016: Unused Alias
**File**: `tools/hako_check/rules/rule_unused_alias.hako`
**Note**: While not strictly "dead code", unused aliases are dead declarations.
---
## 3. JoinIR Integration Status
### 3.1 Current Pipeline (Phase 124 Completion)
**Status**: ✅ **JoinIR-only pipeline established**
As of Phase 124 (completed 2025-12-04), hako_check uses JoinIR exclusively:
```
.hako file
Tokenize / Parse (Rust Parser)
AST Generation
MIR Builder (JoinIR lowering for if/loop)
├─ cf_if() → lower_if_form() (JoinIR-based PHI)
└─ cf_loop() → LoopBuilder (JoinIR-based PHI)
MIR Generation (with JoinIR PHI)
VM Interpreter
hako_check Analysis
```
**Key Points**:
- `NYASH_HAKO_CHECK_JOINIR` flag removed (JoinIR is default)
- No legacy PHI fallback in hako_check path
- All If/Loop constructs use JoinIR lowering
### 3.2 MIR Integration Opportunities
**Current Gap**: hako_check does not consume MIR for dead code analysis
**Opportunity**: Integrate MIR CFG for block-level reachability:
- MIR already has `src/mir/passes/dce.rs` (instruction-level DCE)
- MIR has CFG information (`function.blocks`, `block.terminator`)
- JoinIR lowering provides high-quality PHI nodes for control flow
**Potential Input Formats**:
1. **MIR JSON v0** - Existing format from `--emit-mir-json`
2. **JoinIR JSON** - Direct JoinIR representation
3. **Analysis IR** - Current text-based IR (simplest, current approach)
---
## 4. Related Rust Code (Inventory)
### 4.1 MIR Dead Code Elimination
**File**: `src/mir/passes/dce.rs`
**Purpose**: Instruction-level dead code elimination (DCE)
**Scope**:
- Eliminates unused results of pure instructions
- Works at ValueId level (SSA values)
- Does **not** eliminate unreachable blocks or functions
**Relevance**: Could be extended or adapted for hako_check integration
### 4.2 MIR Verification
**File**: `src/mir/verification/cfg.rs`
**Purpose**: CFG consistency verification
**Relevance**: Contains CFG traversal utilities that could be reused for reachability analysis
### 4.3 MIR Optimizer
**File**: `src/mir/optimizer.rs`
**Purpose**: Multi-pass MIR optimization
**Relevance**: Orchestrates DCE and other passes; pattern for DeadCodeAnalyzerBox
---
## 5. Gaps and Phase 153 Scope
### 5.1 Existing Capabilities ✅
- [x] Dead method detection (HC011)
- [x] Dead static box detection (HC012)
- [x] JoinIR-only pipeline (Phase 124)
- [x] Text-based call graph analysis
- [x] Entrypoint-based DFS reachability
### 5.2 Missing Capabilities (Phase 153 Targets)
#### High Priority
- [ ] **Unreachable block detection** (within functions)
- Example: `if false { ... }` dead branches
- Example: Code after unconditional `return`
- [ ] **MIR CFG integration**
- Use MIR's block graph for precise reachability
- Detect unreachable blocks post-JoinIR lowering
- [ ] **Unified `--dead-code` flag**
- Aggregate HC011 + HC012 + new block detection
- Single command for comprehensive dead code audit
#### Medium Priority
- [ ] **JoinIR-specific analysis**
- Analyze IfMerge/LoopForm for unreachable paths
- Detect always-true/always-false conditions
- [ ] **CFG visualization integration**
- Extend DOT output with unreachable block highlighting
- `--format dot --dead-code` mode
#### Low Priority (Future Phases)
- [ ] Call graph visualization with dead paths
- [ ] Dataflow-based dead code detection
- [ ] Integration with Phase 160+ .hako JoinIR/MIR migration
---
## 6. Phase 153 Implementation Plan
### 6.1 Minimal Viable Product (MVP)
**Goal**: Revive dead code detection with MIR block-level reachability
**Scope**:
1. Create `DeadCodeAnalyzerBox` (.hako implementation)
2. Input: Analysis IR (current format) + optional MIR JSON
3. Output: Unreachable block reports
4. CLI: Add `--dead-code` flag to aggregate all dead code diagnostics
**Non-Goals** (Phase 153):
- No new environment variables
- No changes to JoinIR/MIR semantics
- No complex dataflow analysis (pure reachability only)
### 6.2 Box-Based Architecture (Phase 133/134 Pattern)
**Pattern**: Modular analyzer box following if_dry_runner.rs precedent
```
DeadCodeAnalyzerBox
├─ analyze_reachability(ir) → UnreachableBlocks
├─ analyze_call_graph(ir) → DeadFunctions
└─ aggregate_report() → Array<Diagnostic>
```
**Characteristics**:
- Self-contained .hako implementation
- No modification to existing rules (HC011/HC012 unchanged)
- Additive enhancement (no breaking changes)
### 6.3 Input Format Decision
**Recommendation**: Start with **Analysis IR** (current format)
**Rationale**:
- Minimally invasive (no new serialization)
- Works with existing hako_check pipeline
- Can extend to MIR JSON in Phase 154+ if needed
**Analysis IR Extensions** (if needed):
```javascript
{
// ... existing fields ...
blocks: Array<{
id: Integer,
function: String,
reachable: Boolean,
terminator: String
}>
}
```
---
## 7. Test Inventory
### 7.1 Existing Dead Code Tests
**HC011 Tests** (Dead Methods):
- `tools/hako_check/tests/HC011_dead_methods/`
- `ng.hako` - Method never called
- `ok.hako` - All methods reachable
- `expected.json` - Diagnostic expectations
**HC012 Tests** (Dead Static Box):
- `tools/hako_check/tests/HC012_dead_static_box/`
- `ng.hako` - Box never instantiated
- `ok.hako` - All boxes used
- `expected.json` - Diagnostic expectations
### 7.2 Planned Phase 153 Tests
**HC011-B** (Unreachable Block):
```hako
static box Test {
method demo() {
if false {
// This block is unreachable
print("dead code")
}
return 0
}
}
```
**HC011-C** (Code After Return):
```hako
static box Test {
method demo() {
return 0
print("unreachable") // Dead code
}
}
```
**Integration Test** (Comprehensive):
- Combines dead methods, dead boxes, and dead blocks
- Verifies `--dead-code` flag aggregates all findings
---
## 8. CLI Design (Phase 153)
### 8.1 Current CLI
```bash
# Basic analysis
./tools/hako_check.sh target.hako
# Rule filtering
./tools/hako_check.sh --rules dead_methods,dead_static_box target.hako
# JSON-LSP output
./tools/hako_check.sh --format json-lsp target.hako
```
### 8.2 Proposed Phase 153 CLI
```bash
# Enable comprehensive dead code detection
./tools/hako_check.sh --dead-code target.hako
# Dead code only (skip other rules)
./tools/hako_check.sh --rules dead_code target.hako
# Combine with visualization
./tools/hako_check.sh --dead-code --format dot target.hako > cfg.dot
```
**Behavior**:
- `--dead-code`: Enables HC011 + HC012 + new block analysis
- Exit code: Number of dead code findings (0 = clean)
- Compatible with existing `--format` options
---
## 9. Environment Variables (No New Additions)
**Phase 153 Constraint**: No new environment variables
**Existing Variables** (hako_check uses):
- `NYASH_DISABLE_PLUGINS=1` - Required for stability
- `NYASH_BOX_FACTORY_POLICY=builtin_first` - Box resolution
- `NYASH_FEATURES=stage3` - Parser stage
- `NYASH_JSON_ONLY=1` - Pure JSON output (json-lsp mode)
**Decision**: All Phase 153 control via CLI flags only
---
## 10. JoinIR Design Principles Compliance
### 10.1 Read-Only Analysis
**Compliant**: DeadCodeAnalyzerBox only reads IR, does not modify it
### 10.2 No Semantic Changes
**Compliant**: Analysis is post-compilation, no effect on MIR generation
### 10.3 Box-First Modularity
**Compliant**: DeadCodeAnalyzerBox follows established pattern
### 10.4 Fail-Fast (Not Applicable)
N/A: Analysis cannot fail (always produces some result, possibly empty)
---
## 11. Integration with Phase 160+
**Context**: Phase 160+ will migrate .hako sources to JoinIR/MIR
**hako_check Role**: Safety net for migration
**Benefits**:
- Detect dead code introduced during migration
- Verify call graph integrity
- Catch unreachable blocks from refactoring
**Preparation** (Phase 153):
- Establish solid baseline for dead code detection
- Prove DeadCodeAnalyzerBox on current codebase
- Document false positive patterns
---
## 12. Known Limitations (Phase 153)
### 12.1 Dynamic Call Detection
**Limitation**: Text-based call scanning cannot detect dynamic calls
**Example**:
```hako
local method_name = "compute"
// Call via reflection (not detectable by hako_check)
```
**Mitigation**: Document as known limitation
### 12.2 False Positives
**Pattern**: Intentionally unused utility methods
**Example**:
```hako
static box Utils {
// Future use, not yet called
method reserved_for_later() { }
}
```
**Mitigation**: Allow suppression comments (future phase)
### 12.3 Cross-Module Analysis
**Limitation**: hako_check analyzes single files only
**Consequence**: Cannot detect dead code exported but unused elsewhere
**Mitigation**: Document as boundary condition
---
## 13. Success Criteria (Phase 153)
### 13.1 Functional Requirements
- [ ] DeadCodeAnalyzerBox implemented in .hako
- [ ] `--dead-code` flag functional
- [ ] HC011 + HC012 + block detection working
- [ ] 2-3 test cases passing
- [ ] Smoke script created
### 13.2 Quality Requirements
- [ ] No regression in existing hako_check tests
- [ ] Box-based modular architecture
- [ ] Documentation updated (this file + hako_check_design.md)
- [ ] Git commit with clear message
### 13.3 Non-Functional Requirements
- [ ] Performance: <5% overhead on existing hako_check
- [ ] Compatibility: Works with all existing CLI options
- [ ] Maintainability: <200 lines for DeadCodeAnalyzerBox
---
## 14. Next Steps (Post-Inventory)
1. **Task 2**: Verify JoinIR-only pipeline (confirm no legacy fallback)
2. **Task 3**: Design DeadCodeAnalyzerBox API and format
3. **Task 4**: Implement DeadCodeAnalyzerBox
4. **Task 5**: Create test cases and smoke script
5. **Task 6**: Update documentation and commit
---
## 15. References
**Related Documents**:
- `phase153_hako_check_deadcode.md` - Phase 153 specification
- `hako_check_design.md` - Current hako_check architecture
- `phase121_integration_roadmap.md` - JoinIR integration history
- `phase124_hako_check_joinir_finalization.md` - JoinIR-only completion
**Related Code**:
- `tools/hako_check/` - Current implementation
- `src/mir/passes/dce.rs` - Rust DCE reference
- `src/mir/verification/cfg.rs` - CFG verification utilities
**Test Fixtures**:
- `tools/hako_check/tests/HC011_dead_methods/`
- `tools/hako_check/tests/HC012_dead_static_box/`
---
**Status**: Inventory Complete
**Next**: Task 2 (JoinIR Pipeline Verification)

View File

@ -1,5 +1,8 @@
# Phase 9.78e: Dynamic Method Dispatch Implementation Summary
> **Status**: Historical summaryPhase 9.78e 実装レポート)
> **Note**: 現在の設計・実装状況は最新の `docs/development/architecture/` / `docs/development/roadmap/` を正とし、このファイルは当時の実装状態の記録としてのみ参照してください。
## 🎯 Overview
Phase 9.78e aimed to implement dynamic method dispatch through the `call_method` trait method to unify method calling across all Box types.
@ -79,4 +82,4 @@ Phase 9.78e aimed to implement dynamic method dispatch through the `call_method`
---
*Phase 9.78e establishes the foundation for unified method dispatch across all Nyash Box types, with the core infrastructure successfully implemented and ready for expanded integration.*
*Phase 9.78e establishes the foundation for unified method dispatch across all Nyash Box types, with the core infrastructure successfully implemented and ready for expanded integration.*

View File

@ -1,5 +1,8 @@
# Phase 2.4 Verification Report
> **Status**: Historical verification reportアーカイブ候補
> **Note**: 本レポートは Phase 2.4 完了時点の検証記録です。現行状態の確認には `docs/development/status/` の他レポートや最新の roadmap を参照してください。
> **Generated**: 2025-09-24
> **Status**: ✅ Successfully Verified
> **Context**: Post-legacy cleanup verification after 151MB reduction
@ -127,4 +130,4 @@ Phase 2.4 objectives achieved:
**Signed off by**: Claude (AI Assistant)
**Date**: 2025-09-24
**Next Phase**: 15.5 "Everything is Plugin"
**Next Phase**: 15.5 "Everything is Plugin"