~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to lib/rdoc/ri/ri_cache.rb

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
module 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
 
187
end