Class: BitClust::MethodDatabase

Inherits:
Database show all
Includes:
Completion
Defined in:
lib/bitclust/methoddatabase.rb

Overview

Database for Ruby entries (library, class, method).

Constant Summary

Constants included from NameUtils

NameUtils::CHAR_TO_MARK, NameUtils::CHAR_TO_NAME, NameUtils::CLASS_NAME_RE, NameUtils::CLASS_PATH_RE, NameUtils::CONST_PATH_RE, NameUtils::CONST_RE, NameUtils::GVAR_RE, NameUtils::LIBNAME_RE, NameUtils::MARK_TO_CHAR, NameUtils::MARK_TO_NAME, NameUtils::METHOD_NAME_RE, NameUtils::METHOD_SPEC_RE, NameUtils::MID, NameUtils::NAME_TO_CHAR, NameUtils::NAME_TO_MARK, NameUtils::TYPEMARK_RE

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Database

#atomic_write_open, connect, datadir?, #dummy?, #encoding, #entries, #exist?, #foreach_line, #load_properties, #makepath, #properties, #propget, #propkeys, #propset, #read, #save_properties, #transaction

Methods included from NameUtils

build_method_id, classid2name, classname2id, classname?, decodeid, decodename_fs, decodename_url, encodeid, encodename_fs, encodename_rdocurl, encodename_url, functionname?, gvarname?, html_filename, libid2name, libname2id, libname?, method_spec?, methodid2classid, methodid2libid, methodid2mname, methodid2specparts, methodid2specstring, methodid2typechar, methodid2typemark, methodid2typename, methodname?, split_method_id, split_method_spec, typechar2mark, typechar2name, typechar?, typemark2char, typemark2name, typemark?, typename2char, typename2mark, typename?

Constructor Details

#initialize(prefix) ⇒ MethodDatabase

Returns a new instance of MethodDatabase.


34
35
36
37
38
39
40
41
42
43
44
# File 'lib/bitclust/methoddatabase.rb', line 34

def initialize(prefix)
  super prefix
  @librarymap = nil
  @classmap = {}
  @class_extent_loaded = false
  @in_transaction = false
  @dirty_libraries = {}
  @dirty_classes = {}
  @dirty_methods = {}
  @refs = nil
end

Instance Attribute Details

#refsObject


164
165
166
# File 'lib/bitclust/methoddatabase.rb', line 164

def refs
  @refs ||= RefsDatabase.load(realpath('refs'))
end

Class Method Details

.dummy(params = {}) ⇒ Object


28
29
30
31
32
# File 'lib/bitclust/methoddatabase.rb', line 28

def MethodDatabase.dummy(params = {})
  db = super
  db.refs = RefsDatabase.new
  db
end

Instance Method Details

#classesObject

Classe Entry


259
260
261
# File 'lib/bitclust/methoddatabase.rb', line 259

def classes
  classmap().values
end

#clear_dirtyObject


124
125
126
127
128
# File 'lib/bitclust/methoddatabase.rb', line 124

def clear_dirty
  @dirty_libraries.clear
  @dirty_classes.clear
  @dirty_methods.clear
end

#copy_docObject


177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/bitclust/methoddatabase.rb', line 177

def copy_doc
  Dir.glob("#{@root}/../../doc/**/*.rd").each do |f|
    if %r!\A#{Regexp.escape(@root)}/\.\./\.\./doc/([-\./\w]+)\.rd\z! =~ f
      id = libname2id($1)
      se = DocEntry.new(self, id)
      s = Preprocessor.read(f, properties)
      title, source = RRDParser.split_doc(s)
      se.title = title
      se.source = source
      se.save
    end
  end
end

#dirty?Boolean

Returns:

  • (Boolean)

88
89
90
91
92
# File 'lib/bitclust/methoddatabase.rb', line 88

def dirty?
  not @dirty_libraries.empty? or
  not @dirty_classes.empty? or
  not @dirty_methods.empty?
end

#dirty_class(c) ⇒ Object


108
109
110
# File 'lib/bitclust/methoddatabase.rb', line 108

def dirty_class(c)
  @dirty_classes[c] = true
end

#dirty_library(lib) ⇒ Object


100
101
102
# File 'lib/bitclust/methoddatabase.rb', line 100

def dirty_library(lib)
  @dirty_libraries[lib] = true
end

#dirty_method(m) ⇒ Object


116
117
118
# File 'lib/bitclust/methoddatabase.rb', line 116

