Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 88
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 215
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 216
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 217
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 218
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 219
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 220
PK ! !
anon_class.rbnu [ # frozen_string_literal: true
##
# An anonymous class like:
#
# c = Class.new do end
#
# AnonClass is currently not used.
class RDoc::AnonClass < RDoc::ClassModule
end
PK ! G^
require.rbnu [ # frozen_string_literal: true
##
# A file loaded by \#require
class RDoc::Require < RDoc::CodeObject
##
# Name of the required file
attr_accessor :name
##
# Creates a new Require that loads +name+ with +comment+
def initialize(name, comment)
super()
@name = name.gsub(/'|"/, "") #'
@top_level = nil
self.comment = comment
end
def inspect # :nodoc:
"#<%s:0x%x require '%s' in %s>" % [
self.class,
object_id,
@name,
@parent ? @parent.base_name : '(unknown)'
]
end
def to_s # :nodoc:
"require #{name} in: #{parent}"
end
##
# The RDoc::TopLevel corresponding to this require, or +nil+ if not found.
def top_level
@top_level ||= begin
tl = RDoc::TopLevel.all_files_hash[name + '.rb']
if tl.nil? and RDoc::TopLevel.all_files.first.full_name =~ %r(^lib/) then
# second chance
tl = RDoc::TopLevel.all_files_hash['lib/' + name + '.rb']
end
tl
end
end
end
PK ! Ϸ5 mixin.rbnu [ # frozen_string_literal: true
##
# A Mixin adds features from a module into another context. RDoc::Include and
# RDoc::Extend are both mixins.
class RDoc::Mixin < RDoc::CodeObject
##
# Name of included module
attr_accessor :name
##
# Creates a new Mixin for +name+ with +comment+
def initialize(name, comment)
super()
@name = name
self.comment = comment
@module = nil # cache for module if found
end
##
# Mixins are sorted by name
def <=>(other)
return unless self.class === other
name <=> other.name
end
def ==(other) # :nodoc:
self.class === other and @name == other.name
end
alias eql? == # :nodoc:
##
# Full name based on #module
def full_name
m = self.module
RDoc::ClassModule === m ? m.full_name : @name
end
def hash # :nodoc:
[@name, self.module].hash
end
def inspect # :nodoc:
"#<%s:0x%x %s.%s %s>" % [
self.class,
object_id,
parent_name, self.class.name.downcase, @name,
]
end
##
# Attempts to locate the included module object. Returns the name if not
# known.
#
# The scoping rules of Ruby to resolve the name of an included module are:
# - first look into the children of the current context;
# - if not found, look into the children of included modules,
# in reverse inclusion order;
# - if still not found, go up the hierarchy of names.
#
# This method has O(n!) behavior when the module calling
# include is referencing nonexistent modules. Avoid calling #module until
# after all the files are parsed. This behavior is due to ruby's constant
# lookup behavior.
#
# As of the beginning of October, 2011, no gem includes nonexistent modules.
def module
return @module if @module
# search the current context
return @name unless parent
full_name = parent.child_name(@name)
@module = @store.modules_hash[full_name]
return @module if @module
return @name if @name =~ /^::/
# search the includes before this one, in reverse order
searched = parent.includes.take_while { |i| i != self }.reverse
searched.each do |i|
inc = i.module
next if String === inc
full_name = inc.child_name(@name)
@module = @store.modules_hash[full_name]
return @module if @module
end
# go up the hierarchy of names
up = parent.parent
while up
full_name = up.child_name(@name)
@module = @store.modules_hash[full_name]
return @module if @module
up = up.parent
end
@name
end
##
# Sets the store for this class or module and its contained code objects.
def store=(store)
super
@file = @store.add_file @file.full_name if @file
end
def to_s # :nodoc:
"#{self.class.name.downcase} #@name in: #{parent}"
end
end
PK !
eOPv Pv
context.rbnu [ # frozen_string_literal: true
##
# A Context is something that can hold modules, classes, methods, attributes,
# aliases, requires, and includes. Classes, modules, and files are all
# Contexts.
class RDoc::Context < RDoc::CodeObject
include Comparable
##
# Types of methods
TYPES = %w[class instance]
##
# If a context has these titles it will be sorted in this order.
TOMDOC_TITLES = [nil, 'Public', 'Internal', 'Deprecated'] # :nodoc:
TOMDOC_TITLES_SORT = TOMDOC_TITLES.sort_by { |title| title.to_s } # :nodoc:
##
# Class/module aliases
attr_reader :aliases
##
# All attr* methods
attr_reader :attributes
##
# Block params to be used in the next MethodAttr parsed under this context
attr_accessor :block_params
##
# Constants defined
attr_reader :constants
##
# Sets the current documentation section of documentation
attr_writer :current_section
##
# Files this context is found in
attr_reader :in_files
##
# Modules this context includes
attr_reader :includes
##
# Modules this context is extended with
attr_reader :extends
##
# Methods defined in this context
attr_reader :method_list
##
# Name of this class excluding namespace. See also full_name
attr_reader :name
##
# Files this context requires
attr_reader :requires
##
# Use this section for the next method, attribute or constant added.
attr_accessor :temporary_section
##
# Hash old_name => [aliases], for aliases
# that haven't (yet) been resolved to a method/attribute.
# (Not to be confused with the aliases of the context.)
attr_accessor :unmatched_alias_lists
##
# Aliases that could not be resolved.
attr_reader :external_aliases
##
# Current visibility of this context
attr_accessor :visibility
##
# Current visibility of this line
attr_writer :current_line_visibility
##
# Hash of registered methods. Attributes are also registered here,
# twice if they are RW.
attr_reader :methods_hash
##
# Params to be used in the next MethodAttr parsed under this context
attr_accessor :params
##
# Hash of registered constants.
attr_reader :constants_hash
##
# Creates an unnamed empty context with public current visibility
def initialize
super
@in_files = []
@name ||= "unknown"
@parent = nil
@visibility = :public
@current_section = Section.new self, nil, nil
@sections = { nil => @current_section }
@temporary_section = nil
@classes = {}
@modules = {}
initialize_methods_etc
end
##
# Sets the defaults for methods and so-forth
def initialize_methods_etc
@method_list = []
@attributes = []
@aliases = []
@requires = []
@includes = []
@extends = []
@constants = []
@external_aliases = []
@current_line_visibility = nil
# This Hash maps a method name to a list of unmatched aliases (aliases of
# a method not yet encountered).
@unmatched_alias_lists = {}
@methods_hash = {}
@constants_hash = {}
@params = nil
@store ||= nil
end
##
# Contexts are sorted by full_name
def <=>(other)
return nil unless RDoc::CodeObject === other
full_name <=> other.full_name
end
##
# Adds an item of type +klass+ with the given +name+ and +comment+ to the
# context.
#
# Currently only RDoc::Extend and RDoc::Include are supported.
def add(klass, name, comment)
if RDoc::Extend == klass then
ext = RDoc::Extend.new name, comment
add_extend ext
elsif RDoc::Include == klass then
incl = RDoc::Include.new name, comment
add_include incl
else
raise NotImplementedError, "adding a #{klass} is not implemented"
end
end
##
# Adds +an_alias+ that is automatically resolved
def add_alias(an_alias)
return an_alias unless @document_self
method_attr = find_method(an_alias.old_name, an_alias.singleton) ||
find_attribute(an_alias.old_name, an_alias.singleton)
if method_attr then
method_attr.add_alias an_alias, self
else
add_to @external_aliases, an_alias
unmatched_alias_list =
@unmatched_alias_lists[an_alias.pretty_old_name] ||= []
unmatched_alias_list.push an_alias
end
an_alias
end
##
# Adds +attribute+ if not already there. If it is (as method(s) or attribute),
# updates the comment if it was empty.
#
# The attribute is registered only if it defines a new method.
# For instance, attr_reader :foo will not be registered
# if method +foo+ exists, but attr_accessor :foo will be registered
# if method +foo+ exists, but foo= does not.
def add_attribute(attribute)
return attribute unless @document_self
# mainly to check for redefinition of an attribute as a method
# TODO find a policy for 'attr_reader :foo' + 'def foo=()'
register = false
key = nil
if attribute.rw.index 'R' then
key = attribute.pretty_name
known = @methods_hash[key]
if known then
known.comment = attribute.comment if known.comment.empty?
elsif registered = @methods_hash[attribute.pretty_name + '='] and
RDoc::Attr === registered then
registered.rw = 'RW'
else
@methods_hash[key] = attribute
register = true
end
end
if attribute.rw.index 'W' then
key = attribute.pretty_name + '='
known = @methods_hash[key]
if known then
known.comment = attribute.comment if known.comment.empty?
elsif registered = @methods_hash[attribute.pretty_name] and
RDoc::Attr === registered then
registered.rw = 'RW'
else
@methods_hash[key] = attribute
register = true
end
end
if register then
attribute.visibility = @visibility
add_to @attributes, attribute
resolve_aliases attribute
end
attribute
end
##
# Adds a class named +given_name+ with +superclass+.
#
# Both +given_name+ and +superclass+ may contain '::', and are
# interpreted relative to the +self+ context. This allows handling correctly
# examples like these:
# class RDoc::Gauntlet < Gauntlet
# module Mod
# class Object # implies < ::Object
# class SubObject < Object # this is _not_ ::Object
#
# Given class Container::Item RDoc assumes +Container+ is a module
# unless it later sees class Container. +add_class+ automatically
# upgrades +given_name+ to a class in this case.
def add_class(class_type, given_name, superclass = '::Object')
# superclass +nil+ is passed by the C parser in the following cases:
# - registering Object in 1.8 (correct)
# - registering BasicObject in 1.9 (correct)
# - registering RubyVM in 1.9 in iseq.c (incorrect: < Object in vm.c)
#
# If we later find a superclass for a registered class with a nil
# superclass, we must honor it.
# find the name & enclosing context
if given_name =~ /^:+(\w+)$/ then
full_name = $1
enclosing = top_level
name = full_name.split(/:+/).last
else
full_name = child_name given_name
if full_name =~ /^(.+)::(\w+)$/ then
name = $2
ename = $1
enclosing = @store.classes_hash[ename] || @store.modules_hash[ename]
# HACK: crashes in actionpack/lib/action_view/helpers/form_helper.rb (metaprogramming)
unless enclosing then
# try the given name at top level (will work for the above example)
enclosing = @store.classes_hash[given_name] ||
@store.modules_hash[given_name]
return enclosing if enclosing
# not found: create the parent(s)
names = ename.split('::')
enclosing = self
names.each do |n|
enclosing = enclosing.classes_hash[n] ||
enclosing.modules_hash[n] ||
enclosing.add_module(RDoc::NormalModule, n)
end
end
else
name = full_name
enclosing = self
end
end
# fix up superclass
if full_name == 'BasicObject' then
superclass = nil
elsif full_name == 'Object' then
superclass = '::BasicObject'
end
# find the superclass full name
if superclass then
if superclass =~ /^:+/ then
superclass = $' #'
else
if superclass =~ /^(\w+):+(.+)$/ then
suffix = $2
mod = find_module_named($1)
superclass = mod.full_name + '::' + suffix if mod
else
mod = find_module_named(superclass)
superclass = mod.full_name if mod
end
end
# did we believe it was a module?
mod = @store.modules_hash.delete superclass
upgrade_to_class mod, RDoc::NormalClass, mod.parent if mod
# e.g., Object < Object
superclass = nil if superclass == full_name
end
klass = @store.classes_hash[full_name]
if klass then
# if TopLevel, it may not be registered in the classes:
enclosing.classes_hash[name] = klass
# update the superclass if needed
if superclass then
existing = klass.superclass
existing = existing.full_name unless existing.is_a?(String) if existing
if existing.nil? ||
(existing == 'Object' && superclass != 'Object') then
klass.superclass = superclass
end
end
else
# this is a new class
mod = @store.modules_hash.delete full_name
if mod then
klass = upgrade_to_class mod, RDoc::NormalClass, enclosing
klass.superclass = superclass unless superclass.nil?
else
klass = class_type.new name, superclass
enclosing.add_class_or_module(klass, enclosing.classes_hash,
@store.classes_hash)
end
end
klass.parent = self
klass
end
##
# Adds the class or module +mod+ to the modules or
# classes Hash +self_hash+, and to +all_hash+ (either
# TopLevel::modules_hash or TopLevel::classes_hash),
# unless #done_documenting is +true+. Sets the #parent of +mod+
# to +self+, and its #section to #current_section. Returns +mod+.
def add_class_or_module(mod, self_hash, all_hash)
mod.section = current_section # TODO declaring context? something is
# wrong here...
mod.parent = self
mod.full_name = nil
mod.store = @store
unless @done_documenting then
self_hash[mod.name] = mod
# this must be done AFTER adding mod to its parent, so that the full
# name is correct:
all_hash[mod.full_name] = mod
if @store.unmatched_constant_alias[mod.full_name] then
to, file = @store.unmatched_constant_alias[mod.full_name]
add_module_alias mod, mod.name, to, file
end
end
mod
end
##
# Adds +constant+ if not already there. If it is, updates the comment,
# value and/or is_alias_for of the known constant if they were empty/nil.
def add_constant(constant)
return constant unless @document_self
# HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code)
# (this is a #ifdef: should be handled by the C parser)
known = @constants_hash[constant.name]
if known then
known.comment = constant.comment if known.comment.empty?
known.value = constant.value if
known.value.nil? or known.value.strip.empty?
known.is_alias_for ||= constant.is_alias_for
else
@constants_hash[constant.name] = constant
add_to @constants, constant
end
constant
end
##
# Adds included module +include+ which should be an RDoc::Include
def add_include(include)
add_to @includes, include
include
end
##
# Adds extension module +ext+ which should be an RDoc::Extend
def add_extend(ext)
add_to @extends, ext
ext
end
##
# Adds +method+ if not already there. If it is (as method or attribute),
# updates the comment if it was empty.
def add_method(method)
return method unless @document_self
# HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code)
key = method.pretty_name
known = @methods_hash[key]
if known then
if @store then # otherwise we are loading
known.comment = method.comment if known.comment.empty?
previously = ", previously in #{known.file}" unless
method.file == known.file
@store.options.warn \
"Duplicate method #{known.full_name} in #{method.file}#{previously}"
end
else
@methods_hash[key] = method
if @current_line_visibility
method.visibility, @current_line_visibility = @current_line_visibility, nil
else
method.visibility = @visibility
end
add_to @method_list, method
resolve_aliases method
end
method
end
##
# Adds a module named +name+. If RDoc already knows +name+ is a class then
# that class is returned instead. See also #add_class.
def add_module(class_type, name)
mod = @classes[name] || @modules[name]
return mod if mod
full_name = child_name name
mod = @store.modules_hash[full_name] || class_type.new(name)
add_class_or_module mod, @modules, @store.modules_hash
end
##
# Adds a module by +RDoc::NormalModule+ instance. See also #add_module.
def add_module_by_normal_module(mod)
add_class_or_module mod, @modules, @store.modules_hash
end
##
# Adds an alias from +from+ (a class or module) to +name+ which was defined
# in +file+.
def add_module_alias(from, from_name, to, file)
return from if @done_documenting
to_full_name = child_name to.name
# if we already know this name, don't register an alias:
# see the metaprogramming in lib/active_support/basic_object.rb,
# where we already know BasicObject is a class when we find
# BasicObject = BlankSlate
return from if @store.find_class_or_module to_full_name
unless from
@store.unmatched_constant_alias[child_name(from_name)] = [to, file]
return to
end
new_to = from.dup
new_to.name = to.name
new_to.full_name = nil
if new_to.module? then
@store.modules_hash[to_full_name] = new_to
@modules[to.name] = new_to
else
@store.classes_hash[to_full_name] = new_to
@classes[to.name] = new_to
end
# Registers a constant for this alias. The constant value and comment
# will be updated later, when the Ruby parser adds the constant
const = RDoc::Constant.new to.name, nil, new_to.comment
const.record_location file
const.is_alias_for = from
add_constant const
new_to
end
##
# Adds +require+ to this context's top level
def add_require(require)
return require unless @document_self
if RDoc::TopLevel === self then
add_to @requires, require
else
parent.add_require require
end
end
##
# Returns a section with +title+, creating it if it doesn't already exist.
# +comment+ will be appended to the section's comment.
#
# A section with a +title+ of +nil+ will return the default section.
#
# See also RDoc::Context::Section
def add_section(title, comment = nil)
if section = @sections[title] then
section.add_comment comment if comment
else
section = Section.new self, title, comment
@sections[title] = section
end
section
end
##
# Adds +thing+ to the collection +array+
def add_to(array, thing)
array << thing if @document_self
thing.parent = self
thing.store = @store if @store
thing.section = current_section
end
##
# Is there any content?
#
# This means any of: comment, aliases, methods, attributes, external
# aliases, require, constant.
#
# Includes and extends are also checked unless includes == false.
def any_content(includes = true)
@any_content ||= !(
@comment.empty? &&
@method_list.empty? &&
@attributes.empty? &&
@aliases.empty? &&
@external_aliases.empty? &&
@requires.empty? &&
@constants.empty?
)
@any_content || (includes && !(@includes + @extends).empty? )
end
##
# Creates the full name for a child with +name+
def child_name(name)
if name =~ /^:+/
$' #'
elsif RDoc::TopLevel === self then
name
else
"#{self.full_name}::#{name}"
end
end
##
# Class attributes
def class_attributes
@class_attributes ||= attributes.select { |a| a.singleton }
end
##
# Class methods
def class_method_list
@class_method_list ||= method_list.select { |a| a.singleton }
end
##
# Array of classes in this context
def classes
@classes.values
end
##
# All classes and modules in this namespace
def classes_and_modules
classes + modules
end
##
# Hash of classes keyed by class name
def classes_hash
@classes
end
##
# The current documentation section that new items will be added to. If
# temporary_section is available it will be used.
def current_section
if section = @temporary_section then
@temporary_section = nil
else
section = @current_section
end
section
end
def display(method_attr) # :nodoc:
if method_attr.is_a? RDoc::Attr
"#{method_attr.definition} #{method_attr.pretty_name}"
else
"method #{method_attr.pretty_name}"
end
end
##
# Iterator for ancestors for duck-typing. Does nothing. See
# RDoc::ClassModule#each_ancestor.
#
# This method exists to make it easy to work with Context subclasses that
# aren't part of RDoc.
def each_ancestor(&_) # :nodoc:
end
##
# Iterator for classes and modules
def each_classmodule(&block) # :yields: module
classes_and_modules.sort.each(&block)
end
##
# Iterator for methods
def each_method # :yields: method
return enum_for __method__ unless block_given?
@method_list.sort.each { |m| yield m }
end
##
# Iterator for each section's contents sorted by title. The +section+, the
# section's +constants+ and the sections +attributes+ are yielded. The
# +constants+ and +attributes+ collections are sorted.
#
# To retrieve methods in a section use #methods_by_type with the optional
# +section+ parameter.
#
# NOTE: Do not edit collections yielded by this method
def each_section # :yields: section, constants, attributes
return enum_for __method__ unless block_given?
constants = @constants.group_by do |constant| constant.section end
attributes = @attributes.group_by do |attribute| attribute.section end
constants.default = []
attributes.default = []
sort_sections.each do |section|
yield section, constants[section].select(&:display?).sort, attributes[section].select(&:display?).sort
end
end
##
# Finds an attribute +name+ with singleton value +singleton+.
def find_attribute(name, singleton)
name = $1 if name =~ /^(.*)=$/
@attributes.find { |a| a.name == name && a.singleton == singleton }
end
##
# Finds an attribute with +name+ in this context
def find_attribute_named(name)
case name
when /\A#/ then
find_attribute name[1..-1], false
when /\A::/ then
find_attribute name[2..-1], true
else
@attributes.find { |a| a.name == name }
end
end
##
# Finds a class method with +name+ in this context
def find_class_method_named(name)
@method_list.find { |meth| meth.singleton && meth.name == name }
end
##
# Finds a constant with +name+ in this context
def find_constant_named(name)
@constants.find do |m|
m.name == name || m.full_name == name
end
end
##
# Find a module at a higher scope
def find_enclosing_module_named(name)
parent && parent.find_module_named(name)
end
##
# Finds an external alias +name+ with singleton value +singleton+.
def find_external_alias(name, singleton)
@external_aliases.find { |m| m.name == name && m.singleton == singleton }
end
##
# Finds an external alias with +name+ in this context
def find_external_alias_named(name)
case name
when /\A#/ then
find_external_alias name[1..-1], false
when /\A::/ then
find_external_alias name[2..-1], true
else
@external_aliases.find { |a| a.name == name }
end
end
##
# Finds an instance method with +name+ in this context
def find_instance_method_named(name)
@method_list.find { |meth| !meth.singleton && meth.name == name }
end
##
# Finds a method, constant, attribute, external alias, module or file
# named +symbol+ in this context.
def find_local_symbol(symbol)
find_method_named(symbol) or
find_constant_named(symbol) or
find_attribute_named(symbol) or
find_external_alias_named(symbol) or
find_module_named(symbol) or
@store.find_file_named(symbol)
end
##
# Finds a method named +name+ with singleton value +singleton+.
def find_method(name, singleton)
@method_list.find { |m|
if m.singleton
m.name == name && m.singleton == singleton
else
m.name == name && !m.singleton && !singleton
end
}
end
##
# Finds a instance or module method with +name+ in this context
def find_method_named(name)
case name
when /\A#/ then
find_method name[1..-1], false
when /\A::/ then
find_method name[2..-1], true
else
@method_list.find { |meth| meth.name == name }
end
end
##
# Find a module with +name+ using ruby's scoping rules
def find_module_named(name)
res = @modules[name] || @classes[name]
return res if res
return self if self.name == name
find_enclosing_module_named name
end
##
# Look up +symbol+, first as a module, then as a local symbol.
def find_symbol(symbol)
find_symbol_module(symbol) || find_local_symbol(symbol)
end
##
# Look up a module named +symbol+.
def find_symbol_module(symbol)
result = nil
# look for a class or module 'symbol'
case symbol
when /^::/ then
result = @store.find_class_or_module symbol
when /^(\w+):+(.+)$/
suffix = $2
top = $1
searched = self
while searched do
mod = searched.find_module_named(top)
break unless mod
result = @store.find_class_or_module "#{mod.full_name}::#{suffix}"
break if result || searched.is_a?(RDoc::TopLevel)
searched = searched.parent
end
else
searched = self
while searched do
result = searched.find_module_named(symbol)
break if result || searched.is_a?(RDoc::TopLevel)
searched = searched.parent
end
end
result
end
##
# The full name for this context. This method is overridden by subclasses.
def full_name
'(unknown)'
end
##
# Does this context and its methods and constants all have documentation?
#
# (Yes, fully documented doesn't mean everything.)
def fully_documented?
documented? and
attributes.all? { |a| a.documented? } and
method_list.all? { |m| m.documented? } and
constants.all? { |c| c.documented? }
end
##
# URL for this with a +prefix+
def http_url
path = name_for_path
path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /<
path = path.split('::')
File.join(*path.compact) + '.html'
end
##
# Instance attributes
def instance_attributes
@instance_attributes ||= attributes.reject { |a| a.singleton }
end
##
# Instance methods
def instance_methods
@instance_methods ||= method_list.reject { |a| a.singleton }
end
##
# Instance methods
#--
# TODO remove this later
def instance_method_list
warn '#instance_method_list is obsoleted, please use #instance_methods'
@instance_methods ||= method_list.reject { |a| a.singleton }
end
##
# Breaks method_list into a nested hash by type ('class' or
# 'instance') and visibility (+:public+, +:protected+, +:private+).
#
# If +section+ is provided only methods in that RDoc::Context::Section will
# be returned.
def methods_by_type(section = nil)
methods = {}
TYPES.each do |type|
visibilities = {}
RDoc::VISIBILITIES.each do |vis|
visibilities[vis] = []
end
methods[type] = visibilities
end
each_method do |method|
next if section and not method.section == section
methods[method.type][method.visibility] << method
end
methods
end
##
# Yields AnyMethod and Attr entries matching the list of names in +methods+.
def methods_matching(methods, singleton = false, &block)
(@method_list + @attributes).each do |m|
yield m if methods.include?(m.name) and m.singleton == singleton
end
each_ancestor do |parent|
parent.methods_matching(methods, singleton, &block)
end
end
##
# Array of modules in this context
def modules
@modules.values
end
##
# Hash of modules keyed by module name
def modules_hash
@modules
end
##
# Name to use to generate the url.
# #full_name by default.
def name_for_path
full_name
end
##
# Changes the visibility for new methods to +visibility+
def ongoing_visibility=(visibility)
@visibility = visibility
end
##
# Record +top_level+ as a file +self+ is in.
def record_location(top_level)
@in_files << top_level unless @in_files.include?(top_level)
end
##
# Should we remove this context from the documentation?
#
# The answer is yes if:
# * #received_nodoc is +true+
# * #any_content is +false+ (not counting includes)
# * All #includes are modules (not a string), and their module has
# #remove_from_documentation? == true
# * All classes and modules have #remove_from_documentation? == true
def remove_from_documentation?
@remove_from_documentation ||=
@received_nodoc &&
!any_content(false) &&
@includes.all? { |i| !i.module.is_a?(String) && i.module.remove_from_documentation? } &&
classes_and_modules.all? { |cm| cm.remove_from_documentation? }
end
##
# Removes methods and attributes with a visibility less than +min_visibility+.
#--
# TODO mark the visibility of attributes in the template (if not public?)
def remove_invisible(min_visibility)
return if [:private, :nodoc].include? min_visibility
remove_invisible_in @method_list, min_visibility
remove_invisible_in @attributes, min_visibility
remove_invisible_in @constants, min_visibility
end
##
# Only called when min_visibility == :public or :private
def remove_invisible_in(array, min_visibility) # :nodoc:
if min_visibility == :public then
array.reject! { |e|
e.visibility != :public and not e.force_documentation
}
else
array.reject! { |e|
e.visibility == :private and not e.force_documentation
}
end
end
##
# Tries to resolve unmatched aliases when a method or attribute has just
# been added.
def resolve_aliases(added)
# resolve any pending unmatched aliases
key = added.pretty_name
unmatched_alias_list = @unmatched_alias_lists[key]
return unless unmatched_alias_list
unmatched_alias_list.each do |unmatched_alias|
added.add_alias unmatched_alias, self
@external_aliases.delete unmatched_alias
end
@unmatched_alias_lists.delete key
end
##
# Returns RDoc::Context::Section objects referenced in this context for use
# in a table of contents.
def section_contents
used_sections = {}
each_method do |method|
next unless method.display?
used_sections[method.section] = true
end
# order found sections
sections = sort_sections.select do |section|
used_sections[section]
end
# only the default section is used
return [] if
sections.length == 1 and not sections.first.title
sections
end
##
# Sections in this context
def sections
@sections.values
end
def sections_hash # :nodoc:
@sections
end
##
# Sets the current section to a section with +title+. See also #add_section
def set_current_section(title, comment)
@current_section = add_section title, comment
end
##
# Given an array +methods+ of method names, set the visibility of each to
# +visibility+
def set_visibility_for(methods, visibility, singleton = false)
methods_matching methods, singleton do |m|
m.visibility = visibility
end
end
##
# Given an array +names+ of constants, set the visibility of each constant to
# +visibility+
def set_constant_visibility_for(names, visibility)
names.each do |name|
constant = @constants_hash[name] or next
constant.visibility = visibility
end
end
##
# Sorts sections alphabetically (default) or in TomDoc fashion (none,
# Public, Internal, Deprecated)
def sort_sections
titles = @sections.map { |title, _| title }
if titles.length > 1 and
TOMDOC_TITLES_SORT ==
(titles | TOMDOC_TITLES).sort_by { |title| title.to_s } then
@sections.values_at(*TOMDOC_TITLES).compact
else
@sections.sort_by { |title, _|
title.to_s
}.map { |_, section|
section
}
end
end
def to_s # :nodoc:
"#{self.class.name} #{self.full_name}"
end
##
# Return the TopLevel that owns us
#--
# FIXME we can be 'owned' by several TopLevel (see #record_location &
# #in_files)
def top_level
return @top_level if defined? @top_level
@top_level = self
@top_level = @top_level.parent until RDoc::TopLevel === @top_level
@top_level
end
##
# Upgrades NormalModule +mod+ in +enclosing+ to a +class_type+
def upgrade_to_class(mod, class_type, enclosing)
enclosing.modules_hash.delete mod.name
klass = RDoc::ClassModule.from_module class_type, mod
klass.store = @store
# if it was there, then we keep it even if done_documenting
@store.classes_hash[mod.full_name] = klass
enclosing.classes_hash[mod.name] = klass
klass
end
autoload :Section, "#{__dir__}/context/section"
end
PK ! "# # method_attr.rbnu [ # frozen_string_literal: true
##
# Abstract class representing either a method or an attribute.
class RDoc::MethodAttr < RDoc::CodeObject
include Comparable
##
# Name of this method/attribute.
attr_accessor :name
##
# public, protected, private
attr_accessor :visibility
##
# Is this a singleton method/attribute?
attr_accessor :singleton
##
# Source file token stream
attr_reader :text
##
# Array of other names for this method/attribute
attr_reader :aliases
##
# The method/attribute we're aliasing
attr_accessor :is_alias_for
#--
# The attributes below are for AnyMethod only.
# They are left here for the time being to
# allow ri to operate.
# TODO modify ri to avoid calling these on attributes.
#++
##
# Parameters yielded by the called block
attr_reader :block_params
##
# Parameters for this method
attr_accessor :params
##
# Different ways to call this method
attr_accessor :call_seq
##
# The call_seq or the param_seq with method name, if there is no call_seq.
attr_reader :arglists
##
# Creates a new MethodAttr from token stream +text+ and method or attribute
# name +name+.
#
# Usually this is called by super from a subclass.
def initialize(text, name, singleton: false)
super()
@text = text
@name = name
@aliases = []
@is_alias_for = nil
@parent_name = nil
@singleton = singleton
@visibility = :public
@see = false
@arglists = nil
@block_params = nil
@call_seq = nil
@params = nil
end
##
# Resets cached data for the object so it can be rebuilt by accessor methods
def initialize_copy(other) # :nodoc:
@full_name = nil
end
def initialize_visibility # :nodoc:
super
@see = nil
end
##
# Order by #singleton then #name
def <=>(other)
return unless other.respond_to?(:singleton) &&
other.respond_to?(:name)
[@singleton ? 0 : 1, name_ord_range, name] <=>
[other.singleton ? 0 : 1, other.name_ord_range, other.name]
end
def ==(other) # :nodoc:
equal?(other) or self.class == other.class and full_name == other.full_name
end
##
# A method/attribute is documented if any of the following is true:
# - it was marked with :nodoc:;
# - it has a comment;
# - it is an alias for a documented method;
# - it has a +#see+ method that is documented.
def documented?
super or
(is_alias_for and is_alias_for.documented?) or
(see and see.documented?)
end
##
# A method/attribute to look at,
# in particular if this method/attribute has no documentation.
#
# It can be a method/attribute of the superclass or of an included module,
# including the Kernel module, which is always appended to the included
# modules.
#
# Returns +nil+ if there is no such method/attribute.
# The +#is_alias_for+ method/attribute, if any, is not included.
#
# Templates may generate a "see also ..." if this method/attribute
# has documentation, and "see ..." if it does not.
def see
@see = find_see if @see == false
@see
end
##
# Sets the store for this class or module and its contained code objects.
def store=(store)
super
@file = @store.add_file @file.full_name if @file
end
def find_see # :nodoc:
return nil if singleton || is_alias_for
# look for the method
other = find_method_or_attribute name
return other if other
# if it is a setter, look for a getter
return nil unless name =~ /[a-z_]=$/i # avoid == or ===
return find_method_or_attribute name[0..-2]
end
def find_method_or_attribute(name) # :nodoc:
return nil unless parent.respond_to? :ancestors
searched = parent.ancestors
kernel = @store.modules_hash['Kernel']
searched << kernel if kernel &&
parent != kernel && !searched.include?(kernel)
searched.each do |ancestor|
next if String === ancestor
next if parent == ancestor
other = ancestor.find_method_named('#' + name) ||
ancestor.find_attribute_named(name)
return other if other
end
nil
end
##
# Abstract method. Contexts in their building phase call this
# to register a new alias for this known method/attribute.
#
# - creates a new AnyMethod/Attribute named an_alias.new_name;
# - adds +self+ as an alias for the new method or attribute
# - adds the method or attribute to #aliases
# - adds the method or attribute to +context+.
def add_alias(an_alias, context)
raise NotImplementedError
end
##
# HTML fragment reference for this method
def aref
type = singleton ? 'c' : 'i'
# % characters are not allowed in html names => dash instead
"#{aref_prefix}-#{type}-#{html_name}"
end
##
# Prefix for +aref+, defined by subclasses.
def aref_prefix
raise NotImplementedError
end
##
# Attempts to sanitize the content passed by the Ruby parser:
# remove outer parentheses, etc.
def block_params=(value)
# 'yield.to_s' or 'assert yield, msg'
return @block_params = '' if value =~ /^[\.,]/
# remove trailing 'if/unless ...'
return @block_params = '' if value =~ /^(if|unless)\s/
value = $1.strip if value =~ /^(.+)\s(if|unless)\s/
# outer parentheses
value = $1 if value =~ /^\s*\((.*)\)\s*$/
value = value.strip
# proc/lambda
return @block_params = $1 if value =~ /^(proc|lambda)(\s*\{|\sdo)/
# surrounding +...+ or [...]
value = $1.strip if value =~ /^\+(.*)\+$/
value = $1.strip if value =~ /^\[(.*)\]$/
return @block_params = '' if value.empty?
# global variable
return @block_params = 'str' if value =~ /^\$[&0-9]$/
# wipe out array/hash indices
value.gsub!(/(\w)\[[^\[]+\]/, '\1')
# remove @ from class/instance variables
value.gsub!(/@@?([a-z0-9_]+)/, '\1')
# method calls => method name
value.gsub!(/([A-Z:a-z0-9_]+)\.([a-z0-9_]+)(\s*\(\s*[a-z0-9_.,\s]*\s*\)\s*)?/) do
case $2
when 'to_s' then $1
when 'const_get' then 'const'
when 'new' then
$1.split('::').last. # ClassName => class_name
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
gsub(/([a-z\d])([A-Z])/, '\1_\2').
downcase
else
$2
end
end
# class prefixes
value.gsub!(/[A-Za-z0-9_:]+::/, '')
# simple expressions
value = $1 if value =~ /^([a-z0-9_]+)\s*[-*+\/]/
@block_params = value.strip
end
##
# HTML id-friendly method/attribute name
def html_name
require 'cgi/escape'
CGI.escape(@name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '')
end
##
# Full method/attribute name including namespace
def full_name
@full_name ||= "#{parent_name}#{pretty_name}"
end
def inspect # :nodoc:
alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil
visibility = self.visibility
visibility = "forced #{visibility}" if force_documentation
"#<%s:0x%x %s (%s)%s>" % [
self.class, object_id,
full_name,
visibility,
alias_for,
]
end
##
# '::' for a class method/attribute, '#' for an instance method.
def name_prefix
@singleton ? '::' : '#'
end
##
# Method/attribute name with class/instance indicator
def pretty_name
"#{name_prefix}#{@name}"
end
##
# Type of method/attribute (class or instance)
def type
singleton ? 'class' : 'instance'
end
##
# Path to this method for use with HTML generator output.
def path
"#{@parent.path}##{aref}"
end
##
# Name of our parent with special handling for un-marshaled methods
def parent_name
@parent_name || super
end
def pretty_print(q) # :nodoc:
alias_for =
if @is_alias_for.respond_to? :name then
"alias for #{@is_alias_for.name}"
elsif Array === @is_alias_for then
"alias for #{@is_alias_for.last}"
end
q.group 2, "[#{self.class.name} #{full_name} #{visibility}", "]" do
if alias_for then
q.breakable
q.text alias_for
end
if text then
q.breakable
q.text "text:"
q.breakable
q.pp @text
end
unless comment.empty? then
q.breakable
q.text "comment:"
q.breakable
q.pp @comment
end
end
end
##
# Used by RDoc::Generator::JsonIndex to create a record for the search
# engine.
def search_record
[
@name,
full_name,
@name,
@parent.full_name,
path,
params,
snippet(@comment),
]
end
def to_s # :nodoc:
if @is_alias_for
"#{self.class.name}: #{full_name} -> #{is_alias_for}"
else
"#{self.class.name}: #{full_name}"
end
end
def name_ord_range # :nodoc:
case name.ord
when 0..64 # anything below "A"
1
when 91..96 # the symbols between "Z" and "a"
2
when 123..126 # 7-bit symbols above "z": "{", "|", "}", "~"
3
else # everythig else can be sorted as normal
4
end
end
end
PK ! =]+0Z Z class_module.rbnu [ # frozen_string_literal: true
##
# ClassModule is the base class for objects representing either a class or a
# module.
class RDoc::ClassModule < RDoc::Context
##
# 1::
# RDoc 3.7
# * Added visibility, singleton and file to attributes
# * Added file to constants
# * Added file to includes
# * Added file to methods
# 2::
# RDoc 3.13
# * Added extends
# 3::
# RDoc 4.0
# * Added sections
# * Added in_files
# * Added parent name
# * Complete Constant dump
MARSHAL_VERSION = 3 # :nodoc:
##
# Constants that are aliases for this class or module
attr_accessor :constant_aliases
##
# Comment and the location it came from. Use #add_comment to add comments
attr_accessor :comment_location
##
# Class or module this constant is an alias for
attr_accessor :is_alias_for
##
# Return a RDoc::ClassModule of class +class_type+ that is a copy
# of module +module+. Used to promote modules to classes.
#--
# TODO move to RDoc::NormalClass (I think)
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.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
##
# Creates a new ClassModule with +name+ with optional +superclass+
#
# This is a constructor for subclasses, and must never be called directly.
def initialize(name, superclass = nil)
@constant_aliases = []
@is_alias_for = nil
@name = name
@superclass = superclass
@comment_location = [] # [[comment, location]]
super()
end
##
# Adds +comment+ to this ClassModule's list of comments at +location+. This
# method is preferred over #comment= since it allows ri data to be updated
# across multiple runs.
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
def add_things(my_things, other_things) # :nodoc:
other_things.each do |group, things|
my_things[group].each { |thing| yield false, thing } if
my_things.include? group
things.each do |thing|
yield true, thing
end
end
end
##
# Ancestors list for this ClassModule: the list of included modules
# (classes will add their superclass if any).
#
# Returns the included classes or modules, not the includes
# themselves. The returned values are either String or
# RDoc::NormalModule instances (see RDoc::Include#module).
#
# The values are returned in reverse order of their inclusion,
# which is the order suitable for searching methods/attributes
# in the ancestors. The superclass, if any, comes last.
def ancestors
includes.map { |i| i.module }.reverse
end
def aref_prefix # :nodoc:
raise NotImplementedError, "missing aref_prefix for #{self.class}"
end
##
# HTML fragment reference for this module or class. See
# RDoc::NormalClass#aref and RDoc::NormalModule#aref
def aref
"#{aref_prefix}-#{full_name}"
end
##
# Ancestors of this class or module only
alias direct_ancestors ancestors
##
# Clears the comment. Used by the Ruby parser.
def clear_comment
@comment = ''
end
##
# This method is deprecated, use #add_comment instead.
#
# Appends +comment+ to the current comment, but separated by a rule. Works
# more like +=.
def comment=(comment) # :nodoc:
comment = case comment
when RDoc::Comment then
comment.normalize
else
normalize_comment comment
end
comment = "#{@comment.to_s}\n---\n#{comment.to_s}" unless @comment.empty?
super comment
end
##
# Prepares this ClassModule for use by a generator.
#
# See RDoc::Store#complete
def complete(min_visibility)
update_aliases
remove_nodoc_children
embed_mixins
update_includes
update_extends
remove_invisible min_visibility
end
##
# Does this ClassModule or any of its methods have document_self set?
def document_self_or_methods
document_self || method_list.any?{ |m| m.document_self }
end
##
# Does this class or module have a comment with content or is
# #received_nodoc true?
def documented?
return true if @received_nodoc
return false if @comment_location.empty?
@comment_location.any? { |comment, _| not comment.empty? }
end
##
# Iterates the ancestors of this class or module for which an
# RDoc::ClassModule exists.
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
##
# Looks for a symbol in the #ancestors. See Context#find_local_symbol.
def find_ancestor_local_symbol(symbol)
each_ancestor do |m|
res = m.find_local_symbol(symbol)
return res if res
end
nil
end
##
# Finds a class or module with +name+ in this namespace or its descendants
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
##
# Return the fully qualified name of this class or module
def full_name
@full_name ||= if RDoc::ClassModule === parent then
"#{parent.full_name}::#{@name}"
else
@name
end
end
##
# Return array of full_name splitted by +::+.
def nesting_namespaces
@namespaces ||= full_name.split("::").reject(&:empty?)
end
##
# Return array of fully qualified nesting namespaces.
#
# For example, if full_name is +A::B::C+, this method returns ["A", "A::B", "A::B::C"]
def fully_qualified_nesting_namespaces
return nesting_namespaces if nesting_namespaces.length < 2
@fqns ||= nesting_namespaces.inject([]) do |list, n|
list << (list.empty? ? n : "#{list.last}::#{n}")
end
end
##
# TODO: filter included items by #display?
def marshal_dump # :nodoc:
attrs = attributes.sort.map do |attr|
next unless attr.display?
[ attr.name, attr.rw,
attr.visibility, attr.singleton, attr.file_name,
]
end.compact
method_types = methods_by_type.map do |type, visibilities|
visibilities = visibilities.map do |visibility, methods|
method_names = methods.map do |method|
next unless method.display?
[method.name, method.file_name]
end.compact
[visibility, method_names.uniq]
end
[type, visibilities]
end
[ MARSHAL_VERSION,
@name,
full_name,
@superclass,
parse(@comment_location),
attrs,
constants.select { |constant| constant.display? },
includes.map do |incl|
next unless incl.display?
[incl.name, parse(incl.comment), incl.file_name]
end.compact,
method_types,
extends.map do |ext|
next unless ext.display?
[ext.name, parse(ext.comment), ext.file_name]
end.compact,
@sections.values,
@in_files.map do |tl|
tl.relative_name
end,
parent.full_name,
parent.class,
]
end
def marshal_load(array) # :nodoc:
initialize_visibility
initialize_methods_etc
@current_section = nil
@document_self = true
@done_documenting = false
@parent = nil
@temporary_section = nil
@visibility = nil
@classes = {}
@modules = {}
@name = array[1]
@full_name = array[2]
@superclass = array[3]
document = array[4]
@comment = RDoc::Comment.from_document document
@comment_location = if RDoc::Markup::Document === document.parts.first then
document
else
RDoc::Markup::Document.new document
end
array[5].each do |name, rw, visibility, singleton, file|
singleton ||= false
visibility ||= :public
attr = RDoc::Attr.new nil, name, rw, nil, singleton: singleton
add_attribute attr
attr.visibility = visibility
attr.record_location RDoc::TopLevel.new file
end
array[6].each do |constant, document, file|
case constant
when RDoc::Constant then
add_constant constant
else
constant = add_constant RDoc::Constant.new(constant, nil, RDoc::Comment.from_document(document))
constant.record_location RDoc::TopLevel.new file
end
end
array[7].each do |name, document, file|
incl = add_include RDoc::Include.new(name, RDoc::Comment.from_document(document))
incl.record_location RDoc::TopLevel.new file
end
array[8].each do |type, visibilities|
visibilities.each do |visibility, methods|
@visibility = visibility
methods.each do |name, file|
method = RDoc::AnyMethod.new nil, name, singleton: type == 'class'
method.record_location RDoc::TopLevel.new file
add_method method
end
end
end
array[9].each do |name, document, file|
ext = add_extend RDoc::Extend.new(name, RDoc::Comment.from_document(document))
ext.record_location RDoc::TopLevel.new file
end if array[9] # Support Marshal version 1
sections = (array[10] || []).map do |section|
[section.title, section]
end
@sections = Hash[*sections.flatten]
@current_section = add_section nil
@in_files = []
(array[11] || []).each do |filename|
record_location RDoc::TopLevel.new filename
end
@parent_name = array[12]
@parent_class = array[13]
end
##
# Merges +class_module+ into this ClassModule.
#
# The data in +class_module+ is preferred over the receiver.
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 = RDoc::Comment.from_document(document)
@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
##
# Merges collection +mine+ with +other+ preferring other. +other_files+ is
# used to help determine which items should be deleted.
#
# Yields whether the item should be added or removed (true or false) and the
# item to be added or removed.
#
# merge_collections things, other.things, other.in_files do |add, thing|
# if add then
# # add the thing
# else
# # remove the thing
# end
# end
def merge_collections(mine, other, other_files, &block) # :nodoc:
my_things = mine. group_by { |thing| thing.file }
other_things = other.group_by { |thing| thing.file }
remove_things my_things, other_files, &block
add_things my_things, other_things, &block
end
##
# Merges the comments in this ClassModule with the comments in the other
# ClassModule +cm+.
def merge_sections(cm) # :nodoc:
my_sections = sections.group_by { |section| section.title }
other_sections = cm.sections.group_by { |section| section.title }
other_files = cm.in_files
remove_things my_sections, other_files do |_, section|
@sections.delete section.title
end
other_sections.each do |group, sections|
if my_sections.include? group
my_sections[group].each do |my_section|
other_section = cm.sections_hash[group]
my_comments = my_section.comments
other_comments = other_section.comments
other_files = other_section.in_files
merge_collections my_comments, other_comments, other_files do |add, comment|
if add then
my_section.add_comment comment
else
my_section.remove_comment comment
end
end
end
else
sections.each do |section|
add_section group, section.comments
end
end
end
end
##
# Does this object represent a module?
def module?
false
end
##
# Allows overriding the initial name.
#
# Used for modules and classes that are constant aliases.
def name=(new_name)
@name = new_name
end
##
# Parses +comment_location+ into an RDoc::Markup::Document composed of
# multiple RDoc::Markup::Documents with their file set.
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 to this class or module for use with HTML generator output.
def path
prefix = options.class_module_path_prefix
return http_url unless prefix
File.join(prefix, http_url)
end
##
# Name to use to generate the url:
# modules and classes that are aliases for another
# module or class return the name of the latter.
def name_for_path
is_alias_for ? is_alias_for.full_name : full_name
end
##
# Returns the classes and modules that are not constants
# aliasing another class or module. For use by formatters
# only (caches its result).
def non_aliases
@non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for }
end
##
# Updates the child modules or classes of class/module +parent+ by
# deleting the ones that have been removed from the documentation.
#
# +parent_hash+ is either parent.modules_hash or
# parent.classes_hash and +all_hash+ is ::all_modules_hash or
# ::all_classes_hash.
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
def remove_things(my_things, other_files) # :nodoc:
my_things.delete_if do |file, things|
next false unless other_files.include? file
things.each do |thing|
yield false, thing
end
true
end
end
##
# Search record used by RDoc::Generator::JsonIndex
def search_record
[
name,
full_name,
full_name,
'',
path,
'',
snippet(@comment_location),
]
end
##
# Sets the store for this class or module and its contained code objects.
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
##
# Get the superclass of this class. Attempts to retrieve the superclass
# object, returns the name if it is not known.
def superclass
@store.find_class_named(@superclass) || @superclass
end
##
# Set the superclass of this class to +superclass+
#
# where +superclass+ is one of:
#
# - +nil+
# - a String containing the full name of the superclass
# - the RDoc::ClassModule representing the superclass
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
##
# Get all super classes of this class in an array. The last element might be
# a string if the name is unknown.
def super_classes
result = []
parent = self
while parent = parent.superclass
result << parent
return result if parent.is_a?(String)
end
result
end
def to_s # :nodoc:
if is_alias_for then
"#{self.class.name} #{self.full_name} -> #{is_alias_for}"
else
super
end
end
##
# 'module' or 'class'
def type
module? ? 'module' : 'class'
end
##
# Updates the child modules & classes by replacing the ones that are
# aliases through a constant.
#
# The aliased module/class is replaced in the children and in
# RDoc::Store#modules_hash or RDoc::Store#classes_hash
# by a copy that has RDoc::ClassModule#is_alias_for set to
# the aliased module/class, and this copy is added to #aliases
# of the aliased module/class.
#
# Formatters can use the #non_aliases method to retrieve children that
# are not aliases, for instance to list the namespace content, since
# the aliased modules are included in the constants of the class/module,
# that are listed separately.
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
##
# Deletes from #includes those whose module has been removed from the
# documentation.
#--
# FIXME: includes are not reliably removed, see _possible_bug test case
def update_includes
includes.reject! do |include|
mod = include.module
!(String === mod) && @store.modules_hash[mod.full_name].nil?
end
includes.uniq!
end
##
# Deletes from #extends those whose module has been removed from the
# documentation.
#--
# FIXME: like update_includes, extends are not reliably removed
def update_extends
extends.reject! do |ext|
mod = ext.module
!(String === mod) && @store.modules_hash[mod.full_name].nil?
end
extends.uniq!
end
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
private
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
end
PK ! :ԫ
include.rbnu [ # frozen_string_literal: true
##
# A Module included in a class with \#include
#
# RDoc::Include.new 'Enumerable', 'comment ...'
class RDoc::Include < RDoc::Mixin
end
PK ! tJ$ extend.rbnu [ # frozen_string_literal: true
##
# A Module extension to a class with \#extend
#
# RDoc::Extend.new 'Enumerable', 'comment ...'
class RDoc::Extend < RDoc::Mixin
end
PK ! \ 6 6 top_level.rbnu [ # frozen_string_literal: true
##
# A TopLevel context is a representation of the contents of a single file
class RDoc::TopLevel < RDoc::Context
MARSHAL_VERSION = 0 # :nodoc:
##
# Relative name of this file
attr_accessor :relative_name
##
# Absolute name of this file
attr_accessor :absolute_name
##
# All the classes or modules that were declared in
# this file. These are assigned to either +#classes_hash+
# or +#modules_hash+ once we know what they really are.
attr_reader :classes_or_modules
##
# The parser class that processed this file
attr_reader :parser
##
# Creates a new TopLevel for the file at +absolute_name+. If documentation
# is being generated outside the source dir +relative_name+ is relative to
# the source directory.
def initialize(absolute_name, relative_name = absolute_name)
super()
@name = nil
@absolute_name = absolute_name
@relative_name = relative_name
@parser = nil
@classes_or_modules = []
end
##
# Sets the parser for this toplevel context, also the store.
def parser=(val)
@parser = val
@store.update_parser_of_file(absolute_name, val) if @store
@parser
end
##
# An RDoc::TopLevel is equal to another with the same relative_name
def ==(other)
self.class === other and @relative_name == other.relative_name
end
alias eql? ==
##
# Adds +an_alias+ to +Object+ instead of +self+.
def add_alias(an_alias)
object_class.record_location self
return an_alias unless @document_self
object_class.add_alias an_alias
end
##
# Adds +constant+ to +Object+ instead of +self+.
def add_constant(constant)
object_class.record_location self
return constant unless @document_self
object_class.add_constant constant
end
##
# Adds +include+ to +Object+ instead of +self+.
def add_include(include)
object_class.record_location self
return include unless @document_self
object_class.add_include include
end
##
# Adds +method+ to +Object+ instead of +self+.
def add_method(method)
object_class.record_location self
return method unless @document_self
object_class.add_method method
end
##
# Adds class or module +mod+. Used in the building phase
# by the Ruby parser.
def add_to_classes_or_modules(mod)
@classes_or_modules << mod
end
##
# Base name of this file
def base_name
File.basename @relative_name
end
alias name base_name
##
# Only a TopLevel that contains text file) will be displayed. See also
# RDoc::CodeObject#display?
def display?
text? and super
end
##
# See RDoc::TopLevel::find_class_or_module
#--
# TODO Why do we search through all classes/modules found, not just the
# ones of this instance?
def find_class_or_module(name)
@store.find_class_or_module name
end
##
# Finds a class or module named +symbol+
def find_local_symbol(symbol)
find_class_or_module(symbol) || super
end
##
# Finds a module or class with +name+
def find_module_named(name)
find_class_or_module(name)
end
##
# Returns the relative name of this file
def full_name
@relative_name
end
##
# An RDoc::TopLevel has the same hash as another with the same
# relative_name
def hash
@relative_name.hash
end
##
# URL for this with a +prefix+
def http_url
@relative_name.tr('.', '_') + '.html'
end
def inspect # :nodoc:
"#<%s:0x%x %p modules: %p classes: %p>" % [
self.class, object_id,
base_name,
@modules.map { |n, m| m },
@classes.map { |n, c| c }
]
end
##
# Dumps this TopLevel for use by ri. See also #marshal_load
def marshal_dump
[
MARSHAL_VERSION,
@relative_name,
@parser,
parse(@comment),
]
end
##
# Loads this TopLevel from +array+.
def marshal_load(array) # :nodoc:
initialize array[1]
@parser = array[2]
@comment = RDoc::Comment.from_document array[3]
end
##
# Returns the NormalClass "Object", creating it if not found.
#
# Records +self+ as a location in "Object".
def object_class
@object_class ||= begin
oc = @store.find_class_named('Object') || add_class(RDoc::NormalClass, 'Object')
oc.record_location self
oc
end
end
##
# Base name of this file without the extension
def page_name
basename = File.basename @relative_name
basename =~ /\.(rb|rdoc|txt|md)$/i
$` || basename
end
##
# Path to this file for use with HTML generator output.
def path
prefix = options.file_path_prefix
return http_url unless prefix
File.join(prefix, http_url)
end
def pretty_print(q) # :nodoc:
q.group 2, "[#{self.class}: ", "]" do
q.text "base name: #{base_name.inspect}"
q.breakable
items = @modules.map { |n, m| m }
items.concat @modules.map { |n, c| c }
q.seplist items do |mod| q.pp mod end
end
end
##
# Search record used by RDoc::Generator::JsonIndex
def search_record
return unless @parser < RDoc::Parser::Text
[
page_name,
'',
page_name,
'',
path,
'',
snippet(@comment),
]
end
##
# Is this TopLevel from a text file instead of a source code file?
def text?
@parser and @parser.include? RDoc::Parser::Text
end
def to_s # :nodoc:
"file #{full_name}"
end
end
PK !
context/section.rbnu [ # frozen_string_literal: true
require 'cgi/escape'
##
# A section of documentation like:
#
# # :section: The title
# # The body
#
# Sections can be referenced multiple times and will be collapsed into a
# single section.
class RDoc::Context::Section
include RDoc::Text
MARSHAL_VERSION = 0 # :nodoc:
##
# Section comment
attr_reader :comment
##
# Section comments
attr_reader :comments
##
# Context this Section lives in
attr_reader :parent
##
# Section title
attr_reader :title
##
# Creates a new section with +title+ and +comment+
def initialize(parent, title, comment)
@parent = parent
@title = title ? title.strip : title
@comments = []
add_comment comment
end
##
# Sections are equal when they have the same #title
def ==(other)
self.class === other and @title == other.title
end
alias eql? ==
##
# Adds +comment+ to this section
def add_comment(comment)
comments = Array(comment)
comments.each do |c|
extracted_comment = extract_comment(c)
@comments << extracted_comment unless extracted_comment.empty?
end
end
##
# Anchor reference for linking to this section
def aref
title = @title || '[untitled]'
CGI.escape(title).gsub('%', '-').sub(/^-/, '')
end
##
# Extracts the comment for this section from the original comment block.
# If the first line contains :section:, strip it and use the rest.
# Otherwise remove lines up to the line containing :section:, and look
# for those lines again at the end and remove them. This lets us write
#
# # :section: The title
# # The body
def extract_comment(comment)
case comment
when nil
RDoc::Comment.new ''
when RDoc::Comment then
if comment.text =~ /^#[ \t]*:section:.*\n/ then
start = $`
rest = $'
comment.text = if start.empty? then
rest
else
rest.sub(/#{start.chomp}\Z/, '')
end
end
comment
else
raise TypeError, "unknown comment #{comment.inspect}"
end
end
def inspect # :nodoc:
"#<%s:0x%x %p>" % [self.class, object_id, title]
end
def hash # :nodoc:
@title.hash
end
##
# The files comments in this section come from
def in_files
@comments.map(&:file)
end
##
# Serializes this Section. The title and parsed comment are saved, but not
# the section parent which must be restored manually.
def marshal_dump
[
MARSHAL_VERSION,
@title,
parse,
]
end
##
# De-serializes this Section. The section parent must be restored manually.
def marshal_load(array)
@parent = nil
@title = array[1]
@comments = array[2].parts.map { |doc| RDoc::Comment.from_document(doc) }
end
##
# Parses +comment_location+ into an RDoc::Markup::Document composed of
# multiple RDoc::Markup::Documents with their file set.
def parse
RDoc::Markup::Document.new(*@comments.map(&:parse))
end
##
# The section's title, or 'Top Section' if the title is nil.
#
# This is used by the table of contents template so the name is silly.
def plain_html
@title || 'Top Section'
end
##
# Removes a comment from this section if it is from the same file as
# +comment+
def remove_comment(target_comment)
@comments.delete_if do |stored_comment|
stored_comment.file == target_comment.file
end
end
end
PK ! oX ghost_method.rbnu [ # frozen_string_literal: true
##
# GhostMethod represents a method referenced only by a comment
class RDoc::GhostMethod < RDoc::AnyMethod
end
PK ! |y" y"
any_method.rbnu [ # frozen_string_literal: true
##
# AnyMethod is the base class for objects representing methods
class RDoc::AnyMethod < RDoc::MethodAttr
##
# 2::
# RDoc 4
# Added calls_super
# Added parent name and class
# Added section title
# 3::
# RDoc 4.1
# Added is_alias_for
MARSHAL_VERSION = 3 # :nodoc:
##
# Don't rename \#initialize to \::new
attr_accessor :dont_rename_initialize
##
# The C function that implements this method (if it was defined in a C file)
attr_accessor :c_function
# The section title of the method (if defined in a C file via +:category:+)
attr_accessor :section_title
##
# If true this method uses +super+ to call a superclass version
attr_accessor :calls_super
include RDoc::TokenStream
##
# Creates a new AnyMethod with a token stream +text+ and +name+
def initialize(text, name, singleton: false)
super(text, name, singleton: singleton)
@c_function = nil
@dont_rename_initialize = false
@token_stream = nil
@calls_super = false
@superclass_method = nil
end
##
# Adds +an_alias+ as an alias for this method in +context+.
def add_alias(an_alias, context = nil)
method = self.class.new an_alias.text, an_alias.new_name, singleton: singleton
method.record_location an_alias.file
method.params = self.params
method.visibility = self.visibility
method.comment = an_alias.comment
method.is_alias_for = self
@aliases << method
context.add_method method if context
method
end
##
# Prefix for +aref+ is 'method'.
def aref_prefix
'method'
end
##
# The call_seq or the param_seq with method name, if there is no call_seq.
#
# Use this for displaying a method's argument lists.
def arglists
if @call_seq then
@call_seq
elsif @params then
"#{name}#{param_seq}"
end
end
##
# Different ways to call this method
def call_seq
unless call_seq = _call_seq
call_seq = is_alias_for._call_seq if is_alias_for
end
return unless call_seq
deduplicate_call_seq(call_seq)
end
##
# Sets the different ways you can call this method. If an empty +call_seq+
# is given nil is assumed.
#
# See also #param_seq
def call_seq=(call_seq)
return if call_seq.nil? || call_seq.empty?
@call_seq = call_seq
end
##
# Whether the method has a call-seq.
def has_call_seq?
!!(@call_seq || is_alias_for&._call_seq)
end
##
# Loads is_alias_for from the internal name. Returns nil if the alias
# cannot be found.
def is_alias_for # :nodoc:
case @is_alias_for
when RDoc::MethodAttr then
@is_alias_for
when Array then
return nil unless @store
klass_name, singleton, method_name = @is_alias_for
return nil unless klass = @store.find_class_or_module(klass_name)
@is_alias_for = klass.find_method method_name, singleton
end
end
##
# Dumps this AnyMethod for use by ri. See also #marshal_load
def marshal_dump
aliases = @aliases.map do |a|
[a.name, parse(a.comment)]
end
is_alias_for = [
@is_alias_for.parent.full_name,
@is_alias_for.singleton,
@is_alias_for.name
] if @is_alias_for
[ MARSHAL_VERSION,
@name,
full_name,
@singleton,
@visibility,
parse(@comment),
@call_seq,
@block_params,
aliases,
@params,
@file.relative_name,
@calls_super,
@parent.name,
@parent.class,
@section.title,
is_alias_for,
]
end
##
# Loads this AnyMethod from +array+. For a loaded AnyMethod the following
# methods will return cached values:
#
# * #full_name
# * #parent_name
def marshal_load(array)
initialize_visibility
@dont_rename_initialize = nil
@token_stream = nil
@aliases = []
@parent = nil
@parent_name = nil
@parent_class = nil
@section = nil
@file = nil
version = array[0]
@name = array[1]
@full_name = array[2]
@singleton = array[3]
@visibility = array[4]
@comment = RDoc::Comment.from_document array[5]
@call_seq = array[6]
@block_params = array[7]
# 8 handled below
@params = array[9]
# 10 handled below
@calls_super = array[11]
@parent_name = array[12]
@parent_title = array[13]
@section_title = array[14]
@is_alias_for = array[15]
array[8].each do |new_name, document|
add_alias RDoc::Alias.new(nil, @name, new_name, RDoc::Comment.from_document(document), singleton: @singleton)
end
@parent_name ||= if @full_name =~ /#/ then
$`
else
name = @full_name.split('::')
name.pop
name.join '::'
end
@file = RDoc::TopLevel.new array[10] if version > 0
end
##
# Method name
#
# If the method has no assigned name, it extracts it from #call_seq.
def name
return @name if @name
@name =
@call_seq[/^.*?\.(\w+)/, 1] ||
@call_seq[/^.*?(\w+)/, 1] ||
@call_seq if @call_seq
end
##
# A list of this method's method and yield parameters. +call-seq+ params
# are preferred over parsed method and block params.
def param_list
if @call_seq then
params = @call_seq.split("\n").last
params = params.sub(/.*?\((.*)\)/, '\1')
params = params.sub(/(\{|do)\s*\|([^|]*)\|.*/, ',\2')
elsif @params then
params = @params.sub(/\((.*)\)/, '\1')
params << ",#{@block_params}" if @block_params
elsif @block_params then
params = @block_params
else
return []
end
if @block_params then
# If this method has explicit block parameters, remove any explicit
# &block
params = params.sub(/,?\s*&\w+/, '')
else
params = params.sub(/\&(\w+)/, '\1')
end
params = params.gsub(/\s+/, '').split(',').reject(&:empty?)
params.map { |param| param.sub(/=.*/, '') }
end
##
# Pretty parameter list for this method. If the method's parameters were
# given by +call-seq+ it is preferred over the parsed values.
def param_seq
if @call_seq then
params = @call_seq.split("\n").last
params = params.sub(/[^( ]+/, '')
params = params.sub(/(\|[^|]+\|)\s*\.\.\.\s*(end|\})/, '\1 \2')
elsif @params then
params = @params.gsub(/\s*\#.*/, '')
params = params.tr_s("\n ", " ")
params = "(#{params})" unless params[0] == ?(
else
params = ''
end
if @block_params then
# If this method has explicit block parameters, remove any explicit
# &block
params = params.sub(/,?\s*&\w+/, '')
block = @block_params.tr_s("\n ", " ")
if block[0] == ?(
block = block.sub(/^\(/, '').sub(/\)/, '')
end
params << " { |#{block}| ... }"
end
params
end
##
# Whether to skip the method description, true for methods that have
# aliases with a call-seq that doesn't include the method name.
def skip_description?
has_call_seq? && call_seq.nil? && !!(is_alias_for || !aliases.empty?)
end
##
# Sets the store for this method and its referenced code objects.
def store=(store)
super
@file = @store.add_file @file.full_name if @file
end
##
# For methods that +super+, find the superclass method that would be called.
def superclass_method
return unless @calls_super
return @superclass_method if @superclass_method
parent.each_ancestor do |ancestor|
if method = ancestor.method_list.find { |m| m.name == @name } then
@superclass_method = method
break
end
end
@superclass_method
end
protected
##
# call_seq without deduplication and alias lookup.
def _call_seq
@call_seq if defined?(@call_seq) && @call_seq
end
private
##
# call_seq with alias examples information removed, if this
# method is an alias method.
def deduplicate_call_seq(call_seq)
return call_seq unless is_alias_for || !aliases.empty?
method_name = self.name
method_name = method_name[0, 1] if method_name =~ /\A\[/
entries = call_seq.split "\n"
ignore = aliases.map(&:name)
if is_alias_for
ignore << is_alias_for.name
ignore.concat is_alias_for.aliases.map(&:name)
end
ignore.map! { |n| n =~ /\A\[/ ? /\[.*\]/ : n}
ignore.delete(method_name)
ignore = Regexp.union(ignore)
matching = entries.reject do |entry|
entry =~ /^\w*\.?#{ignore}[$\(\s]/ or
entry =~ /\s#{ignore}\s/
end
matching.empty? ? nil : matching.join("\n")
end
end
PK ! { single_class.rbnu [ # frozen_string_literal: true
##
# A singleton class
class RDoc::SingleClass < RDoc::ClassModule
##
# Adds the superclass to the included modules.
def ancestors
superclass ? super + [superclass] : super
end
def aref_prefix # :nodoc:
'sclass'
end
##
# The definition of this singleton class, class << MyClassName
def definition
"class << #{full_name}"
end
def pretty_print(q) # :nodoc:
q.group 2, "[class << #{full_name}", "]" do
next
end
end
end
PK ! alias.rbnu [ # frozen_string_literal: true
##
# Represent an alias, which is an old_name/new_name pair associated with a
# particular context
#--
# TODO implement Alias as a proxy to a method/attribute, inheriting from
# MethodAttr
class RDoc::Alias < RDoc::CodeObject
##
# Aliased method's name
attr_reader :new_name
alias name new_name
##
# Aliasee method's name
attr_reader :old_name
##
# Is this an alias declared in a singleton context?
attr_reader :singleton
##
# Source file token stream
attr_reader :text
##
# Creates a new Alias with a token stream of +text+ that aliases +old_name+
# to +new_name+, has +comment+ and is a +singleton+ context.
def initialize(text, old_name, new_name, comment, singleton: false)
super()
@text = text
@singleton = singleton
@old_name = old_name
@new_name = new_name
self.comment = comment
end
##
# Order by #singleton then #new_name
def <=>(other)
[@singleton ? 0 : 1, new_name] <=> [other.singleton ? 0 : 1, other.new_name]
end
##
# HTML fragment reference for this alias
def aref
type = singleton ? 'c' : 'i'
"#alias-#{type}-#{html_name}"
end
##
# HTML id-friendly version of +#new_name+.
def html_name
CGI.escape(@new_name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '')
end
def inspect # :nodoc:
parent_name = parent ? parent.name : '(unknown)'
"#<%s:0x%x %s.alias_method %s, %s>" % [
self.class, object_id,
parent_name, @old_name, @new_name,
]
end
##
# '::' for the alias of a singleton method/attribute, '#' for instance-level.
def name_prefix
singleton ? '::' : '#'
end
##
# Old name with prefix '::' or '#'.
def pretty_old_name
"#{singleton ? '::' : '#'}#{@old_name}"
end
##
# New name with prefix '::' or '#'.
def pretty_new_name
"#{singleton ? '::' : '#'}#{@new_name}"
end
alias pretty_name pretty_new_name
def to_s # :nodoc:
"alias: #{self.new_name} -> #{self.pretty_old_name} in: #{parent}"
end
end
PK ! meta_method.rbnu [ # frozen_string_literal: true
##
# MetaMethod represents a meta-programmed method
class RDoc::MetaMethod < RDoc::AnyMethod
end
PK ! uK normal_class.rbnu [ # frozen_string_literal: true
##
# A normal class, neither singleton nor anonymous
class RDoc::NormalClass < RDoc::ClassModule
##
# The ancestors of this class including modules. Unlike Module#ancestors,
# this class is not included in the result. The result will contain both
# RDoc::ClassModules and Strings.
def ancestors
if String === superclass then
super << superclass
elsif superclass then
ancestors = super
ancestors << superclass
ancestors.concat superclass.ancestors
else
super
end
end
def aref_prefix # :nodoc:
'class'
end
##
# The definition of this class, class MyClassName
def definition
"class #{full_name}"
end
def direct_ancestors
superclass ? super + [superclass] : super
end
def inspect # :nodoc:
superclass = @superclass ? " < #{@superclass}" : nil
"<%s:0x%x class %s%s includes: %p extends: %p attributes: %p methods: %p aliases: %p>" % [
self.class, object_id,
full_name, superclass, @includes, @extends, @attributes, @method_list, @aliases
]
end
def to_s # :nodoc:
display = "#{self.class.name} #{self.full_name}"
if superclass
display += ' < ' + (superclass.is_a?(String) ? superclass : superclass.full_name)
end
display += ' -> ' + is_alias_for.to_s if is_alias_for
display
end
def pretty_print(q) # :nodoc:
superclass = @superclass ? " < #{@superclass}" : nil
q.group 2, "[class #{full_name}#{superclass}", "]" do
q.breakable
q.text "includes:"
q.breakable
q.seplist @includes do |inc| q.pp inc end
q.breakable
q.text "constants:"
q.breakable
q.seplist @constants do |const| q.pp const end
q.breakable
q.text "attributes:"
q.breakable
q.seplist @attributes do |attr| q.pp attr end
q.breakable
q.text "methods:"
q.breakable
q.seplist @method_list do |meth| q.pp meth end
q.breakable
q.text "aliases:"
q.breakable
q.seplist @aliases do |aliaz| q.pp aliaz end
q.breakable
q.text "comment:"
q.breakable
q.pp comment
end
end
end
PK ! BsN normal_module.rbnu [ # frozen_string_literal: true
##
# A normal module, like NormalClass
class RDoc::NormalModule < RDoc::ClassModule
def aref_prefix # :nodoc:
'module'
end
def inspect # :nodoc:
"#<%s:0x%x module %s includes: %p extends: %p attributes: %p methods: %p aliases: %p>" % [
self.class, object_id,
full_name, @includes, @extends, @attributes, @method_list, @aliases
]
end
##
# The definition of this module, module MyModuleName
def definition
"module #{full_name}"
end
##
# This is a module, returns true
def module?
true
end
def pretty_print(q) # :nodoc:
q.group 2, "[module #{full_name}:", "]" do
q.breakable
q.text "includes:"
q.breakable
q.seplist @includes do |inc| q.pp inc end
q.breakable
q.breakable
q.text "constants:"
q.breakable
q.seplist @constants do |const| q.pp const end
q.text "attributes:"
q.breakable
q.seplist @attributes do |attr| q.pp attr end
q.breakable
q.text "methods:"
q.breakable
q.seplist @method_list do |meth| q.pp meth end
q.breakable
q.text "aliases:"
q.breakable
q.seplist @aliases do |aliaz| q.pp aliaz end
q.breakable
q.text "comment:"
q.breakable
q.pp comment
end
end
##
# Modules don't have one, raises NoMethodError
def superclass
raise NoMethodError, "#{full_name} is a module"
end
end
PK ! w~ ~ constant.rbnu [ # frozen_string_literal: true
##
# A constant
class RDoc::Constant < RDoc::CodeObject
MARSHAL_VERSION = 0 # :nodoc:
##
# Sets the module or class this is constant is an alias for.
attr_writer :is_alias_for
##
# The constant's name
attr_accessor :name
##
# The constant's value
attr_accessor :value
##
# The constant's visibility
attr_accessor :visibility
##
# Creates a new constant with +name+, +value+ and +comment+
def initialize(name, value, comment)
super()
@name = name
@value = value
@is_alias_for = nil
@visibility = :public
self.comment = comment
end
##
# Constants are ordered by name
def <=>(other)
return unless self.class === other
[parent_name, name] <=> [other.parent_name, other.name]
end
##
# Constants are equal when their #parent and #name is the same
def ==(other)
self.class == other.class and
@parent == other.parent and
@name == other.name
end
##
# A constant is documented if it has a comment, or is an alias
# for a documented class or module.
def documented?
return true if super
return false unless @is_alias_for
case @is_alias_for
when String then
found = @store.find_class_or_module @is_alias_for
return false unless found
@is_alias_for = found
end
@is_alias_for.documented?
end
##
# Full constant name including namespace
def full_name
@full_name ||= "#{parent_name}::#{@name}"
end
##
# The module or class this constant is an alias for
def is_alias_for
case @is_alias_for
when String then
found = @store.find_class_or_module @is_alias_for
@is_alias_for = found if found
@is_alias_for
else
@is_alias_for
end
end
def inspect # :nodoc:
"#<%s:0x%x %s::%s>" % [
self.class, object_id,
parent_name, @name,
]
end
##
# Dumps this Constant for use by ri. See also #marshal_load
def marshal_dump
alias_name = case found = is_alias_for
when RDoc::CodeObject then found.full_name
else found
end
[ MARSHAL_VERSION,
@name,
full_name,
@visibility,
alias_name,
parse(@comment),
@file.relative_name,
parent.name,
parent.class,
section.title,
]
end
##
# Loads this Constant from +array+. For a loaded Constant the following
# methods will return cached values:
#
# * #full_name
# * #parent_name
def marshal_load(array)
initialize array[1], nil, RDoc::Comment.from_document(array[5])
@full_name = array[2]
@visibility = array[3] || :public
@is_alias_for = array[4]
# 5 handled above
# 6 handled below
@parent_name = array[7]
@parent_class = array[8]
@section_title = array[9]
@file = RDoc::TopLevel.new array[6]
end
##
# Path to this constant for use with HTML generator output.
def path
"#{@parent.path}##{@name}"
end
def pretty_print(q) # :nodoc:
q.group 2, "[#{self.class.name} #{full_name}", "]" do
unless comment.empty? then
q.breakable
q.text "comment:"
q.breakable
q.pp @comment
end
end
end
##
# Sets the store for this class or module and its contained code objects.
def store=(store)
super
@file = @store.add_file @file.full_name if @file
end
def to_s # :nodoc:
parent_name = parent ? parent.full_name : '(unknown)'
if is_alias_for
"constant #{parent_name}::#@name -> #{is_alias_for}"
else
"constant #{parent_name}::#@name"
end
end
end
PK ! ' attr.rbnu [ # frozen_string_literal: true
##
# An attribute created by \#attr, \#attr_reader, \#attr_writer or
# \#attr_accessor
class RDoc::Attr < RDoc::MethodAttr
##
# 3::
# RDoc 4
# Added parent name and class
# Added section title
MARSHAL_VERSION = 3 # :nodoc:
##
# Is the attribute readable ('R'), writable ('W') or both ('RW')?
attr_accessor :rw
##
# Creates a new Attr with body +text+, +name+, read/write status +rw+ and
# +comment+. +singleton+ marks this as a class attribute.
def initialize(text, name, rw, comment, singleton: false)
super(text, name, singleton: singleton)
@rw = rw
self.comment = comment
end
##
# Attributes are equal when their names, singleton and rw are identical
def ==(other)
self.class == other.class and
self.name == other.name and
self.rw == other.rw and
self.singleton == other.singleton
end
##
# Add +an_alias+ as an attribute in +context+.
def add_alias(an_alias, context)
new_attr = self.class.new(text, an_alias.new_name, rw, comment, singleton: singleton)
new_attr.record_location an_alias.file
new_attr.visibility = self.visibility
new_attr.is_alias_for = self
@aliases << new_attr
context.add_attribute new_attr
new_attr
end
##
# The #aref prefix for attributes
def aref_prefix
'attribute'
end
##
# Attributes never call super. See RDoc::AnyMethod#calls_super
#
# An RDoc::Attr can show up in the method list in some situations (see
# Gem::ConfigFile)
def calls_super # :nodoc:
false
end
##
# Returns attr_reader, attr_writer or attr_accessor as appropriate.
def definition
case @rw
when 'RW' then 'attr_accessor'
when 'R' then 'attr_reader'
when 'W' then 'attr_writer'
end
end
def inspect # :nodoc:
alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil
visibility = self.visibility
visibility = "forced #{visibility}" if force_documentation
"#<%s:0x%x %s %s (%s)%s>" % [
self.class, object_id,
full_name,
rw,
visibility,
alias_for,
]
end
##
# Dumps this Attr for use by ri. See also #marshal_load
def marshal_dump
[ MARSHAL_VERSION,
@name,
full_name,
@rw,
@visibility,
parse(@comment),
singleton,
@file.relative_name,
@parent.full_name,
@parent.class,
@section.title
]
end
##
# Loads this Attr from +array+. For a loaded Attr the following
# methods will return cached values:
#
# * #full_name
# * #parent_name
def marshal_load(array)
initialize_visibility
@aliases = []
@parent = nil
@parent_name = nil
@parent_class = nil
@section = nil
@file = nil
version = array[0]
@name = array[1]
@full_name = array[2]
@rw = array[3]
@visibility = array[4]
@comment = RDoc::Comment.from_document array[5]
@singleton = array[6] || false # MARSHAL_VERSION == 0
# 7 handled below
@parent_name = array[8]
@parent_class = array[9]
@section_title = array[10]
@file = RDoc::TopLevel.new array[7] if version > 1
@parent_name ||= @full_name.split('#', 2).first
end
def pretty_print(q) # :nodoc:
q.group 2, "[#{self.class.name} #{full_name} #{rw} #{visibility}", "]" do
unless comment.empty? then
q.breakable
q.text "comment:"
q.breakable
q.pp @comment
end
end
end
def to_s # :nodoc:
"#{definition} #{name} in: #{parent}"
end
##
# Attributes do not have token streams.
#
# An RDoc::Attr can show up in the method list in some situations (see
# Gem::ConfigFile)
def token_stream # :nodoc:
end
end
PK ! !
anon_class.rbnu [ PK ! G^
require.rbnu [ PK ! Ϸ5 mixin.rbnu [ PK !
eOPv Pv
: context.rbnu [ PK ! "# # Ć method_attr.rbnu [ PK ! =]+0Z Z class_module.rbnu [ PK ! :ԫ
include.rbnu [ PK ! tJ$ extend.rbnu [ PK ! \ 6 6 top_level.rbnu [ PK !
context/section.rbnu [ PK ! oX
* ghost_method.rbnu [ PK ! |y" y"
* any_method.rbnu [ PK ! { M single_class.rbnu [ PK ! O alias.rbnu [ PK ! X meta_method.rbnu [ PK ! uK X normal_class.rbnu [ PK ! BsN a normal_module.rbnu [ PK ! w~ ~ g constant.rbnu [ PK ! ' 9v attr.rbnu [ PK j