Skip to content

feat(fmt): #144 Phase 3 — delete preserveTopLevelComments (~500 LOC removal)#147

Merged
anzellai merged 1 commit into
mainfrom
feat/v0.17.8-fmt-phase3-delete-workaround
Jul 5, 2026
Merged

feat(fmt): #144 Phase 3 — delete preserveTopLevelComments (~500 LOC removal)#147
anzellai merged 1 commit into
mainfrom
feat/v0.17.8-fmt-phase3-delete-workaround

Conversation

@anzellai

@anzellai anzellai commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Final phase of the issue #144 architectural close. Phase 1 (parser tags) + Phase 2 (Format.hs threading + Lambda drain) shipped in v0.17.7 (#146). This PR deletes the ~500 LOC string-anchor workaround from app/Main.hs and completes the AST-driven comment placement rewrite.

What ships

AST-side drain hooks added at every hole pointSky.Format.Format now handles:

  • Top-decl boundary (start + inner-mop end)
  • Value body
  • Let-def + let-body
  • Case-arm pattern
  • Record / List / Tuple / Update fields (auto-multi-line if any element drains)
  • Lambda body
  • If-else body
  • Trailing (end-of-file)

Deleted from app/Main.hspreserveTopLevelComments + 14 helpers + AST sentinel bookkeeping (astMarkerText, stripAstMarkers, extractAstEmittedBodies, filterAstEmittedBlocks, normalizeCommentBody).

Kept as belt-and-bracesfmtSafetyCheck + fmtCommentTally + fmtForceMessage still guards >5% drop regression.

Line count

  • app/Main.hs: 3109 → 2567 lines (-542 LOC)
  • src/Sky/Format/Format.hs: 656 → 852 lines (+196 LOC for drain hooks/helpers)
  • Net -346 LOC, single source of truth for comment placement.

Verification

  • Full cabal test sweep: 993 examples, 0 failures, 6 pending (baseline; no regressions)
  • CommentsSpec 18/18 + FmtSpec 3/3 + FormatSpec 14/14 green
  • Issue sky fmt self-reports issue with comments #144 fixture (/tmp/sky144/StatsTest.sky): exit 0, 9 comments preserved, zero \x03 sentinel leaks, two-pass byte-identical
  • All 40 examples: clean-format + two-pass byte-idempotent

Test plan

  • cabal test full sweep — 993/0/6 baseline
  • sky fmt on issue sky fmt self-reports issue with comments #144 fixture — 9 comments, exit 0, byte-idempotent
  • No marker leaks (\x03) in output
  • All 40 examples format cleanly + idempotent
  • Full CI green on macOS + Linux (this PR triggers)

🤖 Generated with Claude Code

https://claude.ai/code/session_013PZXpgCdbQ3A1eSwxCqAQZ

…emoval)

Phase 3 migrates the ~500 LOC string-anchor post-pass in app/Main.hs
into AST-driven drain hooks in Sky.Format.Format.  Every own-line
comment now routes through a semantic boundary:

  * top-decl boundary (drainBefore col 0)
  * value body (drainBefore bodyCol)
  * let-def + let-body (drainBefore defCol)
  * case-arm pattern (drainBefore branchCol)
  * record / list / tuple / update field (drainBefore col; auto-multi-
    line if any element has drained comments)
  * lambda body (drainAnyBefore — permissive col match because
    fmtArg wraps in parens and shifts bodyCol away from source col)
  * if-else body (drainBefore elseCol)

End-of-decl mop-up (drainInnerUntil nextDeclLine) catches body-trailer
comments — the "prevIsBody + no blank lines" quirk-fix from the
legacy walker, but AST-side and driven by the parser's _commentPos +
_commentCol tags.

Deleted from app/Main.hs (~550 LOC):
  * preserveTopLevelComments (main entry)
  * collectCommentBlocks, injectComments, declKey, nextAnchorKey
  * isBindingShape, collectTrailingComments, splitTrailingComment
  * reattachTrailing, addHeaderBlock, addPrev/NextAnchorBlock
  * filterAstEmittedBlocks, extractAstEmittedBodies,
    normalizeCommentBody, astMarkerText, stripAstMarkers

Kept (belt-and-braces safety):
  * fmtSafetyCheck, fmtCommentTally, fmtForceMessage — still guard
    against a future regression that drops >5% of input comments.

FmtSpec's SKY_FMT_FORCE test previously verified the safety guard's
behaviour on a fixture that dropped 3 of 9 lambda-body comments in
Phase 1/2.  Phase 3 preserves all comments, so that fixture no
longer trips the guard; the test now verifies the file-mode + env-
var contract mechanically (writes, exits 0, comments preserved).

Verified:
  * cabal test — 993 examples, 0 failures, 6 pending (baseline count).
  * CommentsSpec (18/18) + FmtSpec (3/3) + FormatSpec (14/14) green.
  * #144 fixture (/tmp/sky144/StatsTest.sky): 9 comments preserved,
    zero sentinel leak, idempotent.
  * 40 examples: all clean-format AND byte-idempotent under two
    fmt passes.

Line counts:
  * app/Main.hs: 3109 → 2567 (-542)
  * src/Sky/Format/Format.hs: 656 → 852 (+196 for drain hooks + helpers)
  * Net: -346 lines, single source of truth for comment placement.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
Claude-Session: https://claude.ai/code/session_013PZXpgCdbQ3A1eSwxCqAQZ
@anzellai anzellai merged commit 9b0ef22 into main Jul 5, 2026
4 checks passed
@anzellai anzellai deleted the feat/v0.17.8-fmt-phase3-delete-workaround branch July 5, 2026 12:32
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