feat(joinir): Phase 171 complete - Trim pattern LoopBodyLocal promotion
Phase 171-C-4/5 + impl-Trim: Full Trim pattern validation infrastructure ## CarrierInfo 統合 (C-4) - CarrierInfo::merge_from(): Deduplicated carrier merging - TrimPatternInfo::to_carrier_info(): Conversion helper - Pattern2/4: Promoted carrier merge integration - 7 unit tests for merge logic ## TrimLoopHelper 設計 (C-5) - TrimLoopHelper struct: Trim-specific validation box - carrier_type(), initial_value(), whitespace helpers - CarrierInfo::trim_helper() accessor - 5 unit tests ## Validation-Only Integration (impl-Trim) - TrimLoopHelper::is_safe_trim(), is_trim_like(), has_valid_structure() - Pattern2/4: Trim exception route with safety validation - body_locals extraction from loop body AST - LoopBodyCarrierPromoter: ASTNode::Local handler extension - 4 unit tests for safety validation ## Architecture - Box Theory: TrimLoopHelper is "validation only" (no JoinIR generation) - Fail-Fast: Non-Trim LoopBodyLocal immediately rejected - Whitelist approach: Only Trim pattern bypasses LoopBodyLocal restriction Tests: 16 new unit tests, all passing E2E: test_trim_main_pattern.hako validation successful Next: Phase 172 - Actual JoinIR lowering for Trim pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -254,4 +254,171 @@ loop(start < end && is_whitespace) {
|
||||
- `is_substring_method_call()`: Detects `substring()` method calls
|
||||
- `extract_equality_literals()`: Extracts string literals from OR chains
|
||||
- `TrimPatternInfo`: Captures pattern details for carrier promotion
|
||||
- Phase 171-C-3: ⏳ Integration with Pattern 2/4 routing
|
||||
- Phase 171-C-3: ✅ Integration with Pattern 2/4 routing complete
|
||||
- Phase 171-C-4: ✅ CarrierInfo integration complete (2025-12-07)
|
||||
- `CarrierInfo::merge_from()`: Deduplicated carrier merging with deterministic sorting
|
||||
- `TrimPatternInfo::to_carrier_info()`: Conversion to CarrierInfo with TrimLoopHelper
|
||||
- Pattern 2/4 lowerers: Promoted carrier merging in `Promoted` branch
|
||||
- 7 unit tests: Merge success/failure/duplication/determinism validation
|
||||
- Phase 171-C-5: ✅ TrimLoopHelper design complete (2025-12-07)
|
||||
- `TrimLoopHelper` struct: Encapsulates Trim pattern lowering logic
|
||||
- `CarrierInfo::trim_helper()`: Accessor for pattern-specific helper
|
||||
- Module export: `mod.rs` updated with `pub use TrimLoopHelper`
|
||||
- 4 unit tests: Helper creation and accessor validation
|
||||
|
||||
---
|
||||
|
||||
## Phase 171-C-3/4/5: Responsibility Positions and Data Flow
|
||||
|
||||
### Responsibility Separation Principle
|
||||
|
||||
The promotion system follows Box Theory's single responsibility principle:
|
||||
|
||||
1. **router.rs**: Pattern table + `can_lower()`/`lower()` call abstraction (no Scope/condition logic)
|
||||
2. **Pattern 2/4 lowerer**: Holds LoopScope / ConditionScope / CarrierInfo / Promoter
|
||||
3. **LoopBodyCarrierPromoter**: LoopBodyLocal handling specialist box
|
||||
4. **TrimLoopHelper**: Trim pattern-specific helper (future extensibility)
|
||||
|
||||
### Data Flow Diagram
|
||||
|
||||
```
|
||||
LoopConditionScopeBox::analyze()
|
||||
↓
|
||||
has_loop_body_local()?
|
||||
↓ true
|
||||
LoopBodyCarrierPromoter::try_promote()
|
||||
↓ Promoted { trim_info }
|
||||
TrimPatternInfo::to_carrier_info()
|
||||
↓
|
||||
CarrierInfo::merge_from()
|
||||
↓
|
||||
TrimLoopHelper (attached to CarrierInfo)
|
||||
↓
|
||||
Pattern 2/4 lowerer (JoinIR generation)
|
||||
```
|
||||
|
||||
### Implementation Locations
|
||||
|
||||
**Phase 171-C-4 Changes**:
|
||||
- `src/mir/join_ir/lowering/carrier_info.rs`: Added `merge_from()`, `trim_helper()`, `trim_helper` field
|
||||
- `src/mir/loop_pattern_detection/loop_body_carrier_promoter.rs`: Updated `to_carrier_info()` to attach TrimLoopHelper
|
||||
- `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`: Promoted branch now merges carriers
|
||||
- `src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs`: Promoted branch now merges carriers
|
||||
|
||||
**Phase 171-C-5 Changes**:
|
||||
- `src/mir/loop_pattern_detection/trim_loop_helper.rs`: NEW - TrimLoopHelper struct with 4 unit tests
|
||||
- `src/mir/loop_pattern_detection/mod.rs`: Export TrimLoopHelper module
|
||||
|
||||
---
|
||||
|
||||
## Phase 171-impl-Trim: Trim 特例の実戦投入
|
||||
|
||||
**Date**: 2025-12-08
|
||||
**Status**: ✅ Validation complete
|
||||
**Purpose**: Safely integrate Trim pattern detection into JoinIR pipeline with validation-only implementation
|
||||
|
||||
### 設計原則
|
||||
|
||||
> **「LoopBodyLocal を全面解禁」ではなく、Trim パターンだけを箱経由でホワイトリストに載せる**
|
||||
|
||||
### 安全機構
|
||||
|
||||
1. `TrimLoopHelper::is_safe_trim()` - 構造的に安全か判定
|
||||
2. `TrimLoopHelper::is_trim_like()` - Trim パターンに合致するか判定
|
||||
3. `TrimLoopHelper::has_valid_structure()` - 構造チェック
|
||||
|
||||
### データフロー(Trim 特例)
|
||||
|
||||
```
|
||||
LoopConditionScopeBox::analyze()
|
||||
↓
|
||||
has_loop_body_local() == true
|
||||
↓
|
||||
LoopBodyCarrierPromoter::try_promote()
|
||||
↓ Promoted { trim_info }
|
||||
TrimPatternInfo::to_carrier_info()
|
||||
↓
|
||||
CarrierInfo::merge_from()
|
||||
↓
|
||||
carrier_info.trim_helper()?.is_safe_trim()
|
||||
↓ true
|
||||
✅ Validation Success (TODO: JoinIR lowering in Phase 172)
|
||||
```
|
||||
|
||||
### 実装状況
|
||||
|
||||
- [x] Phase 171-impl-Trim-1: 受け入れ条件を 1 箇所に ✅
|
||||
- `TrimLoopHelper::is_safe_trim()` implemented
|
||||
- `Pattern2/4` で Trim 特例ルート実装
|
||||
- Fail-Fast on unsafe patterns
|
||||
- [x] Phase 171-impl-Trim-2: TrimLoopHelper 判定メソッド ✅
|
||||
- `is_trim_like()`, `has_valid_structure()` implemented
|
||||
- 4+ ユニットテスト追加 (9 tests total, all passing)
|
||||
- [x] Phase 171-impl-Trim-3: E2E テスト ✅
|
||||
- `local_tests/test_trim_main_pattern.hako` validated
|
||||
- 出力: `[pattern2/trim] Safe Trim pattern detected`
|
||||
- 出力: `✅ Trim pattern validation successful!`
|
||||
- Status: Validation-only (JoinIR lowering deferred to Phase 172)
|
||||
- [x] Phase 171-impl-Trim-4: ドキュメント更新 ✅
|
||||
- `phase171-pattern5-loop-inventory.md` updated
|
||||
- `CURRENT_TASK.md` status tracking
|
||||
|
||||
### 実装詳細
|
||||
|
||||
**ファイル変更**:
|
||||
1. `src/mir/loop_pattern_detection/trim_loop_helper.rs`
|
||||
- `is_safe_trim()`, `is_trim_like()`, `has_valid_structure()` methods
|
||||
- 4 new unit tests for safety validation
|
||||
|
||||
2. `src/mir/builder/control_flow/joinir/patterns/pattern2_with_break.rs`
|
||||
- Trim exception route with safety check
|
||||
- `body_locals` extraction from loop body AST
|
||||
- Validation message for successful detection
|
||||
|
||||
3. `src/mir/builder/control_flow/joinir/patterns/pattern4_with_continue.rs`
|
||||
- Same Trim exception logic as Pattern2
|
||||
- `body_locals` extraction from normalized loop body
|
||||
|
||||
4. `src/mir/loop_pattern_detection/loop_body_carrier_promoter.rs`
|
||||
- `ASTNode::Local { variables, initial_values, .. }` handler
|
||||
- Support for `local ch = expr` pattern recognition
|
||||
|
||||
### テスト結果
|
||||
|
||||
**ユニットテスト**: ✅ 9/9 passing
|
||||
- `test_is_safe_trim`
|
||||
- `test_is_safe_trim_empty_carrier`
|
||||
- `test_is_safe_trim_no_whitespace`
|
||||
- `test_has_valid_structure`
|
||||
- (+ 5 existing tests)
|
||||
|
||||
**E2E テスト**: ✅ Validation successful
|
||||
```
|
||||
[pattern2/check] Analyzing condition scope: 3 variables
|
||||
[pattern2/check] 'ch': LoopBodyLocal
|
||||
[pattern2/promoter] LoopBodyLocal 'ch' promoted to carrier 'is_ch_match'
|
||||
[pattern2/trim] Safe Trim pattern detected, bypassing LoopBodyLocal restriction
|
||||
[pattern2/trim] Carrier: 'is_ch_match', original var: 'ch', whitespace chars: ["\r", "\n", "\t", " "]
|
||||
✅ Trim pattern validation successful! Carrier 'is_ch_match' ready for Phase 172 implementation.
|
||||
(Pattern detection: PASS, Safety check: PASS, JoinIR lowering: TODO)
|
||||
```
|
||||
|
||||
**ビルド結果**: ✅ Success
|
||||
- `cargo build --release`: Success
|
||||
- `cargo test --lib trim_loop_helper`: 9/9 passing
|
||||
|
||||
### 重要な発見
|
||||
|
||||
1. **AST構造の理解**: `local ch = expr` は `ASTNode::Local { variables, initial_values, .. }` として表現される
|
||||
2. **body_locals 抽出**: Pattern2/4 で `LoopScopeShape.body_locals` を AST から抽出する必要があった
|
||||
3. **段階的実装**: Validation-only approach で安全性を先に確立し、JoinIR lowering は Phase 172 に分離
|
||||
|
||||
### 次のステップ (Phase 172)
|
||||
|
||||
- [ ] Phase 172-1: Trim pattern JoinIR generation
|
||||
- Carrier initialization code
|
||||
- Carrier update logic (substring + OR chain → bool)
|
||||
- Exit PHI mapping
|
||||
- [ ] Phase 172-2: JsonParser loops への展開
|
||||
- Similar pattern recognition
|
||||
- Generalized carrier promotion
|
||||
|
||||
Reference in New Issue
Block a user