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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
require 'rdoc/ri'
class RDoc::RI::Error < RuntimeError; end
##
# Break argument into its constituent class or module names, an
# optional method type, and a method name
class RDoc::RI::NameDescriptor
attr_reader :class_names
attr_reader :method_name
##
# true and false have the obvious meaning. nil means we don't care
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 = nil
tokens = arg.split(/(\.|::|#)/)
# 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
break unless separator == "::"
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 RDoc::RI::Error.new("Bad argument: #{arg}")
end
if separator && separator != '.'
@is_class_method = separator == "::"
end
end
end
# Return the full class name (with '::' between the components) or "" if
# there's no class name
def full_class_name
@class_names.join("::")
end
end
|