зеркало из https://github.com/github/ruby.git
[ruby/irb] Improve constant lookup in SourceFinder
(https://github.com/ruby/irb/pull/871) https://github.com/ruby/irb/commit/87c279ccf2
This commit is contained in:
Родитель
eea7ce55de
Коммит
d0412599e0
|
@ -69,10 +69,18 @@ module IRB
|
||||||
|
|
||||||
def find_source(signature, super_level = 0)
|
def find_source(signature, super_level = 0)
|
||||||
case signature
|
case signature
|
||||||
when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
|
when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName
|
||||||
eval_receiver_or_owner(signature) # trigger autoload
|
eval_receiver_or_owner(signature) # trigger autoload
|
||||||
base = @irb_context.workspace.binding.receiver.yield_self { |r| r.is_a?(Module) ? r : Object }
|
*parts, name = signature.split('::', -1)
|
||||||
file, line = base.const_source_location(signature)
|
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
|
when /\A(?<owner>[A-Z]\w*(::[A-Z]\w*)*)#(?<method>[^ :.]+)\z/ # Class#method
|
||||||
owner = eval_receiver_or_owner(Regexp.last_match[:owner])
|
owner = eval_receiver_or_owner(Regexp.last_match[:owner])
|
||||||
method = Regexp.last_match[:method]
|
method = Regexp.last_match[:method]
|
||||||
|
@ -122,5 +130,10 @@ module IRB
|
||||||
rescue NameError
|
rescue NameError
|
||||||
raise EvaluationError
|
raise EvaluationError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -362,5 +362,36 @@ module TestIRB
|
||||||
refute_match(/NameError/, out)
|
refute_match(/NameError/, out)
|
||||||
assert_match(%r[Defined in binary file:.+io/console], out)
|
assert_match(%r[Defined in binary file:.+io/console], out)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_show_source_with_constant_lookup
|
||||||
|
write_ruby <<~RUBY
|
||||||
|
X = 1
|
||||||
|
module M
|
||||||
|
Y = 1
|
||||||
|
Z = 2
|
||||||
|
end
|
||||||
|
class A
|
||||||
|
Z = 1
|
||||||
|
Array = 1
|
||||||
|
class B
|
||||||
|
include M
|
||||||
|
Object.new.instance_eval { binding.irb }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
out = run_ruby_file do
|
||||||
|
type "show_source X"
|
||||||
|
type "show_source Y"
|
||||||
|
type "show_source Z"
|
||||||
|
type "show_source Array"
|
||||||
|
type "exit"
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_match(%r[#{@ruby_file.to_path}:1\s+X = 1], out)
|
||||||
|
assert_match(%r[#{@ruby_file.to_path}:3\s+Y = 1], out)
|
||||||
|
assert_match(%r[#{@ruby_file.to_path}:7\s+Z = 1], out)
|
||||||
|
assert_match(%r[#{@ruby_file.to_path}:8\s+Array = 1], out)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче