Part of #1097.
Current state
crates/perry-codegen/src/expr.rs is 15,044 lines. The single function lower_expr spans roughly lines 1212 → 13483 (~12k lines) — one match arm per Expr::* variant, several of which are 500+ lines each. Helpers (lower_object_literal, lower_array_literal, lower_index_set_fast, lower_channel_reduction, try_lower_flat_const_index_get, the NaN-box inline helpers, the V8-export-call helpers, etc.) sit on either side.
The problem isn't conceptual — it's mechanical. Adding a new variant means scrolling past 10k+ lines, and ripgrep'ping for a helper named lower_object_literal returns the right hit instantly but you still land in a sea of unrelated arms.
Proposed split
Move the file into a directory module crates/perry-codegen/src/expr/ with:
expr/mod.rs — keeps lower_expr as the entry point + the trivial arms (literals, LocalGet/LocalSet, Update, Undefined, Null, Bool, DateNow, etc.). Maybe ~1k–1.5k lines.
expr/typeof_void.rs — Expr::TypeOf, Expr::Void
expr/binary.rs — Expr::Binary arm (lines ~1732–2028)
expr/unary.rs — Expr::Unary arm (~2028–2084)
expr/compare.rs — Expr::Compare arm (~2084–2437)
expr/object_literal.rs — Expr::Object arm + lower_object_literal helper (~14072–14260)
expr/array_literal.rs — Expr::Array, Expr::ArraySpread arms + lower_array_literal (~14260–14439)
expr/index.rs — Expr::IndexGet, lower_index_set_fast, try_lower_flat_const_index_get (~2507–2983, ~13518–13614, ~14439–14591)
expr/property_get.rs — the cluster of Expr::PropertyGet arms (~2983–3200+, several distinct shapes)
expr/v8_interop.rs — emit_v8_export_call, emit_v8_member_method_call, try_static_class_name, import_origin_suffix (lines 62–328)
expr/nanbox_inline.rs — nanbox_pointer_inline, nanbox_bigint_inline, nanbox_string_inline, i32_bool_to_nanbox, unbox_to_i64, unbox_str_handle (~35–388, 13937–14046)
expr/strings.rs — emit_string_literal_global, Expr::String, Expr::WtfString arms
expr/channel.rs — try_match_channel_reduction, lower_channel_reduction, extract_array_of_object_shape (~14611–end)
expr/i32_fast_path.rs — is_known_finite, can_lower_expr_as_i32, lower_expr_as_i32, try_flat_const_2d_int (~13483–13860)
expr/url_helpers.rs — lower_url_string_getter
expr/write_barrier.rs — emit_write_barrier, lower_stream_super_init
Each submodule re-exports its pub(crate) helpers; expr/mod.rs keeps pub(crate) fn lower_expr as the single dispatch entry point that delegates each variant to its module.
Acceptance
- Pure file moves:
git diff -M -C90% shows ≥95% rename detection
cargo test --release --workspace --exclude perry-ui-* green
./run_parity_tests.sh shows no regression vs. main
- Public surface (anything
pub(crate) consumed outside expr.rs) preserved via re-exports
Part of #1097.
Current state
crates/perry-codegen/src/expr.rsis 15,044 lines. The single functionlower_exprspans roughly lines 1212 → 13483 (~12k lines) — one match arm perExpr::*variant, several of which are 500+ lines each. Helpers (lower_object_literal,lower_array_literal,lower_index_set_fast,lower_channel_reduction,try_lower_flat_const_index_get, the NaN-box inline helpers, the V8-export-call helpers, etc.) sit on either side.The problem isn't conceptual — it's mechanical. Adding a new variant means scrolling past 10k+ lines, and ripgrep'ping for a helper named
lower_object_literalreturns the right hit instantly but you still land in a sea of unrelated arms.Proposed split
Move the file into a directory module
crates/perry-codegen/src/expr/with:expr/mod.rs— keepslower_expras the entry point + the trivial arms (literals,LocalGet/LocalSet,Update,Undefined,Null,Bool,DateNow, etc.). Maybe ~1k–1.5k lines.expr/typeof_void.rs—Expr::TypeOf,Expr::Voidexpr/binary.rs—Expr::Binaryarm (lines ~1732–2028)expr/unary.rs—Expr::Unaryarm (~2028–2084)expr/compare.rs—Expr::Comparearm (~2084–2437)expr/object_literal.rs—Expr::Objectarm +lower_object_literalhelper (~14072–14260)expr/array_literal.rs—Expr::Array,Expr::ArraySpreadarms +lower_array_literal(~14260–14439)expr/index.rs—Expr::IndexGet,lower_index_set_fast,try_lower_flat_const_index_get(~2507–2983, ~13518–13614, ~14439–14591)expr/property_get.rs— the cluster ofExpr::PropertyGetarms (~2983–3200+, several distinct shapes)expr/v8_interop.rs—emit_v8_export_call,emit_v8_member_method_call,try_static_class_name,import_origin_suffix(lines 62–328)expr/nanbox_inline.rs—nanbox_pointer_inline,nanbox_bigint_inline,nanbox_string_inline,i32_bool_to_nanbox,unbox_to_i64,unbox_str_handle(~35–388, 13937–14046)expr/strings.rs—emit_string_literal_global,Expr::String,Expr::WtfStringarmsexpr/channel.rs—try_match_channel_reduction,lower_channel_reduction,extract_array_of_object_shape(~14611–end)expr/i32_fast_path.rs—is_known_finite,can_lower_expr_as_i32,lower_expr_as_i32,try_flat_const_2d_int(~13483–13860)expr/url_helpers.rs—lower_url_string_getterexpr/write_barrier.rs—emit_write_barrier,lower_stream_super_initEach submodule re-exports its
pub(crate)helpers;expr/mod.rskeepspub(crate) fn lower_expras the single dispatch entry point that delegates each variant to its module.Acceptance
git diff -M -C90%shows ≥95% rename detectioncargo test --release --workspace --exclude perry-ui-*green./run_parity_tests.shshows no regression vs. mainpub(crate)consumed outsideexpr.rs) preserved via re-exports