class RDoc::ClassModule

ClassModule 是表示类或模块的对象的基类。

属性

comment_location[RW]

注释及其来源位置。使用 add_comment 添加注释

constant_aliases[RW]

此类或模块的别名常量

is_alias_for[RW]

此常量为其别名的类或模块

公共类方法

from_module(class_type, mod) 点击以切换源代码

返回一个 class_type 类的 RDoc::ClassModule,它是模块 module 的副本。用于将模块提升为类。

# File rdoc/code_object/class_module.rb, line 50
def self.from_module class_type, mod
  klass = class_type.new mod.name

  mod.comment_location.each do |comment, location|
    klass.add_comment comment, location
  end

  klass.parent = mod.parent
  klass.section = mod.section
  klass.viewer = mod.viewer

  klass.attributes.concat mod.attributes
  klass.method_list.concat mod.method_list
  klass.aliases.concat mod.aliases
  klass.external_aliases.concat mod.external_aliases
  klass.constants.concat mod.constants
  klass.includes.concat mod.includes
  klass.extends.concat mod.extends

  klass.methods_hash.update mod.methods_hash
  klass.constants_hash.update mod.constants_hash

  klass.current_section = mod.current_section
  klass.in_files.concat mod.in_files
  klass.sections.concat mod.sections
  klass.unmatched_alias_lists = mod.unmatched_alias_lists
  klass.current_section = mod.current_section
  klass.visibility = mod.visibility

  klass.classes_hash.update mod.classes_hash
  klass.modules_hash.update mod.modules_hash
  klass.metadata.update mod.metadata

  klass.document_self = mod.received_nodoc ? nil : mod.document_self
  klass.document_children = mod.document_children
  klass.force_documentation = mod.force_documentation
  klass.done_documenting = mod.done_documenting

  # update the parent of all children

  (klass.attributes +
   klass.method_list +
   klass.aliases +
   klass.external_aliases +
   klass.constants +
   klass.includes +
   klass.extends +
   klass.classes +
   klass.modules).each do |obj|
    obj.parent = klass
    obj.full_name = nil
  end

  klass
end
new(name, superclass = nil) 点击以切换源代码

使用 name 创建一个新的 ClassModule,并可选择指定 superclass

这是子类的构造函数,绝不能直接调用。

调用超类方法 RDoc::Context::new
# File rdoc/code_object/class_module.rb, line 111
def initialize(name, superclass = nil)
  @constant_aliases = []
  @diagram          = nil
  @is_alias_for     = nil
  @name             = name
  @superclass       = superclass
  @comment_location = [] # [[comment, location]]

  super()
end

公共实例方法

add_comment(comment, location) 点击以切换源代码

locationcomment 添加到此 ClassModule 的注释列表中。此方法优先于 comment=,因为它允许在多次运行中更新 ri 数据。

# File rdoc/code_object/class_module.rb, line 127
def add_comment comment, location
  return unless document_self

  original = comment

  comment = case comment
            when RDoc::Comment then
              comment.normalize
            else
              normalize_comment comment
            end

  if location.parser == RDoc::Parser::C
    @comment_location.delete_if { |(_, l)| l == location }
  end

  @comment_location << [comment, location]

  self.comment = original
end
ancestors() 点击以切换源代码

此 ClassModule 的祖先列表:包含的模块列表(类将添加其超类,如果有的话)。

