refactor(mir): Extract TypeContext from MirBuilder (Phase 136 follow-up 1/7)
## Summary Extract type-related fields into dedicated TypeContext for better code organization and maintainability. First step of 7-context refactoring plan. ## Changes - **New**: src/mir/builder/type_context.rs - Consolidates value_types, value_kinds, value_origin_newbox - Provides clean API for type operations - BTreeMap/HashMap as appropriate for determinism - **Modified**: src/mir/builder.rs - Add type_ctx field to MirBuilder - Deprecate old fields (backward compat) - Add sync helpers for gradual migration - Initialize type_ctx in new() - **Doc**: phase-136-context-box-progress.md - Track refactoring progress (1/7 complete) - Document design principles - Plan next steps (CoreContext) ## Impact - 16 files with 113 deprecated field usages - No breaking changes (gradual migration) - All tests pass (997/997) ## Test Results ✅ cargo build --release (warnings only) ✅ cargo test --release --lib (997 passed) ✅ phase135_trim_mir_verify.sh (PASS) ✅ phase132_exit_phi_parity.sh (3/3 PASS) ## Next Step CoreContext extraction (ValueId/BlockId generators) Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,90 @@
|
|||||||
|
# Phase 136 Follow-up: Builder Context Box化 進捗
|
||||||
|
|
||||||
|
## 概要
|
||||||
|
|
||||||
|
builder.rs の 1219 行を責任ごとに Context Box に分割し、保守性・テスト容易性を向上させる段階的リファクタリング。
|
||||||
|
|
||||||
|
## 完了した Context (1/7)
|
||||||
|
|
||||||
|
### ✅ TypeContext (Step 1) - 完了
|
||||||
|
|
||||||
|
**実装日**: 2025-12-15
|
||||||
|
|
||||||
|
**抽出したフィールド** (3個):
|
||||||
|
- `value_types: BTreeMap<ValueId, MirType>` - 型注釈マップ
|
||||||
|
- `value_kinds: HashMap<ValueId, MirValueKind>` - 型種別マップ (Phase 26-A)
|
||||||
|
- `value_origin_newbox: BTreeMap<ValueId, String>` - Box クラス名由来追跡
|
||||||
|
|
||||||
|
**ファイル**:
|
||||||
|
- `/home/tomoaki/git/hakorune-selfhost/src/mir/builder/type_context.rs` (新規作成)
|
||||||
|
|
||||||
|
**統合方法**:
|
||||||
|
- `MirBuilder` に `type_ctx: TypeContext` フィールドを追加
|
||||||
|
- 既存フィールドは `#[deprecated]` でマーク(後方互換性維持)
|
||||||
|
- 同期ヘルパー (`sync_type_ctx_to_legacy()`, `sync_legacy_to_type_ctx()`) を実装
|
||||||
|
|
||||||
|
**テスト結果**:
|
||||||
|
- ✅ `cargo build --release` 成功 (警告のみ)
|
||||||
|
- ✅ `cargo test --release --lib` - 997/997 PASS
|
||||||
|
- ✅ `phase135_trim_mir_verify.sh` - PASS
|
||||||
|
- ✅ `phase132_exit_phi_parity.sh` - 3/3 PASS
|
||||||
|
|
||||||
|
**影響範囲**:
|
||||||
|
- 16 ファイルで 113 箇所が deprecated フィールドを使用中
|
||||||
|
- 段階的移行により破壊的変更なし
|
||||||
|
|
||||||
|
**コミット**: (次回コミット時に記載)
|
||||||
|
|
||||||
|
## 残りの Context (6/7)
|
||||||
|
|
||||||
|
### 2. CoreContext (計画中)
|
||||||
|
- `value_gen: ValueIdGenerator`
|
||||||
|
- `block_gen: BasicBlockIdGenerator`
|
||||||
|
- `next_fn_id: u32` (将来追加予定)
|
||||||
|
|
||||||
|
### 3. ScopeContext (計画中)
|
||||||
|
- `lexical_scope_stack: Vec<LexicalScopeFrame>`
|
||||||
|
- `scope_stack: Vec<...>` (既存の control flow スタック)
|
||||||
|
- `current_function: Option<MirFunction>`
|
||||||
|
|
||||||
|
### 4. BindingContext (計画中)
|
||||||
|
- `bindings_stack: ...`
|
||||||
|
- `global_bindings: ...`
|
||||||
|
- `next_binding_id: u32`
|
||||||
|
- `binding_map: BTreeMap<String, BindingId>`
|
||||||
|
|
||||||
|
### 5. ControlFlowContext (計画中)
|
||||||
|
- `current_basic_block: Option<BasicBlockId>`
|
||||||
|
- `pending_phis: Vec<...>`
|
||||||
|
- `loop_header_stack: Vec<BasicBlockId>`
|
||||||
|
- `loop_exit_stack: Vec<BasicBlockId>`
|
||||||
|
- `if_merge_stack: Vec<BasicBlockId>`
|
||||||
|
|
||||||
|
### 6. MetadataContext (計画中)
|
||||||
|
- `metadata: ...`
|
||||||
|
- `loc_gen: ...`
|
||||||
|
- `source_map: ...`
|
||||||
|
- `hint_sink: HintSink`
|
||||||
|
|
||||||
|
### 7. ResourceContext (計画中)
|
||||||
|
- `handle_registry: ...` (将来追加予定)
|
||||||
|
- その他リソース管理関連
|
||||||
|
|
||||||
|
## 設計原則
|
||||||
|
|
||||||
|
1. **段階的移行** - 全フィールドを一度に移行せず、1-2 Context ずつ
|
||||||
|
2. **後方互換性** - 既存の public API は維持(内部で Context 経由に変更)
|
||||||
|
3. **Box-First** - 各 Context は独立した struct として配置
|
||||||
|
4. **テスト駆動** - 各段階で全テストが PASS することを確認
|
||||||
|
|
||||||
|
## 次のステップ
|
||||||
|
|
||||||
|
**優先順位 2**: CoreContext 抽出
|
||||||
|
- ValueId/BlockId 生成の中核部分
|
||||||
|
- 依存関係が少なく、分離が容易
|
||||||
|
- テスト影響範囲が小さい
|
||||||
|
|
||||||
|
## 参考資料
|
||||||
|
|
||||||
|
- [Phase 136 分析ドキュメント](./phase-136-builder-analysis.md) (前提分析)
|
||||||
|
- [Builder.rs](../../../../src/mir/builder.rs) (対象ファイル)
|
||||||
@ -52,6 +52,7 @@ mod router; // RouterPolicyBox(Unified vs BoxCall)
|
|||||||
mod schedule; // BlockScheduleBox(物理順序: PHI→materialize→body)
|
mod schedule; // BlockScheduleBox(物理順序: PHI→materialize→body)
|
||||||
mod ssa; // LocalSSA helpers (in-block materialization)
|
mod ssa; // LocalSSA helpers (in-block materialization)
|
||||||
mod stmts;
|
mod stmts;
|
||||||
|
mod type_context; // Phase 136 follow-up: TypeContext extraction
|
||||||
mod type_facts; // Phase 136 follow-up: Type inference facts box
|
mod type_facts; // Phase 136 follow-up: Type inference facts box
|
||||||
pub(crate) mod type_registry;
|
pub(crate) mod type_registry;
|
||||||
mod types; // types::annotation / inference(型注釈/推論の箱: 推論は後段)
|
mod types; // types::annotation / inference(型注釈/推論の箱: 推論は後段)
|
||||||
@ -88,6 +89,11 @@ pub struct MirBuilder {
|
|||||||
/// Noneの場合、従来のフィールドを使用(後方互換性)
|
/// Noneの場合、従来のフィールドを使用(後方互換性)
|
||||||
pub(super) compilation_context: Option<context::BoxCompilationContext>,
|
pub(super) compilation_context: Option<context::BoxCompilationContext>,
|
||||||
|
|
||||||
|
/// Phase 136 follow-up: Type information context
|
||||||
|
/// Consolidates value_types, value_kinds, value_origin_newbox for better organization.
|
||||||
|
/// Direct field access for backward compatibility (migration in progress).
|
||||||
|
pub(super) type_ctx: type_context::TypeContext,
|
||||||
|
|
||||||
/// Variable name to ValueId mapping (for SSA conversion)
|
/// Variable name to ValueId mapping (for SSA conversion)
|
||||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
/// 注意: compilation_contextがSomeの場合は使用されません
|
||||||
/// Phase 25.1: HashMap → BTreeMap(PHI生成の決定性確保)
|
/// Phase 25.1: HashMap → BTreeMap(PHI生成の決定性確保)
|
||||||
@ -103,10 +109,12 @@ pub struct MirBuilder {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
|
pub(super) pending_phis: Vec<(BasicBlockId, ValueId, String)>,
|
||||||
|
|
||||||
/// Origin tracking for simple optimizations (e.g., object.method after new)
|
/// [DEPRECATED] Origin tracking for simple optimizations (e.g., object.method after new)
|
||||||
/// Maps a ValueId to the class name if it was produced by NewBox of that class
|
/// Maps a ValueId to the class name if it was produced by NewBox of that class
|
||||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
/// 注意: compilation_contextがSomeの場合は使用されません
|
||||||
|
/// Phase 136: Moved to type_ctx.value_origin_newbox (backward compat wrapper)
|
||||||
// Phase 25.1: HashMap → BTreeMap(決定性確保)
|
// Phase 25.1: HashMap → BTreeMap(決定性確保)
|
||||||
|
#[deprecated(note = "Use type_ctx.value_origin_newbox instead")]
|
||||||
pub(super) value_origin_newbox: BTreeMap<ValueId, String>,
|
pub(super) value_origin_newbox: BTreeMap<ValueId, String>,
|
||||||
|
|
||||||
/// Names of user-defined boxes declared in the current module
|
/// Names of user-defined boxes declared in the current module
|
||||||
@ -123,15 +131,19 @@ pub struct MirBuilder {
|
|||||||
/// Class-level field origin (cross-function heuristic): (BaseBoxName, field) -> FieldBoxName
|
/// Class-level field origin (cross-function heuristic): (BaseBoxName, field) -> FieldBoxName
|
||||||
pub(super) field_origin_by_box: HashMap<(String, String), String>,
|
pub(super) field_origin_by_box: HashMap<(String, String), String>,
|
||||||
|
|
||||||
/// Optional per-value type annotations (MIR-level): ValueId -> MirType
|
/// [DEPRECATED] Optional per-value type annotations (MIR-level): ValueId -> MirType
|
||||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
/// 注意: compilation_contextがSomeの場合は使用されません
|
||||||
|
/// Phase 136: Moved to type_ctx.value_types (backward compat wrapper)
|
||||||
// Phase 25.1: HashMap → BTreeMap(決定性確保)
|
// Phase 25.1: HashMap → BTreeMap(決定性確保)
|
||||||
|
#[deprecated(note = "Use type_ctx.value_types instead")]
|
||||||
pub(super) value_types: BTreeMap<ValueId, super::MirType>,
|
pub(super) value_types: BTreeMap<ValueId, super::MirType>,
|
||||||
|
|
||||||
/// Phase 26-A: ValueId型情報マップ(型安全性強化)
|
/// [DEPRECATED] Phase 26-A: ValueId型情報マップ(型安全性強化)
|
||||||
/// ValueId -> MirValueKind のマッピング
|
/// ValueId -> MirValueKind のマッピング
|
||||||
/// - GUARDバグ予防: ValueId(0)がParameterかLocalか区別可能
|
/// - GUARDバグ予防: ValueId(0)がParameterかLocalか区別可能
|
||||||
/// - デフォルト: 未登録のValueIdはTemporary扱い
|
/// - デフォルト: 未登録のValueIdはTemporary扱い
|
||||||
|
/// Phase 136: Moved to type_ctx.value_kinds (backward compat wrapper)
|
||||||
|
#[deprecated(note = "Use type_ctx.value_kinds instead")]
|
||||||
pub(super) value_kinds: HashMap<ValueId, super::MirValueKind>,
|
pub(super) value_kinds: HashMap<ValueId, super::MirValueKind>,
|
||||||
|
|
||||||
/// 関数スコープの SlotRegistry(観測専用)
|
/// 関数スコープの SlotRegistry(観測専用)
|
||||||
@ -284,18 +296,19 @@ impl MirBuilder {
|
|||||||
current_block: None,
|
current_block: None,
|
||||||
value_gen: ValueIdGenerator::new(),
|
value_gen: ValueIdGenerator::new(),
|
||||||
block_gen: BasicBlockIdGenerator::new(),
|
block_gen: BasicBlockIdGenerator::new(),
|
||||||
compilation_context: None, // 箱理論: デフォルトは従来モード
|
compilation_context: None, // 箱理論: デフォルトは従来モード
|
||||||
|
type_ctx: type_context::TypeContext::new(), // Phase 136: Type context
|
||||||
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保
|
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保
|
||||||
lexical_scope_stack: Vec::new(),
|
lexical_scope_stack: Vec::new(),
|
||||||
pending_phis: Vec::new(),
|
pending_phis: Vec::new(),
|
||||||
value_origin_newbox: BTreeMap::new(), // Phase 25.1: 決定性確保
|
value_origin_newbox: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
||||||
user_defined_boxes: HashSet::new(),
|
user_defined_boxes: HashSet::new(),
|
||||||
weak_fields_by_box: HashMap::new(),
|
weak_fields_by_box: HashMap::new(),
|
||||||
property_getters_by_box: HashMap::new(),
|
property_getters_by_box: HashMap::new(),
|
||||||
field_origin_class: HashMap::new(),
|
field_origin_class: HashMap::new(),
|
||||||
field_origin_by_box: HashMap::new(),
|
field_origin_by_box: HashMap::new(),
|
||||||
value_types: BTreeMap::new(), // Phase 25.1: 決定性確保
|
value_types: BTreeMap::new(), // Phase 25.1: 決定性確保 (backward compat)
|
||||||
value_kinds: HashMap::new(), // Phase 26-A: ValueId型安全化
|
value_kinds: HashMap::new(), // Phase 26-A: ValueId型安全化 (backward compat)
|
||||||
current_slot_registry: None,
|
current_slot_registry: None,
|
||||||
type_registry: type_registry::TypeRegistry::new(),
|
type_registry: type_registry::TypeRegistry::new(),
|
||||||
plugin_method_sigs,
|
plugin_method_sigs,
|
||||||
@ -344,6 +357,23 @@ impl MirBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Phase 136: TypeContext synchronization helpers ----
|
||||||
|
/// Sync type_ctx changes back to legacy fields (backward compatibility)
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fn sync_type_ctx_to_legacy(&mut self) {
|
||||||
|
self.value_types = self.type_ctx.value_types.clone();
|
||||||
|
self.value_kinds = self.type_ctx.value_kinds.clone();
|
||||||
|
self.value_origin_newbox = self.type_ctx.value_origin_newbox.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sync legacy field changes to type_ctx (backward compatibility)
|
||||||
|
#[allow(deprecated)]
|
||||||
|
fn sync_legacy_to_type_ctx(&mut self) {
|
||||||
|
self.type_ctx.value_types = self.value_types.clone();
|
||||||
|
self.type_ctx.value_kinds = self.value_kinds.clone();
|
||||||
|
self.type_ctx.value_origin_newbox = self.value_origin_newbox.clone();
|
||||||
|
}
|
||||||
|
|
||||||
/// Push/pop helpers for If merge context (best-effort; optional usage)
|
/// Push/pop helpers for If merge context (best-effort; optional usage)
|
||||||
pub(super) fn push_if_merge(&mut self, bb: BasicBlockId) {
|
pub(super) fn push_if_merge(&mut self, bb: BasicBlockId) {
|
||||||
self.if_merge_stack.push(bb);
|
self.if_merge_stack.push(bb);
|
||||||
|
|||||||
80
src/mir/builder/type_context.rs
Normal file
80
src/mir/builder/type_context.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*!
|
||||||
|
* TypeContext - Type information management for MirBuilder
|
||||||
|
*
|
||||||
|
* Phase 136 follow-up: Extract type-related fields from MirBuilder
|
||||||
|
* to improve code organization and testability.
|
||||||
|
*
|
||||||
|
* Consolidates:
|
||||||
|
* - value_types: ValueId -> MirType mapping
|
||||||
|
* - value_kinds: ValueId -> MirValueKind mapping (Phase 26-A)
|
||||||
|
* - value_origin_newbox: ValueId -> Box class name origin tracking
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::mir::{MirType, MirValueKind, ValueId};
|
||||||
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
|
/// Type information context for MIR builder
|
||||||
|
///
|
||||||
|
/// Manages all type-related mappings and origin tracking for ValueIds.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub(crate) struct TypeContext {
|
||||||
|
/// Optional per-value type annotations (MIR-level): ValueId -> MirType
|
||||||
|
/// Phase 25.1: BTreeMap for deterministic iteration
|
||||||
|
pub value_types: BTreeMap<ValueId, MirType>,
|
||||||
|
|
||||||
|
/// Phase 26-A: ValueId type kind mapping (type safety enhancement)
|
||||||
|
/// ValueId -> MirValueKind mapping
|
||||||
|
/// - GUARD bug prevention: Distinguish Parameter vs Local for ValueId(0)
|
||||||
|
/// - Default: Unregistered ValueIds are treated as Temporary
|
||||||
|
pub value_kinds: HashMap<ValueId, MirValueKind>,
|
||||||
|
|
||||||
|
/// Origin tracking for simple optimizations (e.g., object.method after new)
|
||||||
|
/// Maps a ValueId to the class name if it was produced by NewBox of that class
|
||||||
|
/// Phase 25.1: BTreeMap for deterministic iteration
|
||||||
|
pub value_origin_newbox: BTreeMap<ValueId, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeContext {
|
||||||
|
/// Create a new empty TypeContext
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the type annotation for a ValueId, if present
|
||||||
|
pub fn get_type(&self, value_id: ValueId) -> Option<&MirType> {
|
||||||
|
self.value_types.get(&value_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the type annotation for a ValueId
|
||||||
|
pub fn set_type(&mut self, value_id: ValueId, ty: MirType) {
|
||||||
|
self.value_types.insert(value_id, ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the value kind for a ValueId, defaulting to Temporary if not registered
|
||||||
|
pub fn get_kind(&self, value_id: ValueId) -> MirValueKind {
|
||||||
|
self.value_kinds
|
||||||
|
.get(&value_id)
|
||||||
|
.copied()
|
||||||
|
.unwrap_or(MirValueKind::Temporary)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the value kind for a ValueId
|
||||||
|
pub fn set_kind(&mut self, value_id: ValueId, kind: MirValueKind) {
|
||||||
|
self.value_kinds.insert(value_id, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the origin box class name for a ValueId, if tracked
|
||||||
|
pub fn get_origin_box(&self, value_id: ValueId) -> Option<&str> {
|
||||||
|
self.value_origin_newbox.get(&value_id).map(|s| s.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the origin box class name for a ValueId
|
||||||
|
pub fn set_origin_box(&mut self, value_id: ValueId, class_name: String) {
|
||||||
|
self.value_origin_newbox.insert(value_id, class_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear all origin box mappings (useful for cleanup)
|
||||||
|
pub fn clear_origin_boxes(&mut self) {
|
||||||
|
self.value_origin_newbox.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user