def dirty_method(m)
  @dirty_methods[m] = true
end

#docsObject

Doc Entry


195
196
197
# File 'lib/bitclust/methoddatabase.rb', line 195

def docs
  docmap().values
end

#each_dirty_class(&block) ⇒ Object


112
113
114
# File 'lib/bitclust/methoddatabase.rb', line 112

def each_dirty_class(&block)
  @dirty_classes.each_key(&block)
end

#each_dirty_entry(&block) ⇒ Object


94
95
96
97
98
# File 'lib/bitclust/methoddatabase.rb', line 94

def each_dirty_entry(&block)
  (@dirty_libraries.keys +
   @dirty_classes.keys +
   @dirty_methods.keys).each(&block)
end

#each_dirty_library(&block) ⇒ Object


104
105
106
# File 'lib/bitclust/methoddatabase.rb', line 104

def each_dirty_library(&block)
  @dirty_libraries.each_key(&block)
end

#each_dirty_method(&block) ⇒ Object


120
121
122
# File 'lib/bitclust/methoddatabase.rb', line 120

def each_dirty_method(&block)
  @dirty_methods.each_key(&block)
end

#fetch_class(name) ⇒ Object

This method does not work in transaction.


286
287
288
289
290
291
# File 'lib/bitclust/methoddatabase.rb', line 286

def fetch_class(name)
  id = intern_classname(name) or
      raise ClassNotFound, "class not found: #{name.inspect}"
  load_class(id) or
      raise "must not happen: #{name.inspect}, #{id.inspect}"
end

#fetch_class_id(id) ⇒ Object


293
294
295
296
# File 'lib/bitclust/methoddatabase.rb', line 293

def fetch_class_id(id)
  load_class(id) or
      raise ClassNotFound, "class not found: #{id.inspect}"
end

#fetch_doc(name) ⇒ Object


209
210
211
212
# File 'lib/bitclust/methoddatabase.rb', line 209

def fetch_doc(name)
  docmap()[libname2id(name)] or
      raise DocNotFound, "doc not found: #{name.inspect}"
end

#fetch_library(name) ⇒ Object


232
233
234
235
# File 'lib/bitclust/methoddatabase.rb', line 232

def fetch_library(name)
  librarymap()[libname2id(name)] or
      raise LibraryNotFound, "library not found: #{name.inspect}"
end

#fetch_library_id(id) ⇒ Object


237
238
239
240
# File 'lib/bitclust/methoddatabase.rb', line 237

def fetch_library_id(id)
  librarymap()[id] or
      raise LibraryNotFound, "library not found: #{id.inspect}"
end

#fetch_method(spec) ⇒ Object


377
378
379
# File 'lib/bitclust/methoddatabase.rb', line 377

def fetch_method(spec)
  fetch_class(spec.klass).fetch_method(spec)
end

#fetch_methods(spec) ⇒ Object


373
374
375
# File 'lib/bitclust/methoddatabase.rb', line 373

def fetch_methods(spec)
  fetch_class(spec.klass).fetch_methods(spec)
end

#get_class(name) ⇒ Object

get a class entry if it exists, or create a new class entry object if it doesn't exist.


275
276
277
278
279
280
281
282
283
# File 'lib/bitclust/methoddatabase.rb', line 275

def get_class(name)
  if id = intern_classname(name)
    load_class(id) or
        raise "must not happen: #{name.inspect}, #{id.inspect}"
  else
    id = classname2id(name)
    @classmap[id] ||= ClassEntry.new(self, id)
  end
end

#get_doc(name) ⇒ Object


204
205
206
207
# File 'lib/bitclust/methoddatabase.rb', line 204

def get_doc(name)
  id = libname2id(name)
  docmap()[id] ||= DocEntry.new(self, id)
end

#get_library(name) ⇒ Object


227
228
229
230
# File 'lib/bitclust/methoddatabase.rb', line 227

def get_library(name)
  id = libname2id(name)
  librarymap()[id] ||= LibraryEntry.new(self, id)
end

#get_method(spec) ⇒ Object


369
370
371
# File 'lib/bitclust/methoddatabase.rb', line 369

def get_method(spec)
  get_class(spec.klass).get_method(spec)
end

#initObject


48
49
50
51
52
53
54
55
56
57
# File 'lib/bitclust/methoddatabase.rb', line 48

