summaryrefslogtreecommitdiff
path: root/lib/rdoc/ri/ri_util.rb
blob: 07f79b1d628fe716d3427bfad605573883a91d37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
######################################################################

class RiError < Exception; end
#
# Break argument into its constituent class or module names, an
# optional method type, and a method name

class NameDescriptor

  attr_reader :class_names
  attr_reader :method_name
  attr_reader :is_class_method

  # arg may be
  # 1. a class or module name (optionally qualified with other class
  #    or module names (Kernel, File::Stat etc)
  # 2. a method name
  # 3. a method name qualified by a optionally fully qualified class
  #    or module name
  #
  # We're fairly casual about delimiters: folks can say Kernel::puts,
  # Kernel.puts, or Kernel\#puts for example. There's one exception:
  # if you say IO::read, we look for a class method, but if you
  # say IO.read, we look for an instance method

  def initialize(arg)
    @class_names = []
    separator = "."

    tokens = arg.split(/\b/)

    # Skip leading '::', '#' or '.', but remember it might
    # be a method name qualifier
    separator = tokens.shift if tokens[0] =~ /^(\.|::|#)/

    # Skip leading '::', but remember we potentially have an inst

    # leading stuff must be class names
    
    while tokens[0] =~ /^[A-Z]/
      @class_names << tokens.shift
      unless tokens.empty?
        separator = tokens.shift
      end
    end
    
    # Now must have a single token, the method name, or an empty
    # array
    unless tokens.empty?
      @method_name = tokens.shift
      # We may now have a trailing !, ?, or = to roll into
      # the method name
      if !tokens.empty? && tokens[0] =~ /^[!?=]$/
        @method_name << tokens.shift
      end

      if @method_name =~ /::|\.|#/ or !tokens.empty?
        raise RiError.new("Bad argument: #{arg}") 
      end
      @is_class_method = separator == "::"
    end
  end
end