返回包含的类或模块,而不是 include 本身。返回的值要么是 String,要么是 RDoc::NormalModule 实例(请参阅 RDoc::Include#module)。

这些值按其包含的相反顺序返回,这适合在祖先中搜索方法/属性的顺序。超类(如果有)最后出现。

# File rdoc/code_object/class_module.rb, line 171
def ancestors
  includes.map { |i| i.module }.reverse
end
别名为:direct_ancestors
aref() 点击以切换源代码

此模块或类的 HTML 片段引用。请参阅 RDoc::NormalClass#arefRDoc::NormalModule#aref

# File rdoc/code_object/class_module.rb, line 183
def aref
  "#{aref_prefix}-#{full_name}"
end
clear_comment() 点击以切换源代码

清除注释。由 Ruby 解析器使用。

# File rdoc/code_object/class_module.rb, line 195
def clear_comment
  @comment = ''
end
complete(min_visibility) 点击以切换源代码

准备此 ClassModule 以供生成器使用。

请参阅 RDoc::Store#complete

# File rdoc/code_object/class_module.rb, line 223
def complete min_visibility
  update_aliases
  remove_nodoc_children
  embed_mixins
  update_includes
  remove_invisible min_visibility
end
description() 点击以切换源代码

用于标记此类或模块的注释的便捷包装器

# File rdoc/generator/markup.rb, line 131
def description
  markup @comment_location
end
direct_ancestors()

仅限此类的或模块的祖先

别名为:ancestors
document_self_or_methods() 点击以切换源代码

ClassModule 或其任何方法是否设置了 document_self?

# File rdoc/code_object/class_module.rb, line 234
def document_self_or_methods
  document_self || method_list.any?{ |m| m.document_self }
end
documented?() 点击以切换源代码

此类或模块是否具有带内容的注释,或者 received_nodoc 是否为 true?

# File rdoc/code_object/class_module.rb, line 242
def documented?
  return true if @received_nodoc
  return false if @comment_location.empty?
  @comment_location.any? { |comment, _| not comment.empty? }
end
each_ancestor() { |module| ... } 点击以切换源代码

迭代此存在 RDoc::ClassModule 的类或模块的祖先。

# File rdoc/code_object/class_module.rb, line 252
def each_ancestor # :yields: module
  return enum_for __method__ unless block_given?

  ancestors.each do |mod|
    next if String === mod
    next if self == mod
    yield mod
  end
end
embed_mixins() 点击以切换源代码
# File rdoc/code_object/class_module.rb, line 829
def embed_mixins
  return unless options.embed_mixins

  includes.each do |include|
    next if String === include.module
    include.module.method_list.each do |code_object|
      add_method(prepare_to_embed(code_object))
    end
    include.module.constants.each do |code_object|
      add_constant(prepare_to_embed(code_object))
    end
    include.module.attributes.each do |code_object|
      add_attribute(prepare_to_embed(code_object))
    end
  end

  extends.each do |ext|
    next if String === ext.module
    ext.module.method_list.each do |code_object|
      add_method(prepare_to_embed(code_object, true))
    end
    ext.module.attributes.each do |code_object|
      add_attribute(prepare_to_embed(code_object, true))
    end
  end
end
find_ancestor_local_symbol(symbol) 点击以切换源代码

ancestors 中查找符号。请参阅 Context#find_local_symbol。

# File rdoc/code_object/class_module.rb, line 265
def find_ancestor_local_symbol symbol
  each_ancestor do |m|
    res = m.find_local_symbol(symbol)
    return res if res
  end

  nil
end
find_class_named(name) 点击以切换源代码

在此命名空间或其后代中查找名为 name 的类或模块

# File rdoc/code_object/class_module.rb, line 277
def find_class_named name
  return self if full_name == name
  return self if @name == name

  @classes.values.find do |klass|
    next if klass == self
    klass.find_class_named name
  end
end
full_name() 点击以切换源代码

返回此类或模块的完全限定名称

# File rdoc/code_object/class_module.rb, line 290
def full_name
  @full_name ||= if RDoc::ClassModule === parent then
                   "#{parent.full_name}::#{@name}"
                 else
                   @name
                 end
end
merge(class_module) 点击以切换源代码

class_module 合并到此 ClassModule 中。

class_module 中的数据优先于接收器。

# File rdoc/code_object/class_module.rb, line 436
def merge class_module
  @parent      = class_module.parent
  @parent_name = class_module.parent_name

  other_document = parse class_module.comment_location

  if other_document then
    document = parse @comment_location

    document = document.merge other_document

    @comment = @comment_location = document
  end

  cm = class_module
  other_files = cm.in_files

  merge_collections attributes, cm.attributes, other_files do |add, attr|
    if add then
      add_attribute attr
    else
      @attributes.delete attr
      @methods_hash.delete attr.pretty_name
    end
  end

  merge_collections constants, cm.constants, other_files do |add, const|
    if add then
      add_constant const
    else
      @constants.delete const
      @constants_hash.delete const.name
    end
  end

  merge_collections includes, cm.includes, other_files do |add, incl|
    if add then
      add_include incl
    else
      @includes.delete incl
    end
  end

  @includes.uniq! # clean up

  merge_collections extends, cm.extends, other_files do |add, ext|
    if add then
      add_extend ext
    else
      @extends.delete ext
    end
  end

  @extends.uniq! # clean up

  merge_collections method_list, cm.method_list, other_files do |add, meth|
    if add then
      add_method meth
    else
      @method_list.delete meth
      @methods_hash.delete meth.pretty_name
    end
  end

  merge_sections cm

  self
end
module?() 点击以切换源代码

此对象是否表示模块?

# File rdoc/code_object/class_module.rb, line 571
def module?
  false
end
name=(new_name) 点击以切换源代码

允许覆盖初始名称。

用于作为常量别名的模块和类。

# File rdoc/code_object/class_module.rb, line 580
def name= new_name
  @name = new_name
end
name_for_path() 点击以切换源代码

用于生成 URL 的名称:作为另一个模块或类的别名的模块和类返回后者的名称。

# File rdoc/code_object/class_module.rb, line 623
def name_for_path
  is_alias_for ? is_alias_for.full_name : full_name
end
non_aliases() 点击以切换源代码

返回不是常量别名另一个类或模块的类和模块。仅供格式化程序使用(缓存其结果)。

# File rdoc/code_object/class_module.rb, line 632
def non_aliases
  @non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for }
