irb 1.11.2 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -8
  3. data/lib/irb/cmd/nop.rb +3 -52
  4. data/lib/irb/{cmd → command}/backtrace.rb +1 -1
  5. data/lib/irb/command/base.rb +64 -0
  6. data/lib/irb/{cmd → command}/break.rb +1 -1
  7. data/lib/irb/{cmd → command}/catch.rb +1 -1
  8. data/lib/irb/{cmd → command}/chws.rb +4 -6
  9. data/lib/irb/{cmd → command}/continue.rb +1 -1
  10. data/lib/irb/{cmd → command}/debug.rb +3 -4
  11. data/lib/irb/{cmd → command}/delete.rb +1 -1
  12. data/lib/irb/command/edit.rb +70 -0
  13. data/lib/irb/{cmd → command}/exit.rb +2 -4
  14. data/lib/irb/{cmd → command}/finish.rb +1 -1
  15. data/lib/irb/command/force_exit.rb +20 -0
  16. data/lib/irb/command/help.rb +84 -0
  17. data/lib/irb/{cmd → command}/history.rb +3 -3
  18. data/lib/irb/{cmd → command}/info.rb +1 -1
  19. data/lib/irb/{cmd → command}/irb_info.rb +5 -6
  20. data/lib/irb/{cmd → command}/load.rb +3 -5
  21. data/lib/irb/{cmd → command}/ls.rb +10 -4
  22. data/lib/irb/{cmd → command}/measure.rb +2 -4
  23. data/lib/irb/{cmd → command}/next.rb +1 -1
  24. data/lib/irb/{cmd → command}/pushws.rb +20 -5
  25. data/lib/irb/{cmd → command}/show_doc.rb +17 -5
  26. data/lib/irb/{cmd → command}/show_source.rb +26 -10
  27. data/lib/irb/{cmd → command}/step.rb +1 -1
  28. data/lib/irb/{cmd → command}/subirb.rb +3 -5
  29. data/lib/irb/{cmd → command}/whereami.rb +2 -4
  30. data/lib/irb/{extend-command.rb → command.rb} +50 -85
  31. data/lib/irb/completion.rb +1 -1
  32. data/lib/irb/context.rb +56 -18
  33. data/lib/irb/ext/change-ws.rb +4 -4
  34. data/lib/irb/ext/eval_history.rb +3 -3
  35. data/lib/irb/ext/loader.rb +4 -4
  36. data/lib/irb/ext/multi-irb.rb +1 -1
  37. data/lib/irb/ext/tracer.rb +1 -1
  38. data/lib/irb/ext/use-loader.rb +6 -8
  39. data/lib/irb/ext/workspaces.rb +11 -34
  40. data/lib/irb/frame.rb +1 -1
  41. data/lib/irb/help.rb +1 -1
  42. data/lib/irb/history.rb +2 -2
  43. data/lib/irb/init.rb +22 -14
  44. data/lib/irb/input-method.rb +18 -2
  45. data/lib/irb/inspector.rb +2 -2
  46. data/lib/irb/lc/error.rb +1 -6
  47. data/lib/irb/lc/ja/error.rb +1 -6
  48. data/lib/irb/locale.rb +1 -1
  49. data/lib/irb/notifier.rb +1 -1
  50. data/lib/irb/output-method.rb +2 -8
  51. data/lib/irb/ruby-lex.rb +1 -1
  52. data/lib/irb/source_finder.rb +98 -38
  53. data/lib/irb/statement.rb +25 -3
  54. data/lib/irb/version.rb +3 -3
  55. data/lib/irb/workspace.rb +4 -4
  56. data/lib/irb/ws-for-case-2.rb +1 -1
  57. data/lib/irb/xmp.rb +1 -1
  58. data/lib/irb.rb +29 -22
  59. metadata +30 -29
  60. data/lib/irb/cmd/edit.rb +0 -60
  61. data/lib/irb/cmd/help.rb +0 -23
  62. data/lib/irb/cmd/show_cmds.rb +0 -59
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/lib/tracer.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -1,10 +1,10 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # use-loader.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
5
5
  #
6
6
 
