class IRB::SourceFinder
Public Class Methods
new
(irb_context)
# File lib/irb/source_finder.rb, line 66 def initialize(irb_context) @irb_context = irb_context end
Public Instance Methods
find_source
(signature, super_level = 0)
# File lib/irb/source_finder.rb, line 70 def find_source(signature, super_level = 0) case signature when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName eval_receiver_or_owner(signature) # trigger autoload *parts, name = signature.split('::', -1) base = if parts.empty? # ConstName find_const_owner(name) elsif parts == [''] # ::ConstName Object else # ConstPath::ConstName eval_receiver_or_owner(parts.join('::')) end file, line = base.const_source_location(name) when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method owner = eval_receiver_or_owner(Regexp.last_match[:owner]) method = Regexp.last_match[:method] return unless owner.respond_to?(:instance_method) method = method_target(owner, super_level, method, "owner") file, line = method&.source_location when /\A((?<receiver>.+)(\.|::))?(?<method>[^ :.]+)\z/ # method, receiver.method, receiver::method receiver = eval_receiver_or_owner(Regexp.last_match[:receiver] || 'self') method = Regexp.last_match[:method] return unless receiver.respond_to?(method, true) method = method_target(receiver, super_level, method, "receiver") file, line = method&.source_location end return unless file && line if File.exist?(file) Source.new(file, line) elsif method # Method defined with eval, probably in IRB session source = RubyVM::InstructionSequence.of(method)&.script_lines&.join rescue nil Source.new(file, line, source) end rescue EvaluationError nil end