Skip to content

Commit 54f90cb

Browse files
committed
Use Ripper::Lexer#scan to take broken tokens
ref. ruby/reline#242
1 parent 212897d commit 54f90cb

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

lib/irb/ruby-lex.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def set_input(io, p = nil, &block)
6666
unprocessed_tokens = []
6767
line_num_offset = 0
6868
tokens.each do |t|
69+
next if t[1] == :on_parse_error || t[1] == :compile_error
6970
partial_tokens << t
7071
unprocessed_tokens << t
7172
if t[2].include?("\n")
@@ -110,7 +111,12 @@ def ripper_lex_without_warning(code)
110111
verbose, $VERBOSE = $VERBOSE, nil
111112
tokens = nil
112113
self.class.compile_with_errors_suppressed(code) do |inner_code, line_no|
113-
tokens = Ripper.lex(inner_code, '-', line_no)
114+
lexer = Ripper::Lexer.new(inner_code, '-', line_no)
115+
if lexer.respond_to?(:scan) # Ruby 2.7+
116+
tokens = lexer.scan
117+
else
118+
tokens = lexer.parse
119+
end
114120
end
115121
$VERBOSE = verbose
116122
tokens
@@ -122,6 +128,7 @@ def find_prev_spaces(line_index)
122128
prev_spaces = md.nil? ? 0 : md[1].count(' ')
123129
line_count = 0
124130
@tokens.each_with_index do |t, i|
131+
next if t[1] == :on_parse_error || t[1] == :compile_error
125132
if t[2].include?("\n")
126133
line_count += t[2].count("\n")
127134
if line_count >= line_index
@@ -350,6 +357,7 @@ def process_nesting_level(tokens = @tokens)
350357
indent = 0
351358
in_oneliner_def = nil
352359
tokens.each_with_index { |t, index|
360+
next if t[1] == :on_parse_error || t[1] == :compile_error
353361
# detecting one-liner method definition
354362
if in_oneliner_def.nil?
355363
if t[3].allbits?(Ripper::EXPR_ENDFN)
@@ -435,6 +443,7 @@ def check_newline_depth_difference
435443
open_brace_on_line = 0
436444
in_oneliner_def = nil
437445
@tokens.each_with_index do |t, index|
446+
next if t[1] == :on_parse_error || t[1] == :compile_error
438447
# detecting one-liner method definition
439448
if in_oneliner_def.nil?
440449
if t[3].allbits?(Ripper::EXPR_ENDFN)
@@ -504,6 +513,7 @@ def check_corresponding_token_depth
504513
open_brace_on_line = 0
505514
in_oneliner_def = nil
506515
@tokens.each_with_index do |t, index|
516+
next if t[1] == :on_parse_error || t[1] == :compile_error
507517
# detecting one-liner method definition
508518
if in_oneliner_def.nil?
509519
if t[3].allbits?(Ripper::EXPR_ENDFN)

test/irb/test_ruby_lex.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,25 @@ def test_oneliner_def_in_multiple_lines
367367
end
368368
end
369369

370+
def test_broken_heredoc
371+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7.0')
372+
skip 'This test needs Ripper::Lexer#scan to take broken tokens'
373+
end
374+
input_with_correct_indents = [
375+
Row.new(%q(def foo), nil, 2, 1),
376+
Row.new(%q( <<~Q), nil, 2, 1),
377+
Row.new(%q( Qend), nil, 2, 1),
378+
]
379+
380+
lines = []
381+
input_with_correct_indents.each do |row|
382+
lines << row.content
383+
assert_indenting(lines, row.current_line_spaces, false)
384+
assert_indenting(lines, row.new_line_spaces, true)
385+
assert_nesting_level(lines, row.nesting_level)
386+
end
387+
end
388+
370389
PromptRow = Struct.new(:prompt, :content)
371390

372391
class MockIO_DynamicPrompt

0 commit comments

Comments
 (0)