Class: BitClust::ClassEntry

Inherits:
Entry show all
Includes:
Enumerable
Defined in:
lib/bitclust/classentry.rb

Overview

Represents a class, a module or a singleton object (like ARGF, main, etc.).

Defined Under Namespace

Classes: Parts

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 Entry

#detail_source, #encoding, #loaded?, persistent_properties, property, #synopsis_source, #type_id

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(db, id) ⇒ ClassEntry

Returns a new instance of ClassEntry.


24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/bitclust/classentry.rb', line 24

def initialize(db, id)
  super db
  @id = id
  if saved?
    @entries = nil
    @ancestors_checked = true
    @s_ancestors_checked = true
  else
    @entries = []
    @ancestors_checked = false
    @s_ancestors_checked = false
  end
  init_properties
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id


39
40
41
# File 'lib/bitclust/classentry.rb', line 39

def id
  @id
end

Class Method Details

.type_idObject


20
21
22
# File 'lib/bitclust/classentry.rb', line 20

def ClassEntry.type_id
  :class
end

Instance Method Details

#<=>(other) ⇒ Object


51
52
53
# File 'lib/bitclust/classentry.rb', line 51

def <=>(other)
  @id <=> other.id
end

#==(other) ⇒ Object Also known as: eql?


41
42
43
# File 'lib/bitclust/classentry.rb', line 41

def ==(other)
  @id == other.id
end

#_cmapObject

internal use only


410
411
412
# File 'lib/bitclust/classentry.rb', line 410

def _cmap
  @_cmap ||= makemap('c', included_modules(), constants())
end

#_imapObject

internal use only


405
406
407
# File 'lib/bitclust/classentry.rb', line 405

def _imap
  @_imap ||= makemap('i', included_modules(), instance_methods())
end

#_smapObject

internal use only


400
401
402
# File 'lib/bitclust/classentry.rb', line 400

def _smap
  @_smap ||= makemap('s', extended_modules(), singleton_methods())
end

#add_method(m) ⇒ Object


240
241
242
243
# File 'lib/bitclust/classentry.rb', line 240

def add_method(m)
  # FIXME: check duplication?
  entries().push m
end

#alias(c) ⇒ Object

Add a alias c to the alias list.


166
167
168
# File 'lib/bitclust/classentry.rb', line 166

def alias(c)
  aliases().push c
end

#alias?Boolean

Returns:

  • (Boolean)

127
128
129
# File 'lib/bitclust/classentry.rb', line 127

def alias?
  !! aliasof()
end

#ancestorsObject


210
211
212
213
214
# File 'lib/bitclust/classentry.rb', line 210

def ancestors
  @ancestors ||=
      [ self, included().map {|m| m.ancestors },
        superclass() ? superclass().ancestors : [] ].flatten
end

#check_ancestor_typeObject


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/bitclust/classentry.rb', line 170

def check_ancestor_type
  s = superclass()
  if s and not s.class? and not s.dummy?
    raise InvalidAncestor, "#{name()} inherits #{s.name} but it is a #{s.type} (class expected)"
  end
  included().each do |c|
    unless c.module? or c.dummy?
      raise InvalidAncestor, "#{name()} includes #{c.name} but it is a #{c.type} (module expected)"
    end
  end
  extended().each do |c|
    unless c.module? or c.dummy?
      raise InvalidAncestor, "#{name()} extends #{c.name} but it is a #{c.type} (module expected)"
    end
  end
end

187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/bitclust/classentry.rb', line 187

def check_ancestors_link(path = [])
  return if @ancestors_checked
  if path.include?(name())
    raise InvalidLink, "ancestor link looped: #{path_string(path)}"
  end
  ([superclass()] + included()).compact.each do |c|
    path.push name()
    c.check_ancestors_link path
    path.pop
  end
  @ancestors_checked = true
end

200
201
202
203
204
205
206
207
208
# File 'lib/bitclust/classentry.rb', line 200

def check_singleton_ancestors_link(path = [])
  return if @s_ancestors_checked
  extended().each do |c|
    path.push name()
    c.check_singleton_ancestors_link path
    path.pop
  end
  @s_ancestors_checked = true
end

#class?Boolean

Returns:

  • (Boolean)

115
116
117
# File 'lib/bitclust/classentry.rb', line 115

def class?
  type() == :class
end

#clear_cacheObject


395
396
397
# File 'lib/bitclust/classentry.rb', line 395

def clear_cache
  @_smap = @_imap = @_cmap = nil
end

#constant?(name, inherit = true) ⇒ Boolean

Returns:

  • (Boolean)

337
338
339
340
341
342
343
# File 'lib/bitclust/classentry.rb', line 337

def constant?(name, inherit = true)
  if inherit
    ancestors().any? {|c| c.constant?(name, false) }
  else
    constants(false).detect {|m| m.name?(name) }
  end
end

#constant_namesObject


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

def constant_names
  _index().keys.select {|name| /\A\:/ =~ name }.map {|name| name[1..-1] }
end

#constants(level = 0) ⇒ Object


313
314
315
# File 'lib/bitclust/classentry.rb', line 313

