feat(joinir): Phase 171-C-2 Trim pattern detection in LoopBodyCarrierPromoter
Implements the Trim pattern detection logic for carrier promotion:
- find_definition_in_body(): Iterative AST traversal to locate variable definitions
- is_substring_method_call(): Detects substring() method calls
- extract_equality_literals(): Extracts string literals from OR chains (ch == " " || ch == "\t")
- TrimPatternInfo: Captures detected pattern details for carrier promotion
This enables Pattern 5 to detect trim-style loops:
```hako
loop(start < end) {
local ch = s.substring(start, start+1)
if ch == " " || ch == "\t" || ch == "\n" || ch == "\r" {
start = start + 1
} else {
break
}
}
```
Unit tests cover:
- Simple and nested definition detection
- substring method call detection
- Single and chained equality literal extraction
- Full Trim pattern detection with 2-4 whitespace characters
Next: Phase 171-C-3 integration with Pattern 2/4 routing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -91,12 +91,50 @@ JoinIR ラインで守るべきルールを先に書いておくよ:
|
||||
- `ConditionEnv` 経由で「変数名 → JoinIR ValueId」のみを見る。
|
||||
- host 側の ValueId は `ConditionBinding { name, host_value, join_value }` として JoinInlineBoundary に記録する。
|
||||
|
||||
- **LoopConditionScopeBox(設計中)**
|
||||
- 予定ファイル: `src/mir/loop_pattern_detection/loop_condition_scope.rs` 等
|
||||
- **LoopConditionScopeBox(Phase 170-D 実装済み)**
|
||||
- ファイル: `src/mir/loop_pattern_detection/loop_condition_scope.rs`
|
||||
- 責務:
|
||||
- 条件式に登場する変数が、ループパラメータ(LoopParam)/ループ外ローカル(OuterLocal)/ループ本体ローカル(LoopBodyLocal)のどれかを分類する。
|
||||
- Pattern2/4 が「対応してよい条件のスコープ」を判定するための箱。
|
||||
- ループ本体ローカルを条件に含む高度なパターンは、将来の Pattern5+ で扱う設計とし、現状は Fail‑Fast で明示的に弾く。
|
||||
- ループ本体ローカルを条件に含む高度なパターンは、**LoopBodyCarrierPromoter(Phase 171)** で carrier に昇格させる。
|
||||
- **Bug Fix(2025-12-07)**:
|
||||
- 関数パラメータが LoopBodyLocal と誤分類される問題を修正。
|
||||
- `condition_var_analyzer.rs` の `is_outer_scope_variable()` で、`variable_definitions` に含まれない変数を OuterLocal とする。
|
||||
- これにより JsonParserBox などの関数パラメータを含むループが正しく動作。
|
||||
|
||||
- **LoopBodyCarrierPromoter(Phase 171-C-1 実装中)**
|
||||
- ファイル: `src/mir/loop_pattern_detection/loop_body_carrier_promoter.rs`
|
||||
- 責務:
|
||||
- LoopBodyLocal 変数を carrier に昇格させ、Pattern 2/4 で処理可能にする。
|
||||
- 昇格成功 → Pattern 2/4 にルーティング(新しい carrier 情報付き)。
|
||||
- 昇格失敗 → UnsupportedPattern(Fail-Fast)。
|
||||
- **Pattern 2/4 + Pattern 5 の境界線**:
|
||||
- **Pattern 2/4 の守備範囲**: LoopParam + OuterLocal のみ。LoopBodyLocal 条件は受け入れない。
|
||||
- **Pattern 5 の守備範囲**: LoopBodyLocal を carrier に昇格。成功なら Pattern 2/4 へ委譲。
|
||||
- **境界**: LoopConditionScopeBox が LoopBodyLocal 検出 → LoopBodyCarrierPromoter で昇格試行。
|
||||
- **Design Strategy(Design D: Evaluated Bool Carrier)**:
|
||||
- `ch == " " || ...` のような条件を `is_whitespace` (bool carrier) に変換。
|
||||
- 昇格例:
|
||||
```hako
|
||||
// Before (blocked)
|
||||
loop(start < end) {
|
||||
local ch = s.substring(start, start+1)
|
||||
if ch == " " || ... { ... } else { break }
|
||||
}
|
||||
|
||||
// After (Pattern2 compatible)
|
||||
local is_whitespace = true
|
||||
loop(start < end && is_whitespace) {
|
||||
local ch = s.substring(start, start+1)
|
||||
is_whitespace = (ch == " " || ...)
|
||||
if is_whitespace { ... } else { break }
|
||||
}
|
||||
```
|
||||
- **Current Status(Phase 171-C-1)**:
|
||||
- ✅ API 定義: `PromotionRequest` → `PromotionResult`
|
||||
- ✅ Skeleton 実装: LoopBodyLocal 検出・定義探索
|
||||
- ⏳ Promotion logic: Phase 171-C-2 で Trim パターンの実際の昇格ロジックを実装予定
|
||||
- **詳細**: `docs/development/current/main/phase171-pattern5-loop-inventory.md`
|
||||
|
||||
### 2.3 キャリア / Exit / Boundary ライン
|
||||
|
||||
|
||||
Reference in New Issue
Block a user