7
- require_relative "../cmd/load"
7
+ require_relative "../command/load"
8
8
  require_relative "loader"
9
9
 
10
10
  class Object
@@ -17,12 +17,12 @@ module IRB
17
17
  remove_method :irb_load if method_defined?(:irb_load)
18
18
  # Loads the given file similarly to Kernel#load, see IrbLoader#irb_load
19
19
  def irb_load(*opts, &b)
20
- ExtendCommand::Load.execute(irb_context, *opts, &b)
20
+ Command::Load.execute(irb_context, *opts, &b)
21
21
  end
22
22
  remove_method :irb_require if method_defined?(:irb_require)
23
23
  # Loads the given file similarly to Kernel#require
24
24
  def irb_require(*opts, &b)
25
- ExtendCommand::Require.execute(irb_context, *opts, &b)
25
+ Command::Require.execute(irb_context, *opts, &b)
26
26
  end
27
27
  end
28
28
 
@@ -49,14 +49,12 @@ module IRB
49
49
  if IRB.conf[:USE_LOADER] != opt
50
50
  IRB.conf[:USE_LOADER] = opt
51
51
  if opt
52
- if !$".include?("irb/cmd/load")
53
- end
54
- (class<<@workspace.main;self;end).instance_eval {
52
+ (class<<workspace.main;self;end).instance_eval {
55
53
  alias_method :load, :irb_load
56
54
  alias_method :require, :irb_require
57
55
  }
58
56
  else
59
- (class<<@workspace.main;self;end).instance_eval {
57
+ (class<<workspace.main;self;end).instance_eval {
60
58
  alias_method :load, :__original__load__IRB_use_loader__
61
59
  alias_method :require, :__original__require__IRB_use_loader__
62
60
  }
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # push-ws.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -6,21 +6,6 @@
6
6
 
7
7
  module IRB # :nodoc:
8
8
  class Context
9
-
10
- # Size of the current WorkSpace stack
11
- def irb_level
12
- workspace_stack.size
13
- end
14
-
15
- # WorkSpaces in the current stack
16
- def workspaces
17
- if defined? @workspaces
18
- @workspaces
19
- else
20
- @workspaces = []
21
- end
22
- end
23
-
24
9
  # Creates a new workspace with the given object or binding, and appends it
25
10
  # onto the current #workspaces stack.
26
11
  #
@@ -28,20 +13,16 @@ module IRB # :nodoc:
28
13
  # information.
29
14
  def push_workspace(*_main)
30
15
  if _main.empty?
31
- if workspaces.empty?
32
- print "No other workspace\n"
33
- return nil
16
+ if @workspace_stack.size > 1
17
+ # swap the top two workspaces
18
+ previous_workspace, current_workspace = @workspace_stack.pop(2)
19
+ @workspace_stack.push current_workspace, previous_workspace
20
+ end
21
+ else
22
+ @workspace_stack.push WorkSpace.new(workspace.binding, _main[0])
23
+ if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
24
+ main.extend ExtendCommandBundle
34
25
  end
35
- ws = workspaces.pop
36
- workspaces.push @workspace
37
- @workspace = ws
38
- return workspaces
39
- end
40
-
41
- workspaces.push @workspace
42
- @workspace = WorkSpace.new(@workspace.binding, _main[0])
43
- if !(class<<main;ancestors;end).include?(ExtendCommandBundle)
44
- main.extend ExtendCommandBundle
45
26
  end
46
27
  end
47
28
 
@@ -50,11 +31,7 @@ module IRB # :nodoc:
50
31
  #
51
32
  # Also, see #push_workspace.
52
33
  def pop_workspace
53
- if workspaces.empty?
54
- print "workspace stack empty\n"
55
- return
56
- end
57
- @workspace = workspaces.pop
34
+ @workspace_stack.pop if @workspace_stack.size > 1
58
35
  end
59
36
  end
60
37
  end
data/lib/irb/frame.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # frame.rb -
4
4
  # by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd)
data/lib/irb/help.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/help.rb - print usage module
4
4
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
data/lib/irb/history.rb CHANGED
@@ -16,7 +16,7 @@ module IRB
16
16
  if history_file = IRB.conf[:HISTORY_FILE]
17
17
  history_file = File.expand_path(history_file)
18
18
  end
19
- history_file = IRB.rc_file("_history") unless history_file
19
+ history_file = IRB.rc_files("_history").first unless history_file
20
20
  if File.exist?(history_file)
21
21
  File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f|
22
22
  f.each { |l|
@@ -41,7 +41,7 @@ module IRB
41
41
  if history_file = IRB.conf[:HISTORY_FILE]
42
42
  history_file = File.expand_path(history_file)
43
43
  end
44
- history_file = IRB.rc_file("_history") unless history_file
44
+ history_file = IRB.rc_files("_history").first unless history_file
45
45
 
46
46
  # Change the permission of a file that already exists[BUG #7694]
47
47
  begin
data/lib/irb/init.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/init.rb - irb initialize module
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -395,33 +395,41 @@ module IRB # :nodoc:
395
395
  # Run the config file
396
396
  def IRB.run_config
397
397
  if @CONF[:RC]
398
- begin
399
- file = rc_file
398
+ rc_files.each do |rc|
400
399
  # Because rc_file always returns `HOME/.irbrc` even if no rc file is present, we can't warn users about missing rc files.
401
400
  # Otherwise, it'd be very noisy.
402
- load file if File.exist?(file)
401
+ load rc if File.exist?(rc)
403
402
  rescue StandardError, ScriptError => e
404
- warn "Error loading RC file '#{file}':\n#{e.full_message(highlight: false)}"
403
+ warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}"
405
404
  end
406
405
  end
407
406
  end
408
407
 
409
408
  IRBRC_EXT = "rc"
410
409
  def IRB.rc_file(ext = IRBRC_EXT)
410
+ warn "rc_file is deprecated, please use rc_files instead."
411
+ rc_files(ext).first
412
+ end
413
+
414
+ def IRB.rc_files(ext = IRBRC_EXT)
411
415
  if !@CONF[:RC_NAME_GENERATOR]
416
+ @CONF[:RC_NAME_GENERATOR] ||= []
417
+ existing_rc_file_generators = []
418
+
412
419
  rc_file_generators do |rcgen|
413
- @CONF[:RC_NAME_GENERATOR] ||= rcgen
414
- if File.exist?(rcgen.call(IRBRC_EXT))
415
- @CONF[:RC_NAME_GENERATOR] = rcgen
416
- break
417
- end
420
+ @CONF[:RC_NAME_GENERATOR] << rcgen
421
+ existing_rc_file_generators << rcgen if File.exist?(rcgen.call(ext))
422
+ end
423
+
424
+ if existing_rc_file_generators.any?
425
+ @CONF[:RC_NAME_GENERATOR] = existing_rc_file_generators
418
426
  end
419
427
  end
420
- case rc_file = @CONF[:RC_NAME_GENERATOR].call(ext)
421
- when String
428
+
429
+ @CONF[:RC_NAME_GENERATOR].map do |rc|
430
+ rc_file = rc.call(ext)
431
+ fail IllegalRCNameGenerator unless rc_file.is_a?(String)
422
432
  rc_file
423
- else
424
- fail IllegalRCNameGenerator
425
433
  end
426
434
  end
427
435
 
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/input-method.rb - input methods used irb
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -20,7 +20,7 @@ module IRB
20
20
  #
21
21
  # See IO#gets for more information.
22
22
  def gets
23
- fail NotImplementedError, "gets"
23
+ fail NotImplementedError
24
24
  end
25
25
  public :gets
26
26
 
@@ -44,6 +44,10 @@ module IRB
44
44
  false
45
45
  end
46
46
 
47
+ def prompting?
48
+ false
49
+ end
50
+
47
51
  # For debug message
48
52
  def inspect
49
53
  'Abstract InputMethod'
@@ -91,6 +95,10 @@ module IRB
91
95
  true
92
96
  end
93
97
 
98
+ def prompting?
99
+ STDIN.tty?
100
+ end
101
+
94
102
  # Returns the current line number for #io.
95
103
  #
96
104
  # #line counts the number of times #gets is called.
@@ -220,6 +228,10 @@ module IRB
220
228
  @eof
221
229
  end
222
230
 
231
+ def prompting?
232
+ true
233
+ end
234
+
223
235
  # For debug message
224
236
  def inspect
225
237
  readline_impl = (defined?(Reline) && Readline == Reline) ? 'Reline' : 'ext/readline'
@@ -467,6 +479,10 @@ module IRB
467
479
  @eof
468
480
  end
469
481
 
482
+ def prompting?
483
+ true
484
+ end
485
+
470
486
  # For debug message
471
487
  def inspect
472
488
  config = Reline::Config.new
data/lib/irb/inspector.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/inspector.rb - inspect methods
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -113,7 +113,7 @@ module IRB # :nodoc:
113
113
  Color.colorize_code(v.inspect, colorable: Color.colorable? && Color.inspect_colorable?(v))
114
114
  }
115
115
  Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v|
116
- IRB::ColorPrinter.pp(v, '').chomp
116
+ IRB::ColorPrinter.pp(v, +'').chomp
117
117
  }
