Module: CoreDocs::MethodInfo
- Defined in:
- lib/core_docs.rb
Class Method Summary collapse
-
.aliases(meth) ⇒ Array
Retrives aliases of a method.
-
.c_files_found?(gem_dir) ⇒ Boolean
True if c files exist?.
-
.cache(meth) ⇒ Object
Cache the file that holds the method or return immediately if file is already cached.
-
.cached?(meth) ⇒ Boolean
Check whether the file containing the method is already cached.
-
.find_gem_dir(meth) ⇒ String
Root directory path of gem that method belongs to, nil if could not be found.
-
.gem_dir_from_method(meth) ⇒ String?
Try to recover the gem directory of a gem based on a method object.
-
.gem_root(dir) ⇒ String
FIXME: this is unnecessarily limited to ext/ and lib/ folders.
-
.guess_gem_name_from_module_name(name, guess) ⇒ String?
Try to guess what the gem name will be based on the name of the module.
-
.info_for(meth) ⇒ YARD::CodeObjects::MethodObject
Retrieve the YARD object that contains the method data.
-
.is_eval_method?(meth) ⇒ Boolean
Determine whether a method is an eval method.
-
.is_singleton?(meth) ⇒ Boolean
Checks whether method is a singleton (i.e class method).
-
.method_host(meth) ⇒ Object
The host of the method (receiver or owner).
-
.parse_and_cache_if_gem_cext(meth) ⇒ Object
Attempts to find the c source files if method belongs to a gem and use YARD to parse and cache the source files for display.
-
.receiver_notation_for(meth) ⇒ String
Convert a method object into the
Class#methodstring notation. - .registry_lookup(meth) ⇒ Object
Class Method Details
.aliases(meth) ⇒ Array
Retrives aliases of a method
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/core_docs.rb', line 48 def self.aliases(meth) # host = is_singleton?(meth) ? meth.receiver : meth.owner # method_type = is_singleton?(meth) ? :method : :instance_method # methods = Pry::Method.send(:all_from_common, host, method_type, false). # map { |m| m.instance_variable_get(:@method) } # methods.select { |m| host.send(method_type,m.name) == host.send(method_type,meth.name) }. # reject { |m| m.name == meth.name }. # map { |m| host.send(method_type,m.name) } [] end |
.c_files_found?(gem_dir) ⇒ Boolean
123 124 125 |
# File 'lib/core_docs.rb', line 123 def self.c_files_found?(gem_dir) Dir.glob("#{gem_dir}/**/*.c").count > 0 end |
.cache(meth) ⇒ Object
Cache the file that holds the method or return immediately if file is already cached. Return if the method cannot be cached - i.e is a C stdlib method.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/core_docs.rb', line 211 def self.cache(meth) file, _ = meth.source_location return if is_eval_method?(meth) return if cached?(meth) if !file parse_and_cache_if_gem_cext(meth) return end log.enter_level(Logger::FATAL) do YARD.parse(file) end end |
.cached?(meth) ⇒ Boolean
Check whether the file containing the method is already cached.
71 72 73 |
# File 'lib/core_docs.rb', line 71 def self.cached?(meth) !!registry_lookup(meth) end |
.find_gem_dir(meth) ⇒ String
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/core_docs.rb', line 143 def self.find_gem_dir(meth) # host = method_host(meth) # begin # host_source_location, _ = WrappedModule.new(host).source_location # break if host_source_location != nil # return unless host.name # host = eval(host.namespace_name) # end while host # # we want to exclude all source_locations that aren't gems (i.e # # stdlib) # if host_source_location && host_source_location =~ %r{/gems/} # gem_root(host_source_location) # else # the WrappedModule approach failed, so try our backup approach gem_dir_from_method(meth) # end end |
.gem_dir_from_method(meth) ⇒ String?
Try to recover the gem directory of a gem based on a method object.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/core_docs.rb', line 189 def self.gem_dir_from_method(meth) guess = 0 host = method_host(meth) return unless host.name root_module_name = host.name.split("::").first while gem_name = guess_gem_name_from_module_name(root_module_name, guess) matches = $LOAD_PATH.grep %r{/gems/#{gem_name}} if !gem_name.empty? if matches && matches.any? return gem_root(matches.first) else guess += 1 end end nil end |
.gem_root(dir) ⇒ String
FIXME: this is unnecessarily limited to ext/ and lib/ folders
134 135 136 137 138 |
# File 'lib/core_docs.rb', line 134 def self.gem_root(dir) if index = dir.rindex(/\/(?:lib|ext)(?:\/|$)/) dir[0..index-1] end end |
.guess_gem_name_from_module_name(name, guess) ⇒ String?
Try to guess what the gem name will be based on the name of the module.
We try a few approaches here depending on the guess parameter.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/core_docs.rb', line 169 def self.guess_gem_name_from_module_name(name, guess) case guess when 0 name.downcase when 1 name.scan(/[A-Z][a-z]+/).map(&:downcase).join('_') when 2 name.scan(/[A-Z][a-z]+/).map(&:downcase).join('_').sub("_", "-") when 3 name.scan(/[A-Z][a-z]+/).map(&:downcase).join('-') when 4 name else nil end end |
.info_for(meth) ⇒ YARD::CodeObjects::MethodObject
Retrieve the YARD object that contains the method data.
92 93 94 95 |
# File 'lib/core_docs.rb', line 92 def self.info_for(meth) cache(meth) registry_lookup(meth) end |
.is_eval_method?(meth) ⇒ Boolean
Determine whether a method is an eval method.
99 100 101 102 103 104 105 106 |
# File 'lib/core_docs.rb', line 99 def self.is_eval_method?(meth) file, _ = meth.source_location if file =~ /(\(.*\))|<.*>/ true else false end end |
.is_singleton?(meth) ⇒ Boolean
Checks whether method is a singleton (i.e class method)
64 65 66 |
# File 'lib/core_docs.rb', line 64 def self.is_singleton?(meth) receiver_notation_for(meth).include?('.') end |
.method_host(meth) ⇒ Object
128 129 130 |
# File 'lib/core_docs.rb', line 128 def self.method_host(meth) is_singleton?(meth) && Module === meth.receiver ? meth.receiver : meth.owner end |
.parse_and_cache_if_gem_cext(meth) ⇒ Object
Attempts to find the c source files if method belongs to a gem and use YARD to parse and cache the source files for display
112 113 114 115 116 117 118 119 |
# File 'lib/core_docs.rb', line 112 def self.parse_and_cache_if_gem_cext(meth) if gem_dir = find_gem_dir(meth) if c_files_found?(gem_dir) warn "Scanning and caching *.c files..." YARD.parse("#{gem_dir}/**/*.c") end end end |
.receiver_notation_for(meth) ⇒ String
This mess is needed in order to support all the modern Rubies. YOU must figure out a better way to distinguish between class methods and instance methods.
Convert a method object into the Class#method string notation.
36 37 38 39 40 41 42 |
# File 'lib/core_docs.rb', line 36 def self.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#<Class:/ owner + name end |
.registry_lookup(meth) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/core_docs.rb', line 75 def self.registry_lookup(meth) obj = YARD::Registry.at(receiver_notation_for(meth)) if obj.nil? if !(aliases = aliases(meth)).empty? obj = YARD::Registry.at(receiver_notation_for(aliases.first)) elsif meth.owner == Kernel # YARD thinks that some methods are on Object when # they're actually on Kernel; so try again on Object if Kernel fails. obj = YARD::Registry.at("Object##{meth.name}") end end obj end |