diff options
author | Stan Lo <stan001212@gmail.com> | 2023-01-10 20:43:33 +0000 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2023-01-14 09:19:09 +0000 |
commit | cb9b885e78bb87195d483df1afedf58d0bb81e41 (patch) | |
tree | 1ba732ebb576213869f099b5bcb1b1d33620de16 /lib/irb/ruby-lex.rb | |
parent | 2082ba7c69c1d38508bfa549df3f2980cf8d066d (diff) |
[ruby/irb] Store context in RubyLex
Some background for this refactor:
1. Through a RubyLex instance's lifetime, the context passed to its methods
should be the same.
Given that `Context` is only initialised in `Irb#initialize`,
this should be true.
2. When `RubyLex` is initialised, the context object should be accessible.
This is also true in all 3 of `RubyLex.new`'s invocations.
With the above observations, we should be able to store the context in `RubyLex`
as an instance variable. And doing so will make `RubyLex`'s instance methods
easier to use and maintain.
https://github.com/ruby/irb/commit/5c8d3df2df
Diffstat (limited to 'lib/irb/ruby-lex.rb')
-rw-r--r-- | lib/irb/ruby-lex.rb | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb index c11a4f8865..9e4a7b28fa 100644 --- a/lib/irb/ruby-lex.rb +++ b/lib/irb/ruby-lex.rb @@ -16,7 +16,8 @@ class RubyLex end end - def initialize + def initialize(context) + @context = context @exp_line_no = @line_no = 1 @indent = 0 @continue = false @@ -42,13 +43,13 @@ class RubyLex end # io functions - def set_input(io, context:, &block) + def set_input(io, &block) @io = io if @io.respond_to?(:check_termination) @io.check_termination do |code| if Reline::IOGate.in_pasting? - lex = RubyLex.new - rest = lex.check_termination_in_prev_line(code, context: context) + lex = RubyLex.new(@context) + rest = lex.check_termination_in_prev_line(code) if rest Reline.delete_text rest.bytes.reverse_each do |c| @@ -61,13 +62,13 @@ class RubyLex else # Accept any single-line input for symbol aliases or commands that transform args command = code.split(/\s/, 2).first - if context.symbol_alias?(command) || context.transform_args?(command) + if @context.symbol_alias?(command) || @context.transform_args?(command) next true end code.gsub!(/\s*\z/, '').concat("\n") - tokens = self.class.ripper_lex_without_warning(code, context: context) - ltype, indent, continue, code_block_open = check_state(code, tokens, context: context) + tokens = self.class.ripper_lex_without_warning(code, context: @context) + ltype, indent, continue, code_block_open = check_state(code, tokens) if ltype or indent > 0 or continue or code_block_open false else @@ -80,7 +81,7 @@ class RubyLex @io.dynamic_prompt do |lines| lines << '' if lines.empty? result = [] - tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, context: context) + tokens = self.class.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, context: @context) code = String.new partial_tokens = [] unprocessed_tokens = [] @@ -93,7 +94,7 @@ class RubyLex t_str.each_line("\n") do |s| code << s next unless s.include?("\n") - ltype, indent, continue, code_block_open = check_state(code, partial_tokens, context: context) + ltype, indent, continue, code_block_open = check_state(code, partial_tokens) result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset) line_num_offset += 1 end @@ -104,7 +105,7 @@ class RubyLex end unless unprocessed_tokens.empty? - ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens, context: context) + ltype, indent, continue, code_block_open = check_state(code, unprocessed_tokens) result << @prompt.call(ltype, indent, continue || code_block_open, @line_no + line_num_offset) end result @@ -187,11 +188,11 @@ class RubyLex prev_spaces end - def set_auto_indent(context) - if @io.respond_to?(:auto_indent) and context.auto_indent_mode + 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) + @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 @@ -200,18 +201,18 @@ class RubyLex 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) + @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, context:) + def check_state(code, tokens) ltype = process_literal_type(tokens) indent = process_nesting_level(tokens) continue = process_continue(tokens) - lvars_code = self.class.generate_local_variables_assign_code(context.local_variables) + lvars_code = self.class.generate_local_variables_assign_code(@context.local_variables) code = "#{lvars_code}\n#{code}" if lvars_code code_block_open = check_code_block(code, tokens) [ltype, indent, continue, code_block_open] @@ -232,13 +233,13 @@ class RubyLex @code_block_open = false end - def each_top_level_statement(context) + def each_top_level_statement initialize_input catch(:TERM_INPUT) do loop do begin prompt - unless l = lex(context) + unless l = lex throw :TERM_INPUT if @line == '' else @line_no += l.count("\n") @@ -268,15 +269,15 @@ class RubyLex end end - def lex(context) + def lex line = @input.call if @io.respond_to?(:check_termination) return line # multiline end code = @line + (line.nil? ? '' : line) code.gsub!(/\s*\z/, '').concat("\n") - @tokens = self.class.ripper_lex_without_warning(code, context: context) - @ltype, @indent, @continue, @code_block_open = check_state(code, @tokens, context: context) + @tokens = self.class.ripper_lex_without_warning(code, context: @context) + @ltype, @indent, @continue, @code_block_open = check_state(code, @tokens) line end @@ -777,8 +778,8 @@ class RubyLex end end - def check_termination_in_prev_line(code, context:) - tokens = self.class.ripper_lex_without_warning(code, context: context) + def check_termination_in_prev_line(code) + tokens = self.class.ripper_lex_without_warning(code, context: @context) past_first_newline = false index = tokens.rindex do |t| # traverse first token before last line |