Skip to content

Commit

Permalink
Fix opalopal <<~END support.
Browse files Browse the repository at this point in the history
* Fixes #2169
* Fixes #2363

Avoid using String#slice! in the dedenter and expect a new string for
replacement in #dedent_string. Most of the other changes are dictated
by Rubocop.
  • Loading branch information
hmdne authored and elia committed Dec 19, 2021
1 parent 2dd6fe8 commit 9fd6b8c
Showing 1 changed file with 14 additions and 25 deletions.
39 changes: 14 additions & 25 deletions lib/opal/parser/patch.rb
Expand Up @@ -52,19 +52,17 @@ def check_lvar_name(name, loc)
# Taken From:
# https://github.com/whitequark/parser/blob/a7c638b7b205db9213a56897b41a8e5620df766e/lib/parser/builders/default.rb#L388
def dedent_string(node, dedent_level)
if !dedent_level.nil?
dedenter = Lexer::Dedenter.new(dedent_level)
unless dedent_level.nil?
dedenter = ::Parser::Lexer::Dedenter.new(dedent_level)

case node.type
when :str
str = node.children.first
dedenter.dedent(str)
node = node.updated(nil, [dedenter.dedent(node.children.first)])
when :dstr, :xstr
children = node.children.map do |str_node|
if str_node.type == :str
str = str_node.children.first
dedenter.dedent(str)
next nil if str.empty?
str_node = str_node.updated(nil, [dedenter.dedent(str_node.children.first)])
next nil if str_node.children.first.empty?
else
dedenter.interrupt
end
Expand All @@ -87,31 +85,20 @@ def dedent(string)
# Prevent the following error when processing binary encoded source.
# "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8)
lines = string.force_encoding(Encoding::BINARY).split("\\\n")
if lines.length == 1
# If the line continuation sequence was found but there is no second
# line, it was not really a line continuation and must be ignored.
lines = [string.force_encoding(original_encoding)]
else
lines.map! {|s| s.force_encoding(original_encoding) }
end

if @at_line_begin
lines_to_dedent = lines
else
_first, *lines_to_dedent = lines
end
lines.map! { |s| s.force_encoding(original_encoding) }

lines_to_dedent.each do |line|
lines.each_with_index do |line, index|
next if (index == 0) && !@at_line_begin
left_to_remove = @dedent_level
remove = 0

line.each_char do |char|
break if left_to_remove <= 0
case char
when ?\s
when "\s"
remove += 1
left_to_remove -= 1
when ?\t
when "\t"
break if TAB_WIDTH * (remove / TAB_WIDTH + 1) > @dedent_level
remove += 1
left_to_remove -= TAB_WIDTH
Expand All @@ -121,12 +108,14 @@ def dedent(string)
end
end

line.slice!(0, remove)
lines[index] = line[remove..-1]
end

string.replace(lines.join)
string = lines.join

@at_line_begin = string.end_with?("\n")

string
end
end
end
Expand Down

0 comments on commit 9fd6b8c

Please sign in to comment.