118
118
  Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v|
119
119
  begin
data/lib/irb/lc/error.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/lc/error.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -12,11 +12,6 @@ module IRB
12
12
  super("Unrecognized switch: #{val}")
13
13
  end
14
14
  end
15
- class NotImplementedError < StandardError
16
- def initialize(val)
17
- super("Need to define `#{val}'")
18
- end
19
- end
20
15
  class CantReturnToNormalMode < StandardError
21
16
  def initialize
22
17
  super("Can't return to normal mode.")
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/lc/ja/error.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -12,11 +12,6 @@ module IRB
12
12
  super("スイッチ(#{val})が分りません")
13
13
  end
14
14
  end
15
- class NotImplementedError < StandardError
16
- def initialize(val)
17
- super("`#{val}'の定義が必要です")
18
- end
19
- end
20
15
  class CantReturnToNormalMode < StandardError
21
16
  def initialize
22
17
  super("Normalモードに戻れません.")
data/lib/irb/locale.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/locale.rb - internationalization module
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
data/lib/irb/notifier.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # notifier.rb - output methods used by irb
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # output-method.rb - output methods used by irb
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -9,16 +9,10 @@ module IRB
9
9
  # IRB::Notifier. You can define your own output method to use with Irb.new,
10
10
  # or Context.new
