Class: RDoc::RI::Store

Inherits:
Object show all
Defined in:
lib/rdoc/ri/store.rb

Overview

A set of ri data.

The store manages reading and writing ri data for a project (gem, path, etc.) and maintains a cache of methods, classes and ancestors in the store.

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Store) initialize(path, type = nil)

Creates a new Store of type that will load or save to path



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rdoc/ri/store.rb', line 37

def initialize path, type = nil
  @dry_run = false
  @type    = type
  @path    = path

  @cache = {
    :class_methods    => {},
    :instance_methods => {},
    :attributes       => {},
    :modules          => [],
    :ancestors        => {},
  }
end

Instance Attribute Details

- (Object) cache (readonly)

The contents of the Store



32
33
34
# File 'lib/rdoc/ri/store.rb', line 32

def cache
  @cache
end

- (Object) dry_run

If true this Store will not write any files



16
17
18
# File 'lib/rdoc/ri/store.rb', line 16

def dry_run
  @dry_run
end

- (Object) path

Path this store reads or writes



21
22
23
# File 'lib/rdoc/ri/store.rb', line 21

def path
  @path
end

- (Object) type

Type of ri datastore this was loaded from. See RDoc::RI::Driver, RDoc::RI::Paths.



27
28
29
# File 'lib/rdoc/ri/store.rb', line 27

def type
  @type
end

Instance Method Details

- (Object) ancestors

Ancestors cache accessor. Maps a klass name to an Array of its ancestors in this store. If Foo in this store inherits from Object, Kernel won't be listed (it will be included from ruby's ri store).



56
57
58
# File 'lib/rdoc/ri/store.rb', line 56

def ancestors
  @cache[:ancestors]
end

- (Object) attributes

Attributes cache accessor. Maps a class to an Array of its attributes.



63
64
65
# File 'lib/rdoc/ri/store.rb', line 63

def attributes
  @cache[:attributes]
end

- (Object) cache_path

Path to the cache file



70
71
72
# File 'lib/rdoc/ri/store.rb', line 70

def cache_path
  File.join @path, 'cache.ri'
end

- (Object) class_file(klass_name)

Path to the ri data for klass_name



77
78
79
80
# File 'lib/rdoc/ri/store.rb', line 77

def class_file klass_name
  name = klass_name.split('::').last
  File.join class_path(klass_name), "cdesc-#{name}.ri"
end

- (Object) class_methods

Class methods cache accessor. Maps a class to an Array of its class methods (not full name).



86
87
88
# File 'lib/rdoc/ri/store.rb', line 86

def class_methods
  @cache[:class_methods]
end

- (Object) class_path(klass_name)

Path where data for klass_name will be stored (methods or class data)



93
94
95
# File 'lib/rdoc/ri/store.rb', line 93

def class_path klass_name
  File.join @path, *klass_name.split('::')
end

- (Object) friendly_path

Friendly rendition of #path



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rdoc/ri/store.rb', line 100

def friendly_path
  case type
  when :gem    then
    sep = Regexp.union(*['/', File::ALT_SEPARATOR].compact)
    @path =~ /#{sep}doc#{sep}(.*?)#{sep}ri$/
    "gem #{$1}"
  when :home   then '~/.ri'
  when :site   then 'ruby site'
  when :system then 'ruby core'
  else @path
  end
end

- (Object) inspect

:nodoc:



113
114
115
# File 'lib/rdoc/ri/store.rb', line 113

def inspect # :nodoc:
  "#<%s:0x%x %s %p>" % [self.class, object_id, @path, modules.sort]
end

- (Object) instance_methods

Instance methods cache accessor. Maps a class to an Array of its instance methods (not full name).



121
122
123
# File 'lib/rdoc/ri/store.rb', line 121

def instance_methods
  @cache[:instance_methods]
end

- (Object) load_cache

Loads cache file for this store



128
129
130
131
132
133
# File 'lib/rdoc/ri/store.rb', line 128

