source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/rdoc/ri/ri_cache.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 4.8 KB
Line 
1module RI
2
3 class ClassEntry
4
5 attr_reader :name
6 attr_reader :path_names
7
8 def initialize(path_name, name, in_class)
9 @path_names = [ path_name ]
10 @name = name
11 @in_class = in_class
12 @class_methods = []
13 @instance_methods = []
14 @inferior_classes = []
15 end
16
17 # We found this class in more tha one place, so add
18 # in the name from there.
19 def add_path(path)
20 @path_names << path
21 end
22
23 # read in our methods and any classes
24 # and modules in our namespace. Methods are
25 # stored in files called name-c|i.yaml,
26 # where the 'name' portion is the external
27 # form of the method name and the c|i is a class|instance
28 # flag
29
30 def load_from(dir)
31 Dir.foreach(dir) do |name|
32 next if name =~ /^\./
33
34 # convert from external to internal form, and
35 # extract the instance/class flag
36
37 if name =~ /^(.*?)-(c|i).yaml$/
38 external_name = $1
39 is_class_method = $2 == "c"
40 internal_name = RiWriter.external_to_internal(external_name)
41 list = is_class_method ? @class_methods : @instance_methods
42 path = File.join(dir, name)
43 list << MethodEntry.new(path, internal_name, is_class_method, self)
44 else
45 full_name = File.join(dir, name)
46 if File.directory?(full_name)
47 inf_class = @inferior_classes.find {|c| c.name == name }
48 if inf_class
49 inf_class.add_path(full_name)
50 else
51 inf_class = ClassEntry.new(full_name, name, self)
52 @inferior_classes << inf_class
53 end
54 inf_class.load_from(full_name)
55 end
56 end
57 end
58 end
59
60 # Return a list of any classes or modules that we contain
61 # that match a given string
62
63 def contained_modules_matching(name)
64 @inferior_classes.find_all {|c| c.name[name]}
65 end
66
67 def classes_and_modules
68 @inferior_classes
69 end
70
71 # Return an exact match to a particular name
72 def contained_class_named(name)
73 @inferior_classes.find {|c| c.name == name}
74 end
75
76 # return the list of local methods matching name
77 # We're split into two because we need distinct behavior
78 # when called from the _toplevel_
79 def methods_matching(name, is_class_method)
80 local_methods_matching(name, is_class_method)
81 end
82
83 # Find methods matching 'name' in ourselves and in
84 # any classes we contain
85 def recursively_find_methods_matching(name, is_class_method)
86 res = local_methods_matching(name, is_class_method)
87 @inferior_classes.each do |c|
88 res.concat(c.recursively_find_methods_matching(name, is_class_method))
89 end
90 res
91 end
92
93
94 # Return our full name
95 def full_name
96 res = @in_class.full_name
97 res << "::" unless res.empty?
98 res << @name
99 end
100
101 # Return a list of all out method names
102 def all_method_names
103 res = @class_methods.map {|m| m.full_name }
104 @instance_methods.each {|m| res << m.full_name}
105 res
106 end
107
108 private
109
110 # Return a list of all our methods matching a given string.
111 # Is +is_class_methods+ if 'nil', we don't care if the method
112 # is a class method or not, otherwise we only return
113 # those methods that match
114 def local_methods_matching(name, is_class_method)
115
116 list = case is_class_method
117 when nil then @class_methods + @instance_methods
118 when true then @class_methods
119 when false then @instance_methods
120 else fail "Unknown is_class_method: #{is_class_method.inspect}"
121 end
122
123 list.find_all {|m| m.name; m.name[name]}
124 end
125 end
126
127 # A TopLevelEntry is like a class entry, but when asked to search
128 # for methods searches all classes, not just itself
129
130 class TopLevelEntry < ClassEntry
131 def methods_matching(name, is_class_method)
132 res = recursively_find_methods_matching(name, is_class_method)
133 end
134
135 def full_name
136 ""
137 end
138
139 def module_named(name)
140
141 end
142
143 end
144
145 class MethodEntry
146 attr_reader :name
147 attr_reader :path_name
148
149 def initialize(path_name, name, is_class_method, in_class)
150 @path_name = path_name
151 @name = name
152 @is_class_method = is_class_method
153 @in_class = in_class
154 end
155
156 def full_name
157 res = @in_class.full_name
158 unless res.empty?
159 if @is_class_method
160 res << "::"
161 else
162 res << "#"
163 end
164 end
165 res << @name
166 end
167 end
168
169 # We represent everything know about all 'ri' files
170 # accessible to this program
171
172 class RiCache
173
174 attr_reader :toplevel
175
176 def initialize(dirs)
177 # At the top level we have a dummy module holding the
178 # overall namespace
179 @toplevel = TopLevelEntry.new('', '::', nil)
180
181 dirs.each do |dir|
182 @toplevel.load_from(dir)
183 end
184 end
185
186 end
187end
Note: See TracBrowser for help on using the repository browser.