Skip to content

Preserve heredoc body when translating multi-line T.let assertions#943

Open
styrmis wants to merge 4 commits into
mainfrom
06-08-fix-spoom-heredoc-handling
Open

Preserve heredoc body when translating multi-line T.let assertions#943
styrmis wants to merge 4 commits into
mainfrom
06-08-fix-spoom-heredoc-handling

Conversation

@styrmis

@styrmis styrmis commented Jun 8, 2026

Copy link
Copy Markdown

When T.let(...) spans multiple lines and wraps a heredoc, the replacement range covers the entire call including the heredoc body. Since the value node's source range only covers the opener line (e.g. <<~MSG.strip), the body and terminator were silently dropped, producing syntactically broken Ruby.

@styrmis styrmis force-pushed the 06-08-fix-spoom-heredoc-handling branch 3 times, most recently from 3bd034d to 3c92653 Compare June 8, 2026 11:30
When `T.let(...)` spans multiple lines and wraps a heredoc, the
replacement range covers the entire call including the heredoc body.
Since the value node's source range only covers the opener line
(e.g. `<<~MSG.strip`), the body and terminator were silently dropped,
producing syntactically broken Ruby.
@styrmis styrmis force-pushed the 06-08-fix-spoom-heredoc-handling branch from 3c92653 to a5d6263 Compare June 8, 2026 11:46
@styrmis styrmis marked this pull request as ready for review June 8, 2026 12:00
@styrmis styrmis requested a review from a team as a code owner June 8, 2026 12:00
Comment thread lib/spoom/sorbet/translate/sorbet_assertions_to_rbs_comments.rb Outdated
Comment thread lib/spoom/sorbet/translate/sorbet_assertions_to_rbs_comments.rb Outdated
Before this change we would stop at the first heredoc.
@styrmis styrmis force-pushed the 06-08-fix-spoom-heredoc-handling branch from c9269d5 to 74e0e3f Compare June 12, 2026 16:33
@styrmis styrmis requested a review from KaanOzkan June 12, 2026 16:47
when Prism::StringNode, Prism::InterpolatedStringNode
opening = node.opening_loc
closing = node.closing_loc
if opening && closing && opening.start_line != closing.start_line

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could split a string in multiple lines 😄

s = T.let(
  "first
  second",
  String,
)

I found slice, so we can add a opening.slice.start_with?("<<") check to the conditional:
opening && closing && opening.start_line != closing.start_line && opening.slice.start_with?("<<")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch—have separately added coverage for backticks in heredocs.

@styrmis styrmis requested a review from KaanOzkan June 17, 2026 13:36
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.

2 participants