def load_cache
  open cache_path, 'rb' do |io|
    @cache = Marshal.load io.read
  end
rescue Errno::ENOENT
end

- (Object) load_class(klass_name)

Loads ri data for klass_name



138
139
140
141
142
# File 'lib/rdoc/ri/store.rb', line 138

def load_class klass_name
  open class_file(klass_name), 'rb' do |io|
    Marshal.load io.read
  end
end

- (Object) load_method(klass_name, method_name)

Loads ri data for method_name in klass_name



147
148
149
150
151
# File 'lib/rdoc/ri/store.rb', line 147

def load_method klass_name, method_name
  open method_file(klass_name, method_name), 'rb' do |io|
    Marshal.load io.read
  end
end

- (Object) method_file(klass_name, method_name)

Path to the ri data for method_name in klass_name



156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/rdoc/ri/store.rb', line 156

def method_file klass_name, method_name
  method_name = method_name.split('::').last
  method_name =~ /#(.*)/
  method_type = $1 ? 'i' : 'c'
  method_name = $1 if $1

  method_name = if ''.respond_to? :ord then
                  method_name.gsub(/\W/) { "%%%02x" % $&[0].ord }
                else
                  method_name.gsub(/\W/) { "%%%02x" % $&[0] }
                end

  File.join class_path(klass_name), "#{method_name}-#{method_type}.ri"
end

- (Object) modules

Modules cache accessor. An Array of all the modules (and classes) in the store.



175
176
177
# File 'lib/rdoc/ri/store.rb', line 175

def modules
  @cache[:modules]
end

- (Object) save_cache

Writes the cache file for this store



182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/rdoc/ri/store.rb', line 182

def save_cache
  # HACK mongrel-1.1.5 documents its files twice
  @cache[:ancestors].       each do |_, m| m.uniq!; m.sort! end
  @cache[:attributes].      each do |_, m| m.uniq!; m.sort! end
  @cache[:class_methods].   each do |_, m| m.uniq!; m.sort! end
  @cache[:instance_methods].each do |_, m| m.uniq!; m.sort! end
  @cache[:modules].uniq!; @cache[:modules].sort!

  return if @dry_run

  open cache_path, 'wb' do |io|
    Marshal.dump @cache, io
  end
end

- (Object) save_class(klass)

Writes the ri data for klass



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/rdoc/ri/store.rb', line 200

def save_class klass
  FileUtils.mkdir_p class_path(klass.full_name) unless @dry_run

  @cache[:modules] << klass.full_name

  path = class_file klass.full_name

  begin
    disk_klass = nil

    open path, 'rb' do |io|
      disk_klass = Marshal.load io.read
    end

    klass.merge disk_klass
  rescue Errno::ENOENT
  end

  # BasicObject has no ancestors
  ancestors = klass.ancestors.compact.map do |ancestor|
    # HACK for classes we don't know about (class X < RuntimeError)
    String === ancestor ? ancestor : ancestor.full_name
  end

  @cache[:ancestors][klass.full_name] ||= []
  @cache[:ancestors][klass.full_name].push(*ancestors)

  attributes = klass.attributes.map do |attribute|
    "#{attribute.definition} #{attribute.name}"
  end

  unless attributes.empty? then
    @cache[:attributes][klass.full_name] ||= []
    @cache[:attributes][klass.full_name].push(*attributes)
  end

  return if @dry_run

  open path, 'wb' do |io|
    Marshal.dump klass, io
  end
end

- (Object) save_method(klass, method)

Writes the ri data for method on klass



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/rdoc/ri/store.rb', line 246

def save_method klass, method
  FileUtils.mkdir_p class_path(klass.full_name) unless @dry_run

  cache = if method.singleton then
            @cache[:class_methods]
          else
            @cache[:instance_methods]
          end
  cache[klass.full_name] ||= []
  cache[klass.full_name] << method.name

  return if @dry_run

  open method_file(klass.full_name, method.full_name), 'wb' do |io|
    Marshal.dump method, io
  end
end