refactor(extractors): Phase 282 P9a - CommonExtractionHelpers SSOT統合(スコープ限定版)

# Phase 282 P9a 完了 (Scope-Limited Integration)

## 実装内容
- **common_helpers.rs 作成**: 4グループの共通ヘルパー統合 (316行)
  - Group 1: Control Flow Counting (count_control_flow - 汎用カウンター)
  - Group 2: Control Flow Detection (has_break/continue/return_statement)
  - Group 3: Condition Validation (extract_loop_variable, is_true_literal)
  - Group 4: Pattern5専用ヘルパー (validate_continue_at_end, validate_break_in_simple_if)

- **Pattern統合完了**: Pattern5 → Pattern4 → Pattern2 → Pattern1
  - Pattern5: ~90行削減 (5 tests PASS)
  - Pattern4: ~66行削減 (5 tests PASS)
  - Pattern2: ~67行削減 (4 tests PASS)
  - Pattern1: ~28行削減 (3 tests PASS)
  - Pattern3: 別フェーズに延期(pattern固有ロジック除外)

## 成果
- **コード削減**: ~251行(Pattern3除く、total ~400行見込み)
- **テスト**: 40 unit tests PASS (23 common_helpers + 17 extractors)
- **スモークテスト**: 45 PASS, 1 pre-existing FAIL(退行ゼロ)
- **ビルド警告**: 130 → 120 (-10)

## USER CORRECTIONS適用済み
1.  スコープ限定(共通ロジックのみ、pattern固有除外)
2.  Placeholder禁止(SSOT違反排除)
3.  統合順序変更(Pattern3を最後/別フェーズへ)

## 追加ドキュメント
- Phase 284 計画追加(Return as ExitKind SSOT)
- 10-Now.md, 30-Backlog.md 更新

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-23 11:14:28 +09:00
parent bf6f4faa1f
commit 41d92bedb9
15 changed files with 1600 additions and 259 deletions

View File

@ -0,0 +1,29 @@
# Phase 284 P0docs-only: Return as ExitKind SSOT
目的: `return` を pattern 個別実装へ散らさず、`ExitKind::Return``compose::*` / `emit_frag()` に収束させるための SSOT を固定する。
## このP0でやることコード変更なし
1. SSOT を 1 枚にまとめる
- `docs/development/current/main/phases/phase-284/README.md` を SSOT として整える(用語・責務・境界)。
2. 既存SSOTとの整合を取る
- Phase 282 の “SSOT=extract / pattern_kind=safety valve / lower re-extract” と矛盾しないこと。
3. “移行期間の穴” を塞ぐ言い方にする
- close-but-unsupported は `Ok(None)` ではなく `Err`Fail-Fastであることを明記。
## 文書に必ず入れる事項(チェックリスト)
- [ ] `return expr``ExitKind::Return` で表現するpattern の特例は禁止)
- [ ] Return edge の返り値は `EdgeArgs`(または Return 用 argsで運ぶ
- [ ] terminator 生成は `emit_frag()` が SSOTReturn も例外なし)
- [ ] extractor の返り値境界: `Ok(None)``Err` の意味を固定(黙殺禁止)
- [ ] Phase 284 の P1+(実装)で “どこを触る” かの導線を箇条書きで残す(ただしコードは書かない)
## SSOTリンク
- `docs/development/current/main/phases/phase-284/README.md`
- `docs/development/current/main/design/edgecfg-fragments.md`
- `src/mir/builder/control_flow/edgecfg/api/compose.rs`
- `src/mir/builder/control_flow/edgecfg/api/emit.rs`
- `docs/development/current/main/phases/phase-282/README.md`

View File