11
11
  class OutputMethod
12
- class NotImplementedError < StandardError
13
- def initialize(val)
14
- super("Need to define `#{val}'")
15
- end
16
- end
17
-
18
12
  # Open this method to implement your own output method, raises a
19
13
  # NotImplementedError if you don't define #print in your own class.
20
14
  def print(*opts)
21
- raise NotImplementedError, "print"
15
+ raise NotImplementedError
22
16
  end
23
17
 
24
18
  # Prints the given +opts+, with a newline delimiter.
data/lib/irb/ruby-lex.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/ruby-lex.rb - ruby lexcal analyzer
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -4,12 +4,63 @@ require_relative "ruby-lex"
4
4
 
5
5
  module IRB
6
6
  class SourceFinder
7
- Source = Struct.new(
8
- :file, # @param [String] - file name
9
- :first_line, # @param [String] - first line
10
- :last_line, # @param [String] - last line
11
- keyword_init: true,
12
- )
7
+ class EvaluationError < StandardError; end
8
+
9
+ class Source
10
+ attr_reader :file, :line
11
+ def initialize(file, line, ast_source = nil)
12
+ @file = file
13
+ @line = line
14
+ @ast_source = ast_source
15
+ end
16
+
17
+ def file_exist?
18
+ File.exist?(@file)
19
+ end
20
+
21
+ def binary_file?
22
+ # If the line is zero, it means that the target's source is probably in a binary file.
23
+ @line.zero?
24
+ end
25
+
26
+ def file_content
27
+ @file_content ||= File.read(@file)
28
+ end
29
+
30
+ def colorized_content
31
+ if !binary_file? && file_exist?
32
+ end_line = find_end
33
+ # To correctly colorize, we need to colorize full content and extract the relevant lines.
34
+ colored = IRB::Color.colorize_code(file_content)
35
+ colored.lines[@line - 1...end_line].join
36
+ elsif @ast_source
37
+ IRB::Color.colorize_code(@ast_source)
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def find_end
44
+ lex = RubyLex.new
45
+ code = file_content
46
+ lines = code.lines[(@line - 1)..-1]
47
+ tokens = RubyLex.ripper_lex_without_warning(lines.join)
48
+ prev_tokens = []
49
+
50
+ # chunk with line number
51
+ tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
52
+ code = lines[0..lnum].join
53
+ prev_tokens.concat chunk
54
+ continue = lex.should_continue?(prev_tokens)
55
+ syntax = lex.check_code_syntax(code, local_variables: [])
56
+ if !continue && syntax == :valid
57
+ return @line + lnum
58
+ end
59
+ end
60
+ @line
61
+ end
62
+ end
63
+
13
64
  private_constant :Source
