mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
advanced module methods now in Pry::WrappedModule
* WrappedModule#source_location, WrappedModule#source, analogous to Pry::Method
This commit is contained in:
parent
f7e0bfadde
commit
87633cd4d9
3 changed files with 83 additions and 61 deletions
|
@ -128,55 +128,15 @@ class Pry
|
||||||
new(meth.source, start_line, meth.source_type)
|
new(meth.source, start_line, meth.source_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
# FIXME: shares too much code with `from_module`
|
|
||||||
#
|
|
||||||
# Retrieve the source location of a module. Return value is in same
|
|
||||||
# format as Method#source_location. If the source location
|
|
||||||
# cannot be found this method returns `nil`.
|
|
||||||
#
|
|
||||||
# @param [Module] mod The module (or class).
|
|
||||||
# @return [Array<String, Fixnum>] The source location of the
|
|
||||||
# module (or class).
|
|
||||||
def module_source_location(mod)
|
|
||||||
mod_type_string = mod.class.to_s.downcase
|
|
||||||
file, line = find_module_method_source_location(mod)
|
|
||||||
|
|
||||||
raise Pry::CommandError, "Can't find #{mod_type_string} code" if !file.is_a?(String)
|
|
||||||
class_regex = /#{mod_type_string}\s*(\w*)(::)?#{mod.name.split(/::/).last}/
|
|
||||||
|
|
||||||
if file == Pry.eval_path
|
|
||||||
all_lines = Pry.line_buffer.drop(1)
|
|
||||||
else
|
|
||||||
all_lines = File.readlines(file)
|
|
||||||
end
|
|
||||||
|
|
||||||
search_lines = all_lines[0..(line - 2)]
|
|
||||||
idx = search_lines.rindex { |v| class_regex =~ v }
|
|
||||||
|
|
||||||
[file, idx + 1]
|
|
||||||
rescue Pry::RescuableException
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
# FIXME: shares too much code with `module_source_location`
|
|
||||||
#
|
|
||||||
# Attempt to extract the source code for module (or class) `mod`.
|
# Attempt to extract the source code for module (or class) `mod`.
|
||||||
#
|
#
|
||||||
# @param [Module, Class] mod The module (or class) of interest.
|
# @param [Module, Class] mod The module (or class) of interest.
|
||||||
# @return [Code]
|
# @return [Code]
|
||||||
def from_module(mod)
|
def from_module(mod, start_line=nil)
|
||||||
file, line = module_source_location(mod)
|
mod = Pry::WrappedModule(mod)
|
||||||
|
|
||||||
raise CommandError, "Could not locate source for #{mod}!" if file.nil?
|
_, start_line = mod.source_location || 1
|
||||||
|
new(mod.source, start_line, :ruby)
|
||||||
if file == Pry.eval_path
|
|
||||||
all_lines = Pry.line_buffer.drop(1)
|
|
||||||
else
|
|
||||||
all_lines = File.readlines(file)
|
|
||||||
end
|
|
||||||
|
|
||||||
mod_code = retrieve_complete_expression_from(all_lines[(line - 1)..-1])
|
|
||||||
new(mod_code, line, :ruby)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -209,21 +169,6 @@ class Pry
|
||||||
|
|
||||||
type
|
type
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_module_method_source_location(klass)
|
|
||||||
ims = Pry::Method.all_from_class(klass, false) + Pry::Method.all_from_obj(klass, false)
|
|
||||||
|
|
||||||
file, line = ims.each do |m|
|
|
||||||
break m.source_location if m.source_location && !m.alias?
|
|
||||||
end
|
|
||||||
|
|
||||||
if file && RbxPath.is_core_path?(file)
|
|
||||||
file = RbxPath.convert_path_to_full(file)
|
|
||||||
end
|
|
||||||
|
|
||||||
[file, line]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :code_type
|
attr_accessor :code_type
|
||||||
|
|
|
@ -220,10 +220,12 @@ class Pry
|
||||||
|
|
||||||
def process_module(name)
|
def process_module(name)
|
||||||
klass = target.eval(name)
|
klass = target.eval(name)
|
||||||
file_name, line = Code.module_source_location(klass)
|
|
||||||
|
mod = Pry::WrappedModule(klass)
|
||||||
|
file_name, line = mod.source_location
|
||||||
set_file_and_dir_locals(file_name)
|
set_file_and_dir_locals(file_name)
|
||||||
output.puts "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{line}:\n\n"
|
output.puts "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} @ line #{line}:\n\n"
|
||||||
Code.from_module(klass).with_line_numbers(use_line_numbers?)
|
Code.from_module(mod).with_line_numbers(use_line_numbers?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def use_line_numbers?
|
def use_line_numbers?
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
class Pry
|
class Pry
|
||||||
|
class << self
|
||||||
|
# If the given object is a `Pry::WrappedModule`, return it unaltered. If it's
|
||||||
|
# anything else, return it wrapped in a `Pry::WrappedModule` instance.
|
||||||
|
def WrappedModule(obj)
|
||||||
|
if obj.is_a? Pry::WrappedModule
|
||||||
|
obj
|
||||||
|
else
|
||||||
|
Pry::WrappedModule.new(obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class WrappedModule
|
class WrappedModule
|
||||||
|
|
||||||
attr_reader :wrapped
|
attr_reader :wrapped
|
||||||
|
@ -10,6 +22,8 @@ class Pry
|
||||||
def initialize(mod)
|
def initialize(mod)
|
||||||
raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod
|
raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod
|
||||||
@wrapped = mod
|
@wrapped = mod
|
||||||
|
@host_file_lines = nil
|
||||||
|
@source = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
# The prefix that would appear before methods defined on this class.
|
# The prefix that would appear before methods defined on this class.
|
||||||
|
@ -69,5 +83,66 @@ class Pry
|
||||||
def respond_to?(method_name)
|
def respond_to?(method_name)
|
||||||
super || wrapped.send(method_name, *args, &block)
|
super || wrapped.send(method_name, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Retrieve the source for the module.
|
||||||
|
def source
|
||||||
|
if @source
|
||||||
|
@source
|
||||||
|
else
|
||||||
|
file, line = source_location
|
||||||
|
raise CommandError, "Could not locate source for #{wrapped}!" if file.nil?
|
||||||
|
|
||||||
|
@source = strip_leading_whitespace(Pry::Code.retrieve_complete_expression_from(@host_file_lines[(line - 1)..-1]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retrieve the source location of a module. Return value is in same
|
||||||
|
# format as Method#source_location. If the source location
|
||||||
|
# cannot be found this method returns `nil`.
|
||||||
|
#
|
||||||
|
# @param [Module] mod The module (or class).
|
||||||
|
# @return [Array<String, Fixnum>] The source location of the
|
||||||
|
# module (or class).
|
||||||
|
def source_location
|
||||||
|
mod_type_string = wrapped.class.to_s.downcase
|
||||||
|
file, line = find_module_method_source_location
|
||||||
|
|
||||||
|
return nil if !file.is_a?(String)
|
||||||
|
|
||||||
|
class_regex = /#{mod_type_string}\s*(\w*)(::)?#{wrapped.name.split(/::/).last}/
|
||||||
|
|
||||||
|
if file == Pry.eval_path
|
||||||
|
@host_file_lines ||= Pry.line_buffer.drop(1)
|
||||||
|
else
|
||||||
|
@host_file_lines ||= File.readlines(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
search_lines = @host_file_lines[0..(line - 2)]
|
||||||
|
idx = search_lines.rindex { |v| class_regex =~ v }
|
||||||
|
|
||||||
|
[file, idx + 1]
|
||||||
|
rescue Pry::RescuableException
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_module_method_source_location
|
||||||
|
ims = Pry::Method.all_from_class(wrapped, false) + Pry::Method.all_from_obj(wrapped, false)
|
||||||
|
|
||||||
|
file, line = ims.each do |m|
|
||||||
|
break m.source_location if m.source_location && !m.alias?
|
||||||
|
end
|
||||||
|
|
||||||
|
if file && RbxPath.is_core_path?(file)
|
||||||
|
file = RbxPath.convert_path_to_full(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
[file, line]
|
||||||
|
end
|
||||||
|
|
||||||
|
def strip_leading_whitespace(text)
|
||||||
|
Pry::Helpers::CommandHelpers.unindent(text)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue