docs: Add comprehensive modularization implementation plan
Create 5-document modularization strategy for 3 large source files: - control_flow.rs (1,632 lines → 19 modules) - generic_case_a.rs (1,056 lines → 7 modules) - loopform_builder.rs (1,166 lines → 11 modules) Documents included: 1. **README.md** (352 lines) Navigation hub with overview, metrics, timeline, ROI analysis 2. **modularization-implementation-plan.md** (960 lines) Complete 20-hour implementation guide with: - Phase-by-phase breakdown (13 phases across 3 files) - Hour-by-hour effort estimates - Risk assessment matrices - Success criteria (quantitative & qualitative) - Public API changes (zero breaking changes) 3. **modularization-quick-start.md** (253 lines) Actionable checklist with: - Copy-paste verification commands - Emergency rollback procedures - Timeline and milestones 4. **modularization-directory-structure.md** (426 lines) Visual guide with: - Before/after directory trees - File size metrics - Import path examples - Code quality comparison 5. **phase4-merge-function-breakdown.md** (789 lines) Detailed implementation for most complex phase: - 714-line merge_joinir_mir_blocks() → 6 focused modules - 10 detailed implementation steps - Common pitfalls and solutions Key metrics: - Total effort: 20 hours (2-3 weeks) - Files: 9 → 37 focused modules - Largest file: 1,632 → 180 lines (-89%) - Backward compatible: Zero breaking changes - ROI: Breakeven in 4 months (5 hrs/month saved) Priority: control_flow.rs Phase 1-4 (high impact) Safety: Fully reversible at each phase 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,426 @@
|
||||
# Modularization Directory Structure Diagrams
|
||||
|
||||
Visual reference for the proposed directory structures after modularization.
|
||||
|
||||
---
|
||||
|
||||
## 1. control_flow.rs Modularization
|
||||
|
||||
### Before (Current State)
|
||||
```
|
||||
src/mir/builder/
|
||||
├── control_flow.rs (1,632 lines) ⚠️ MONOLITH
|
||||
├── if_form.rs
|
||||
├── loops.rs
|
||||
└── ... (other files)
|
||||
```
|
||||
|
||||
### After (Proposed Structure)
|
||||
```
|
||||
src/mir/builder/
|
||||
├── control_flow/
|
||||
│ ├── mod.rs (~150 lines) ✅ Entry points
|
||||
│ │ ├── pub(super) fn cf_block()
|
||||
│ │ ├── pub(super) fn cf_if()
|
||||
│ │ ├── pub(super) fn cf_loop()
|
||||
│ │ ├── pub(super) fn cf_try_catch()
|
||||
│ │ └── pub(super) fn cf_throw()
|
||||
│ │
|
||||
│ ├── debug.rs (~50 lines) ✅ Debug utilities
|
||||
│ │ └── fn trace_varmap()
|
||||
│ │
|
||||
│ ├── utils.rs (~50 lines) ✅ Utility functions
|
||||
│ │ └── fn extract_loop_variable_from_condition()
|
||||
│ │
|
||||
│ ├── joinir/
|
||||
│ │ ├── mod.rs (~100 lines) ✅ JoinIR coordinator
|
||||
│ │ │
|
||||
│ │ ├── routing.rs (~150 lines) ✅ Routing logic
|
||||
│ │ │ ├── fn try_cf_loop_joinir()
|
||||
│ │ │ └── fn cf_loop_joinir_impl()
|
||||
│ │ │
|
||||
│ │ ├── merge/
|
||||
│ │ │ ├── mod.rs (~100 lines) ✅ Merge coordinator
|
||||
│ │ │ │ └── pub fn merge_joinir_mir_blocks()
|
||||
│ │ │ │
|
||||
│ │ │ ├── id_remapper.rs (~150 lines) ✅ ID remapping
|
||||
│ │ │ │ ├── struct JoinIrIdRemapper
|
||||
│ │ │ │ ├── fn create_remapper()
|
||||
│ │ │ │ └── fn remap_ids()
|
||||
│ │ │ │
|
||||
│ │ │ ├── block_allocator.rs (~100 lines) ✅ Block allocation
|
||||
│ │ │ │ └── fn allocate_blocks()
|
||||
│ │ │ │
|
||||
│ │ │ ├── value_collector.rs (~100 lines) ✅ Value collection
|
||||
│ │ │ │ └── fn collect_values()
|
||||
│ │ │ │
|
||||
│ │ │ ├── instruction_rewriter.rs (~150 lines) ✅ Instruction rewriting
|
||||
│ │ │ │ ├── fn rewrite_instructions()
|
||||
│ │ │ │ └── fn convert_call_to_jump()
|
||||
│ │ │ │
|
||||
│ │ │ └── exit_phi_builder.rs (~100 lines) ✅ Exit PHI construction
|
||||
│ │ │ └── fn build_exit_phi()
|
||||
│ │ │
|
||||
│ │ └── patterns/
|
||||
│ │ ├── mod.rs (~50 lines) ✅ Pattern dispatcher
|
||||
│ │ │ └── pub fn dispatch_pattern()
|
||||
│ │ │
|
||||
│ │ ├── pattern1_minimal.rs (~150 lines) ✅ Pattern 1 lowering
|
||||
│ │ │ └── pub fn cf_loop_pattern1_minimal()
|
||||
│ │ │
|
||||
│ │ ├── pattern2_with_break.rs (~130 lines) ✅ Pattern 2 lowering
|
||||
│ │ │ └── pub fn cf_loop_pattern2_with_break()
|
||||
│ │ │
|
||||
│ │ └── pattern3_with_if_phi.rs (~180 lines) ✅ Pattern 3 lowering
|
||||
│ │ └── pub fn cf_loop_pattern3_with_if_phi()
|
||||
│ │
|
||||
│ └── exception/
|
||||
│ ├── mod.rs (~50 lines) ✅ Exception API
|
||||
│ │
|
||||
│ ├── try_catch.rs (~150 lines) ✅ try/catch impl
|
||||
│ │ └── pub fn cf_try_catch()
|
||||
│ │
|
||||
│ └── throw.rs (~30 lines) ✅ throw impl
|
||||
│ └── pub fn cf_throw()
|
||||
│
|
||||
├── if_form.rs
|
||||
├── loops.rs
|
||||
└── ... (other files - unchanged)
|
||||
```
|
||||
|
||||
### Metrics Comparison
|
||||
|
||||
| Metric | Before | After | Change |
|
||||
|--------|--------|-------|--------|
|
||||
| **Total lines** | 1,632 | ~1,850 | +13% (for clarity) |
|
||||
| **Number of files** | 1 | 19 | +1800% |
|
||||
| **Largest file** | 1,632 | ~180 | -89% |
|
||||
| **Average file size** | 1,632 | ~97 | -94% |
|
||||
| **Functions per file** | 13 | 1-2 | Much clearer |
|
||||
|
||||
### Benefits
|
||||
- ✅ **714-line merge function → 6 focused modules** (100-150 lines each)
|
||||
- ✅ **Pattern lowerers isolated** → Easy to add Pattern 4/5/6
|
||||
- ✅ **Debug traces easier to locate** → NYASH_OPTION_C_DEBUG output clearer
|
||||
- ✅ **Merge conflicts reduced** → Changes isolated to specific files
|
||||
- ✅ **Code navigation improved** → Jump to definition works better
|
||||
|
||||
---
|
||||
|
||||
## 2. generic_case_a.rs Modularization
|
||||
|
||||
### Before (Current State)
|
||||
```
|
||||
src/mir/join_ir/lowering/
|
||||
├── generic_case_a.rs (1,056 lines) ⚠️ LARGE
|
||||
├── generic_case_a_entry_builder.rs (4,828 bytes)
|
||||
├── generic_case_a_whitespace_check.rs (4,552 bytes)
|
||||
└── ... (other files)
|
||||
```
|
||||
|
||||
### After (Proposed Structure)
|
||||
```
|
||||
src/mir/join_ir/lowering/
|
||||
├── generic_case_a/
|
||||
│ ├── mod.rs (~100 lines) ✅ Public API
|
||||
│ │ ├── pub use skip_ws::lower_case_a_skip_ws_with_scope
|
||||
│ │ ├── pub use trim::lower_case_a_trim_with_scope
|
||||
│ │ ├── pub use append_defs::lower_case_a_append_defs_with_scope
|
||||
│ │ └── pub use stage1_using_resolver::...
|
||||
│ │
|
||||
│ ├── skip_ws.rs (~220 lines) ✅ skip_ws lowerer
|
||||
│ │ ├── pub fn lower_case_a_skip_ws_with_scope()
|
||||
│ │ └── fn lower_case_a_skip_ws_core()
|
||||
│ │
|
||||
│ ├── trim.rs (~500 lines) ✅ trim lowerer
|
||||
│ │ ├── pub fn lower_case_a_trim_with_scope()
|
||||
│ │ └── fn lower_case_a_trim_core()
|
||||
│ │
|
||||
│ ├── append_defs.rs (~170 lines) ✅ append_defs lowerer
|
||||
│ │ ├── pub fn lower_case_a_append_defs_with_scope()
|
||||
│ │ └── fn lower_case_a_append_defs_core()
|
||||
│ │
|
||||
│ ├── stage1_using_resolver.rs (~180 lines) ✅ stage1 lowerer
|
||||
│ │ ├── pub fn lower_case_a_stage1_usingresolver_with_scope()
|
||||
│ │ └── fn lower_case_a_stage1_usingresolver_core()
|
||||
│ │
|
||||
│ ├── entry_builder.rs (~150 lines) ✅ (moved from parent)
|
||||
│ │ └── struct EntryFunctionBuilder
|
||||
│ │
|
||||
│ └── whitespace_check.rs (~150 lines) ✅ (moved from parent)
|
||||
│ └── fn check_whitespace()
|
||||
│
|
||||
└── ... (other files - unchanged)
|
||||
```
|
||||
|
||||
### Metrics Comparison
|
||||
|
||||
| Metric | Before | After | Change |
|
||||
|--------|--------|-------|--------|
|
||||
| **Total lines** | 1,056 | ~1,470 | +39% (for clarity) |
|
||||
| **Number of files** | 3 (scattered) | 7 (organized) | +133% |
|
||||
| **Largest file** | 1,056 | ~500 | -53% |
|
||||
| **Average file size** | 352 | ~210 | -40% |
|
||||
| **Functions per file** | 4 | 1-2 | Much clearer |
|
||||
|
||||
### Benefits
|
||||
- ✅ **Each lowerer in its own file** → Easy to maintain
|
||||
- ✅ **Companion files integrated** → All Case A logic in one directory
|
||||
- ✅ **trim.rs still large (500 lines)** → Could be further split if needed
|
||||
- ✅ **Clear public API** → mod.rs shows what's exported
|
||||
|
||||
---
|
||||
|
||||
## 3. loopform_builder.rs Modularization
|
||||
|
||||
### Before (Current State - After Phase 191)
|
||||
```
|
||||
src/mir/phi_core/
|
||||
├── loopform_builder.rs (1,166 lines) ⚠️ LARGE
|
||||
├── loopform_context.rs (✅ already modularized)
|
||||
├── loopform_variable_models.rs (✅ already modularized)
|
||||
├── loopform_utils.rs (✅ already modularized)
|
||||
├── loopform_exit_phi.rs (✅ already modularized)
|
||||
└── ... (other files)
|
||||
```
|
||||
|
||||
### After (Proposed Structure)
|
||||
```
|
||||
src/mir/phi_core/
|
||||
├── loopform/
|
||||
│ ├── mod.rs (~100 lines) ✅ Public API
|
||||
│ │ ├── pub use context::LoopFormContext
|
||||
│ │ ├── pub use variable_models::{CarrierVariable, PinnedVariable}
|
||||
│ │ ├── pub use exit_phi::build_exit_phis_for_control
|
||||
│ │ └── pub use builder_core::LoopFormBuilder
|
||||
│ │
|
||||
│ ├── context.rs (~150 lines) ✅ (existing)
|
||||
│ │ └── pub struct LoopFormContext
|
||||
│ │
|
||||
│ ├── variable_models.rs (~150 lines) ✅ (existing)
|
||||
│ │ ├── pub struct CarrierVariable
|
||||
│ │ ├── pub struct PinnedVariable
|
||||
│ │ └── pub struct LoopBypassFlags
|
||||
│ │
|
||||
│ ├── utils.rs (~100 lines) ✅ (existing)
|
||||
│ │ ├── pub fn is_loopform_debug_enabled()
|
||||
│ │ └── pub fn get_loop_bypass_flags()
|
||||
│ │
|
||||
│ ├── exit_phi.rs (~150 lines) ✅ (existing)
|
||||
│ │ └── pub fn build_exit_phis_for_control()
|
||||
│ │
|
||||
│ ├── passes/
|
||||
│ │ ├── mod.rs (~50 lines) ✅ 4-pass coordinator
|
||||
│ │ │ └── pub fn run_4_pass_architecture()
|
||||
│ │ │
|
||||
│ │ ├── pass1_discovery.rs (~150 lines) ✅ Variable discovery
|
||||
│ │ │ └── pub fn discover_variables()
|
||||
│ │ │
|
||||
│ │ ├── pass2_header_phi.rs (~150 lines) ✅ Header PHI
|
||||
│ │ │ └── pub fn build_header_phi()
|
||||
│ │ │
|
||||
│ │ ├── pass3_latch.rs (~100 lines) ✅ Latch processing
|
||||
│ │ │ └── pub fn process_latch()
|
||||
│ │ │
|
||||
│ │ └── pass4_exit_phi.rs (~150 lines) ✅ Exit PHI
|
||||
│ │ └── pub fn build_exit_phi()
|
||||
│ │
|
||||
│ └── builder_core.rs (~200 lines) ✅ Core builder
|
||||
│ └── pub struct LoopFormBuilder
|
||||
│
|
||||
└── ... (other files - unchanged)
|
||||
```
|
||||
|
||||
### Metrics Comparison
|
||||
|
||||
| Metric | Before | After | Change |
|
||||
|--------|--------|-------|--------|
|
||||
| **Total lines** | 1,166 (main file) | ~1,450 | +24% (for clarity) |
|
||||
| **Number of files** | 5 (partially modularized) | 11 (fully modularized) | +120% |
|
||||
| **Largest file** | 1,166 | ~200 | -83% |
|
||||
| **Average file size** | 233 | ~132 | -43% |
|
||||
|
||||
### Benefits
|
||||
- ✅ **Completes Phase 191 modularization** → Finishes what was started
|
||||
- ✅ **4-pass architecture explicit** → Each pass in its own file
|
||||
- ✅ **Already partially modularized** → Lower risk than control_flow.rs
|
||||
- ✅ **Clear separation of concerns** → Context, models, passes, builder
|
||||
|
||||
---
|
||||
|
||||
## File Size Distribution Comparison
|
||||
|
||||
### control_flow.rs
|
||||
```
|
||||
Before:
|
||||
█████████████████████████████████████████████████████████████████ 1,632 lines
|
||||
|
||||
After:
|
||||
merge/instruction_rewriter.rs: ███████ 150 lines
|
||||
pattern1_minimal.rs: ███████ 150 lines
|
||||
routing.rs: ███████ 150 lines
|
||||
pattern3_with_if_phi.rs: ████████ 180 lines
|
||||
try_catch.rs: ███████ 150 lines
|
||||
... (14 more files < 150 lines each)
|
||||
```
|
||||
|
||||
### generic_case_a.rs
|
||||
```
|
||||
Before:
|
||||
███████████████████████████████████████████████████ 1,056 lines
|
||||
|
||||
After:
|
||||
trim.rs: ████████████████████████ 500 lines
|
||||
skip_ws.rs: ██████████ 220 lines
|
||||
stage1_using_resolver.rs: ████████ 180 lines
|
||||
append_defs.rs: ████████ 170 lines
|
||||
... (3 more files < 150 lines each)
|
||||
```
|
||||
|
||||
### loopform_builder.rs
|
||||
```
|
||||
Before:
|
||||
████████████████████████████████████████████████████████ 1,166 lines
|
||||
|
||||
After:
|
||||
builder_core.rs: █████████ 200 lines
|
||||
context.rs: ███████ 150 lines
|
||||
variable_models.rs: ███████ 150 lines
|
||||
exit_phi.rs: ███████ 150 lines
|
||||
pass1_discovery.rs: ███████ 150 lines
|
||||
... (6 more files < 150 lines each)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Import Path Changes
|
||||
|
||||
### control_flow.rs
|
||||
|
||||
#### Before
|
||||
```rust
|
||||
use crate::mir::builder::MirBuilder;
|
||||
|
||||
impl MirBuilder {
|
||||
pub(super) fn cf_loop(...) -> Result<ValueId, String> {
|
||||
// 1,632 lines of code
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### After
|
||||
```rust
|
||||
// src/mir/builder/control_flow/mod.rs
|
||||
use crate::mir::builder::MirBuilder;
|
||||
|
||||
impl MirBuilder {
|
||||
pub(super) fn cf_loop(...) -> Result<ValueId, String> {
|
||||
// Delegates to routing module
|
||||
joinir::routing::try_cf_loop_joinir(self, ...)
|
||||
}
|
||||
}
|
||||
|
||||
// src/mir/builder/control_flow/joinir/routing.rs
|
||||
pub(in crate::mir::builder::control_flow) fn try_cf_loop_joinir(
|
||||
builder: &mut MirBuilder,
|
||||
...
|
||||
) -> Result<Option<ValueId>, String> {
|
||||
// 150 lines of focused code
|
||||
}
|
||||
```
|
||||
|
||||
### generic_case_a.rs
|
||||
|
||||
#### Before
|
||||
```rust
|
||||
// src/mir/join_ir/lowering/generic_case_a.rs
|
||||
pub(crate) fn lower_case_a_skip_ws_with_scope(...) -> Option<JoinModule> {
|
||||
// 200+ lines
|
||||
}
|
||||
```
|
||||
|
||||
#### After
|
||||
```rust
|
||||
// src/mir/join_ir/lowering/generic_case_a/mod.rs
|
||||
pub(crate) use skip_ws::lower_case_a_skip_ws_with_scope;
|
||||
|
||||
// src/mir/join_ir/lowering/generic_case_a/skip_ws.rs
|
||||
pub(crate) fn lower_case_a_skip_ws_with_scope(...) -> Option<JoinModule> {
|
||||
// 220 lines
|
||||
}
|
||||
```
|
||||
|
||||
### loopform_builder.rs
|
||||
|
||||
#### Before
|
||||
```rust
|
||||
// src/mir/phi_core/loopform_builder.rs
|
||||
pub use loopform_context::LoopFormContext;
|
||||
|
||||
pub fn build_exit_phis_for_control<O: LoopFormOps>(...) {
|
||||
// 1,166 lines
|
||||
}
|
||||
```
|
||||
|
||||
#### After
|
||||
```rust
|
||||
// src/mir/phi_core/loopform/mod.rs
|
||||
pub use context::LoopFormContext;
|
||||
pub use exit_phi::build_exit_phis_for_control;
|
||||
|
||||
// src/mir/phi_core/loopform/exit_phi.rs
|
||||
pub fn build_exit_phis_for_control<O: LoopFormOps>(...) {
|
||||
// 150 lines
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Navigation Improvements
|
||||
|
||||
### Before (Monolith Files)
|
||||
```
|
||||
Developer: "Where is the merge function?"
|
||||
Answer: "control_flow.rs, line 864-1578 (search through 1,632 lines)"
|
||||
|
||||
Developer: "Where is Pattern 3 lowering?"
|
||||
Answer: "control_flow.rs, line 696-863 (search through 1,632 lines)"
|
||||
|
||||
Developer: "What does merge_joinir_mir_blocks do?"
|
||||
Answer: "Read 714 lines to understand"
|
||||
```
|
||||
|
||||
### After (Modularized)
|
||||
```
|
||||
Developer: "Where is the merge function?"
|
||||
Answer: "control_flow/joinir/merge/mod.rs (100 lines coordinator)"
|
||||
|
||||
Developer: "Where is Pattern 3 lowering?"
|
||||
Answer: "control_flow/joinir/patterns/pattern3_with_if_phi.rs (180 lines)"
|
||||
|
||||
Developer: "What does merge_joinir_mir_blocks do?"
|
||||
Answer: "Read merge/mod.rs (100 lines) → delegates to 6 sub-modules"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Conclusion
|
||||
|
||||
The modularization dramatically improves code organization:
|
||||
|
||||
- **control_flow.rs**: 1,632 lines → 19 files (avg 97 lines)
|
||||
- **generic_case_a.rs**: 1,056 lines → 7 files (avg 210 lines)
|
||||
- **loopform_builder.rs**: 1,166 lines → 11 files (avg 132 lines)
|
||||
|
||||
**Total Impact**: 3,854 lines → 37 focused modules
|
||||
|
||||
**Developer Experience**:
|
||||
- ✅ Easier navigation (jump to definition works better)
|
||||
- ✅ Clearer separation of concerns
|
||||
- ✅ Less merge conflicts
|
||||
- ✅ Easier to add new patterns/lowerers
|
||||
- ✅ Better code review experience (smaller diffs)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-05
|
||||
Reference in New Issue
Block a user