Skip to content

Commit

Permalink
[ruby/irb] Refactor RubyLex's input/io methods
Browse files Browse the repository at this point in the history
(ruby/irb#583)

1. Make `RubyLex#set_input` simply assign the input block. This matches
   the behavior of `RubyLex#set_prompt`.
2. Merge `RubyLex#set_input`'s IO configuration logic with `#set_auto_indent`
   into `#configure_io`.
  • Loading branch information
st0012 authored and matzbot committed May 18, 2023
1 parent d74b32d commit cfb7997
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 31 deletions.
4 changes: 2 additions & 2 deletions lib/irb.rb
Expand Up @@ -537,7 +537,7 @@ def eval_input
@context.io.prompt
end

@scanner.set_input(@context.io) do
@scanner.set_input do
signal_status(:IN_INPUT) do
if l = @context.io.gets
print l if @context.verbose?
Expand All @@ -555,7 +555,7 @@ def eval_input
end
end

@scanner.set_auto_indent
@scanner.configure_io(@context.io)

@scanner.each_top_level_statement do |line, line_no|
signal_status(:IN_EVAL) do
Expand Down
46 changes: 21 additions & 25 deletions lib/irb/ruby-lex.rb
Expand Up @@ -43,7 +43,11 @@ def self.compile_with_errors_suppressed(code, line_no: 1)
end

# io functions
def set_input(io, &block)
def set_input(&block)
@input = block
end

def configure_io(io)
@io = io
if @io.respond_to?(:check_termination)
@io.check_termination do |code|
Expand Down Expand Up @@ -112,10 +116,22 @@ def set_input(io, &block)
end
end

if block_given?
@input = block
else
@input = Proc.new{@io.gets}
if @io.respond_to?(:auto_indent) and @context.auto_indent_mode
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
if is_newline
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: @context)
prev_spaces = find_prev_spaces(line_index)
depth_difference = check_newline_depth_difference
depth_difference = 0 if depth_difference < 0
prev_spaces + depth_difference * 2
else
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
last_line = lines[line_index]&.byteslice(0, byte_pointer)
code += last_line if last_line
@tokens = self.class.ripper_lex_without_warning(code, context: @context)
check_corresponding_token_depth(lines, line_index)
end
end
end
end

Expand Down Expand Up @@ -184,26 +200,6 @@ def find_prev_spaces(line_index)
prev_spaces
end

def set_auto_indent
if @io.respond_to?(:auto_indent) and @context.auto_indent_mode
@io.auto_indent do |lines, line_index, byte_pointer, is_newline|
if is_newline
@tokens = self.class.ripper_lex_without_warning(lines[0..line_index].join("\n"), context: @context)
prev_spaces = find_prev_spaces(line_index)
depth_difference = check_newline_depth_difference
depth_difference = 0 if depth_difference < 0
prev_spaces + depth_difference * 2
else
code = line_index.zero? ? '' : lines[0..(line_index - 1)].map{ |l| l + "\n" }.join
last_line = lines[line_index]&.byteslice(0, byte_pointer)
code += last_line if last_line
@tokens = self.class.ripper_lex_without_warning(code, context: @context)
check_corresponding_token_depth(lines, line_index)
end
end
end
end

def check_state(code, tokens)
ltype = process_literal_type(tokens)
indent = process_nesting_level(tokens)
Expand Down
8 changes: 4 additions & 4 deletions test/irb/test_ruby_lex.rb
Expand Up @@ -41,8 +41,8 @@ def calculate_indenting(lines, add_new_line)
ruby_lex = RubyLex.new(context)
mock_io = MockIO_AutoIndent.new(lines, last_line_index, byte_pointer, add_new_line)

ruby_lex.set_input(mock_io)
ruby_lex.set_auto_indent
ruby_lex.set_input { @io.gets }
ruby_lex.configure_io(mock_io)
mock_io.calculated_indent
end

Expand Down Expand Up @@ -99,7 +99,7 @@ def ruby_lex_for_lines(lines, local_variables: [])
ruby_lex = RubyLex.new(context)

io = proc{ lines.join("\n") }
ruby_lex.set_input(io) do
ruby_lex.set_input do
lines.join("\n")
end
ruby_lex.lex
Expand Down Expand Up @@ -658,7 +658,7 @@ def assert_dynamic_prompt(lines, expected_prompt_list)
ruby_lex.set_prompt do |ltype, indent, continue, line_no|
'%03d:%01d:%1s:%s ' % [line_no, indent, ltype, continue ? '*' : '>']
end
ruby_lex.set_input(io)
ruby_lex.set_input { @io.gets }
end

def test_dyanmic_prompt
Expand Down

0 comments on commit cfb7997

Please sign in to comment.