2010-04-01 03:45:16 -04:00
|
|
|
require 'rdoc/code_object'
|
|
|
|
require 'rdoc/tokenstream'
|
|
|
|
|
|
|
|
##
|
|
|
|
# AnyMethod is the base class for objects representing methods
|
|
|
|
|
|
|
|
class RDoc::AnyMethod < RDoc::CodeObject
|
|
|
|
|
2010-04-10 02:36:13 -04:00
|
|
|
MARSHAL_VERSION = 1 # :nodoc:
|
2010-04-01 03:45:16 -04:00
|
|
|
|
|
|
|
include Comparable
|
|
|
|
|
|
|
|
##
|
|
|
|
# Method name
|
|
|
|
|
|
|
|
attr_writer :name
|
|
|
|
|
|
|
|
##
|
|
|
|
# public, protected, private
|
|
|
|
|
|
|
|
attr_accessor :visibility
|
|
|
|
|
|
|
|
##
|
|
|
|
# Parameters yielded by the called block
|
|
|
|
|
|
|
|
attr_accessor :block_params
|
|
|
|
|
|
|
|
##
|
|
|
|
# Don't rename \#initialize to \::new
|
|
|
|
|
|
|
|
attr_accessor :dont_rename_initialize
|
|
|
|
|
|
|
|
##
|
|
|
|
# Is this a singleton method?
|
|
|
|
|
|
|
|
attr_accessor :singleton
|
|
|
|
|
|
|
|
##
|
|
|
|
# Source file token stream
|
|
|
|
|
|
|
|
attr_reader :text
|
|
|
|
|
|
|
|
##
|
|
|
|
# Array of other names for this method
|
|
|
|
|
|
|
|
attr_reader :aliases
|
|
|
|
|
|
|
|
##
|
|
|
|
# The method we're aliasing
|
|
|
|
|
|
|
|
attr_accessor :is_alias_for
|
|
|
|
|
|
|
|
##
|
|
|
|
# Parameters for this method
|
|
|
|
|
2010-04-10 02:36:13 -04:00
|
|
|
attr_accessor :params
|
2010-04-01 03:45:16 -04:00
|
|
|
|
|
|
|
##
|
|
|
|
# Different ways to call this method
|
|
|
|
|
|
|
|
attr_accessor :call_seq
|
|
|
|
|
|
|
|
include RDoc::TokenStream
|
|
|
|
|
|
|
|
def initialize(text, name)
|
|
|
|
super()
|
|
|
|
|
|
|
|
@text = text
|
|
|
|
@name = name
|
|
|
|
|
|
|
|
@aliases = []
|
|
|
|
@block_params = nil
|
|
|
|
@call_seq = nil
|
|
|
|
@dont_rename_initialize = false
|
|
|
|
@is_alias_for = nil
|
2010-04-10 02:36:13 -04:00
|
|
|
@params = nil
|
2010-04-01 03:45:16 -04:00
|
|
|
@parent_name = nil
|
|
|
|
@singleton = nil
|
|
|
|
@token_stream = nil
|
|
|
|
@visibility = :public
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Order by #singleton then #name
|
|
|
|
|
|
|
|
def <=>(other)
|
|
|
|
[@singleton ? 0 : 1, @name] <=> [other.singleton ? 0 : 1, other.name]
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Adds +method+ as an alias for this method
|
|
|
|
|
|
|
|
def add_alias(method)
|
|
|
|
@aliases << method
|
|
|
|
end
|
|
|
|
|
2010-04-19 01:08:28 -04:00
|
|
|
##
|
|
|
|
# HTML fragment reference for this method
|
|
|
|
|
|
|
|
def aref
|
|
|
|
type = singleton ? 'c' : 'i'
|
|
|
|
|
|
|
|
"method-#{type}-#{CGI.escape name}"
|
|
|
|
end
|
|
|
|
|
2010-04-10 02:36:13 -04:00
|
|
|
##
|
|
|
|
# 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
|
|
|
|
|
2010-04-01 03:45:16 -04:00
|
|
|
##
|
|
|
|
# HTML id-friendly method name
|
|
|
|
|
|
|
|
def html_name
|
|
|
|
@name.gsub(/[^a-z]+/, '-')
|
|
|
|
end
|
|
|
|
|
|
|
|
def inspect # :nodoc:
|
|
|
|
alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil
|
|
|
|
"#<%s:0x%x %s (%s)%s>" % [
|
|
|
|
self.class, object_id,
|
|
|
|
full_name,
|
|
|
|
visibility,
|
|
|
|
alias_for,
|
|
|
|
]
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Full method name including namespace
|
|
|
|
|
|
|
|
def full_name
|
|
|
|
@full_name ||= "#{@parent ? @parent.full_name : '(unknown)'}#{pretty_name}"
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Dumps this AnyMethod for use by ri. See also #marshal_load
|
|
|
|
|
|
|
|
def marshal_dump
|
|
|
|
aliases = @aliases.map do |a|
|
|
|
|
[a.full_name, parse(a.comment)]
|
|
|
|
end
|
|
|
|
|
|
|
|
[ MARSHAL_VERSION,
|
|
|
|
@name,
|
|
|
|
full_name,
|
|
|
|
@singleton,
|
|
|
|
@visibility,
|
|
|
|
parse(@comment),
|
|
|
|
@call_seq,
|
|
|
|
@block_params,
|
|
|
|
aliases,
|
2010-04-10 02:36:13 -04:00
|
|
|
@params,
|
2010-04-01 03:45:16 -04:00
|
|
|
]
|
|
|
|
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)
|
|
|
|
@dont_rename_initialize = nil
|
|
|
|
@is_alias_for = nil
|
|
|
|
@token_stream = nil
|
2010-04-20 23:10:03 -04:00
|
|
|
@aliases = []
|
2010-04-01 03:45:16 -04:00
|
|
|
|
|
|
|
@name = array[1]
|
|
|
|
@full_name = array[2]
|
|
|
|
@singleton = array[3]
|
|
|
|
@visibility = array[4]
|
|
|
|
@comment = array[5]
|
|
|
|
@call_seq = array[6]
|
|
|
|
@block_params = array[7]
|
2010-04-10 02:36:13 -04:00
|
|
|
@params = array[9]
|
2010-04-01 03:45:16 -04:00
|
|
|
|
|
|
|
@parent_name = if @full_name =~ /#/ then
|
|
|
|
$`
|
|
|
|
else
|
|
|
|
name = @full_name.split('::')
|
|
|
|
name.pop
|
|
|
|
name.join '::'
|
|
|
|
end
|
|
|
|
|
2010-04-20 23:10:03 -04:00
|
|
|
array[8].each do |new_name, comment|
|
|
|
|
add_alias RDoc::Alias.new(nil, @name, new_name, comment)
|
2010-04-01 03:45:16 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Method name
|
|
|
|
|
|
|
|
def name
|
|
|
|
return @name if @name
|
|
|
|
|
|
|
|
@name = @call_seq[/^.*?\.(\w+)/, 1] || @call_seq if @call_seq
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Pretty parameter list for this method
|
|
|
|
|
|
|
|
def param_seq
|
2010-04-10 02:36:13 -04:00
|
|
|
params = @params.gsub(/\s*\#.*/, '')
|
2010-04-01 03:45:16 -04:00
|
|
|
params = params.tr("\n", " ").squeeze(" ")
|
2010-04-10 02:36:13 -04:00
|
|
|
params = "(#{params})" unless params[0] == ?(
|
2010-04-01 03:45:16 -04:00
|
|
|
|
2010-04-10 02:36:13 -04:00
|
|
|
if @block_params then
|
2010-04-01 03:45:16 -04:00
|
|
|
# If this method has explicit block parameters, remove any explicit
|
|
|
|
# &block
|
2010-04-10 02:36:13 -04:00
|
|
|
params.sub!(/,?\s*&\w+/, '')
|
2010-04-01 03:45:16 -04:00
|
|
|
|
2010-04-10 02:36:13 -04:00
|
|
|
block = @block_params.gsub(/\s*\#.*/, '')
|
2010-04-01 03:45:16 -04:00
|
|
|
block = block.tr("\n", " ").squeeze(" ")
|
|
|
|
if block[0] == ?(
|
|
|
|
block.sub!(/^\(/, '').sub!(/\)/, '')
|
|
|
|
end
|
|
|
|
params << " { |#{block}| ... }"
|
|
|
|
end
|
|
|
|
|
|
|
|
params
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Name of our parent with special handling for un-marshaled methods
|
|
|
|
|
|
|
|
def parent_name
|
|
|
|
@parent_name || super
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Path to this method
|
|
|
|
|
|
|
|
def path
|
2010-04-19 01:08:28 -04:00
|
|
|
"#{@parent.path}##{aref}"
|
2010-04-01 03:45:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Method name with class/instance indicator
|
|
|
|
|
|
|
|
def pretty_name
|
|
|
|
"#{singleton ? '::' : '#'}#{@name}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def pretty_print q # :nodoc:
|
|
|
|
alias_for = @is_alias_for ? "alias for #{@is_alias_for.name}" : nil
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
def to_s # :nodoc:
|
|
|
|
"#{self.class.name}: #{full_name} (#{@text})\n#{@comment}"
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# Type of method (class or instance)
|
|
|
|
|
|
|
|
def type
|
|
|
|
singleton ? 'class' : 'instance'
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|