From aa6e98139c8e1ea442fb2182341aaa08ff55b529 Mon Sep 17 00:00:00 2001 From: usa Date: Tue, 14 May 2013 11:27:23 +0000 Subject: add tag v1_9_3_426 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_3_426@40733 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ruby_1_9_3/lib/rdoc/method_attr.rb | 355 +++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 ruby_1_9_3/lib/rdoc/method_attr.rb (limited to 'ruby_1_9_3/lib/rdoc/method_attr.rb') diff --git a/ruby_1_9_3/lib/rdoc/method_attr.rb b/ruby_1_9_3/lib/rdoc/method_attr.rb new file mode 100644 index 0000000000..a4cd3c5fff --- /dev/null +++ b/ruby_1_9_3/lib/rdoc/method_attr.rb @@ -0,0 +1,355 @@ +require 'rdoc/code_object' + +## +# 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 + + ## + # Pretty parameter list for this method + + attr_reader :param_seq + + + ## + # 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 + super() + + @text = text + @name = name + + @aliases = [] + @is_alias_for = nil + @parent_name = nil + @singleton = nil + @visibility = :public + @see = false + + @arglists = nil + @block_params = nil + @call_seq = nil + @param_seq = nil + @params = nil + end + + ## + # Order by #singleton then #name + + def <=>(other) + [@singleton ? 0 : 1, name] <=> [other.singleton ? 0 : 1, other.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 + + 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 = RDoc::TopLevel.all_modules_hash['Kernel'] + + searched << kernel if kernel && + parent != kernel && !searched.include?(kernel) + + searched.each do |ancestor| + next if parent == ancestor + next if String === 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 +newa+ named an_alias.new_name; + # - adds +self+ as +newa.is_alias_for+; + # - adds +newa+ to #aliases + # - adds +newa+ to the methods/attributes of +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 + CGI.escape(@name.gsub('-', '-2D')).gsub('%','-').sub(/^-/, '') + end + + ## + # Full method/attribute name including namespace + + def full_name + @full_name || "#{parent_name}#{pretty_name}" + 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 + + 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 = @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 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 + + def to_s # :nodoc: + if @is_alias_for + "#{self.class.name}: #{full_name} -> #{is_alias_for}" + else + "#{self.class.name}: #{full_name}" + end + end + +end + -- cgit v1.2.3