class RDoc::CrossReference

RDoc::CrossReference is a reusable way to create cross references for names.

Constants

ALL_CROSSREF_REGEXP

Version of CROSSREF_REGEXP used when --hyperlink-all is specified.

CLASS_REGEXP_STR

Regular expression to match class references

  1. There can be a ‘\’ in front of text to suppress the cross-reference

  2. There can be a ‘::’ in front of class names to reference from the top-level namespace.

  3. The method can be followed by parenthesis (not recommended)

CROSSREF_REGEXP

Regular expressions matching text that should potentially have cross-reference links generated are passed to add_regexp_handling. Note that these expressions are meant to pick up text for which cross-references have been suppressed, since the suppression characters are removed by the code that is triggered.

METHOD_ARGS_REGEXP_STR

Regular expression to match method arguments.

METHOD_ARG_REGEXP_STR

Regular expression to match a single method argument.

METHOD_REGEXP_STR

Regular expression to match method references.

See CLASS_REGEXP_STR

Attributes

Hash of references that have been looked-up to their replacements

Public Class Methods

Allows cross-references to be created based on the given context (RDoc::Context).

# File lib/rdoc/cross_reference.rb, line 127
def initialize(context)
  @context = context
  @store   = context.store

  @seen = {}
end

Public Instance Methods

Returns a reference to name.

If the reference is found and name is not documented text will be returned. If name is escaped name is returned. If name is not found text is returned.

# File lib/rdoc/cross_reference.rb, line 199
def resolve(name, text)
  return @seen[name] if @seen.include? name

  ref = case name
        when /^\\(#{CLASS_REGEXP_STR})$/o then
          @context.find_symbol $1
        else
          @context.find_symbol name
        end

  ref = resolve_local_symbol name unless ref

  # Try a page name
  ref = @store.page name if not ref and name =~ /^[\w.\/]+$/

  ref = nil if RDoc::Alias === ref # external alias, can't link to it

  out = if name == '\\' then
          name
        elsif name =~ /^\\/ then
          # we remove the \ only in front of what we know:
          # other backslashes are treated later, only outside of <tt>
          ref ? $' : name
        elsif ref then
          if ref.display? then
            ref
          else
            text
          end
        else
          text
        end

  @seen[name] = out

  out
end

Returns a method, attribute or constant reference to name if it exists in the containing context object. It returns nil otherwise.

For example, this method would decompose name = ‘A::CONSTANT’ into a container object A and a symbol ‘CONSTANT’, and it would try to find ‘CONSTANT’ in A.

# File lib/rdoc/cross_reference.rb, line 143
def resolve_local_symbol(name)
  ref = nil
  type = nil
  container = nil

  case name
  when /#{CLASS_REGEXP_STR}::([A-Z]\w*)\z/o then
    symbol = $2
    container = @context.find_symbol_module($1)
  when /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o then
    type = $2
    if '.' == type # will find either #method or ::method
      symbol = $3
    else
      symbol = "#{type}#{$3}"
    end
    container = @context.find_symbol_module($1)
  when /^([.#]|::)#{METHOD_REGEXP_STR}/o then
    type = $1
    if '.' == type
      symbol = $2
    else
      symbol = "#{type}#{$2}"
    end
    container = @context
  end

  if container then
    unless RDoc::TopLevel === container then
      if '.' == type then
        if 'new' == symbol then # AnyClassName.new will be class method
          ref = container.find_local_symbol symbol
          ref = container.find_ancestor_local_symbol symbol unless ref
        else
          ref = container.find_local_symbol "::#{symbol}"
          ref = container.find_ancestor_local_symbol "::#{symbol}" unless ref
          ref = container.find_local_symbol "##{symbol}" unless ref
          ref = container.find_ancestor_local_symbol "##{symbol}" unless ref
        end
      else
        ref = container.find_local_symbol symbol
        ref = container.find_ancestor_local_symbol symbol unless ref
      end
    end
  end

  ref
end