require_relative "show_source_with_c_internals" class Pry module MethodInfo class << self ## # Retrieve the YARD object that contains the method data. # # @param [Method, UnboundMethod] meth The method object # @return [YARD::CodeObjects::MethodObject] the YARD data for the method def info_for(meth) cache(meth) registry_lookup(meth) end ## # Retrieves aliases of the given method. # # @param [Method, UnboundMethod] meth The method object # @return [Array] the aliases of the given method if they # exist, otherwise an empty array def aliases(meth) owner = meth.owner name = meth.name (owner.instance_methods + owner.private_instance_methods).uniq.map do |m| aliased_method = owner.__send__(:instance_method, m) next unless aliased_method == owner.__send__(:instance_method, name) next if m == name aliased_method end.compact! end ## # FIXME: this is unnecessarily limited to ext/ and lib/ directories. # # @return [String] the root directory of a given gem directory def gem_root(dir) return unless (index = dir.rindex(%r(/(?:lib|ext)(?:/|$)))) dir[0..index-1] end private ## # Convert a method object into the `Class#method` string notation. # # @param [Method, UnboundMethod] meth # @return [String] the method in string receiver notation # @note This mess is needed to support all the modern Rubies. Somebody has # to figure out a better way to distinguish between class methods and # instance methods. def receiver_notation_for(meth) match = meth.inspect.match(/\A#<(?:Unbound)?Method: (.+)([#\.].+?)(?:\(.+\))?>\z/) owner = meth.owner.to_s.sub(/#<.+?:(.+?)>/, '\1') name = match[2] name.sub!('#', '.') if match[1] =~ /\A#/ # No need to cache already cached methods. return if registry_lookup(meth) unless file parse_and_cache_if_gem_cext(meth) return end log.enter_level(Logger::FATAL) do YARD.parse(file) end end end end end