end
parse(comment_location) 点击以切换源代码

comment_location 解析为由多个 RDoc::Markup::Documents 组成的 RDoc::Markup::Document,并设置它们的文件。

调用超类方法 RDoc::Text#parse
# File rdoc/code_object/class_module.rb, line 588
def parse comment_location
  case comment_location
  when String then
    super
  when Array then
    docs = comment_location.map do |comment, location|
      doc = super comment
      doc.file = location
      doc
    end

    RDoc::Markup::Document.new(*docs)
  when RDoc::Comment then
    doc = super comment_location.text, comment_location.format
    doc.file = comment_location.location
    doc
  when RDoc::Markup::Document then
    return comment_location
  else
    raise ArgumentError, "unknown comment class #{comment_location.class}"
  end
end
path() 点击以切换源代码

用于 HTML 生成器输出的此类或模块的路径。

# File rdoc/code_object/class_module.rb, line 614
def path
  http_url @store.rdoc.generator.class_dir
end
remove_nodoc_children() 点击以切换源代码

通过删除已从文档中删除的子模块或类来更新类/模块 parent 的子模块或类。

parent_hash 要么是 parent.modules_hash,要么是 parent.classes_hash,而 all_hash 是 ::all_modules_hash 或 ::all_classes_hash。

# File rdoc/code_object/class_module.rb, line 644
def remove_nodoc_children
  prefix = self.full_name + '::'

  modules_hash.each_key do |name|
    full_name = prefix + name
    modules_hash.delete name unless @store.modules_hash[full_name]
  end

  classes_hash.each_key do |name|
    full_name = prefix + name
    classes_hash.delete name unless @store.classes_hash[full_name]
  end
end
search_record() 点击以切换源代码

RDoc::Generator::JsonIndex 使用的搜索记录

# File rdoc/code_object/class_module.rb, line 673
def search_record
  [
    name,
    full_name,
    full_name,
    '',
    path,
    '',
    snippet(@comment_location),
  ]
end
store=(store) 点击以切换源代码

设置此类或模块及其包含的代码对象的存储。

