refactor(engine): extract the splittable-leaf placement into its own compiler#360
Merged
Merged
Conversation
…compiler compileSplittableLeaf held the trickiest pagination code — the loop that splits a leaf across pages through NodeDefinition.split, emitting each piece and advancing the page cursor — inline in LayoutCompiler. Move it verbatim to a package-private SplittableLeafCompiler.compile, trimming LayoutCompiler by ~165 lines and giving the split loop a home and a direct test surface. Byte-identical: the body is unchanged except addPlacedFragments(...) is inlined to fragments.addAll(CompositeDecoration.toPlacedFragments(...)) (its exact definition) so the collaborator needs nothing private from LayoutCompiler. New SplittableLeafCompilerTest drives the whole-fit, no-progress-guard, and too-large branches in isolation with a stub NodeDefinition.
7e70ac5 to
13386ef
Compare
This was referenced Jul 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
LayoutCompiler.compileSplittableLeaf(~150 lines) carried the trickiest paginationlogic — the loop that splits a
SPLITTABLEleaf across pages viaNodeDefinition.split,emits each piece on the page it lands on, advances the page cursor, and guards against a
non-advancing split. It's self-contained (no recursion into other
compile*), so it belongsin its own file where it can be read and tested apart from the rest of the compiler. This is
the substantive step of the ongoing
LayoutCompilerbreakdown (#356–#359).What
SplittableLeafCompilerwith a staticcompile(...)holding thesplit loop verbatim;
LayoutCompilerdispatches to it and drops the private method(−165 LOC, 1361 → 1196).
addPlacedFragments(...)→fragments.addAll(CompositeDecoration.toPlacedFragments(...)),which is that helper's exact body — so the collaborator needs nothing private from
LayoutCompiler(it throws via theAtomicNodeTooLargeException.forNodefactory from refactor(engine): give AtomicNodeTooLargeException its own message factory #359).SplittableLeafCompilerTest: drives the whole-fit single-page placement, theno-progress split guard (
IllegalStateException), and the un-splittable-on-empty-pagetoo-large throw with a stub
NodeDefinition— branches the qa corpus doesn't reliably reach.Tests
./mvnw -f aggregator/pom.xml verify -pl :graph-compose-qa -am— full compile + javadocgate + the qa visual/parity byte-identity suite (643): green. Pagination of splittable
leaves (long tables / paragraphs) renders identically.
SplittableLeafCompilerTest: 3 tests, 0 failures.Byte-identical lift — the split loop is unchanged, now isolated and directly tested. The
14-parameter
compile(...)signature is inherited from the private method as-is; bundlingits shared context is a possible follow-up, kept out of this byte-identical move.