Skip to content

feat(engine): match leaves across containers and preserve sibling moves - #64

Merged
HarshK97 merged 3 commits into
mainfrom
fix/cross-container-leaf-moves
Aug 7, 2026
Merged

feat(engine): match leaves across containers and preserve sibling moves#64
HarshK97 merged 3 commits into
mainfrom
fix/cross-container-leaf-moves

Conversation

@HarshK97

@HarshK97 HarshK97 commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Problem

  1. Leaf matching in MatchUnmatchedLeaves required leaves to share the exact same immediate parent container. When code was refactored across container types (like comments moving from an elif clause into an if block, or a for loop refactored into a dictionary comprehension), unmatched leaves were skipped, so we ended up with spurious delete and insert pairs instead of clean structural moves.
  2. normalizeBareLiteralMoves in post-processing split any literal or identifier Move into a Delete + Insert whenever its parent container was unmapped. So when a for loop moved into a for_in_clause, cookie and cj got split into delete/insert actions while for and in stayed as moves.
  3. In the TUI, mergeAllSpans iterated sequentially over line spans without grouping by action kind. Interleaved container kindDelete spans blocked adjacent kindMove spans from merging, which left red background gaps inside blue move highlights.

What Changed

  • Added SharedMatchedAncestor in internal/engine/utils.go so MatchUnmatchedLeaves can pair leaves across container boundaries if they share an enclosing statement or block ancestor.
  • Added RollupMatchedContainers in internal/engine/bottom-up.go to pair unmatched container nodes post-order when their mapped children belong to the same unmatched destination parent.
  • Filtered candidate structural pairs in LCSStructure when subtrees contain long leaf tokens (len > 3) and LeafSimilarity is 0, so distinct key-value pairs like status codes 414 vs 422 don't get falsely matched.
  • Updated normalizeBareLiteralMoves in internal/postprocess/normalize.go with hasMovedSiblingFromSameParent to preserve literal and identifier moves when destination siblings also moved from the same source parent.
  • Grouped line spans by actionKind in internal/tui/highlight.go (mergeAllSpans) so move spans merge smoothly across gaps without getting interrupted by container delete spans.
  • Updated golden test baselines in tests/testdata/ and added unit tests in internal/engine/, internal/postprocess/, and internal/tui/.

Visual Comparison

1.tests/testdata/py_requests_add_rfc9110

Before
image
After
  • Zero spurious moves or updates. The diff correctly reports 4 clean Insert actions for the newly added status codes.
image

@HarshK97
HarshK97 merged commit 4491c85 into main Aug 7, 2026
13 checks passed
@HarshK97
HarshK97 deleted the fix/cross-container-leaf-moves branch August 7, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant