Class: IRB::SourceFinder
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Exceptions:
| |
Inherits: | Object |
Defined in: | lib/irb/source_finder.rb |
Class Method Summary
- .new(irb_context) ⇒ SourceFinder constructor
Instance Method Summary
Constructor Details
.new(irb_context) ⇒ SourceFinder
# File 'lib/irb/source_finder.rb', line 66
def initialize(irb_context) @irb_context = irb_context end
Instance Method Details
#eval_receiver_or_owner(code) (private)
[ GitHub ]# File 'lib/irb/source_finder.rb', line 127
def eval_receiver_or_owner(code) context_binding = @irb_context.workspace.binding eval(code, context_binding) rescue NameError raise EvaluationError end
#find_const_owner(name) (private)
[ GitHub ]# File 'lib/irb/source_finder.rb', line 134
def find_const_owner(name) module_nesting = @irb_context.workspace.binding.eval('::Module.nesting') module_nesting.find { |mod| mod.const_defined?(name, false) } || module_nesting.find { |mod| mod.const_defined?(name) } || Object end
#find_source(signature, super_level = 0)
[ GitHub ]# 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::AbstractSyntaxTree.of(method)&.source rescue nil Source.new(file, line, source) end rescue EvaluationError nil end
#method_target(owner_receiver, super_level, method, type) (private)
[ GitHub ]# File 'lib/irb/source_finder.rb', line 112
def method_target(owner_receiver, super_level, method, type) case type when "owner" target_method = owner_receiver.instance_method(method) when "receiver" target_method = owner_receiver.method(method) end super_level.times do |s| target_method = target_method.super_method if target_method end target_method rescue NameError nil end