14
65
 
15
66
  def initialize(irb_context)
@@ -17,50 +68,47 @@ module IRB
17
68
  end
18
69
 
19
70
  def find_source(signature, super_level = 0)
20
- context_binding = @irb_context.workspace.binding
21
71
  case signature
22
- when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
23
- eval(signature, context_binding) # trigger autoload
24
- base = context_binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
25
- file, line = base.const_source_location(signature)
72
+ when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName
73
+ eval_receiver_or_owner(signature) # trigger autoload
74
+ *parts, name = signature.split('::', -1)
75
+ base =
76
+ if parts.empty? # ConstName
77
+ find_const_owner(name)
78
+ elsif parts == [''] # ::ConstName
79
+ Object
80
+ else # ConstPath::ConstName
81
+ eval_receiver_or_owner(parts.join('::'))
82
+ end
83
+ file, line = base.const_source_location(name)
26
84
  when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
27
- owner = eval(Regexp.last_match[:owner], context_binding)
85
+ owner = eval_receiver_or_owner(Regexp.last_match[:owner])
28
86
  method = Regexp.last_match[:method]
29
87
  return unless owner.respond_to?(:instance_method)
30
- file, line = method_target(owner, super_level, method, "owner")
88
+ method = method_target(owner, super_level, method, "owner")
89
+ file, line = method&.source_location
31
90
  when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method
32
- receiver = eval(Regexp.last_match[:receiver] || 'self', context_binding)
91
+ receiver = eval_receiver_or_owner(Regexp.last_match[:receiver] || 'self')
33
92
  method = Regexp.last_match[:method]
34
93
  return unless receiver.respond_to?(method, true)
35
- file, line = method_target(receiver, super_level, method, "receiver")
94
+ method = method_target(receiver, super_level, method, "receiver")
95
+ file, line = method&.source_location
36
96
  end
37
- # If the line is zero, it means that the target's source is probably in a binary file, which we should ignore.
38
- if file && line && !line.zero? && File.exist?(file)
39
- Source.new(file: file, first_line: line, last_line: find_end(file, line))
97
+ return unless file && line
98
+
99
+ if File.exist?(file)
100
+ Source.new(file, line)
101
+ elsif method
102
+ # Method defined with eval, probably in IRB session
103
+ source = RubyVM::AbstractSyntaxTree.of(method)&.source rescue nil
104
+ Source.new(file, line, source)
40
105
  end
106
+ rescue EvaluationError
107
+ nil
41
108
  end
42
109
 
43
110
  private
44
111
 
45
- def find_end(file, first_line)
46
- lex = RubyLex.new
47
- lines = File.read(file).lines[(first_line - 1)..-1]
48
- tokens = RubyLex.ripper_lex_without_warning(lines.join)
49
- prev_tokens = []
50
-
51
- # chunk with line number
52
- tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk|
53
- code = lines[0..lnum].join
54
- prev_tokens.concat chunk
55
- continue = lex.should_continue?(prev_tokens)
56
- syntax = lex.check_code_syntax(code, local_variables: [])
57
- if !continue && syntax == :valid
58
- return first_line + lnum
59
- end
60
- end
61
- first_line
62
- end
63
-
64
112
  def method_target(owner_receiver, super_level, method, type)
