From 130268e264f59c037eda31205c6e2223cffafbbe Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Sun, 10 Dec 2023 04:21:41 +0000 Subject: [ruby/irb] Simplify show_source's super calculation (https://github.com/ruby/irb/pull/807) https://github.com/ruby/irb/commit/2cccc448de --- lib/irb/cmd/show_source.rb | 13 +++++-------- lib/irb/source_finder.rb | 18 ++++++------------ test/irb/cmd/test_show_source.rb | 13 +++++++++++++ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/irb/cmd/show_source.rb b/lib/irb/cmd/show_source.rb index 9a0364e3eb..826cb11ed2 100644 --- a/lib/irb/cmd/show_source.rb +++ b/lib/irb/cmd/show_source.rb @@ -27,17 +27,14 @@ module IRB puts "Error: Expected a string but got #{str.inspect}" return end - if str.include? " -s" - str, esses = str.split(" -") - s_count = esses.count("^s").zero? ? esses.size : 1 - source = SourceFinder.new(@irb_context).find_source(str, s_count) - else - source = SourceFinder.new(@irb_context).find_source(str) - end + + str, esses = str.split(" -") + super_level = esses ? esses.count("s") : 0 + source = SourceFinder.new(@irb_context).find_source(str, super_level) if source show_source(source) - elsif s_count + elsif super_level > 0 puts "Error: Couldn't locate a super definition for #{str}" else puts "Error: Couldn't locate a definition for #{str}" diff --git a/lib/irb/source_finder.rb b/lib/irb/source_finder.rb index a0aedcee68..659d4200fd 100644 --- a/lib/irb/source_finder.rb +++ b/lib/irb/source_finder.rb @@ -16,7 +16,7 @@ module IRB @irb_context = irb_context end - def find_source(signature, s_count = nil) + def find_source(signature, super_level = 0) context_binding = @irb_context.workspace.binding case signature when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name @@ -27,12 +27,12 @@ module IRB owner = eval(Regexp.last_match[:owner], context_binding) method = Regexp.last_match[:method] return unless owner.respond_to?(:instance_method) - file, line = method_target(owner, s_count, method, "owner") + file, line = method_target(owner, super_level, method, "owner") when /\A((?.+)(\.|::))?(?[^ :.]+)\z/ # method, receiver.method, receiver::method receiver = eval(Regexp.last_match[:receiver] || 'self', context_binding) method = Regexp.last_match[:method] return unless receiver.respond_to?(method, true) - file, line = method_target(receiver, s_count, method, "receiver") + file, line = method_target(receiver, super_level, method, "receiver") end if file && line && File.exist?(file) Source.new(file: file, first_line: line, last_line: find_end(file, line)) @@ -60,20 +60,14 @@ module IRB first_line end - def method_target(owner_receiver, s_count, method, type) + def method_target(owner_receiver, super_level, method, type) case type when "owner" target_method = owner_receiver.instance_method(method) - return target_method.source_location unless s_count when "receiver" - if s_count - target_method = owner_receiver.class.instance_method(method) - else - target_method = method - return owner_receiver.method(method).source_location - end + target_method = owner_receiver.method(method) end - s_count.times do |s| + super_level.times do |s| target_method = target_method.super_method if target_method end target_method.nil? ? nil : target_method.source_location diff --git a/test/irb/cmd/test_show_source.rb b/test/irb/cmd/test_show_source.rb index 89b1142390..cedec8aa6f 100644 --- a/test/irb/cmd/test_show_source.rb +++ b/test/irb/cmd/test_show_source.rb @@ -39,6 +39,19 @@ module TestIRB assert_match(%r[/irb\/init\.rb], out) end + def test_show_source_with_missing_signature + write_ruby <<~'RUBY' + binding.irb + RUBY + + out = run_ruby_file do + type "show_source foo" + type "exit" + end + + assert_match(%r[Couldn't locate a definition for foo], out) + end + def test_show_source_string write_ruby <<~'RUBY' binding.irb -- cgit v1.2.3