refactor(mir): Extract BindingContext from MirBuilder (Phase 136 follow-up 4/7)
## Summary Extracted binding management into dedicated BindingContext struct, completing step 4 of 7 in the Context Box refactoring plan. ## Changes - NEW: src/mir/builder/binding_context.rs (BindingContext struct + helpers) - Modified 7 files to use binding_ctx (SSOT pattern with legacy sync) - Added comprehensive unit tests for BindingContext ## Extracted Fields - binding_map: BTreeMap<String, BindingId> → binding_ctx.binding_map ## Benefits - Clear separation: BindingId mapping isolated from MirBuilder - Better testability: BindingContext can be tested independently - Consistent pattern: Same SSOT + legacy sync approach as previous steps ## Tests - cargo test --release --lib: 1008/1008 passed - phase135_trim_mir_verify.sh: PASS - Backward compatibility: 100% maintained (deprecated fields synced) ## Progress Phase 136 Context Extraction: 4/7 complete (57%) - ✅ Step 1: TypeContext - ✅ Step 2: CoreContext - ✅ Step 3: ScopeContext - ✅ Step 4: BindingContext (this commit) - ⏳ Step 5: VariableContext - ⏳ Step 6: MetadataContext - ⏳ Step 7: RegionContext 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -18,6 +18,7 @@ use std::collections::{BTreeMap, HashMap};
|
||||
mod builder_calls;
|
||||
mod call_resolution; // ChatGPT5 Pro: Type-safe call resolution utilities
|
||||
mod calls; // Call system modules (refactored from builder_calls)
|
||||
mod binding_context; // Phase 136 follow-up (Step 4/7): BindingContext extraction
|
||||
mod context; // BoxCompilationContext - 箱理論による静的Boxコンパイル時のコンテキスト分離
|
||||
mod core_context; // Phase 136 follow-up (Step 2/7): CoreContext extraction
|
||||
mod decls; // declarations lowering split
|
||||
@ -113,6 +114,11 @@ pub struct MirBuilder {
|
||||
/// Direct field access for backward compatibility (migration in progress).
|
||||
pub(super) scope_ctx: scope_context::ScopeContext,
|
||||
|
||||
/// Phase 136 follow-up (Step 4/7): Binding context
|
||||
/// Consolidates binding_map (String -> BindingId mapping).
|
||||
/// Direct field access for backward compatibility (migration in progress).
|
||||
pub(super) binding_ctx: binding_context::BindingContext,
|
||||
|
||||
/// Variable name to ValueId mapping (for SSA conversion)
|
||||
/// 注意: compilation_contextがSomeの場合は使用されません
|
||||
/// Phase 25.1: HashMap → BTreeMap(PHI生成の決定性確保)
|
||||
@ -210,11 +216,9 @@ pub struct MirBuilder {
|
||||
#[deprecated(note = "Use core_ctx.next_binding_id instead")]
|
||||
pub next_binding_id: u32,
|
||||
|
||||
/// Phase 74: BindingId mapping for lexical variable bindings
|
||||
/// Maps variable names to their current BindingId.
|
||||
/// Parallel to `variable_map` (String -> ValueId), but tracks binding identity.
|
||||
/// Restored on lexical scope exit (see `pop_lexical_scope()`).
|
||||
/// BTreeMap for deterministic iteration (Phase 25.1 consistency).
|
||||
/// [DEPRECATED] Phase 74: BindingId mapping for lexical variable bindings
|
||||
/// Phase 136: Moved to binding_ctx.binding_map (backward compat wrapper)
|
||||
#[deprecated(note = "Use binding_ctx.binding_map instead")]
|
||||
pub binding_map: BTreeMap<String, super::BindingId>,
|
||||
|
||||
// include guards removed
|
||||
@ -335,6 +339,7 @@ impl MirBuilder {
|
||||
compilation_context: None, // 箱理論: デフォルトは従来モード
|
||||
type_ctx: type_context::TypeContext::new(), // Phase 136: Type context
|
||||
scope_ctx: scope_context::ScopeContext::new(), // Phase 136 Step 3/7: Scope context
|
||||
binding_ctx: binding_context::BindingContext::new(), // Phase 136 Step 4/7: Binding context
|
||||
variable_map: BTreeMap::new(), // Phase 25.1: 決定性確保
|
||||
lexical_scope_stack: Vec::new(),
|
||||
pending_phis: Vec::new(),
|
||||
@ -436,6 +441,19 @@ impl MirBuilder {
|
||||
self.scope_ctx.debug_scope_stack = self.debug_scope_stack.clone();
|
||||
}
|
||||
|
||||
// ---- Phase 136 Step 4/7: BindingContext synchronization helpers ----
|
||||
/// Sync binding_ctx changes back to legacy fields (backward compatibility)
|
||||
#[allow(deprecated)]
|
||||
fn sync_binding_ctx_to_legacy(&mut self) {
|
||||
self.binding_map = self.binding_ctx.binding_map.clone();
|
||||
}
|
||||
|
||||
/// Sync legacy field changes to binding_ctx (backward compatibility)
|
||||
#[allow(deprecated)]
|
||||
fn sync_legacy_to_binding_ctx(&mut self) {
|
||||
self.binding_ctx.binding_map = self.binding_map.clone();
|
||||
}
|
||||
|
||||
/// Push/pop helpers for If merge context (best-effort; optional usage)
|
||||
#[allow(deprecated)]
|
||||
pub(super) fn push_if_merge(&mut self, bb: BasicBlockId) {
|
||||
@ -1223,7 +1241,8 @@ use crate::mir::loop_pattern_detection::BindingMapProvider;
|
||||
impl BindingMapProvider for MirBuilder {
|
||||
#[cfg(feature = "normalized_dev")]
|
||||
fn get_binding_map(&self) -> Option<&std::collections::BTreeMap<String, crate::mir::BindingId>> {
|
||||
Some(&self.binding_map)
|
||||
// Phase 136 Step 4/7: Use binding_ctx (SSOT)
|
||||
Some(self.binding_ctx.binding_map())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "normalized_dev"))]
|
||||
@ -1237,9 +1256,12 @@ mod binding_id_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_binding_map_initialization() {
|
||||
let builder = MirBuilder::new();
|
||||
assert_eq!(builder.next_binding_id, 0);
|
||||
// Phase 136 Step 4/7: Check both binding_ctx (SSOT) and legacy field
|
||||
assert!(builder.binding_ctx.is_empty());
|
||||
assert!(builder.binding_map.is_empty());
|
||||
}
|
||||
|
||||
@ -1257,6 +1279,7 @@ mod binding_id_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_shadowing_binding_restore() {
|
||||
let mut builder = MirBuilder::new();
|
||||
|
||||
@ -1269,8 +1292,11 @@ mod binding_id_tests {
|
||||
builder
|
||||
.declare_local_in_current_scope("x", outer_vid)
|
||||
.unwrap();
|
||||
let outer_bid = *builder.binding_map.get("x").unwrap();
|
||||
// Phase 136 Step 4/7: Check binding_ctx (SSOT)
|
||||
let outer_bid = builder.binding_ctx.lookup("x").unwrap();
|
||||
assert_eq!(outer_bid.raw(), 0);
|
||||
// Also verify legacy field is synced
|
||||
assert_eq!(*builder.binding_map.get("x").unwrap(), outer_bid);
|
||||
|
||||
// Enter inner scope and shadow x
|
||||
builder.push_lexical_scope();
|
||||
@ -1279,14 +1305,20 @@ mod binding_id_tests {
|
||||
builder
|
||||
.declare_local_in_current_scope("x", inner_vid)
|
||||
.unwrap();
|
||||
let inner_bid = *builder.binding_map.get("x").unwrap();
|
||||
// Phase 136 Step 4/7: Check binding_ctx (SSOT)
|
||||
let inner_bid = builder.binding_ctx.lookup("x").unwrap();
|
||||
assert_eq!(inner_bid.raw(), 1);
|
||||
// Also verify legacy field is synced
|
||||
assert_eq!(*builder.binding_map.get("x").unwrap(), inner_bid);
|
||||
|
||||
// Exit inner scope - should restore outer binding
|
||||
builder.pop_lexical_scope();
|
||||
let restored_bid = *builder.binding_map.get("x").unwrap();
|
||||
// Phase 136 Step 4/7: Check binding_ctx (SSOT)
|
||||
let restored_bid = builder.binding_ctx.lookup("x").unwrap();
|
||||
assert_eq!(restored_bid, outer_bid);
|
||||
assert_eq!(restored_bid.raw(), 0);
|
||||
// Also verify legacy field is synced
|
||||
assert_eq!(*builder.binding_map.get("x").unwrap(), restored_bid);
|
||||
|
||||
// Cleanup
|
||||
builder.pop_lexical_scope();
|
||||
|
||||
Reference in New Issue
Block a user