65
113
  case type
66
114
  when "owner"
@@ -71,9 +119,21 @@ module IRB
71
119
  super_level.times do |s|
72
120
  target_method = target_method.super_method if target_method
73
121
  end
74
- target_method.nil? ? nil : target_method.source_location
122
+ target_method
75
123
  rescue NameError
76
124
  nil
77
125
  end
126
+
127
+ def eval_receiver_or_owner(code)
128
+ context_binding = @irb_context.workspace.binding
129
+ eval(code, context_binding)
130
+ rescue NameError
131
+ raise EvaluationError
132
+ end
133
+
134
+ def find_const_owner(name)
135
+ module_nesting = @irb_context.workspace.binding.eval('::Module.nesting')
136
+ module_nesting.find { |mod| mod.const_defined?(name, false) } || module_nesting.find { |mod| mod.const_defined?(name) } || Object
137
+ end
78
138
  end
79
139
  end
data/lib/irb/statement.rb CHANGED
@@ -20,6 +20,29 @@ module IRB
20
20
  raise NotImplementedError
21
21
  end
22
22
 
23
+ class EmptyInput < Statement
24
+ def is_assignment?
25
+ false
26
+ end
27
+
28
+ def suppresses_echo?
29
+ true
30
+ end
31
+
32
+ # Debugger takes empty input to repeat the last command
33
+ def should_be_handled_by_debugger?
34
+ true
35
+ end
36
+
37
+ def code
38
+ ""
39
+ end
40
+
41
+ def evaluable_code
42
+ code
43
+ end
44
+ end
45
+
23
46
  class Expression < Statement
24
47
  def initialize(code, is_assignment)
25
48
  @code = code
@@ -60,9 +83,8 @@ module IRB
60
83
  end
61
84
 
62
85
  def should_be_handled_by_debugger?
63
- require_relative 'cmd/help'
64
- require_relative 'cmd/debug'
65
- IRB::ExtendCommand::DebugCommand > @command_class || IRB::ExtendCommand::Help == @command_class
86
+ require_relative 'command/debug'
87
+ IRB::Command::DebugCommand > @command_class
66
88
  end
67
89
 
68
90
  def evaluable_code
data/lib/irb/version.rb CHANGED
@@ -1,11 +1,11 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/version.rb - irb version definition file
4
4
  # by Keiju ISHITSUKA(keiju@ishitsuka.com)
5
5
  #
6
6
 
7
7
  module IRB # :nodoc:
8
- VERSION = "1.11.2"
8
+ VERSION = "1.12.0"
9
9
  @RELEASE_VERSION = VERSION
10
- @LAST_UPDATE_DATE = "2024-02-07"
10
+ @LAST_UPDATE_DATE = "2024-03-06"
11
11
  end
data/lib/irb/workspace.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/workspace-binding.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
@@ -90,11 +90,11 @@ EOF
90
90
  IRB.conf[:__MAIN__] = @main
91
91
  @main.singleton_class.class_eval do
92
92
  private
93
- define_method(:exit) do |*a, &b|
94
- # Do nothing, will be overridden
95
- end
96
93
  define_method(:binding, Kernel.instance_method(:binding))
97
94
  define_method(:local_variables, Kernel.instance_method(:local_variables))
95
+ # Define empty method to avoid delegator warning, will be overridden.
96
+ define_method(:exit) {|*a, &b| }
97
+ define_method(:exit!) {|*a, &b| }
98
98
  end
99
99
  @binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, *@binding.source_location)
100
100
  end
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # irb/ws-for-case-2.rb -
4
4
  # by Keiju ISHITSUKA(keiju@ruby-lang.org)
data/lib/irb/xmp.rb CHANGED
@@ -1,4 +1,4 @@
1
- # frozen_string_literal: false
1
+ # frozen_string_literal: true
2
2
  #
3
3
  # xmp.rb - irb version of gotoken xmp
4
4
  # by Keiju ISHITSUKA(Nippon Rational Inc.)