Repository navigation
Fix data section loss, chain indent idempotency, and else comments - #124
Merged
Merged
Conversation
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.
Three formatter bugs found by ad-hoc property testing over Rails-style code (crash / idempotency / AST equivalence / comment preservation, plus a DATA-section property the existing corpus check does not cover).
What was broken
The `END` data section was silently dropped. `Rfmt.format("puts DATA.read\n\n__END__\nhello\n")` returned only `"puts DATA.read\n"`, destroying any script that reads `DATA`. The section is not part of Prism's AST, and the formatter rebuilds output from the AST, so nothing ever emitted it. Fix: `NativeAdapter::parse` records `data_loc()`'s start offset in the root metadata, and `Formatter::format` re-appends the verbatim source slice after printing. `data_loc` comes from Prism, so a fake `END` inside a heredoc cannot false-positive.
Chain continuation indentation was not idempotent. The chain reformatter baked the statement's input column into a `Doc::Text`, but the doc engine places the statement at its output position. On misindented input (conflict resolutions, generated code) the first pass under- or over-indented continuations and the second pass moved them again. Fix: `reformat_chain_lines` became `reformat_chain_doc`, emitting continuation lines as `hardline` docs inside `indent(...)` so the printer anchors them at render time. Multi-line arguments keep their offset relative to the chain; heredoc bodies are emitted through `literalline` verbatim, because for plain/dash heredocs the leading whitespace is string content (a lexical heredoc scanner marks those lines; ambiguity fails toward verbatim, the semantics-safe direction).
A trailing comment on `else` moved below the line, where it reads as annotating the branch body. The `ElseNode` arm never consumed the else-line comment as a trailing comment, so the body's leading-comment path claimed it. Fix mirrors the existing if-header and end-line handling.
Verification
Known follow-ups (pre-existing, not regressions)