调用超类方法 RDoc::CodeObject#store=
# File rdoc/code_object/class_module.rb, line 688
def store= store
  super

  @attributes .each do |attr|  attr.store  = store end
  @constants  .each do |const| const.store = store end
  @includes   .each do |incl|  incl.store  = store end
  @extends    .each do |ext|   ext.store   = store end
  @method_list.each do |meth|  meth.store  = store end
end
super_classes() 点击以切换源代码

获取此类的所有超类并放入数组中。如果名称未知,则最后一个元素可能是字符串。

# File rdoc/code_object/class_module.rb, line 731
def super_classes
  result = []
  parent = self
  while parent = parent.superclass
    result << parent
    return result if parent.is_a?(String)
  end
  result
end
superclass() 点击以切换源代码

获取此类的超类。尝试检索超类对象,如果未知则返回名称。

# File rdoc/code_object/class_module.rb, line 702
def superclass
  @store.find_class_named(@superclass) || @superclass
end
superclass=(superclass) 点击以切换源代码

将此类的超类设置为 superclass

其中 superclass 是以下之一

# File rdoc/code_object/class_module.rb, line 715
def superclass=(superclass)
  raise NoMethodError, "#{full_name} is a module" if module?
  case superclass
  when RDoc::ClassModule
    @superclass = superclass.full_name
  when nil, String
    @superclass = superclass
  else
    raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}"
  end
end
type() 点击以切换源代码

“module”或“class”

# File rdoc/code_object/class_module.rb, line 752
def type
  module? ? 'module' : 'class'
end
update_aliases() 点击以切换源代码

通过替换通过常量作为别名的子模块和类来更新它们。

别名的模块/类在子项和 RDoc::Store#modules_hashRDoc::Store#classes_hash 中被替换为一个 RDoc::ClassModule#is_alias_for 设置为别名模块/类的副本,此副本被添加到别名模块/类的 #aliases 中。

格式化程序可以使用 non_aliases 方法来检索非别名的子项,例如列出命名空间内容,因为别名模块包含在类/模块的常量中,这些常量是单独列出的。

# File rdoc/code_object/class_module.rb, line 771
def update_aliases
  constants.each do |const|
    next unless cm = const.is_alias_for
    cm_alias = cm.dup
    cm_alias.name = const.name

    # Don't move top-level aliases under Object, they look ugly there
    unless RDoc::TopLevel === cm_alias.parent then
      cm_alias.parent = self
      cm_alias.full_name = nil # force update for new parent
    end

    cm_alias.aliases.clear
    cm_alias.is_alias_for = cm

    if cm.module? then
      @store.modules_hash[cm_alias.full_name] = cm_alias
      modules_hash[const.name] = cm_alias
    else
      @store.classes_hash[cm_alias.full_name] = cm_alias
      classes_hash[const.name] = cm_alias
    end

    cm.aliases << cm_alias
  end
end
update_extends() 点击以切换源代码

extends 中删除模块已从文档中删除的项。

# File rdoc/code_object/class_module.rb, line 819
def update_extends
  extends.reject! do |ext|
    mod = ext.module

    !(String === mod) && @store.modules_hash[mod.full_name].nil?
  end

  extends.uniq!
end
update_includes() 点击以切换源代码

includes 中删除模块已从文档中删除的项。

# File rdoc/code_object/class_module.rb, line 804
def update_includes
  includes.reject! do |include|
    mod = include.module
    !(String === mod) && @store.modules_hash[mod.full_name].nil?
  end

  includes.uniq!
end

私有实例方法

prepare_to_embed(code_object, singleton=false) 点击以切换源代码
# File rdoc/code_object/class_module.rb, line 858
def prepare_to_embed(code_object, singleton=false)
  code_object = code_object.dup
  code_object.mixin_from = code_object.parent
  code_object.singleton = true if singleton
  set_current_section(code_object.section.title, code_object.section.comment)
  # add_method and add_attribute will reassign self's visibility back to the method/attribute
  # so we need to sync self's visibility with the object's to properly retain that information
  self.visibility = code_object.visibility
  code_object
end