summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Lo <[email protected]>2024-07-16 16:58:08 +0100
committergit <[email protected]>2024-07-16 15:58:15 +0000
commit4a4e1bf357f5b5f568ead4da0537eb4506e20e5f (patch)
treef95a378bdff0a5e4b866ea47042cc541504d41eb
parent4fe3082b63a801abe15711ebb907bd66aa58bc35 (diff)
[ruby/irb] Group class methods under `class << self`
(https://github.com/ruby/irb/pull/981) https://github.com/ruby/irb/commit/cdaa356df2
-rw-r--r--lib/irb.rb58
-rw-r--r--lib/irb/command/base.rb18
-rw-r--r--lib/irb/command/debug.rb14
-rw-r--r--lib/irb/default_commands.rb10
-rw-r--r--lib/irb/input-method.rb12
-rw-r--r--lib/irb/inspector.rb61
-rw-r--r--lib/irb/nesting_parser.rb390
-rw-r--r--lib/irb/ruby-lex.rb166
-rw-r--r--lib/irb/workspace.rb12
-rw-r--r--test/irb/test_context.rb1
-rw-r--r--test/irb/test_workspace.rb1
11 files changed, 379 insertions, 364 deletions
diff --git a/lib/irb.rb b/lib/irb.rb
index b417d9c2ec..3d45fa89db 100644
--- a/lib/irb.rb
+++ b/lib/irb.rb
@@ -880,40 +880,42 @@ module IRB
# An exception raised by IRB.irb_abort
class Abort < Exception;end
- # The current IRB::Context of the session, see IRB.conf
- #
- # irb
- # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
- # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
- def IRB.CurrentContext # :nodoc:
- IRB.conf[:MAIN_CONTEXT]
- end
+ class << self
+ # The current IRB::Context of the session, see IRB.conf
+ #
+ # irb
+ # irb(main):001:0> IRB.CurrentContext.irb_name = "foo"
+ # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo"
+ def CurrentContext # :nodoc:
+ conf[:MAIN_CONTEXT]
+ end
- # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
- def IRB.start(ap_path = nil)
- STDOUT.sync = true
- $0 = File::basename(ap_path, ".rb") if ap_path
+ # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING`
+ def start(ap_path = nil)
+ STDOUT.sync = true
+ $0 = File::basename(ap_path, ".rb") if ap_path
- IRB.setup(ap_path)
+ setup(ap_path)
- if @CONF[:SCRIPT]
- irb = Irb.new(nil, @CONF[:SCRIPT])
- else
- irb = Irb.new
+ if @CONF[:SCRIPT]
+ irb = Irb.new(nil, @CONF[:SCRIPT])
+ else
+ irb = Irb.new
+ end
+ irb.run(@CONF)
end
- irb.run(@CONF)
- end
- # Quits irb
- def IRB.irb_exit(*) # :nodoc:
- throw :IRB_EXIT, false
- end
+ # Quits irb
+ def irb_exit(*) # :nodoc:
+ throw :IRB_EXIT, false
+ end
- # Aborts then interrupts irb.
- #
- # Will raise an Abort exception, or the given `exception`.
- def IRB.irb_abort(irb, exception = Abort) # :nodoc:
- irb.context.thread.raise exception, "abort then interrupt!"
+ # Aborts then interrupts irb.
+ #
+ # Will raise an Abort exception, or the given `exception`.
+ def irb_abort(irb, exception = Abort) # :nodoc:
+ irb.context.thread.raise exception, "abort then interrupt!"
+ end
end
class Irb
diff --git a/lib/irb/command/base.rb b/lib/irb/command/base.rb
index 1d406630a2..af810ed343 100644
--- a/lib/irb/command/base.rb
+++ b/lib/irb/command/base.rb
@@ -10,8 +10,10 @@ module IRB
module Command
class CommandArgumentError < StandardError; end
- def self.extract_ruby_args(*args, **kwargs)
- throw :EXTRACT_RUBY_ARGS, [args, kwargs]
+ class << self
+ def extract_ruby_args(*args, **kwargs)
+ throw :EXTRACT_RUBY_ARGS, [args, kwargs]
+ end
end
class Base
@@ -31,6 +33,12 @@ module IRB
@help_message
end
+ def execute(irb_context, arg)
+ new(irb_context).execute(arg)
+ rescue CommandArgumentError => e
+ puts e.message
+ end
+
private
def highlight(text)
@@ -38,12 +46,6 @@ module IRB
end
end
- def self.execute(irb_context, arg)
- new(irb_context).execute(arg)
- rescue CommandArgumentError => e
- puts e.message
- end
-
def initialize(irb_context)
@irb_context = irb_context
end
diff --git a/lib/irb/command/debug.rb b/lib/irb/command/debug.rb
index 8a091a49ed..3ebb57fe54 100644
--- a/lib/irb/command/debug.rb
+++ b/lib/irb/command/debug.rb
@@ -58,13 +58,15 @@ module IRB
end
class DebugCommand < Debug
- def self.category
- "Debugging"
- end
+ class << self
+ def category
+ "Debugging"
+ end
- def self.description
- command_name = self.name.split("::").last.downcase
- "Start the debugger of debug.gem and run its `#{command_name}` command."
+ def description
+ command_name = self.name.split("::").last.downcase
+ "Start the debugger of debug.gem and run its `#{command_name}` command."
+ end
end
end
end
diff --git a/lib/irb/default_commands.rb b/lib/irb/default_commands.rb
index e27a3d4e00..fec41df4e2 100644
--- a/lib/irb/default_commands.rb
+++ b/lib/irb/default_commands.rb
@@ -259,10 +259,12 @@ module IRB
# Deprecated. Doesn't have any effect.
@EXTEND_COMMANDS = []
- # Drepcated. Use Command.regiser instead.
- def self.def_extend_command(cmd_name, cmd_class, _, *aliases)
- Command._register_with_aliases(cmd_name, cmd_class, *aliases)
- Command.class_variable_set(:@@command_override_policies, nil)
+ class << self
+ # Drepcated. Use Command.regiser instead.
+ def def_extend_command(cmd_name, cmd_class, _, *aliases)
+ Command._register_with_aliases(cmd_name, cmd_class, *aliases)
+ Command.class_variable_set(:@@command_override_policies, nil)
+ end
end
end
end
diff --git a/lib/irb/input-method.rb b/lib/irb/input-method.rb
index ced35a2c5a..f6b8d00e53 100644
--- a/lib/irb/input-method.rb
+++ b/lib/irb/input-method.rb
@@ -171,11 +171,13 @@ module IRB
end
class ReadlineInputMethod < StdioInputMethod
- def self.initialize_readline
- require "readline"
- rescue LoadError
- else
- include ::Readline
+ class << self
+ def initialize_readline
+ require "readline"
+ rescue LoadError
+ else
+ include ::Readline
+ end
end
include HistorySavingAbility
diff --git a/lib/irb/inspector.rb b/lib/irb/inspector.rb
index 667087ccba..8046744f88 100644
--- a/lib/irb/inspector.rb
+++ b/lib/irb/inspector.rb
@@ -6,7 +6,6 @@
module IRB # :nodoc:
-
# Convenience method to create a new Inspector, using the given +inspect+
# proc, and optional +init+ proc and passes them to Inspector.new
#
@@ -43,38 +42,40 @@ module IRB # :nodoc:
# +:marshal+:: Using Marshal.dump
INSPECTORS = {}
- # Determines the inspector to use where +inspector+ is one of the keys passed
- # during inspector definition.
- def self.keys_with_inspector(inspector)
- INSPECTORS.select{|k, v| v == inspector}.collect{|k, v| k}
- end
-
- # Example
- #
- # Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
- # Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
- # Inspector.def_inspector(key, inspector)
- # Inspector.def_inspector([key1,...], inspector)
- def self.def_inspector(key, arg=nil, &block)
- if block_given?
- inspector = IRB::Inspector(block, arg)
- else
- inspector = arg
+ class << self
+ # Determines the inspector to use where +inspector+ is one of the keys passed
+ # during inspector definition.
+ def keys_with_inspector(inspector)
+ INSPECTORS.select{|k, v| v == inspector}.collect{|k, v| k}
end
- case key
- when Array
- for k in key
- def_inspector(k, inspector)
+ # Example
+ #
+ # Inspector.def_inspector(key, init_p=nil){|v| v.inspect}
+ # Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect}
+ # Inspector.def_inspector(key, inspector)
+ # Inspector.def_inspector([key1,...], inspector)
+ def def_inspector(key, arg=nil, &block)
+ if block_given?
+ inspector = IRB::Inspector(block, arg)
+ else
+ inspector = arg
+ end
+
+ case key
+ when Array
+ for k in key
+ def_inspector(k, inspector)
+ end
+ when Symbol
+ INSPECTORS[key] = inspector
+ INSPECTORS[key.to_s] = inspector
+ when String
+ INSPECTORS[key] = inspector
+ INSPECTORS[key.intern] = inspector
+ else
+ INSPECTORS[key] = inspector
end
- when Symbol
- INSPECTORS[key] = inspector
- INSPECTORS[key.to_s] = inspector
- when String
- INSPECTORS[key] = inspector
- INSPECTORS[key.intern] = inspector
- else
- INSPECTORS[key] = inspector
end
end
diff --git a/lib/irb/nesting_parser.rb b/lib/irb/nesting_parser.rb
index 5aa940cc28..fc71d64aee 100644
--- a/lib/irb/nesting_parser.rb
+++ b/lib/irb/nesting_parser.rb
@@ -3,235 +3,237 @@ module IRB
module NestingParser
IGNORE_TOKENS = %i[on_sp on_ignored_nl on_comment on_embdoc_beg on_embdoc on_embdoc_end]
- # Scan each token and call the given block with array of token and other information for parsing
- def self.scan_opens(tokens)
- opens = []
- pending_heredocs = []
- first_token_on_line = true
- tokens.each do |t|
- skip = false
- last_tok, state, args = opens.last
- case state
- when :in_alias_undef
- skip = t.event == :on_kw
- when :in_unquoted_symbol
- unless IGNORE_TOKENS.include?(t.event)
- opens.pop
- skip = true
- end
- when :in_lambda_head
- opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do')
- when :in_method_head
- unless IGNORE_TOKENS.include?(t.event)
- next_args = []
- body = nil
- if args.include?(:receiver)
- case t.event
- when :on_lparen, :on_ivar, :on_gvar, :on_cvar
- # def (receiver). | def @ivar. | def $gvar. | def @@cvar.
- next_args << :dot
- when :on_kw
- case t.tok
- when 'self', 'true', 'false', 'nil'
- # def self(arg) | def self.
- next_args.push(:arg, :dot)
- else
- # def if(arg)
+ class << self
+ # Scan each token and call the given block with array of token and other information for parsing
+ def scan_opens(tokens)
+ opens = []
+ pending_heredocs = []
+ first_token_on_line = true
+ tokens.each do |t|
+ skip = false
+ last_tok, state, args = opens.last
+ case state
+ when :in_alias_undef
+ skip = t.event == :on_kw
+ when :in_unquoted_symbol
+ unless IGNORE_TOKENS.include?(t.event)
+ opens.pop
+ skip = true
+ end
+ when :in_lambda_head
+ opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do')
+ when :in_method_head
+ unless IGNORE_TOKENS.include?(t.event)
+ next_args = []
+ body = nil
+ if args.include?(:receiver)
+ case t.event
+ when :on_lparen, :on_ivar, :on_gvar, :on_cvar
+ # def (receiver). | def @ivar. | def $gvar. | def @@cvar.
+ next_args << :dot
+ when :on_kw
+ case t.tok
+ when 'self', 'true', 'false', 'nil'
+ # def self(arg) | def self.
+ next_args.push(:arg, :dot)
+ else
+ # def if(arg)
+ skip = true
+ next_args << :arg
+ end
+ when :on_op, :on_backtick
+ # def +(arg)
skip = true
next_args << :arg
+ when :on_ident, :on_const
+ # def a(arg) | def a.
+ next_args.push(:arg, :dot)
end
- when :on_op, :on_backtick
- # def +(arg)
- skip = true
- next_args << :arg
- when :on_ident, :on_const
- # def a(arg) | def a.
- next_args.push(:arg, :dot)
end
- end
- if args.include?(:dot)
- # def receiver.name
- next_args << :name if t.event == :on_period || (t.event == :on_op && t.tok == '::')
- end
- if args.include?(:name)
- if %i[on_ident on_const on_op on_kw on_backtick].include?(t.event)
- # def name(arg) | def receiver.name(arg)
- next_args << :arg
- skip = true
+ if args.include?(:dot)
+ # def receiver.name
+ next_args << :name if t.event == :on_period || (t.event == :on_op && t.tok == '::')
end
- end
- if args.include?(:arg)
- case t.event
- when :on_nl, :on_semicolon
- # def receiver.f;
- body = :normal
- when :on_lparen
- # def receiver.f()
- next_args << :eq
- else
+ if args.include?(:name)
+ if %i[on_ident on_const on_op on_kw on_backtick].include?(t.event)
+ # def name(arg) | def receiver.name(arg)
+ next_args << :arg
+ skip = true
+ end
+ end
+ if args.include?(:arg)
+ case t.event
+ when :on_nl, :on_semicolon
+ # def receiver.f;
+ body = :normal
+ when :on_lparen
+ # def receiver.f()
+ next_args << :eq
+ else
+ if t.event == :on_op && t.tok == '='
+ # def receiver.f =
+ body = :oneliner
+ else
+ # def receiver.f arg
+ next_args << :arg_without_paren
+ end
+ end
+ end
+ if args.include?(:eq)
if t.event == :on_op && t.tok == '='
- # def receiver.f =
body = :oneliner
else
- # def receiver.f arg
- next_args << :arg_without_paren
+ body = :normal
end
end
- end
- if args.include?(:eq)
- if t.event == :on_op && t.tok == '='
- body = :oneliner
- else
- body = :normal
+ if args.include?(:arg_without_paren)
+ if %i[on_semicolon on_nl].include?(t.event)
+ # def f a;
+ body = :normal
+ else
+ # def f a, b
+ next_args << :arg_without_paren
+ end
end
- end
- if args.include?(:arg_without_paren)
- if %i[on_semicolon on_nl].include?(t.event)
- # def f a;
- body = :normal
+ if body == :oneliner
+ opens.pop
+ elsif body
+ opens[-1] = [last_tok, nil]
else
- # def f a, b
- next_args << :arg_without_paren
+ opens[-1] = [last_tok, :in_method_head, next_args]
end
end
- if body == :oneliner
- opens.pop
- elsif body
+ when :in_for_while_until_condition
+ if t.event == :on_semicolon || t.event == :on_nl || (t.event == :on_kw && t.tok == 'do')
+ skip = true if t.event == :on_kw && t.tok == 'do'
opens[-1] = [last_tok, nil]
- else
- opens[-1] = [last_tok, :in_method_head, next_args]
end
end
- when :in_for_while_until_condition
- if t.event == :on_semicolon || t.event == :on_nl || (t.event == :on_kw && t.tok == 'do')
- skip = true if t.event == :on_kw && t.tok == 'do'
- opens[-1] = [last_tok, nil]
- end
- end
- unless skip
- case t.event
- when :on_kw
- case t.tok
- when 'begin', 'class', 'module', 'do', 'case'
- opens << [t, nil]
- when 'end'
- opens.pop
- when 'def'
- opens << [t, :in_method_head, [:receiver, :name]]
- when 'if', 'unless'
- unless t.state.allbits?(Ripper::EXPR_LABEL)
+ unless skip
+ case t.event
+ when :on_kw
+ case t.tok
+ when 'begin', 'class', 'module', 'do', 'case'
opens << [t, nil]
- end
- when 'while', 'until'
- unless t.state.allbits?(Ripper::EXPR_LABEL)
- opens << [t, :in_for_while_until_condition]
- end
- when 'ensure', 'rescue'
- unless t.state.allbits?(Ripper::EXPR_LABEL)
+ when 'end'
+ opens.pop
+ when 'def'
+ opens << [t, :in_method_head, [:receiver, :name]]
+ when 'if', 'unless'
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
+ opens << [t, nil]
+ end
+ when 'while', 'until'
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
+ opens << [t, :in_for_while_until_condition]
+ end
+ when 'ensure', 'rescue'
+ unless t.state.allbits?(Ripper::EXPR_LABEL)
+ opens.pop
+ opens << [t, nil]
+ end
+ when 'alias'
+ opens << [t, :in_alias_undef, 2]
+ when 'undef'
+ opens << [t, :in_alias_undef, 1]
+ when 'elsif', 'else', 'when'
opens.pop
opens << [t, nil]
+ when 'for'
+ opens << [t, :in_for_while_until_condition]
+ when 'in'
+ if last_tok&.event == :on_kw && %w[case in].include?(last_tok.tok) && first_token_on_line
+ opens.pop
+ opens << [t, nil]
+ end
end
- when 'alias'
- opens << [t, :in_alias_undef, 2]
- when 'undef'
- opens << [t, :in_alias_undef, 1]
- when 'elsif', 'else', 'when'
+ when :on_tlambda
+ opens << [t, :in_lambda_head]
+ when :on_lparen, :on_lbracket, :on_lbrace, :on_tlambeg, :on_embexpr_beg, :on_embdoc_beg
+ opens << [t, nil]
+ when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end, :on_embdoc_end
+ opens.pop
+ when :on_heredoc_beg
+ pending_heredocs << t
+ when :on_heredoc_end
opens.pop
+ when :on_backtick
+ opens << [t, nil] if t.state.allbits?(Ripper::EXPR_BEG)
+ when :on_tstring_beg, :on_words_beg, :on_qwords_beg, :on_symbols_beg, :on_qsymbols_beg, :on_regexp_beg
opens << [t, nil]
- when 'for'
- opens << [t, :in_for_while_until_condition]
- when 'in'
- if last_tok&.event == :on_kw && %w[case in].include?(last_tok.tok) && first_token_on_line
- opens.pop
+ when :on_tstring_end, :on_regexp_end, :on_label_end
+ opens.pop
+ when :on_symbeg
+ if t.tok == ':'
+ opens << [t, :in_unquoted_symbol]
+ else
opens << [t, nil]
end
end
- when :on_tlambda
- opens << [t, :in_lambda_head]
- when :on_lparen, :on_lbracket, :on_lbrace, :on_tlambeg, :on_embexpr_beg, :on_embdoc_beg
- opens << [t, nil]
- when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end, :on_embdoc_end
- opens.pop
- when :on_heredoc_beg
- pending_heredocs << t
- when :on_heredoc_end
- opens.pop
- when :on_backtick
- opens << [t, nil] if t.state.allbits?(Ripper::EXPR_BEG)
- when :on_tstring_beg, :on_words_beg, :on_qwords_beg, :on_symbols_beg, :on_qsymbols_beg, :on_regexp_beg
- opens << [t, nil]
- when :on_tstring_end, :on_regexp_end, :on_label_end
- opens.pop
- when :on_symbeg
- if t.tok == ':'
- opens << [t, :in_unquoted_symbol]
- else
- opens << [t, nil]
- end
end
+ if t.event == :on_nl || t.event == :on_semicolon
+ first_token_on_line = true
+ elsif t.event != :on_sp
+ first_token_on_line = false
+ end
+ if pending_heredocs.any? && t.tok.include?("\n")
+ pending_heredocs.reverse_each { |t| opens << [t, nil] }
+ pending_heredocs = []
+ end
+ if opens.last && opens.last[1] == :in_alias_undef && !IGNORE_TOKENS.include?(t.event) && t.event != :on_heredoc_end
+ tok, state, arg = opens.pop
+ opens << [tok, state, arg - 1] if arg >= 1
+ end
+ yield t, opens if block_given?
end
- if t.event == :on_nl || t.event == :on_semicolon
- first_token_on_line = true
- elsif t.event != :on_sp
- first_token_on_line = false
- end
- if pending_heredocs.any? && t.tok.include?("\n")
- pending_heredocs.reverse_each { |t| opens << [t, nil] }
- pending_heredocs = []
- end
- if opens.last && opens.last[1] == :in_alias_undef && !IGNORE_TOKENS.include?(t.event) && t.event != :on_heredoc_end
- tok, state, arg = opens.pop
- opens << [tok, state, arg - 1] if arg >= 1
- end
- yield t, opens if block_given?
+ opens.map(&:first) + pending_heredocs.reverse
end
- opens.map(&:first) + pending_heredocs.reverse
- end
- def self.open_tokens(tokens)
- # scan_opens without block will return a list of open tokens at last token position
- scan_opens(tokens)
- end
+ def open_tokens(tokens)
+ # scan_opens without block will return a list of open tokens at last token position
+ scan_opens(tokens)
+ end
- # Calculates token information [line_tokens, prev_opens, next_opens, min_depth] for each line.
- # Example code
- # ["hello
- # world"+(
- # First line
- # line_tokens: [[lbracket, '['], [tstring_beg, '"'], [tstring_content("hello\nworld"), "hello\n"]]
- # prev_opens: []
- # next_tokens: [lbracket, tstring_beg]
- # min_depth: 0 (minimum at beginning of line)
- # Second line
- # line_tokens: [[tstring_content("hello\nworld"), "world"], [tstring_end, '"'], [op, '+'], [lparen, '(']]
- # prev_opens: [lbracket, tstring_beg]
- # next_tokens: [lbracket, lparen]
- # min_depth: 1 (minimum just after tstring_end)
- def self.parse_by_line(tokens)
- line_tokens = []
- prev_opens = []
- min_depth = 0
- output = []
- last_opens = scan_opens(tokens) do |t, opens|
- depth = t == opens.last&.first ? opens.size - 1 : opens.size
- min_depth = depth if depth < min_depth
- if t.tok.include?("\n")
- t.tok.each_line do |line|
- line_tokens << [t, line]
- next if line[-1] != "\n"
- next_opens = opens.map(&:first)
- output << [line_tokens, prev_opens, next_opens, min_depth]
- prev_opens = next_opens
- min_depth = prev_opens.size
- line_tokens = []
+ # Calculates token information [line_tokens, prev_opens, next_opens, min_depth] for each line.
+ # Example code
+ # ["hello
+ # world"+(
+ # First line
+ # line_tokens: [[lbracket, '['], [tstring_beg, '"'], [tstring_content("hello\nworld"), "hello\n"]]
+ # prev_opens: []
+ # next_tokens: [lbracket, tstring_beg]
+ # min_depth: 0 (minimum at beginning of line)
+ # Second line
+ # line_tokens: [[tstring_content("hello\nworld"), "world"], [tstring_end, '"'], [op, '+'], [lparen, '(']]
+ # prev_opens: [lbracket, tstring_beg]
+ # next_tokens: [lbracket, lparen]
+ # min_depth: 1 (minimum just after tstring_end)
+ def parse_by_line(tokens)
+ line_tokens = []
+ prev_opens = []
+ min_depth = 0
+ output = []
+ last_opens = scan_opens(tokens) do |t, opens|
+ depth = t == opens.last&.first ? opens.size - 1 : opens.size
+ min_depth = depth if depth < min_depth
+ if t.tok.include?("\n")
+ t.tok.each_line do |line|
+ line_tokens << [t, line]
+ next if line[-1] != "\n"
+ next_opens = opens.map(&:first)
+ output << [line_tokens, prev_opens, next_opens, min_depth]
+ prev_opens = next_opens
+ min_depth = prev_opens.size
+ line_tokens = []
+ end
+ else
+ line_tokens << [t, t.tok]
end
- else
- line_tokens << [t, t.tok]
end
+ output << [line_tokens, prev_opens, last_opens, min_depth] if line_tokens.any?
+ output
end
- output << [line_tokens, prev_opens, last_opens, min_depth] if line_tokens.any?
- output
end
end
end
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb
index f6ac7f0f5f..3abb53b4ea 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -36,29 +36,6 @@ module IRB
:massign,
]
- class TerminateLineInput < StandardError
- def initialize
- super("Terminate Line Input")
- end
- end
-
- def self.compile_with_errors_suppressed(code, line_no: 1)
- begin
- result = yield code, line_no
- rescue ArgumentError
- # Ruby can issue an error for the code if there is an
- # incomplete magic comment for encoding in it. Force an
- # expression with a new line before the code in this
- # case to prevent magic comment handling. To make sure
- # line numbers in the lexed code remain the same,
- # decrease the line number by one.
- code = ";\n#{code}"
- line_no -= 1
- result = yield code, line_no
- end
- result
- end
-
ERROR_TOKENS = [
:on_parse_error,
:compile_error,
@@ -68,70 +45,102 @@ module IRB
:on_param_error
]
- def self.generate_local_variables_assign_code(local_variables)
- "#{local_variables.join('=')}=nil;" unless local_variables.empty?
+ LTYPE_TOKENS = %i[
+ on_heredoc_beg on_tstring_beg
+ on_regexp_beg on_symbeg on_backtick
+ on_symbols_beg on_qsymbols_beg
+ on_words_beg on_qwords_beg
+ ]
+
+ class TerminateLineInput < StandardError
+ def initialize
+ super("Terminate Line Input")
+ end
end
- # Some part of the code is not included in Ripper's token.
- # Example: DATA part, token after heredoc_beg when heredoc has unclosed embexpr.
- # With interpolated tokens, tokens.map(&:tok).join will be equal to code.
- def self.interpolate_ripper_ignored_tokens(code, tokens)
- line_positions = [0]
- code.lines.each do |line|
- line_positions << line_positions.last + line.bytesize
+ class << self
+ def compile_with_errors_suppressed(code, line_no: 1)
+ begin
+ result = yield code, line_no
+ rescue ArgumentError
+ # Ruby can issue an error for the code if there is an
+ # incomplete magic comment for encoding in it. Force an
+ # expression with a new line before the code in this
+ # case to prevent magic comment handling. To make sure
+ # line numbers in the lexed code remain the same,
+ # decrease the line number by one.
+ code = ";\n#{code}"
+ line_no -= 1
+ result = yield code, line_no
+ end
+ result
+ end
+
+ def generate_local_variables_assign_code(local_variables)
+ "#{local_variables.join('=')}=nil;" unless local_variables.empty?
end
- prev_byte_pos = 0
- interpolated = []
- prev_line = 1
- tokens.each do |t|
- line, col = t.pos
- byte_pos = line_positions[line - 1] + col
- if prev_byte_pos < byte_pos
- tok = code.byteslice(prev_byte_pos...byte_pos)
+
+ # Some part of the code is not included in Ripper's token.
+ # Example: DATA part, token after heredoc_beg when heredoc has unclosed embexpr.
+ # With interpolated tokens, tokens.map(&:tok).join will be equal to code.
+ def interpolate_ripper_ignored_tokens(code, tokens)
+ line_positions = [0]
+ code.lines.each do |line|
+ line_positions << line_positions.last + line.bytesize
+ end
+ prev_byte_pos = 0
+ interpolated = []
+ prev_line = 1
+ tokens.each do |t|
+ line, col = t.pos
+ byte_pos = line_positions[line - 1] + col
+ if prev_byte_pos < byte_pos
+ tok = code.byteslice(prev_byte_pos...byte_pos)
+ pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]]
+ interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0)
+ prev_line += tok.count("\n")
+ end
+ interpolated << t
+ prev_byte_pos = byte_pos + t.tok.bytesize
+ prev_line += t.tok.count("\n")
+ end
+ if prev_byte_pos < code.bytesize
+ tok = code.byteslice(prev_byte_pos..)
pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]]
interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0)
- prev_line += tok.count("\n")
end
- interpolated << t
- prev_byte_pos = byte_pos + t.tok.bytesize
- prev_line += t.tok.count("\n")
- end
- if prev_byte_pos < code.bytesize
- tok = code.byteslice(prev_byte_pos..)
- pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]]
- interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0)
+ interpolated
end
- interpolated
- end
- def self.ripper_lex_without_warning(code, local_variables: [])
- verbose, $VERBOSE = $VERBOSE, nil
- lvars_code = generate_local_variables_assign_code(local_variables)
- original_code = code
- if lvars_code
- code = "#{lvars_code}\n#{code}"
- line_no = 0
- else
- line_no = 1
- end
+ def ripper_lex_without_warning(code, local_variables: [])
+ verbose, $VERBOSE = $VERBOSE, nil
+ lvars_code = generate_local_variables_assign_code(local_variables)
+ original_code = code
+ if lvars_code
+ code = "#{lvars_code}\n#{code}"
+ line_no = 0
+ else
+ line_no = 1
+ end
- compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
- lexer = Ripper::Lexer.new(inner_code, '-', line_no)
- tokens = []
- lexer.scan.each do |t|
- next if t.pos.first == 0
- prev_tk = tokens.last
- position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize
- if position_overlapped
- tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event)
- else
- tokens << t
+ compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no|
+ lexer = Ripper::Lexer.new(inner_code, '-', line_no)
+ tokens = []
+ lexer.scan.each do |t|
+ next if t.pos.first == 0
+ prev_tk = tokens.last
+ position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize
+ if position_overlapped
+ tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event)
+ else
+ tokens << t
+ end
end
+ interpolate_ripper_ignored_tokens(original_code, tokens)
end
- interpolate_ripper_ignored_tokens(original_code, tokens)
+ ensure
+ $VERBOSE = verbose
end
- ensure
- $VERBOSE = verbose
end
def check_code_state(code, local_variables:)
@@ -391,13 +400,6 @@ module IRB
end
end
- LTYPE_TOKENS = %i[
- on_heredoc_beg on_tstring_beg
- on_regexp_beg on_symbeg on_backtick
- on_symbols_beg on_qsymbols_beg
- on_words_beg on_qwords_beg
- ]
-
def ltype_from_open_tokens(opens)
start_token = opens.reverse_each.find do |tok|
LTYPE_TOKENS.include?(tok.event)
diff --git a/lib/irb/workspace.rb b/lib/irb/workspace.rb
index d24d1cc38d..632b432439 100644
--- a/lib/irb/workspace.rb
+++ b/lib/irb/workspace.rb
@@ -176,11 +176,13 @@ EOF
end
module HelpersContainer
- def self.install_helper_methods
- HelperMethod.helper_methods.each do |name, helper_method_class|
- define_method name do |*args, **opts, &block|
- helper_method_class.instance.execute(*args, **opts, &block)
- end unless method_defined?(name)
+ class << self
+ def install_helper_methods
+ HelperMethod.helper_methods.each do |name, helper_method_class|
+ define_method name do |*args, **opts, &block|
+ helper_method_class.instance.execute(*args, **opts, &block)
+ end unless method_defined?(name)
+ end
end
end
diff --git a/test/irb/test_context.rb b/test/irb/test_context.rb
index cd3f2c8f62..7ad8fd2fc4 100644
--- a/test/irb/test_context.rb
+++ b/test/irb/test_context.rb
@@ -28,7 +28,6 @@ module TestIRB
restore_encodings
end
-
def test_eval_input
verbose, $VERBOSE = $VERBOSE, nil
input = TestInputMethod.new([
diff --git a/test/irb/test_workspace.rb b/test/irb/test_workspace.rb
index 199ce95a37..ad515f91df 100644
--- a/test/irb/test_workspace.rb
+++ b/test/irb/test_workspace.rb
@@ -80,7 +80,6 @@ module TestIRB
assert_equal(nil, workspace.code_around_binding)
end
-
def test_toplevel_binding_local_variables
bug17623 = '[ruby-core:102468]'
bundle_exec = ENV.key?('BUNDLE_GEMFILE') ? ['-rbundler/setup'] : []