def constants(level = 0)
  entries(level).select {|m| m.constant? }.sort_by {|entry| entry.sort_key }
end

#dummy?Boolean

Returns:

  • (Boolean)

111
112
113
# File 'lib/bitclust/classentry.rb', line 111

def dummy?
  not type()
end

#dynamic_extend(m, lib) ⇒ Object

Add a module m to the dynamically extended module list.


157
158
159
160
161
162
163
# File 'lib/bitclust/classentry.rb', line 157

def dynamic_extend(m, lib)
  if m.library != lib
    message = "dynamically extended module #{m.name} should be defined in the module #{lib.name}"
    raise InvalidLibrary, message
  end
  dynamically_extended().push m
end

#dynamic_include(m, lib) ⇒ Object

Add a module m to the dynamically included module list.


148
149
150
151
152
153
154
# File 'lib/bitclust/classentry.rb', line 148

def dynamic_include(m, lib)
  if m.library != lib
    message = "dynamically included module #{m.name} should be defined in the module #{lib.name}"
    raise InvalidLibrary, message
  end
  dynamically_included().push m
end

#each(&block) ⇒ Object


236
237
238
# File 'lib/bitclust/classentry.rb', line 236

def each(&block)
  entries().each(&block)
end

#entries(level = 0) ⇒ Object Also known as: methods


226
227
228
229
230
231
232
# File 'lib/bitclust/classentry.rb', line 226

def entries(level = 0)
  @entries ||= @db.entries("method/#{@id}")\
      .map {|ent| MethodEntry.new(@db, "#{@id}/#{ent}") }
  ret = @entries
  ancestors[1..level].each{|c| ret += c.entries }
  ret
end

#error_class?Boolean

Returns:

  • (Boolean)

131
132
133
134
135
136
137
# File 'lib/bitclust/classentry.rb', line 131

def error_class?
  if alias?
    aliasof.error_class?
  else
    ancestors.any?{|k| k.name == 'Exception' }
  end
end

#extend(m) ⇒ Object


143
144
145
# File 'lib/bitclust/classentry.rb', line 143

def extend(m)
  extended().push m
end

#extended_modulesObject


222
223
224
# File 'lib/bitclust/classentry.rb', line 222

def extended_modules
  ancestors().select {|c| c.class? }.map {|c| c.extended }.flatten
end

#fetch_method(spec) ⇒ Object


362
363
364
365
# File 'lib/bitclust/classentry.rb', line 362

def fetch_method(spec)
  get_method(spec) or
      raise MethodNotFound, "no such method: #{spec}"
end

#fetch_methods(spec) ⇒ Object


357
358
359
360
# File 'lib/bitclust/classentry.rb', line 357

def fetch_methods(spec)
  get_methods(spec) or
      raise MethodNotFound, "no such method: #{spec}"
end

#get_method(spec) ⇒ Object


353
354
355
# File 'lib/bitclust/classentry.rb', line 353

def get_method(spec)
  entries().detect {|m| spec.match?(m) }
end

#get_methods(spec) ⇒ Object


349
350
351
# File 'lib/bitclust/classentry.rb', line 349

def get_methods(spec)
  entries().select {|m| spec.match?(m) }
end

#hashObject


47
48
49
# File 'lib/bitclust/classentry.rb', line 47

def hash
  @id.hash
end

#include(m) ⇒ Object


139
140
141
# File 'lib/bitclust/classentry.rb', line 139

def include(m)
  included().push m
end

#included_modulesObject


216
217
218
219
220
# File 'lib/bitclust/classentry.rb', line 216

def included_modules
  list = ancestors().select {|c| c.module? }
  list.delete self
  list
end

#inherited_method_specsObject


389
390
391
392
393
# File 'lib/bitclust/classentry.rb', line 389

def inherited_method_specs
  cname = name()
  _index().map {|mname, specstr| MethodSpec.parse(specstr) }\
      .reject {|spec| spec.klass == cname }.uniq
end

#inspectObject


107
108
109
# File 'lib/bitclust/classentry.rb', line 107

def inspect
  "\#<#{type()} #{@id}>"
end

#instance_method?(name, inherit = true) ⇒ Boolean

Returns:

  • (Boolean)

329
330
331
332
333
334
335
# File 'lib/bitclust/classentry.rb', line 329

def instance_method?(name, inherit = true)
  if inherit
    _imap().key?(name)
  else
    instance_methods(false).detect {|m| m.name?(name) }
  end
end

#instance_method_namesObject


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