@ -0,0 +1,79 @@
# Phase 284 P1code: Return as ExitKind SSOT実装
目的: `return` を pattern 固有の特例にせず、`ExitKind::Return``compose::*` / `emit_frag()` へ収束させる。
前提SSOTP0:
- `docs/development/current/main/phases/phase-284/README.md`
- Phase 282 の境界ルールSSOT=extract / close-but-unsupported=Err: `docs/development/current/main/phases/phase-282/README.md`
## 実装方針(最小)
### 1) 返り値の運搬ExitKind::Return + args
- `return <expr>`**`ExitKind::Return` の edge**として表現する。
- Return edge が持つ値は `EdgeArgs` で運ぶReturn terminator の operand
- terminator は `emit_frag()` が生成するpattern/box が直に Return 命令を生やさない)。
### 2) 「移行期間の穴」を消す
現状は Pattern4/5 などが `return``Err(close-but-unsupported)` にしている。
P1 のゴールは:
- `return` を含む loop-body が “別パターンへ静かに流れる” 状態をなくす
- SSOT 経路で `ExitKind::Return` に落ちるようにする
## 実装タスク(推奨順)
### Step 1: 現状の `return` ハンドリングを棚卸しread-only
- joinir patterns extractors:
- `src/mir/builder/control_flow/joinir/patterns/extractors/pattern4.rs`
- `src/mir/builder/control_flow/joinir/patterns/extractors/pattern5.rs`
- `return` を Err にしている箇所close-but-unsupported の根拠)を列挙する
- control-flow lowering:
- `emit_frag()` が Return edge をどう生成しているか確認するtarget=None の Return wire/exit
- `compose::cleanup()` の Return wiring が想定どおりか確認する
成果物: `docs/development/current/main/phases/phase-284/P1-NOTES.md`短い箇条書きでOK
### Step 2: `return` を ExitKind に落とす “単一入口” を作るroot fix
狙い:
- loop body のどの位置でも `return` が現れたら `ExitKind::Return` で外へ出せること
- これを **1 箇所**に寄せるpattern 側に増やさない)
実装候補(どれか 1 つに決める):
- A) loop loweringFrag 構築)段で Return edge を first-class で追加
- B) JoinIR conversion の merge 段で Return を ExitKind に正規化
要件:
- Fail-Fast: “表現できない return” は Errsilent fallback 禁止)
- 既定挙動は変えないreturn を含む既存 fixture があれば、その期待値は明示して更新)
### Step 3: extractor の `return` ポリシーを更新(穴を埋める)
P1 で Return SSOT が通るようになったら、以下を更新する:
- Pattern4/5 の extractor で `return`**Err にしない**close-but-unsupported ではなくなるため)
- ただし “return があるせいでパターン形状が曖昧になる” 場合は Err を維持Fail-Fast
### Step 4: fixture + smokeVM/LLVMで SSOT を固定
最小 fixture の要件:
- `return` が loop の then/else どちらかに現れる
- exit code が安定stdout 抑制の LLVM でも確認できる)
例(案):
- `apps/tests/phase284_p1_return_in_loop_min.hako`
- loop 内で条件により `return 7` / `continue`
- 最終 exit code を 7 に固定
smoke:
- VM: stdout/exit code を検証
- LLVM: exit code + harness の `Result: <code>` を検証stdout が出ない想定)
## 受け入れ基準
- `return` を含む loop fixture が VM/LLVM で同一動作
- pattern 側に “return の特例 if” が増えていないroot fix のみ)
- `Ok(None)` / `Err` の境界が崩れていないsilent fallback なし)

View File

@ -0,0 +1,58 @@
# Phase 284: Return as ExitKind SSOTpatternに散らさない
Status: Planned (design-first)
## Goal
`return` を “pattern 個別の特例” として増やさず、`ExitKind::Return``compose::*` / `emit_frag()` に収束させる。
移行期間中の検出穴Ok(None) による黙殺を消し、Fail-Fast を構造で担保する。
## SSOT References
- Frag/ExitKind 設計: `docs/development/current/main/design/edgecfg-fragments.md`
- Composition API: `src/mir/builder/control_flow/edgecfg/api/compose.rs`
- Terminator emission: `src/mir/builder/control_flow/edgecfg/api/emit.rs``emit_frag()`
- Router SSOTSSOT=extract / safety valve: `docs/development/current/main/phases/phase-282/README.md`
## Problem移行期間の弱さ
- Pattern 単位で `return` を “未対応” にすると、検出戦略Ok(None)/Err次第で **静かに別経路へ落ちる**
- その結果、同じソースでも「どの lowering が `return` を解釈したか」が曖昧になり、SSOT が割れる。
## Core SSOT決めること
### 1) 返り値の意味ExitKind
- `return expr``ExitKind::Return` として表現する。
- 返り値ValueId`EdgeArgs` で運ぶReturn edge が value を持つ)。
- Return は **必ず emit 側で terminator になる**pattern 側で命令を直に生成しない)。
### 2) Detect の境界Ok(None) / Err
- `Ok(None)`: 一致しない(次の extractor へ)
- `Err(...)`: 一致したが未対応close-but-unsupported**Fail-Fast**
Phase 284 の完了条件は「`return` を含むケースが close-but-unsupported ではなく SSOT 経路で処理される」状態に寄せること。
### 3) 実装の集約点(どこに寄せるか)
- `return` の lowering は **ExitKind + compose + emit_frag** に集約する。
- pattern の extractor は “認識” のみSSOT=extract`return` の解釈ロジックを増やさない。
## Scope
### P0docs-only
- `return` を ExitKind として扱う SSOT を文章で固定する(本ファイル + 参照先リンク)。
- 移行期間のルールOk(None)/Err の境界、黙殺禁止)を Phase 282 と整合させる。
### P1+code
- `return` を含む loop body を、JoinIR/Plan のどちらの経路でも **同じ ExitKind::Return** に落とす。
- VM/LLVM の両方で、`return` を含む fixture を smoke 化して SSOT を固定する。
## Acceptance
- P0: `return` の SSOTExitKind/compose/emitと detect 境界が明文化されている
- P1+: `return` を含む loop fixture が VM/LLVM で同一結果になり、smoke で固定されている