Skip to content

Commit

Permalink
Fix lex compat when dedent should be 0
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed Oct 17, 2023
1 parent fbd101d commit 41c0e0e
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 161 deletions.
9 changes: 8 additions & 1 deletion lib/prism/lex_compat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ def initialize
@dedent_next = true
@dedent = nil
@embexpr_balance = 0
@ended_on_newline = false
end

# As tokens are coming in, we track the minimum amount of common leading
Expand All @@ -366,13 +367,14 @@ def <<(token)
case token.event
when :on_embexpr_beg, :on_heredoc_beg
@embexpr_balance += 1
@dedent = 0 if @dedent_next && @ended_on_newline
when :on_embexpr_end, :on_heredoc_end
@embexpr_balance -= 1
when :on_tstring_content
if embexpr_balance == 0
line = token.value

if !(line.strip.empty? && line.end_with?("\n")) && dedent_next
if dedent_next && !(line.strip.empty? && line.end_with?("\n"))
leading = line[/\A(\s*)\n?/, 1]
next_dedent = 0

Expand All @@ -385,11 +387,16 @@ def <<(token)
end

@dedent = [dedent, next_dedent].compact.min
@dedent_next = true
@ended_on_newline = line.end_with?("\n")
tokens << token
return
end
end
end

@dedent_next = token.event == :on_tstring_content && embexpr_balance == 0
@ended_on_newline = false
tokens << token
end

Expand Down
6 changes: 6 additions & 0 deletions test/prism/fixtures/tilde_heredocs.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<<~EOF
a
#{1}
a
EOF

<<~EOF
a
EOF
Expand Down
5 changes: 5 additions & 0 deletions test/prism/heredoc_dedent_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ class HeredocDedentTest < TestCase
filepath = File.expand_path("fixtures/tilde_heredocs.txt", __dir__)

File.read(filepath).split(/(?=\n)\n(?=<)/).each_with_index do |heredoc, index|
# The first example in this file has incorrect dedent calculated by
# TruffleRuby so we skip it.
next if index == 0 && RUBY_ENGINE == "truffleruby"

define_method "test_heredoc_#{index}" do
node = Prism.parse(heredoc).value.statements.body.first

if node.is_a?(StringNode)
actual = node.unescaped
else
Expand Down
Loading

0 comments on commit 41c0e0e

Please sign in to comment.