Merge branch 'master' of github.com:pry/pry

This commit is contained in:
John Mair 2012-04-17 20:54:31 +12:00
commit dc0e15cf47
1 changed files with 102 additions and 68 deletions

View File

@ -32,94 +32,128 @@ class Pry
else
klass = (target_self.is_a?(Module)) ? target_self : target_self.class
end
if opts.name?
to_put = name_search(pattern, klass)
elsif opts.content?
to_put = content_search(pattern, klass)
matches = if opts.content?
content_search(pattern, klass)
else
name_search(pattern, klass)
end
if matches.empty?
output.puts text.bold("No Methods Matched")
else
to_put = name_search(pattern, klass)
end
1
if to_put.flatten == []
puts text.bold("No Methods Matched")
else
puts text.bold("Methods Matched")
puts "--"
stagger_output to_put.join("\n")
print_matches(matches, pattern)
end
end
private
def puts(item)
output.puts item
# pretty-print a list of matching methods.
#
# @param Array[Method]
def print_matches(matches, pattern)
grouped = matches.group_by(&:owner)
order = grouped.keys.sort_by{ |x| x.name || x.to_s }
order.each do |klass|
output.puts text.bold(klass.name)
grouped[klass].each do |method|
header = method.name_with_owner
extra = if opts.content?
header += ": "
colorize_code((method.source.split(/\n/).select {|x| x =~ pattern }).join("\n#{' ' * header.length}"))
else
""
end
output.puts header + extra
end
end
end
def content_search(pattern, klass, current=[], the_methods=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
meths = []
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).uniq.each do |meth|
next if the_methods.include? meth.name
the_methods << meth.name
# Run the given block against every constant in the provided namespace.
#
# @param Module The namespace in which to start the search.
# @param Hash[Module,Boolean] The namespaces we've already visited (private)
# @yieldparam klazz Each class/module in the namespace.
#
def recurse_namespace(klass, done={}, &block)
if done[klass] || !(Module === klass)
return
end
done[klass] = true
yield klass
klass.constants.each do |name|
next if klass.autoload?(name)
begin
if meth.source =~ pattern && !meth.alias?
header = "#{klass}##{meth.name}: "
meths << header + colorize_code((meth.source.split(/\n/).select {|x| x =~ pattern }).join("\n#{' ' * header.length}"))
end
rescue Pry::RescuableException
next
rescue Pry::CommandError
next
const = klass.const_get(name)
rescue RescuableException => e
# constant loading is an inexact science at the best of times,
# this often happens when a constant was .autoload? but someone
# tried to load it. It's now not .autoload? but will still raise
# a NameError when you access it.
else
recurse_namespace(const, done, &block)
end
end
klass.constants.each do |klazz|
begin
meths += ((res = content_search(pattern, klass.const_get(klazz), current, the_methods)) ? res : [])
rescue Pry::RescuableException
next
end
end
return meths.uniq.flatten
end
def name_search(regex, klass, current=[], the_methods=[])
return unless(klass.is_a? Module)
return if current.include? klass
current << klass
header = text.bold("#{klass.name}:")
meths = []
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).uniq.each do |x|
next if the_methods.include? x.name
the_methods << x.name
if x.name =~ regex
meths << " #{x.name}"
begin
if x.alias?
meths[-1] += "#A|#{x.original_name}" if x.original_name
end
rescue Pry::RescuableException
end
# Gather all the methods in a namespace that pass the given block.
#
# @param Module The namespace in which to search.
# @yieldparam Method The method to test
# @yieldreturn Boolean
# @return Array[Method]
#
def search_all_methods(namespace)
done = Hash.new{ |h,k| h[k] = {} }
matches = []
recurse_namespace(namespace) do |klass|
(Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method|
next if done[method.owner][method.name]
done[method.owner][method.name] = true
matches << method if yield method
end
end
max = meths.map(&:length).max
meths.map! do |x|
if x =~ /#{"#A"}/
x = x.sub!("#A|", ((' ' * ((max - x.length) + 3)) + text.bold("(Alias of "))) + text.bold(")")
end
x
matches
end
# Search for all methods with a name that matches the given regex
# within a namespace.
#
# @param Regex The regex to search for
# @param Module The namespace to search
# @return Array[Method]
#
def name_search(regex, namespace)
search_all_methods(namespace) do |meth|
meth.name =~ regex
end
meths.unshift header if meths.size > 0
klass.constants.each do |x|
end
# Search for all methods who's implementation matches the given regex
# within a namespace.
#
# @param Regex The regex to search for
# @param Module The namespace to search
# @return Array[Method]
#
def content_search(regex, namespace)
search_all_methods(namespace) do |meth|
begin
meths << ((res = name_search(regex, klass.const_get(x), current, the_methods)) ? res : [])
rescue Pry::RescuableException
next
meth.source =~ regex
rescue RescuableException => e
false
end
end
return meths.uniq.flatten
end
end
end