def init
  FileUtils.rm_rf @prefix
  FileUtils.mkdir_p @prefix
  Dir.mkdir "#{@prefix}/library"
  Dir.mkdir "#{@prefix}/class"
  Dir.mkdir "#{@prefix}/method"
  Dir.mkdir "#{@prefix}/doc"
  FileUtils.touch "#{@prefix}/properties"
  FileUtils.touch "#{@prefix}/refs"
end

#librariesObject

Library Entry


218
219
220
# File 'lib/bitclust/methoddatabase.rb', line 218

def libraries
  librarymap().values
end

#make_refsObject


168
169
170
171
172
173
174
175
# File 'lib/bitclust/methoddatabase.rb', line 168

def make_refs
  [classes, libraries, methods, docs].each do |es|
    es.each do |e|
      refs().extract(e)
    end
  end
  refs
end

#methodsObject


365
366
367
# File 'lib/bitclust/methoddatabase.rb', line 365

def methods
  classes().map {|c| c.entries }.flatten
end

#open_class(name) {|c| ... } ⇒ Object

Yields:

  • (c)

306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/bitclust/methoddatabase.rb', line 306

def open_class(name)
  check_transaction
  id = classname2id(name)
  if exist?("class/#{id}")
    c = load_class(id)
    c.clear
  else
    c = (@classmap[id] ||= ClassEntry.new(self, id))
  end
  yield c
  dirty_class c
  c
end

#open_library(name, reopen = false) ⇒ Object


242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/bitclust/methoddatabase.rb', line 242

def open_library(name, reopen = false)
  check_transaction
  map = librarymap()
  id = libname2id(name)
  if lib = map[id]
    lib.clear unless reopen
  else
    lib = (map[id] ||= LibraryEntry.new(self, id))
  end
  dirty_library lib
  lib
end

#open_method(id) {|m| ... } ⇒ Object

Return existing/newly created MethodEntry from the given MethodID

FIXME: see kind

Yields:

  • (m)

350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/bitclust/methoddatabase.rb', line 350

def open_method(id)
  check_transaction
  if m = id.klass.get_method(id)
    m.clear
  else
    m = MethodEntry.new(self, id.idstring)
    id.klass.add_method m
  end
  m.library = id.library
  m.klass   = id.klass
  yield m
  dirty_method m
  m
end

#search_classes(pattern) ⇒ Object


298
299
300
301
302
303
304
# File 'lib/bitclust/methoddatabase.rb', line 298

def search_classes(pattern)
  cs = _search_classes(pattern)
  if cs.empty?
    raise ClassNotFound, "no such class: #{pattern}"
  end
  cs
end

#search_method(pattern) ⇒ Object


381
382
383
# File 'lib/bitclust/methoddatabase.rb', line 381

def search_method(pattern)
  search_methods(pattern).first
end

#search_methods(pattern) ⇒ Object


385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/bitclust/methoddatabase.rb', line 385

def search_methods(pattern)
  result = _search_methods(pattern)
  if result.fail?
    if result.classes.empty?
      loc = pattern.klass ? pattern.klass + '.' : ''
      raise MethodNotFound, "no such method: #{loc}#{pattern.method}"
    end
    if result.classes.size <= 5
      loc = result.classes.map {|c| c.label }.join(', ')
    else
      loc = "#{result.classes.size} classes"
    end
    raise MethodNotFound, "no such method in #{loc}: #{pattern.method}"
  end
  result
end

#update_by_file(path, libname) ⇒ Object


159
160
161
162
# File 'lib/bitclust/methoddatabase.rb', line 159

def update_by_file(path, libname)
  check_transaction
  RRDParser.new(self).parse_file(path, libname, properties())
end

#update_by_stdlibtree(root) ⇒ Object


145
146
147
148
149
150
# File 'lib/bitclust/methoddatabase.rb', line 145

def update_by_stdlibtree(root)
  @root = root
  parse_LIBRARIES("#{root}/LIBRARIES", properties()).each do |libname|
    update_by_file "#{root}/#{libname}.rd", libname
  end
end

#update_requiresObject


130
131
132
133
134
# File 'lib/bitclust/methoddatabase.rb', line 130

def update_requires
  libraries.each{|lib|
    lib.requires = lib.all_requires
  }
end

#update_sublibrariesObject


136
137
138
139
140
141
142
143
# File 'lib/bitclust/methoddatabase.rb', line 136

def update_sublibraries
  libraries.each{|lib|
    re = /\A#{lib.name}\// 
    libraries.each{|l|
      lib.sublibrary(l) if re =~ l.name
    }
  }
end