def instance_method_names
  _index().keys.select {|name| /\A\#/ =~ name }.map {|name| name[1..-1] }
end

#instance_methods(level = 0) ⇒ Object


291
292
293
294
# File 'lib/bitclust/classentry.rb', line 291

def instance_methods(level = 0)
  # FIXME: inheritance
  entries(level).select {|m| m.instance_method? }.sort_by {|entry| entry.sort_key }
end

#labelsObject

FIXME: implement class alias


75
76
77
# File 'lib/bitclust/classentry.rb', line 75

def labels
  [label()]
end

#match_entry(t, mname) ⇒ Object

internal use only


368
369
370
# File 'lib/bitclust/classentry.rb', line 368

def match_entry(t, mname)
  _index()[t + mname]
end

#module?Boolean

Returns:

  • (Boolean)

119
120
121
# File 'lib/bitclust/classentry.rb', line 119

def module?
  type() == :module
end

#nameObject Also known as: label


55
56
57
# File 'lib/bitclust/classentry.rb', line 55

def name
  classid2name(@id)
end

#name?(n) ⇒ Boolean

Returns:

  • (Boolean)

59
60
61
# File 'lib/bitclust/classentry.rb', line 59

def name?(n)
  name() == n
end

#name_match?(re) ⇒ Boolean

Returns:

  • (Boolean)

68
69
70
# File 'lib/bitclust/classentry.rb', line 68

def name_match?(re)
  re =~ name()
end

#object?Boolean

Returns:

  • (Boolean)

123
124
125
# File 'lib/bitclust/classentry.rb', line 123

def object?
  type() == :object
end

#orig_superclassObject

FIXME: do not use superclass property aliasing (#6826)


93
# File 'lib/bitclust/classentry.rb', line 93

alias orig_superclass superclass

#partitioned_entries(level = 0) ⇒ Object


251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/bitclust/classentry.rb', line 251

def partitioned_entries(level = 0)
  s = []; spv = []
  i = []; ipv = []
  mf = []
  c = []; v = []
  added = []
  entries(level).sort_by{|e| e.name}.each do |m|
    case m.kind
    when :defined, :redefined
      case m.type
      when :singleton_method
        (m.public? ? s : spv).push m
      when :instance_method
        (m.public? ? i : ipv).push m
      when :module_function
        mf.push m
      when :constant
        c.push m
      when :special_variable
        v.push m
      else
        raise "must not happen: m.type=#{m.type.inspect} (#{m.inspect})"
      end
    when :added
      added.push m
    end
  end
  Parts.new(s,spv, i,ipv, mf, c, v, added)
end

#private_instance_methods(level = 0) ⇒ Object Also known as: private_methods


306
307
308
309
# File 'lib/bitclust/classentry.rb', line 306

def private_instance_methods(level = 0)
  # FIXME: inheritance
  entries(level).select {|m| m.private_instance_method? }.sort_by {|entry| entry.sort_key }
end

#private_singleton_methods(level = 0) ⇒ Object


296
297
298
299
# File 'lib/bitclust/classentry.rb', line 296

def private_singleton_methods(level = 0)
  # FIXME: inheritance
  entries(level).select {|m| m.private_singleton_method? }.sort_by {|entry| entry.sort_key }
end

#public_instance_methods(level = 0) ⇒ Object


301
302
303
304
# File 'lib/bitclust/classentry.rb', line 301

def public_instance_methods(level = 0)
  # FIXME: inheritance
  entries(level).select {|m| m.public_instance_method? }.sort_by {|entry| entry.sort_key }
end

#public_singleton_methods(level = 0) ⇒ Object


286
287
288
289
# File 'lib/bitclust/classentry.rb', line 286

def public_singleton_methods(level = 0)
  # FIXME: inheritance
  entries(level).select {|m| m.public_singleton_method? }.sort_by {|entry| entry.sort_key }
end

#realnameObject

Return the real class name


64
65
66
# File 'lib/bitclust/classentry.rb', line 64

def realname
  alias? ? aliasof.name : name
end

#saveObject


102
103
104
105
# File 'lib/bitclust/classentry.rb', line 102

def save
  super
  save_index
end

#singleton_method?(name, inherit = true) ⇒ Boolean

Returns:

  • (Boolean)

321
322
323
324
325
326
327
# File 'lib/bitclust/classentry.rb', line 321

def singleton_method?(name, inherit = true)
  if inherit
    _smap().key?(name)
  else
    singleton_methods(false).detect {|m| m.name?(name) }
  end
end

#singleton_method_namesObject


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

def singleton_method_names
  # should remove module functions?
  _index().keys.select {|name| /\A\./ =~ name }.map {|name| name[1..-1] }
end

#singleton_methods(level = 0) ⇒ Object


281
282
283
284
# File 'lib/bitclust/classentry.rb', line 281

def singleton_methods(level = 0)
  # FIXME: inheritance
  entries(level).select {|m| m.singleton_method? }.sort_by {|entry| entry.sort_key }
end

#special_variable?(name) ⇒ Boolean

Returns:

  • (Boolean)

345
346
347
# File 'lib/bitclust/classentry.rb', line 345

def special_variable?(name)
  special_variables().detect {|m| m.name?(name) }
end

#special_variable_namesObject


385
386
387
# File 'lib/bitclust/classentry.rb', line 385

def special_variable_names
  special_variables().map {|m| m.names }.flatten
end

#special_variablesObject


317
318
319
# File 'lib/bitclust/classentry.rb', line 317

def special_variables
  entries().select {|m| m.special_variable? }.sort_by {|entry| entry.sort_key }
end

#superclassObject


94
95
96
97
98
99
100
# File 'lib/bitclust/classentry.rb', line 94

def superclass
  if alias?
    aliasof.superclass
  else
    orig_superclass
  end
end