You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Compiler: lib/Compiler.php is one 62,407-line class with 1,268 methods and 923 fields — trait-based decomposition behind an opcode-md5 corpus gate (lib/Compiler.php, lib/Lint/LintCompiler.php) #36230
Foundation: · maintainability (87 PRs/day land in this file) · child of #36188
Problem
lib/Compiler.php: 62,407 lines, one class, 1,268 methods (902 private / 344 protected / 21 public), 923 property declarations, 3,599 instanceof (3,185 on Op\…), 10 switch. Dispatch is compileOp (:13352) → compileExpr (:14299, a switch (get_class($expr)) with 43 arms) / compileStmt (:13423) / compileTerminal (:44722). 102 PHP builtin names are hardcoded inside lowering (array_merge 39x, array_replace_recursive 32x, var_export 23x, preg_replace_callback_array 13x …). compileCallArgSends alone is 6,431 lines (the super-quadratic compile child of #36188 covers its algorithm). The ~40 mutable fields shared by the 902 private methods (coalesceResultSlots, ternaryMergeVarSlots, activeCatchVarSlotsByName, …) are why nobody can move code safely, and why merge conflicts in this file are constant at fleet velocity. The one subclass, Lint\LintCompiler, overrides five protected methods (lib/Lint/LintCompiler.php:29,39,53,79,90) — a constraint any split must keep.
PHP implementation target
Traits, not collaborator objects: trait methods keep $this, visibility and overridability, so LintCompiler keeps working. One PR per step, each gated by Printer::print md5 equality over a fixed ≥ 100-file corpus (zero opcode diff), in this order:
Compiler\Concern\CompileTimeFold — the ~15 tryFold* methods (all private).
Compiler\Concern\ParameterAsserts — the 9 assertNo*/assertVariadic* methods (:999-1130).
Compiler\Concern\ClassLowering — compileClassBody (:9308), compileInterface, compileTrait, compileClassLike; keep the five LintCompiler-overridden methods on the class.
Category
Foundation:· maintainability (87 PRs/day land in this file) · child of #36188Problem
lib/Compiler.php: 62,407 lines, one class, 1,268 methods (902 private / 344 protected / 21 public), 923 property declarations, 3,599instanceof(3,185 onOp\…), 10switch. Dispatch iscompileOp(:13352) →compileExpr(:14299, aswitch (get_class($expr))with 43 arms) /compileStmt(:13423) /compileTerminal(:44722). 102 PHP builtin names are hardcoded inside lowering (array_merge39x,array_replace_recursive32x,var_export23x,preg_replace_callback_array13x …).compileCallArgSendsalone is 6,431 lines (the super-quadratic compile child of #36188 covers its algorithm). The ~40 mutable fields shared by the 902 private methods (coalesceResultSlots,ternaryMergeVarSlots,activeCatchVarSlotsByName, …) are why nobody can move code safely, and why merge conflicts in this file are constant at fleet velocity. The one subclass,Lint\LintCompiler, overrides five protected methods (lib/Lint/LintCompiler.php:29,39,53,79,90) — a constraint any split must keep.PHP implementation target
Traits, not collaborator objects: trait methods keep
$this, visibility and overridability, soLintCompilerkeeps working. One PR per step, each gated byPrinter::printmd5 equality over a fixed ≥ 100-file corpus (zero opcode diff), in this order:Compiler\Concern\CompileTimeFold— the ~15tryFold*methods (all private).Compiler\Concern\ParameterAsserts— the 9assertNo*/assertVariadic*methods (:999-1130).Compiler\Concern\CoalesceAndNullsafe—compileCoalesce(:15949) + nullsafe prelude machinery.Compiler\Concern\InlineCallArgProducers— the ~60inline*/sibling*/hoisted*/rewire*/slotFor*methods (~18,000 lines) — the staging ground for the def-use rewrite (super-quadratic compile child of Compiler audit (Sep 2026): fast generated code, Zend-shaped runtime, incremental builds, truthful gates — automation tracker #36188).Compiler\Concern\ClassLowering—compileClassBody(:9308),compileInterface,compileTrait,compileClassLike; keep the fiveLintCompiler-overridden methods on the class.compileExprarms into per-op classes behind aLoweringRegistry(the switch is already an exact dispatch table).Do not start with per-op classes — moving state before moving code is where behaviour changes leak in. Add
script/opcode-corpus-md5.sh(the gate) first; it doubles as the safety net for the Simplifier-default and operand-index children of Compiler audit (Sep 2026): fast generated code, Zend-shaped runtime, incremental builds, truthful gates — automation tracker #36188.Done when
script/opcode-corpus-md5.shcommitted and run incheck-generated-docs.sh's fast tierlib/Compiler.php< 20,000 lines;LintCompilertests unchangedCompiler.phpdirectly