Skip to content

Add basic support for parsing and generating heredocs#406

Closed
apiology wants to merge 1 commit intoShopify:mainfrom
apiology:basic_heredoc_support
Closed

Add basic support for parsing and generating heredocs#406
apiology wants to merge 1 commit intoShopify:mainfrom
apiology:basic_heredoc_support

Conversation

@apiology
Copy link
Copy Markdown

Without this change, the data lines in a heredoc are not generated, resulting in a syntax error in the generated RBI:

FOO = <<EOF
bar
EOF

becomes just

FOO = <<EOF

@apiology apiology requested a review from a team as a code owner February 16, 2025 03:13
@apiology
Copy link
Copy Markdown
Author

CLA just signed

Copy link
Copy Markdown
Contributor

@Morriar Morriar left a comment

Choose a reason for hiding this comment

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

Hi @apiology,

Thank you for your contribution but I do not believe this is the right fix.

It looks like the problem stems from the location Prism returns for an heredoc.

Consider this snippet:

require "prism"

ruby_string = <<~RUBY
  FOO = <<~EOF
    foo
  EOF
RUBY

puts Prism.parse(ruby_string).inspect

Prism will return the following AST:

#<Prism::ParseResult:0x000000011f9556f8 @value=@ ProgramNode (location: (1,0)-(1,12))
├── flags: ∅
├── locals: []
└── statements:
    @ StatementsNode (location: (1,0)-(1,12))
    ├── flags: ∅
    └── body: (length: 1)
        └── @ ConstantWriteNode (location: (1,0)-(1,12))
            ├── flags: newline
            ├── name: :FOO
            ├── name_loc: (1,0)-(1,3) = "FOO"
            ├── value:
            │   @ StringNode (location: (1,6)-(1,12))
            │   ├── flags: ∅
            │   ├── opening_loc: (1,6)-(1,12) = "<<~EOF"
            │   ├── content_loc: (2,0)-(3,0) = "  foo\n"
            │   ├── closing_loc: (3,0)-(4,0) = "EOF\n"
            │   └── unescaped: "foo\n"
            └── operator_loc: (1,4)-(1,5) = "="

Note how the closing_loc points to the correct location at the end of the EOF marker yet the node location (@ StringNode (location: (1,6)-(1,12))) only includes the opening marker.

Digging a bit in Prism issues, I found ruby/prism#1260 explaining this behavior is actually desirable.

Given this, I think the best way is to adjust the Prism location when we encounter a constant that holds a heredoc value. I opened #408 that should solve your issue. Could you confirm for me please?

@Morriar Morriar self-assigned this Feb 17, 2025
@Morriar Morriar added the bugfix Fix a bug label Feb 17, 2025
@Morriar Morriar closed this in #408 Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fix a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants