summaryrefslogtreecommitdiffstats
path: root/lib/rdoc/ri/reader.rb
blob: e56c9fb76eac2ce0e6f0c7900b160dbe5251b6db (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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
require 'rdoc/ri'
require 'rdoc/ri/descriptions'
require 'rdoc/ri/writer'
require 'rdoc/markup/simple_markup/to_flow'

class RDoc::RI::Reader

  def initialize(ri_cache)
    @cache = ri_cache
  end

  def top_level_namespace
    [ @cache.toplevel ]
  end

  def lookup_namespace_in(target, namespaces)
    result = []
    for n in namespaces
      result.concat(n.contained_modules_matching(target))
    end
    result
  end

  def find_class_by_name(full_name)
    names = full_name.split(/::/)
    ns = @cache.toplevel
    for name in names
      ns = ns.contained_class_named(name)
      return nil if ns.nil?
    end
    get_class(ns)
  end

  def find_methods(name, is_class_method, namespaces)
    result = []
    namespaces.each do |ns|
      result.concat ns.methods_matching(name, is_class_method)
    end
    result
  end

  ##
  # Return the MethodDescription for a given MethodEntry by deserializing the
  # YAML

  def get_method(method_entry)
    path = method_entry.path_name
    File.open(path) { |f| RI::Description.deserialize(f) }
  end

  ##
  # Return a class description

  def get_class(class_entry)
    result = nil
    for path in class_entry.path_names
      path = RiWriter.class_desc_path(path, class_entry)
      desc = File.open(path) {|f| RI::Description.deserialize(f) }
      if result
        result.merge_in(desc)
      else
        result = desc
      end
    end
    result
  end

  ##
  # Return the names of all classes and modules

  def full_class_names
    res = []
    find_classes_in(res, @cache.toplevel)
  end

  ##
  # Return a list of all classes, modules, and methods

  def all_names
    res = []
    find_names_in(res, @cache.toplevel)
  end

  private

  def find_classes_in(res, klass)
    classes = klass.classes_and_modules
    for c in classes
      res << c.full_name
      find_classes_in(res, c)
    end
    res
  end

  def find_names_in(res, klass)
    classes = klass.classes_and_modules
    for c in classes
      res << c.full_name
      res.concat c.all_method_names
      find_names_in(res, c)
    end
    res
  end

end