rdoc 7.2.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +4 -7
- data/LICENSE.rdoc +4 -0
- data/README.md +43 -2
- data/RI.md +75 -75
- data/doc/markup_reference/markdown.md +104 -3
- data/exe/rdoc +2 -2
- data/lib/rdoc/code_object/alias.rb +70 -74
- data/lib/rdoc/code_object/any_method.rb +305 -298
- data/lib/rdoc/code_object/attr.rb +150 -143
- data/lib/rdoc/code_object/class_module.rb +801 -765
- data/lib/rdoc/code_object/constant.rb +178 -150
- data/lib/rdoc/code_object/context/section.rb +133 -160
- data/lib/rdoc/code_object/context.rb +925 -952
- data/lib/rdoc/code_object/extend.rb +7 -5
- data/lib/rdoc/code_object/include.rb +7 -5
- data/lib/rdoc/code_object/method_attr.rb +325 -324
- data/lib/rdoc/code_object/mixin.rb +97 -95
- data/lib/rdoc/code_object/normal_class.rb +77 -78
- data/lib/rdoc/code_object/normal_module.rb +61 -59
- data/lib/rdoc/code_object/require.rb +23 -39
- data/lib/rdoc/code_object/single_class.rb +21 -19
- data/lib/rdoc/code_object/top_level.rb +212 -213
- data/lib/rdoc/code_object.rb +305 -305
- data/lib/rdoc/comment.rb +274 -337
- data/lib/rdoc/cross_reference.rb +194 -212
- data/lib/rdoc/encoding.rb +105 -103
- data/lib/rdoc/erb_partial.rb +13 -11
- data/lib/rdoc/erbio.rb +29 -27
- data/lib/rdoc/generator/aliki.rb +165 -140
- data/lib/rdoc/generator/darkfish.rb +647 -631
- data/lib/rdoc/generator/json_index.rb +233 -229
- data/lib/rdoc/generator/markup.rb +165 -122
- data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
- data/lib/rdoc/generator/pot/po.rb +52 -51
- data/lib/rdoc/generator/pot/po_entry.rb +138 -132
- data/lib/rdoc/generator/pot.rb +85 -81
- data/lib/rdoc/generator/ri.rb +23 -19
- data/lib/rdoc/generator/template/aliki/DESIGN.md +538 -0
- data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +11 -11
- data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
- data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +8 -6
- data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +8 -6
- data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +2 -2
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/class.rhtml +56 -46
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +538 -283
- data/lib/rdoc/generator/template/aliki/index.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/js/aliki.js +80 -102
- data/lib/rdoc/generator/template/aliki/page.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +2 -2
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +5 -5
- data/lib/rdoc/generator/template/darkfish/class.rhtml +18 -21
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +0 -1
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +3 -3
- data/lib/rdoc/generator.rb +48 -46
- data/lib/rdoc/i18n/locale.rb +99 -95
- data/lib/rdoc/i18n/text.rb +109 -105
- data/lib/rdoc/i18n.rb +7 -5
- data/lib/rdoc/markdown/byte_runtime.rb +80 -0
- data/lib/rdoc/markdown.kpeg +30 -21
- data/lib/rdoc/markdown.rb +329 -151
- data/lib/rdoc/markup/block_quote.rb +12 -8
- data/lib/rdoc/markup/document.rb +127 -123
- data/lib/rdoc/markup/formatter.rb +215 -221
- data/lib/rdoc/markup/heading.rb +1 -4
- data/lib/rdoc/markup/include.rb +33 -29
- data/lib/rdoc/markup/indented_paragraph.rb +37 -33
- data/lib/rdoc/markup/inline_parser.rb +281 -277
- data/lib/rdoc/markup/list.rb +80 -88
- data/lib/rdoc/markup/list_item.rb +73 -85
- data/lib/rdoc/markup/paragraph.rb +23 -19
- data/lib/rdoc/markup/parser.rb +501 -497
- data/lib/rdoc/markup/pre_process.rb +284 -305
- data/lib/rdoc/markup/raw.rb +2 -2
- data/lib/rdoc/markup/rule.rb +16 -12
- data/lib/rdoc/markup/to_ansi.rb +143 -139
- data/lib/rdoc/markup/to_bs.rb +72 -68
- data/lib/rdoc/markup/to_html.rb +600 -493
- data/lib/rdoc/markup/to_html_crossref.rb +221 -191
- data/lib/rdoc/markup/to_html_snippet.rb +232 -227
- data/lib/rdoc/markup/to_joined_paragraph.rb +40 -41
- data/lib/rdoc/markup/to_label.rb +63 -59
- data/lib/rdoc/markup/to_markdown.rb +212 -208
- data/lib/rdoc/markup/to_rdoc.rb +336 -332
- data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
- data/lib/rdoc/markup/to_test.rb +60 -56
- data/lib/rdoc/markup/to_tt_only.rb +83 -86
- data/lib/rdoc/markup/verbatim.rb +62 -58
- data/lib/rdoc/markup.rb +198 -196
- data/lib/rdoc/options.rb +1063 -1076
- data/lib/rdoc/parser/c.rb +1039 -1036
- data/lib/rdoc/parser/changelog.rb +319 -315
- data/lib/rdoc/parser/markdown.rb +17 -13
- data/lib/rdoc/parser/rbs.rb +279 -0
- data/lib/rdoc/parser/rd.rb +17 -13
- data/lib/rdoc/parser/ruby.rb +1231 -2222
- data/lib/rdoc/parser/ruby_colorizer.rb +303 -0
- data/lib/rdoc/parser/simple.rb +31 -27
- data/lib/rdoc/parser/text.rb +12 -8
- data/lib/rdoc/parser.rb +230 -221
- data/lib/rdoc/rbs_helper.rb +186 -0
- data/lib/rdoc/rd/inline.rb +57 -53
- data/lib/rdoc/rd.rb +90 -88
- data/lib/rdoc/rdoc.rb +547 -366
- data/lib/rdoc/ri/driver.rb +1141 -1130
- data/lib/rdoc/ri/formatter.rb +7 -3
- data/lib/rdoc/ri/paths.rb +140 -136
- data/lib/rdoc/ri/servlet.rb +456 -0
- data/lib/rdoc/ri/store.rb +4 -2
- data/lib/rdoc/ri/task.rb +55 -51
- data/lib/rdoc/ri.rb +14 -11
- data/lib/rdoc/rubygems_hook.rb +194 -192
- data/lib/rdoc/server.rb +462 -0
- data/lib/rdoc/stats/normal.rb +46 -42
- data/lib/rdoc/stats/quiet.rb +39 -35
- data/lib/rdoc/stats/verbose.rb +35 -31
- data/lib/rdoc/stats.rb +363 -338
- data/lib/rdoc/store.rb +919 -725
- data/lib/rdoc/task.rb +260 -255
- data/lib/rdoc/text.rb +130 -245
- data/lib/rdoc/token_stream.rb +101 -115
- data/lib/rdoc/tom_doc.rb +203 -201
- data/lib/rdoc/version.rb +1 -1
- data/lib/rdoc.rb +35 -7
- data/lib/rubygems_plugin.rb +2 -11
- data/rdoc-logo.svg +43 -0
- data/rdoc.gemspec +6 -4
- metadata +36 -20
- data/lib/rdoc/code_object/anon_class.rb +0 -10
- data/lib/rdoc/code_object/ghost_method.rb +0 -6
- data/lib/rdoc/code_object/meta_method.rb +0 -6
- data/lib/rdoc/markdown/literals.kpeg +0 -21
- data/lib/rdoc/markdown/literals.rb +0 -454
- data/lib/rdoc/parser/prism_ruby.rb +0 -1112
- data/lib/rdoc/parser/ripper_state_lex.rb +0 -302
- data/lib/rdoc/parser/ruby_tools.rb +0 -163
- data/lib/rdoc/servlet.rb +0 -452
data/lib/rdoc/store.rb
CHANGED
|
@@ -1,997 +1,1191 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require 'fileutils'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
# A set of rdoc data for a single project (gem, path, etc.).
|
|
6
|
-
#
|
|
7
|
-
# The store manages reading and writing ri data for a project and maintains a
|
|
8
|
-
# cache of methods, classes and ancestors in the store.
|
|
9
|
-
#
|
|
10
|
-
# The store maintains a #cache of its contents for faster lookup. After
|
|
11
|
-
# adding items to the store it must be flushed using #save_cache. The cache
|
|
12
|
-
# contains the following structures:
|
|
13
|
-
#
|
|
14
|
-
# @cache = {
|
|
15
|
-
# :ancestors => {}, # class name => ancestor names
|
|
16
|
-
# :attributes => {}, # class name => attributes
|
|
17
|
-
# :class_methods => {}, # class name => class methods
|
|
18
|
-
# :instance_methods => {}, # class name => instance methods
|
|
19
|
-
# :modules => [], # classes and modules in this store
|
|
20
|
-
# :pages => [], # page names
|
|
21
|
-
# }
|
|
22
|
-
#--
|
|
23
|
-
# TODO need to prune classes
|
|
24
|
-
|
|
25
|
-
class RDoc::Store
|
|
26
|
-
|
|
4
|
+
module RDoc
|
|
27
5
|
##
|
|
28
|
-
#
|
|
6
|
+
# A set of rdoc data for a single project (gem, path, etc.).
|
|
7
|
+
#
|
|
8
|
+
# The store manages reading and writing ri data for a project and maintains a
|
|
9
|
+
# cache of methods, classes and ancestors in the store.
|
|
10
|
+
#
|
|
11
|
+
# The store maintains a #cache of its contents for faster lookup. After
|
|
12
|
+
# adding items to the store it must be flushed using #save_cache. The cache
|
|
13
|
+
# contains the following structures:
|
|
14
|
+
#
|
|
15
|
+
# @cache = {
|
|
16
|
+
# :ancestors => {}, # class name => ancestor names
|
|
17
|
+
# :attributes => {}, # class name => attributes
|
|
18
|
+
# :class_methods => {}, # class name => class methods
|
|
19
|
+
# :instance_methods => {}, # class name => instance methods
|
|
20
|
+
# :modules => [], # classes and modules in this store
|
|
21
|
+
# :pages => [], # page names
|
|
22
|
+
# }
|
|
23
|
+
#--
|
|
24
|
+
# TODO need to prune classes
|
|
29
25
|
|
|
30
|
-
class
|
|
31
|
-
end
|
|
26
|
+
class Store
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
##
|
|
29
|
+
# Errors raised from loading or saving the store
|
|
35
30
|
|
|
36
|
-
|
|
31
|
+
class Error < ::RDoc::Error
|
|
32
|
+
end
|
|
37
33
|
|
|
38
34
|
##
|
|
39
|
-
#
|
|
35
|
+
# Raised when a stored file for a class, module, page or method is missing.
|
|
40
36
|
|
|
41
|
-
|
|
37
|
+
class MissingFileError < Error
|
|
42
38
|
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
##
|
|
40
|
+
# The store the file should exist in
|
|
45
41
|
|
|
46
|
-
|
|
42
|
+
attr_reader :store
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
##
|
|
45
|
+
# The file the #name should be saved as
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
attr_reader :file
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# +name+ that should have been in the +store+.
|
|
49
|
+
##
|
|
50
|
+
# The name of the object the #file would be loaded from
|
|
56
51
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
attr_reader :name
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# Creates a new MissingFileError for the missing +file+ for the given
|
|
56
|
+
# +name+ that should have been in the +store+.
|
|
57
|
+
|
|
58
|
+
def initialize(store, file, name)
|
|
59
|
+
@store = store
|
|
60
|
+
@file = file
|
|
61
|
+
@name = name
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def message # :nodoc:
|
|
65
|
+
"store at #{@store.path} missing file #{@file} for #{@name}"
|
|
66
|
+
end
|
|
62
67
|
|
|
63
|
-
def message # :nodoc:
|
|
64
|
-
"store at #{@store.path} missing file #{@file} for #{@name}"
|
|
65
68
|
end
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
##
|
|
71
|
+
# Stores the name of the C variable a class belongs to. This helps wire up
|
|
72
|
+
# classes defined from C across files.
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
# Stores the name of the C variable a class belongs to. This helps wire up
|
|
71
|
-
# classes defined from C across files.
|
|
74
|
+
attr_reader :c_enclosure_classes # :nodoc:
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
attr_reader :c_enclosure_names # :nodoc:
|
|
74
77
|
|
|
75
|
-
|
|
78
|
+
##
|
|
79
|
+
# Maps C variables to class or module names for each parsed C file.
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
# Maps C variables to class or module names for each parsed C file.
|
|
81
|
+
attr_reader :c_class_variables
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
##
|
|
84
|
+
# Maps C variables to singleton class names for each parsed C file.
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
# Maps C variables to singleton class names for each parsed C file.
|
|
86
|
+
attr_reader :c_singleton_class_variables
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
##
|
|
89
|
+
# If true this Store will not write any files
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
# If true this Store will not write any files
|
|
91
|
+
attr_accessor :dry_run
|
|
89
92
|
|
|
90
|
-
|
|
93
|
+
##
|
|
94
|
+
# Path this store reads or writes
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
# Path this store reads or writes
|
|
96
|
+
attr_accessor :path
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
attr_reader :options
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
##
|
|
101
|
+
# Type of ri datastore this was loaded from. See RDoc::RI::Driver,
|
|
102
|
+
# RDoc::RI::Paths.
|
|
98
103
|
|
|
99
|
-
|
|
100
|
-
# Type of ri datastore this was loaded from. See RDoc::RI::Driver,
|
|
101
|
-
# RDoc::RI::Paths.
|
|
104
|
+
attr_accessor :type
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
##
|
|
107
|
+
# The contents of the Store
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
# The contents of the Store
|
|
109
|
+
attr_reader :cache
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
##
|
|
112
|
+
# The encoding of the contents in the Store
|
|
109
113
|
|
|
110
|
-
|
|
111
|
-
# The encoding of the contents in the Store
|
|
114
|
+
attr_accessor :encoding
|
|
112
115
|
|
|
113
|
-
|
|
116
|
+
##
|
|
117
|
+
# Creates a new Store of +type+ that will load or save to +path+
|
|
118
|
+
|
|
119
|
+
def initialize(options, path: nil, type: nil)
|
|
120
|
+
@options = options
|
|
121
|
+
@dry_run = options.dry_run
|
|
122
|
+
@encoding = options.encoding
|
|
123
|
+
@path = path || options.op_dir
|
|
124
|
+
@type = type
|
|
125
|
+
|
|
126
|
+
@cache = {
|
|
127
|
+
:ancestors => {},
|
|
128
|
+
:attributes => {},
|
|
129
|
+
:class_methods => {},
|
|
130
|
+
:c_class_variables => {},
|
|
131
|
+
:c_singleton_class_variables => {},
|
|
132
|
+
:encoding => @encoding,
|
|
133
|
+
:instance_methods => {},
|
|
134
|
+
:main => options.main_page,
|
|
135
|
+
:modules => [],
|
|
136
|
+
:pages => [],
|
|
137
|
+
:title => options.title,
|
|
138
|
+
}
|
|
114
139
|
|
|
115
|
-
|
|
116
|
-
|
|
140
|
+
@classes_hash = {}
|
|
141
|
+
@modules_hash = {}
|
|
142
|
+
@files_hash = {}
|
|
117
143
|
|
|
118
|
-
|
|
144
|
+
@c_enclosure_classes = {}
|
|
145
|
+
@c_enclosure_names = {}
|
|
119
146
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def initialize(options, path: nil, type: nil)
|
|
124
|
-
@options = options
|
|
125
|
-
@dry_run = options.dry_run
|
|
126
|
-
@encoding = options.encoding
|
|
127
|
-
@path = path || options.op_dir
|
|
128
|
-
@type = type
|
|
129
|
-
|
|
130
|
-
@cache = {
|
|
131
|
-
:ancestors => {},
|
|
132
|
-
:attributes => {},
|
|
133
|
-
:class_methods => {},
|
|
134
|
-
:c_class_variables => {},
|
|
135
|
-
:c_singleton_class_variables => {},
|
|
136
|
-
:encoding => @encoding,
|
|
137
|
-
:instance_methods => {},
|
|
138
|
-
:main => options.main_page,
|
|
139
|
-
:modules => [],
|
|
140
|
-
:pages => [],
|
|
141
|
-
:title => options.title,
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@classes_hash = {}
|
|
145
|
-
@modules_hash = {}
|
|
146
|
-
@files_hash = {}
|
|
147
|
-
@text_files_hash = {}
|
|
148
|
-
|
|
149
|
-
@c_enclosure_classes = {}
|
|
150
|
-
@c_enclosure_names = {}
|
|
151
|
-
|
|
152
|
-
@c_class_variables = {}
|
|
153
|
-
@c_singleton_class_variables = {}
|
|
154
|
-
|
|
155
|
-
@unique_classes = nil
|
|
156
|
-
@unique_modules = nil
|
|
157
|
-
|
|
158
|
-
@unmatched_constant_alias = {}
|
|
159
|
-
end
|
|
147
|
+
@c_class_variables = {}
|
|
148
|
+
@c_singleton_class_variables = {}
|
|
160
149
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
150
|
+
@unique_classes = nil
|
|
151
|
+
@unique_modules = nil
|
|
152
|
+
end
|
|
164
153
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
154
|
+
##
|
|
155
|
+
# Adds +module+ as an enclosure (namespace) for the given +variable+ for C
|
|
156
|
+
# files.
|
|
168
157
|
|
|
169
|
-
|
|
170
|
-
|
|
158
|
+
def add_c_enclosure(variable, namespace)
|
|
159
|
+
@c_enclosure_classes[variable] = namespace
|
|
160
|
+
end
|
|
171
161
|
|
|
172
|
-
|
|
173
|
-
|
|
162
|
+
##
|
|
163
|
+
# Adds C variables from an RDoc::Parser::C
|
|
174
164
|
|
|
175
|
-
|
|
165
|
+
def add_c_variables(c_parser)
|
|
166
|
+
filename = c_parser.top_level.relative_name
|
|
176
167
|
|
|
177
|
-
|
|
178
|
-
end
|
|
168
|
+
@c_class_variables[filename] = make_variable_map c_parser.classes
|
|
179
169
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
170
|
+
@c_singleton_class_variables[filename] = c_parser.singleton_classes
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
##
|
|
174
|
+
# Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the
|
|
175
|
+
# created RDoc::TopLevel.
|
|
176
|
+
|
|
177
|
+
def add_file(absolute_name, relative_name: absolute_name, parser: nil)
|
|
178
|
+
unless top_level = @files_hash[relative_name]
|
|
179
|
+
top_level = TopLevel.new absolute_name, relative_name
|
|
180
|
+
top_level.parser = parser if parser
|
|
181
|
+
top_level.store = self
|
|
182
|
+
@files_hash[relative_name] = top_level
|
|
183
|
+
@page_index = nil
|
|
184
|
+
end
|
|
183
185
|
|
|
184
|
-
|
|
185
|
-
unless top_level = @files_hash[relative_name] then
|
|
186
|
-
top_level = RDoc::TopLevel.new absolute_name, relative_name
|
|
187
|
-
top_level.parser = parser if parser
|
|
188
|
-
top_level.store = self
|
|
189
|
-
@files_hash[relative_name] = top_level
|
|
190
|
-
@text_files_hash[relative_name] = top_level if top_level.text?
|
|
186
|
+
top_level
|
|
191
187
|
end
|
|
192
188
|
|
|
193
|
-
|
|
194
|
-
|
|
189
|
+
##
|
|
190
|
+
# Removes a file and its classes/modules from the store. Used by the
|
|
191
|
+
# live-reloading server when a source file is deleted.
|
|
192
|
+
#
|
|
193
|
+
# Note: this does not handle reopened classes correctly. If a class is
|
|
194
|
+
# defined across multiple files (e.g. +Foo+ in both +a.rb+ and +b.rb+),
|
|
195
|
+
# deleting one file removes the entire class from the store — including
|
|
196
|
+
# the parts contributed by the other file. Saving the remaining file
|
|
197
|
+
# triggers a re-parse that restores it.
|
|
198
|
+
|
|
199
|
+
def remove_file(relative_name)
|
|
200
|
+
top_level = @files_hash.delete(relative_name)
|
|
201
|
+
@c_class_variables.delete(relative_name)
|
|
202
|
+
@c_singleton_class_variables.delete(relative_name)
|
|
203
|
+
return unless top_level
|
|
204
|
+
|
|
205
|
+
@page_index = nil
|
|
206
|
+
remove_classes_and_modules(top_level.classes_or_modules)
|
|
207
|
+
end
|
|
195
208
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
209
|
+
##
|
|
210
|
+
# Removes a file's contributions (methods, constants, comments, etc.)
|
|
211
|
+
# from its classes and modules. If no other files contribute to a
|
|
212
|
+
# class or module, it is removed from the store entirely. This
|
|
213
|
+
# prevents duplication when the file is re-parsed while preserving
|
|
214
|
+
# shared namespaces like +RDoc+ that span many files.
|
|
215
|
+
|
|
216
|
+
def clear_file_contributions(relative_name, keep_position: false)
|
|
217
|
+
top_level = @files_hash[relative_name]
|
|
218
|
+
return unless top_level
|
|
219
|
+
|
|
220
|
+
top_level.classes_or_modules.each do |cm|
|
|
221
|
+
# Remove methods and attributes contributed by this file
|
|
222
|
+
cm.method_list.reject! { |m| m.file == top_level }
|
|
223
|
+
cm.attributes.reject! { |a| a.file == top_level }
|
|
224
|
+
|
|
225
|
+
# Rebuild methods_hash from remaining methods and attributes
|
|
226
|
+
cm.methods_hash.clear
|
|
227
|
+
cm.method_list.each { |m| cm.methods_hash[m.pretty_name] = m }
|
|
228
|
+
cm.attributes.each { |a| cm.methods_hash[a.pretty_name] = a }
|
|
229
|
+
|
|
230
|
+
# Remove constants contributed by this file
|
|
231
|
+
cm.constants.reject! { |c| c.file == top_level }
|
|
232
|
+
cm.constants_hash.clear
|
|
233
|
+
cm.constants.each { |c| cm.constants_hash[c.name] = c }
|
|
234
|
+
|
|
235
|
+
# Remove includes, extends, and aliases from this file
|
|
236
|
+
cm.includes.reject! { |i| i.file == top_level }
|
|
237
|
+
cm.extends.reject! { |e| e.file == top_level }
|
|
238
|
+
cm.aliases.reject! { |a| a.file == top_level }
|
|
239
|
+
cm.external_aliases.reject! { |a| a.file == top_level }
|
|
240
|
+
|
|
241
|
+
# Clear or remove comment entries from this file
|
|
242
|
+
if cm.is_a?(ClassModule)
|
|
243
|
+
if keep_position
|
|
244
|
+
cm.comment_location[top_level] = [] if cm.comment_location.key?(top_level)
|
|
245
|
+
else
|
|
246
|
+
cm.comment_location.delete(top_level)
|
|
247
|
+
end
|
|
248
|
+
cm.rebuild_comment_from_location
|
|
249
|
+
end
|
|
199
250
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
251
|
+
unless keep_position
|
|
252
|
+
# Remove this file from the class/module's file list
|
|
253
|
+
cm.in_files.delete(top_level)
|
|
254
|
+
|
|
255
|
+
# If no files contribute to this class/module anymore, remove it
|
|
256
|
+
# from the store entirely. This handles file deletion correctly
|
|
257
|
+
# for classes that are only defined in the deleted file, while
|
|
258
|
+
# preserving classes that span multiple files.
|
|
259
|
+
if cm.in_files.empty?
|
|
260
|
+
if cm.is_a?(NormalModule)
|
|
261
|
+
@modules_hash.delete(cm.full_name)
|
|
262
|
+
else
|
|
263
|
+
@classes_hash.delete(cm.full_name)
|
|
264
|
+
end
|
|
265
|
+
cm.parent&.classes_hash&.delete(cm.name)
|
|
266
|
+
cm.parent&.modules_hash&.delete(cm.name)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
204
269
|
end
|
|
270
|
+
|
|
271
|
+
# Clear the TopLevel's class/module list to prevent duplicates
|
|
272
|
+
top_level.classes_or_modules.clear
|
|
205
273
|
end
|
|
206
|
-
end
|
|
207
274
|
|
|
208
|
-
|
|
209
|
-
|
|
275
|
+
##
|
|
276
|
+
# Removes stale empty placeholders left by +clear_file_contributions+ with
|
|
277
|
+
# <tt>keep_position: true</tt>. After re-parsing, a file may no longer
|
|
278
|
+
# define a class it previously contributed to, leaving an empty entry in
|
|
279
|
+
# +comment_location+ and a stale +in_files+ reference. Call this after
|
|
280
|
+
# all re-parsing is complete.
|
|
281
|
+
|
|
282
|
+
def cleanup_stale_contributions
|
|
283
|
+
all_classes_and_modules.each do |cm|
|
|
284
|
+
cm.comment_location.delete_if { |_, comments| comments.empty? }
|
|
285
|
+
cm.rebuild_comment_from_location
|
|
286
|
+
|
|
287
|
+
cm.in_files.select! { |tl| cm.comment_location.key?(tl) ||
|
|
288
|
+
cm.method_list.any? { |m| m.file == tl } ||
|
|
289
|
+
cm.attributes.any? { |a| a.file == tl } ||
|
|
290
|
+
cm.constants.any? { |c| c.file == tl } }
|
|
291
|
+
|
|
292
|
+
if cm.in_files.empty?
|
|
293
|
+
if cm.is_a?(NormalModule)
|
|
294
|
+
@modules_hash.delete(cm.full_name)
|
|
295
|
+
else
|
|
296
|
+
@classes_hash.delete(cm.full_name)
|
|
297
|
+
end
|
|
298
|
+
cm.parent&.classes_hash&.delete(cm.name)
|
|
299
|
+
cm.parent&.modules_hash&.delete(cm.name)
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
##
|
|
305
|
+
# Make sure any references to C variable names are resolved to the corresponding class.
|
|
306
|
+
#
|
|
210
307
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
308
|
+
def resolve_c_superclasses
|
|
309
|
+
@classes_hash.each_value do |klass|
|
|
310
|
+
if klass.superclass.is_a?(String) && (candidate = find_c_enclosure(klass.superclass))
|
|
311
|
+
klass.superclass = candidate
|
|
312
|
+
end
|
|
313
|
+
end
|
|
214
314
|
end
|
|
215
|
-
end
|
|
216
315
|
|
|
217
|
-
|
|
218
|
-
|
|
316
|
+
##
|
|
317
|
+
# Returns all classes discovered by RDoc
|
|
219
318
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
319
|
+
def all_classes
|
|
320
|
+
@classes_hash.values
|
|
321
|
+
end
|
|
223
322
|
|
|
224
|
-
|
|
225
|
-
|
|
323
|
+
##
|
|
324
|
+
# Returns all classes and modules discovered by RDoc
|
|
226
325
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
326
|
+
def all_classes_and_modules
|
|
327
|
+
@classes_hash.values + @modules_hash.values
|
|
328
|
+
end
|
|
230
329
|
|
|
231
|
-
|
|
232
|
-
|
|
330
|
+
##
|
|
331
|
+
# Returns a hash mapping class/module names to their paths, for use
|
|
332
|
+
# by type signature linking. Maps both qualified names (Foo::Bar) and
|
|
333
|
+
# unambiguous unqualified names (Bar). Ambiguous unqualified names
|
|
334
|
+
# (where multiple classes share the same name) are excluded to avoid
|
|
335
|
+
# wrong links. Cached after first call.
|
|
233
336
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
337
|
+
##
|
|
338
|
+
# Invalidates the cached type name lookup. Server mode calls this after
|
|
339
|
+
# re-parsing changes the set of classes and modules.
|
|
237
340
|
|
|
238
|
-
|
|
239
|
-
|
|
341
|
+
def invalidate_type_name_lookup # :nodoc:
|
|
342
|
+
@type_name_lookup = nil
|
|
343
|
+
end
|
|
240
344
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
345
|
+
def type_name_lookup
|
|
346
|
+
@type_name_lookup ||= begin
|
|
347
|
+
lookup = {}
|
|
348
|
+
unqualified_names = {}
|
|
349
|
+
ambiguous_names = {}
|
|
350
|
+
all_classes_and_modules.each do |cm|
|
|
351
|
+
lookup[cm.full_name] = cm.path
|
|
352
|
+
unqualified_name = cm.name
|
|
353
|
+
|
|
354
|
+
if ambiguous_names[unqualified_name]
|
|
355
|
+
# already known ambiguous, skip
|
|
356
|
+
elsif unqualified_names.key?(unqualified_name)
|
|
357
|
+
unqualified_names.delete(unqualified_name)
|
|
358
|
+
ambiguous_names[unqualified_name] = true
|
|
359
|
+
else
|
|
360
|
+
unqualified_names[unqualified_name] = cm.path
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
lookup.merge!(unqualified_names)
|
|
364
|
+
end
|
|
365
|
+
end
|
|
244
366
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
367
|
+
##
|
|
368
|
+
# Stores RBS type signatures loaded from sidecar .rbs files, keyed by
|
|
369
|
+
# "ClassName#method" or "ClassName.method". Replaces any previously
|
|
370
|
+
# stored set, so passing +{}+ clears it. Inline +#:+ annotations on
|
|
371
|
+
# method objects are NOT touched — those are owned by the source file.
|
|
249
372
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
373
|
+
def merge_rbs_signatures(signatures)
|
|
374
|
+
@rbs_signatures = signatures
|
|
375
|
+
end
|
|
253
376
|
|
|
254
|
-
|
|
255
|
-
|
|
377
|
+
##
|
|
378
|
+
# Returns the RBS type signature lines for +method_attr+ from loaded
|
|
379
|
+
# sidecar +.rbs+ files, or +nil+ if none. Falls through to the
|
|
380
|
+
# canonical method for aliases, and handles +initialize+ -> +.new+
|
|
381
|
+
# singleton mapping.
|
|
382
|
+
|
|
383
|
+
def rbs_signature_for(method_attr)
|
|
384
|
+
return nil unless @rbs_signatures
|
|
385
|
+
cm = method_attr.parent
|
|
386
|
+
return nil unless cm.respond_to?(:full_name)
|
|
387
|
+
|
|
388
|
+
key = method_attr.singleton ? "#{cm.full_name}.#{method_attr.name}" : "#{cm.full_name}##{method_attr.name}"
|
|
389
|
+
sig = @rbs_signatures[key]
|
|
390
|
+
|
|
391
|
+
# RBS keys constructors as #initialize, but RDoc renames them to .new
|
|
392
|
+
if !sig && method_attr.name == 'new' && method_attr.singleton
|
|
393
|
+
sig = @rbs_signatures["#{cm.full_name}#initialize"]
|
|
394
|
+
end
|
|
256
395
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
396
|
+
# For aliases, fall through to the canonical method (its inline #:
|
|
397
|
+
# takes precedence over any sidecar signature on the alias's name).
|
|
398
|
+
if !sig && method_attr.is_alias_for
|
|
399
|
+
canonical = method_attr.is_alias_for
|
|
400
|
+
sig = canonical.type_signature_lines || rbs_signature_for(canonical)
|
|
401
|
+
end
|
|
260
402
|
|
|
261
|
-
|
|
262
|
-
|
|
403
|
+
sig
|
|
404
|
+
end
|
|
263
405
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
406
|
+
def clear_rbs_signatures # :nodoc:
|
|
407
|
+
@rbs_signatures = nil
|
|
408
|
+
end
|
|
267
409
|
|
|
268
|
-
|
|
269
|
-
|
|
410
|
+
##
|
|
411
|
+
# All TopLevels known to RDoc
|
|
270
412
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
end
|
|
413
|
+
def all_files
|
|
414
|
+
@files_hash.values
|
|
415
|
+
end
|
|
275
416
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
# methods (not full name).
|
|
417
|
+
##
|
|
418
|
+
# Returns all modules discovered by RDoc
|
|
279
419
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
420
|
+
def all_modules
|
|
421
|
+
modules_hash.values
|
|
422
|
+
end
|
|
283
423
|
|
|
284
|
-
|
|
285
|
-
|
|
424
|
+
##
|
|
425
|
+
# Ancestors cache accessor. Maps a klass name to an Array of its ancestors
|
|
426
|
+
# in this store. If Foo in this store inherits from Object, Kernel won't be
|
|
427
|
+
# listed (it will be included from ruby's ri store).
|
|
286
428
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
429
|
+
def ancestors
|
|
430
|
+
@cache[:ancestors]
|
|
431
|
+
end
|
|
290
432
|
|
|
291
|
-
|
|
292
|
-
|
|
433
|
+
##
|
|
434
|
+
# Attributes cache accessor. Maps a class to an Array of its attributes.
|
|
293
435
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
436
|
+
def attributes
|
|
437
|
+
@cache[:attributes]
|
|
438
|
+
end
|
|
297
439
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
# sorted
|
|
440
|
+
##
|
|
441
|
+
# Path to the cache file
|
|
301
442
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if item.empty? then
|
|
305
|
-
collection.delete name
|
|
306
|
-
else
|
|
307
|
-
# HACK mongrel-1.1.5 documents its files twice
|
|
308
|
-
item.uniq!
|
|
309
|
-
item.sort!
|
|
310
|
-
end
|
|
443
|
+
def cache_path
|
|
444
|
+
File.join @path, 'cache.ri'
|
|
311
445
|
end
|
|
312
|
-
end
|
|
313
446
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
#
|
|
317
|
-
# It finds unique classes/modules defined, and replaces classes/modules that
|
|
318
|
-
# are aliases for another one by a copy with RDoc::ClassModule#is_alias_for
|
|
319
|
-
# set.
|
|
320
|
-
#
|
|
321
|
-
# It updates the RDoc::ClassModule#constant_aliases attribute of "real"
|
|
322
|
-
# classes or modules.
|
|
323
|
-
#
|
|
324
|
-
# It also completely removes the classes and modules that should be removed
|
|
325
|
-
# from the documentation and the methods that have a visibility below
|
|
326
|
-
# +min_visibility+, which is the <tt>--visibility</tt> option.
|
|
327
|
-
#
|
|
328
|
-
# See also RDoc::Context#remove_from_documentation?
|
|
447
|
+
##
|
|
448
|
+
# Path to the ri data for +klass_name+
|
|
329
449
|
|
|
330
|
-
|
|
331
|
-
|
|
450
|
+
def class_file(klass_name)
|
|
451
|
+
name = klass_name.split('::').last
|
|
452
|
+
File.join class_path(klass_name), "cdesc-#{name}.ri"
|
|
453
|
+
end
|
|
332
454
|
|
|
333
|
-
|
|
334
|
-
|
|
455
|
+
##
|
|
456
|
+
# Class methods cache accessor. Maps a class to an Array of its class
|
|
457
|
+
# methods (not full name).
|
|
335
458
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
remove_nodoc @modules_hash
|
|
459
|
+
def class_methods
|
|
460
|
+
@cache[:class_methods]
|
|
339
461
|
end
|
|
340
462
|
|
|
341
|
-
|
|
342
|
-
|
|
463
|
+
##
|
|
464
|
+
# Path where data for +klass_name+ will be stored (methods or class data)
|
|
343
465
|
|
|
344
|
-
|
|
345
|
-
|
|
466
|
+
def class_path(klass_name)
|
|
467
|
+
File.join @path, *klass_name.split('::')
|
|
346
468
|
end
|
|
347
469
|
|
|
348
|
-
|
|
349
|
-
|
|
470
|
+
##
|
|
471
|
+
# Hash of all classes known to RDoc
|
|
350
472
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
473
|
+
def classes_hash
|
|
474
|
+
@classes_hash
|
|
475
|
+
end
|
|
354
476
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
477
|
+
##
|
|
478
|
+
# Removes empty items and ensures item in each collection are unique and
|
|
479
|
+
# sorted
|
|
480
|
+
|
|
481
|
+
def clean_cache_collection(collection) # :nodoc:
|
|
482
|
+
collection.each do |name, item|
|
|
483
|
+
if item.empty?
|
|
484
|
+
collection.delete name
|
|
485
|
+
else
|
|
486
|
+
# HACK mongrel-1.1.5 documents its files twice
|
|
487
|
+
item.uniq!
|
|
488
|
+
item.sort!
|
|
362
489
|
end
|
|
363
490
|
end
|
|
364
491
|
end
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
##
|
|
368
|
-
# Hash of all files known to RDoc
|
|
369
492
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
493
|
+
##
|
|
494
|
+
# Prepares the RDoc code object tree for use by a generator.
|
|
495
|
+
#
|
|
496
|
+
# It finds unique classes/modules defined, and replaces classes/modules that
|
|
497
|
+
# are aliases for another one by a copy with RDoc::ClassModule#is_alias_for
|
|
498
|
+
# set.
|
|
499
|
+
#
|
|
500
|
+
# It updates the RDoc::ClassModule#constant_aliases attribute of "real"
|
|
501
|
+
# classes or modules.
|
|
502
|
+
#
|
|
503
|
+
# It also completely removes the classes and modules that should be removed
|
|
504
|
+
# from the documentation and the methods that have a visibility below
|
|
505
|
+
# +min_visibility+, which is the <tt>--visibility</tt> option.
|
|
506
|
+
#
|
|
507
|
+
# See also RDoc::Context#remove_from_documentation?
|
|
373
508
|
|
|
374
|
-
|
|
375
|
-
|
|
509
|
+
def complete(min_visibility)
|
|
510
|
+
fix_basic_object_inheritance
|
|
376
511
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
break unless name = @c_enclosure_names[variable]
|
|
512
|
+
# cache included modules before they are removed from the documentation
|
|
513
|
+
all_classes_and_modules.each { |cm| cm.ancestors }
|
|
380
514
|
|
|
381
|
-
|
|
515
|
+
unless min_visibility == :nodoc
|
|
516
|
+
remove_nodoc @classes_hash
|
|
517
|
+
remove_nodoc @modules_hash
|
|
518
|
+
end
|
|
382
519
|
|
|
383
|
-
|
|
384
|
-
|
|
520
|
+
@unique_classes = find_unique @classes_hash
|
|
521
|
+
@unique_modules = find_unique @modules_hash
|
|
385
522
|
|
|
386
|
-
|
|
523
|
+
unique_classes_and_modules.each do |cm|
|
|
524
|
+
cm.complete min_visibility
|
|
525
|
+
end
|
|
387
526
|
|
|
388
|
-
|
|
527
|
+
@files_hash.each_key do |file_name|
|
|
528
|
+
tl = @files_hash[file_name]
|
|
389
529
|
|
|
390
|
-
|
|
530
|
+
unless tl.text?
|
|
531
|
+
tl.modules_hash.clear
|
|
532
|
+
tl.classes_hash.clear
|
|
391
533
|
|
|
392
|
-
|
|
534
|
+
tl.classes_or_modules.each do |cm|
|
|
535
|
+
name = cm.full_name
|
|
536
|
+
if cm.type == 'class'
|
|
537
|
+
tl.classes_hash[name] = cm if @classes_hash[name]
|
|
538
|
+
else
|
|
539
|
+
tl.modules_hash[name] = cm if @modules_hash[name]
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
end
|
|
393
543
|
end
|
|
544
|
+
end
|
|
394
545
|
|
|
395
|
-
|
|
546
|
+
##
|
|
547
|
+
# Hash of all files known to RDoc
|
|
548
|
+
|
|
549
|
+
def files_hash
|
|
550
|
+
@files_hash
|
|
396
551
|
end
|
|
397
|
-
end
|
|
398
552
|
|
|
399
|
-
|
|
400
|
-
|
|
553
|
+
##
|
|
554
|
+
# Finds the enclosure (namespace) for the given C +variable+.
|
|
401
555
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
556
|
+
def find_c_enclosure(variable)
|
|
557
|
+
@c_enclosure_classes.fetch variable do
|
|
558
|
+
break unless name = @c_enclosure_names[variable]
|
|
405
559
|
|
|
406
|
-
|
|
407
|
-
# Finds the class with +name+ starting in namespace +from+
|
|
560
|
+
mod = find_class_or_module name
|
|
408
561
|
|
|
409
|
-
|
|
410
|
-
|
|
562
|
+
unless mod
|
|
563
|
+
loaded_mod = load_class_data name
|
|
411
564
|
|
|
412
|
-
|
|
413
|
-
return nil unless from
|
|
565
|
+
file = loaded_mod.in_files.first
|
|
414
566
|
|
|
415
|
-
|
|
416
|
-
return klass if klass
|
|
567
|
+
return unless file # legacy data source
|
|
417
568
|
|
|
418
|
-
|
|
419
|
-
end
|
|
569
|
+
file.store = self
|
|
420
570
|
|
|
421
|
-
|
|
422
|
-
|
|
571
|
+
mod = file.add_module NormalModule, name
|
|
572
|
+
end
|
|
423
573
|
|
|
424
|
-
|
|
425
|
-
|
|
574
|
+
@c_enclosure_classes[variable] = mod
|
|
575
|
+
end
|
|
576
|
+
end
|
|
426
577
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
@classes_hash[name] || @modules_hash[name]
|
|
430
|
-
end
|
|
578
|
+
##
|
|
579
|
+
# Finds the class with +name+ in all discovered classes
|
|
431
580
|
|
|
432
|
-
|
|
433
|
-
|
|
581
|
+
def find_class_named(name)
|
|
582
|
+
@classes_hash[name]
|
|
583
|
+
end
|
|
434
584
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
end
|
|
585
|
+
##
|
|
586
|
+
# Finds the class with +name+ starting in namespace +from+
|
|
438
587
|
|
|
439
|
-
|
|
440
|
-
|
|
588
|
+
def find_class_named_from(name, from)
|
|
589
|
+
from = find_class_named from unless Context === from
|
|
441
590
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
end
|
|
591
|
+
until TopLevel === from do
|
|
592
|
+
return nil unless from
|
|
445
593
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
594
|
+
klass = from.find_class_named name
|
|
595
|
+
return klass if klass
|
|
596
|
+
|
|
597
|
+
from = from.parent
|
|
598
|
+
end
|
|
449
599
|
|
|
450
|
-
|
|
451
|
-
@text_files_hash.each_value.find do |file|
|
|
452
|
-
file.full_name == file_name
|
|
600
|
+
find_class_named name
|
|
453
601
|
end
|
|
454
|
-
end
|
|
455
602
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
603
|
+
##
|
|
604
|
+
# Finds the class or module with +name+
|
|
605
|
+
|
|
606
|
+
def find_class_or_module(name)
|
|
607
|
+
name = $' if name =~ /^::/
|
|
608
|
+
@classes_hash[name] || @modules_hash[name]
|
|
609
|
+
end
|
|
462
610
|
|
|
463
|
-
|
|
464
|
-
|
|
611
|
+
##
|
|
612
|
+
# Finds the file with +name+ in all discovered files
|
|
465
613
|
|
|
466
|
-
|
|
467
|
-
|
|
614
|
+
def find_file_named(name)
|
|
615
|
+
@files_hash[name]
|
|
468
616
|
end
|
|
469
617
|
|
|
470
|
-
|
|
471
|
-
|
|
618
|
+
##
|
|
619
|
+
# Finds the module with +name+ in all discovered modules
|
|
472
620
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
# Because we assumed all classes without a stated superclass
|
|
477
|
-
# inherit from Object, we have the above wrong inheritance.
|
|
478
|
-
#
|
|
479
|
-
# We fix BasicObject right away if we are running in a Ruby
|
|
480
|
-
# version >= 1.9.
|
|
621
|
+
def find_module_named(name)
|
|
622
|
+
@modules_hash[name]
|
|
623
|
+
end
|
|
481
624
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
basic.superclass = nil
|
|
486
|
-
end
|
|
625
|
+
##
|
|
626
|
+
# Returns the RDoc::TopLevel that is a text file and has the given
|
|
627
|
+
# +file_name+
|
|
487
628
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
def friendly_path
|
|
492
|
-
case type
|
|
493
|
-
when :gem then
|
|
494
|
-
parent = File.expand_path '..', @path
|
|
495
|
-
"gem #{File.basename parent}"
|
|
496
|
-
when :home then RDoc.home
|
|
497
|
-
when :site then 'ruby site'
|
|
498
|
-
when :system then 'ruby core'
|
|
499
|
-
else @path
|
|
629
|
+
def find_text_page(file_name)
|
|
630
|
+
page = @files_hash[file_name]
|
|
631
|
+
page if page&.text?
|
|
500
632
|
end
|
|
501
|
-
end
|
|
502
633
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
634
|
+
##
|
|
635
|
+
# Finds unique classes/modules defined in +all_hash+,
|
|
636
|
+
# and returns them as an array. Performs the alias
|
|
637
|
+
# updates in +all_hash+: see ::complete.
|
|
638
|
+
#--
|
|
639
|
+
# TODO aliases should be registered by Context#add_module_alias
|
|
506
640
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
# instance methods (not full name).
|
|
641
|
+
def find_unique(all_hash)
|
|
642
|
+
unique = []
|
|
510
643
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
644
|
+
all_hash.each_pair do |full_name, cm|
|
|
645
|
+
unique << cm if full_name == cm.full_name
|
|
646
|
+
end
|
|
514
647
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
# documentation tree for use by a generator
|
|
648
|
+
unique
|
|
649
|
+
end
|
|
518
650
|
|
|
519
|
-
|
|
520
|
-
|
|
651
|
+
##
|
|
652
|
+
# Fixes the erroneous <tt>BasicObject < Object</tt> in 1.9.
|
|
653
|
+
#
|
|
654
|
+
# Because we assumed all classes without a stated superclass
|
|
655
|
+
# inherit from Object, we have the above wrong inheritance.
|
|
656
|
+
#
|
|
657
|
+
# We fix BasicObject right away if we are running in a Ruby
|
|
658
|
+
# version >= 1.9.
|
|
521
659
|
|
|
522
|
-
|
|
523
|
-
|
|
660
|
+
def fix_basic_object_inheritance
|
|
661
|
+
basic = classes_hash['BasicObject']
|
|
662
|
+
return unless basic
|
|
663
|
+
basic.superclass = nil
|
|
664
|
+
end
|
|
524
665
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
666
|
+
##
|
|
667
|
+
# Friendly rendition of #path
|
|
668
|
+
|
|
669
|
+
def friendly_path
|
|
670
|
+
case type
|
|
671
|
+
when :gem
|
|
672
|
+
parent = File.expand_path '..', @path
|
|
673
|
+
"gem #{File.basename parent}"
|
|
674
|
+
when :home then ::RDoc.home
|
|
675
|
+
when :site then 'ruby site'
|
|
676
|
+
when :system then 'ruby core'
|
|
677
|
+
else @path
|
|
529
678
|
end
|
|
679
|
+
end
|
|
530
680
|
|
|
531
|
-
|
|
681
|
+
def inspect # :nodoc:
|
|
682
|
+
"#<%s:0x%x %s %p>" % [self.class, object_id, @path, module_names.sort]
|
|
683
|
+
end
|
|
532
684
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
685
|
+
##
|
|
686
|
+
# Instance methods cache accessor. Maps a class to an Array of its
|
|
687
|
+
# instance methods (not full name).
|
|
536
688
|
|
|
537
|
-
|
|
689
|
+
def instance_methods
|
|
690
|
+
@cache[:instance_methods]
|
|
538
691
|
end
|
|
539
692
|
|
|
540
|
-
|
|
541
|
-
|
|
693
|
+
##
|
|
694
|
+
# Loads all items from this store into memory. This recreates a
|
|
695
|
+
# documentation tree for use by a generator
|
|
696
|
+
|
|
697
|
+
def load_all
|
|
698
|
+
load_cache
|
|
542
699
|
|
|
543
|
-
module_names.each do |
|
|
544
|
-
|
|
700
|
+
module_names.each do |module_name|
|
|
701
|
+
mod = find_class_or_module(module_name) || load_class(module_name)
|
|
545
702
|
|
|
546
|
-
|
|
703
|
+
# load method documentation since the loaded class/module does not have
|
|
704
|
+
# it
|
|
705
|
+
loaded_methods = mod.method_list.map do |method|
|
|
706
|
+
load_method module_name, method.full_name
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
mod.method_list.replace loaded_methods
|
|
547
710
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
mod.classes_hash[name] = descendent
|
|
551
|
-
when RDoc::NormalModule then
|
|
552
|
-
mod.modules_hash[name] = descendent
|
|
711
|
+
loaded_attributes = mod.attributes.map do |attribute|
|
|
712
|
+
load_method module_name, attribute.full_name
|
|
553
713
|
end
|
|
714
|
+
|
|
715
|
+
mod.attributes.replace loaded_attributes
|
|
554
716
|
end
|
|
555
|
-
end
|
|
556
717
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
718
|
+
all_classes_and_modules.each do |mod|
|
|
719
|
+
descendent_re = /^#{mod.full_name}::[^:]+$/
|
|
720
|
+
|
|
721
|
+
module_names.each do |name|
|
|
722
|
+
next unless name =~ descendent_re
|
|
723
|
+
|
|
724
|
+
descendent = find_class_or_module name
|
|
725
|
+
|
|
726
|
+
case descendent
|
|
727
|
+
when NormalClass
|
|
728
|
+
mod.classes_hash[name] = descendent
|
|
729
|
+
when NormalModule
|
|
730
|
+
mod.modules_hash[name] = descendent
|
|
731
|
+
end
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
@page_index = nil
|
|
736
|
+
@cache[:pages].each do |page_name|
|
|
737
|
+
@files_hash[page_name] = load_page(page_name)
|
|
738
|
+
end
|
|
561
739
|
end
|
|
562
|
-
end
|
|
563
740
|
|
|
564
|
-
|
|
565
|
-
|
|
741
|
+
##
|
|
742
|
+
# Loads cache file for this store
|
|
566
743
|
|
|
567
|
-
|
|
568
|
-
|
|
744
|
+
def load_cache
|
|
745
|
+
#orig_enc = @encoding
|
|
569
746
|
|
|
570
|
-
|
|
747
|
+
@cache = marshal_load(cache_path)
|
|
571
748
|
|
|
572
|
-
|
|
749
|
+
load_enc = @cache[:encoding]
|
|
573
750
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
751
|
+
# TODO this feature will be time-consuming to add:
|
|
752
|
+
# a) Encodings may be incompatible but transcodeable
|
|
753
|
+
# b) Need to warn in the appropriate spots, wherever they may be
|
|
754
|
+
# c) Need to handle cross-cache differences in encodings
|
|
755
|
+
# d) Need to warn when generating into a cache with different encodings
|
|
756
|
+
#
|
|
757
|
+
#if orig_enc and load_enc != orig_enc then
|
|
758
|
+
# warn "Cached encoding #{load_enc} is incompatible with #{orig_enc}\n" \
|
|
759
|
+
# "from #{path}/cache.ri" unless
|
|
760
|
+
# Encoding.compatible? orig_enc, load_enc
|
|
761
|
+
#end
|
|
585
762
|
|
|
586
|
-
|
|
763
|
+
@encoding = load_enc unless @encoding
|
|
587
764
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
765
|
+
@cache[:pages] ||= []
|
|
766
|
+
@cache[:main] ||= nil
|
|
767
|
+
@cache[:c_class_variables] ||= {}
|
|
768
|
+
@cache[:c_singleton_class_variables] ||= {}
|
|
592
769
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
770
|
+
@cache[:c_class_variables].each do |_, map|
|
|
771
|
+
map.each do |variable, name|
|
|
772
|
+
@c_enclosure_names[variable] = name
|
|
773
|
+
end
|
|
596
774
|
end
|
|
597
|
-
end
|
|
598
775
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
776
|
+
@cache
|
|
777
|
+
rescue Errno::ENOENT
|
|
778
|
+
end
|
|
602
779
|
|
|
603
|
-
|
|
604
|
-
|
|
780
|
+
##
|
|
781
|
+
# Loads ri data for +klass_name+ and hooks it up to this store.
|
|
605
782
|
|
|
606
|
-
|
|
607
|
-
|
|
783
|
+
def load_class(klass_name)
|
|
784
|
+
obj = load_class_data klass_name
|
|
608
785
|
|
|
609
|
-
|
|
786
|
+
obj.store = self
|
|
610
787
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
788
|
+
case obj
|
|
789
|
+
when NormalClass
|
|
790
|
+
@classes_hash[klass_name] = obj
|
|
791
|
+
when SingleClass
|
|
792
|
+
@classes_hash[klass_name] = obj
|
|
793
|
+
when NormalModule
|
|
794
|
+
@modules_hash[klass_name] = obj
|
|
795
|
+
end
|
|
618
796
|
end
|
|
619
|
-
end
|
|
620
797
|
|
|
621
|
-
|
|
622
|
-
|
|
798
|
+
##
|
|
799
|
+
# Loads ri data for +klass_name+
|
|
623
800
|
|
|
624
|
-
|
|
625
|
-
|
|
801
|
+
def load_class_data(klass_name)
|
|
802
|
+
file = class_file klass_name
|
|
626
803
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
804
|
+
marshal_load(file)
|
|
805
|
+
rescue Errno::ENOENT => e
|
|
806
|
+
error = MissingFileError.new(self, file, klass_name)
|
|
807
|
+
error.set_backtrace e.backtrace
|
|
808
|
+
raise error
|
|
809
|
+
end
|
|
633
810
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
811
|
+
##
|
|
812
|
+
# Loads ri data for +method_name+ in +klass_name+
|
|
813
|
+
|
|
814
|
+
def load_method(klass_name, method_name)
|
|
815
|
+
file = method_file klass_name, method_name
|
|
816
|
+
|
|
817
|
+
obj = marshal_load(file)
|
|
818
|
+
obj.store = self
|
|
819
|
+
obj.parent ||= find_class_or_module(klass_name) || load_class(klass_name)
|
|
820
|
+
obj
|
|
821
|
+
rescue Errno::ENOENT => e
|
|
822
|
+
error = MissingFileError.new(self, file, klass_name + method_name)
|
|
823
|
+
error.set_backtrace e.backtrace
|
|
824
|
+
raise error
|
|
825
|
+
end
|
|
649
826
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
827
|
+
##
|
|
828
|
+
# Loads ri data for +page_name+
|
|
829
|
+
|
|
830
|
+
def load_page(page_name)
|
|
831
|
+
file = page_file page_name
|
|
832
|
+
|
|
833
|
+
obj = marshal_load(file)
|
|
834
|
+
obj.store = self
|
|
835
|
+
obj
|
|
836
|
+
rescue Errno::ENOENT => e
|
|
837
|
+
error = MissingFileError.new(self, file, page_name)
|
|
838
|
+
error.set_backtrace e.backtrace
|
|
839
|
+
raise error
|
|
840
|
+
end
|
|
664
841
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
842
|
+
##
|
|
843
|
+
# Gets the main page for this RDoc store. This page is used as the root of
|
|
844
|
+
# the RDoc server.
|
|
668
845
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
846
|
+
def main
|
|
847
|
+
@cache[:main]
|
|
848
|
+
end
|
|
672
849
|
|
|
673
|
-
|
|
674
|
-
|
|
850
|
+
##
|
|
851
|
+
# Sets the main page for this RDoc store.
|
|
675
852
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
853
|
+
def main=(page)
|
|
854
|
+
@cache[:main] = page
|
|
855
|
+
end
|
|
679
856
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
857
|
+
##
|
|
858
|
+
# Converts the variable => ClassModule map +variables+ from a C parser into
|
|
859
|
+
# a variable => class name map.
|
|
683
860
|
|
|
684
|
-
|
|
685
|
-
|
|
861
|
+
def make_variable_map(variables)
|
|
862
|
+
map = {}
|
|
686
863
|
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
864
|
+
variables.each { |variable, class_module|
|
|
865
|
+
map[variable] = class_module.full_name
|
|
866
|
+
}
|
|
690
867
|
|
|
691
|
-
|
|
692
|
-
|
|
868
|
+
map
|
|
869
|
+
end
|
|
693
870
|
|
|
694
|
-
|
|
695
|
-
|
|
871
|
+
##
|
|
872
|
+
# Path to the ri data for +method_name+ in +klass_name+
|
|
696
873
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
874
|
+
def method_file(klass_name, method_name)
|
|
875
|
+
method_name = method_name.split('::').last
|
|
876
|
+
method_name =~ /#(.*)/
|
|
877
|
+
method_type = $1 ? 'i' : 'c'
|
|
878
|
+
method_name = $1 if $1
|
|
879
|
+
method_name = method_name.gsub(/\W/) { "%%%02x" % $&[0].ord }
|
|
703
880
|
|
|
704
|
-
|
|
705
|
-
|
|
881
|
+
File.join class_path(klass_name), "#{method_name}-#{method_type}.ri"
|
|
882
|
+
end
|
|
706
883
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
884
|
+
##
|
|
885
|
+
# Modules cache accessor. An Array of all the module (and class) names in
|
|
886
|
+
# the store.
|
|
710
887
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
888
|
+
def module_names
|
|
889
|
+
@cache[:modules]
|
|
890
|
+
end
|
|
714
891
|
|
|
715
|
-
|
|
716
|
-
|
|
892
|
+
##
|
|
893
|
+
# Hash of all modules known to RDoc
|
|
717
894
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
895
|
+
def modules_hash
|
|
896
|
+
@modules_hash
|
|
897
|
+
end
|
|
721
898
|
|
|
722
|
-
|
|
723
|
-
|
|
899
|
+
##
|
|
900
|
+
# Returns the RDoc::TopLevel that is a file and has the given +name+
|
|
901
|
+
|
|
902
|
+
def page(name)
|
|
903
|
+
@page_index ||= @files_hash.each_value.each_with_object({}) do |file, index|
|
|
904
|
+
index[file.page_name] ||= file
|
|
905
|
+
index[file.base_name] ||= file
|
|
906
|
+
end
|
|
724
907
|
|
|
725
|
-
|
|
726
|
-
@files_hash.each_value.find do |file|
|
|
727
|
-
file.page_name == name or file.base_name == name
|
|
908
|
+
@page_index[name]
|
|
728
909
|
end
|
|
729
|
-
end
|
|
730
910
|
|
|
731
|
-
|
|
732
|
-
|
|
911
|
+
##
|
|
912
|
+
# Path to the ri data for +page_name+
|
|
733
913
|
|
|
734
|
-
|
|
735
|
-
|
|
914
|
+
def page_file(page_name)
|
|
915
|
+
file_name = File.basename(page_name).gsub('.', '_')
|
|
736
916
|
|
|
737
|
-
|
|
738
|
-
|
|
917
|
+
File.join @path, File.dirname(page_name), "page-#{file_name}.ri"
|
|
918
|
+
end
|
|
739
919
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
920
|
+
##
|
|
921
|
+
# Removes from +all_hash+ the contexts that are nodoc or have no content.
|
|
922
|
+
#
|
|
923
|
+
# See RDoc::Context#remove_from_documentation?
|
|
744
924
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
925
|
+
def remove_nodoc(all_hash)
|
|
926
|
+
all_hash.keys.each do |name|
|
|
927
|
+
context = all_hash[name]
|
|
928
|
+
all_hash.delete(name) if context.remove_from_documentation?
|
|
929
|
+
end
|
|
749
930
|
end
|
|
750
|
-
end
|
|
751
931
|
|
|
752
|
-
|
|
753
|
-
|
|
932
|
+
##
|
|
933
|
+
# Saves all entries in the store
|
|
934
|
+
|
|
935
|
+
def save
|
|
936
|
+
load_cache
|
|
754
937
|
|
|
755
|
-
|
|
756
|
-
|
|
938
|
+
all_classes_and_modules.each do |klass|
|
|
939
|
+
save_class klass
|
|
757
940
|
|
|
758
|
-
|
|
759
|
-
|
|
941
|
+
klass.each_method do |method|
|
|
942
|
+
save_method klass, method
|
|
943
|
+
end
|
|
760
944
|
|
|
761
|
-
|
|
762
|
-
|
|
945
|
+
klass.attributes.each do |attribute|
|
|
946
|
+
save_method klass, attribute
|
|
947
|
+
end
|
|
763
948
|
end
|
|
764
949
|
|
|
765
|
-
|
|
766
|
-
|
|
950
|
+
all_files.each do |file|
|
|
951
|
+
save_page file
|
|
767
952
|
end
|
|
768
|
-
end
|
|
769
953
|
|
|
770
|
-
|
|
771
|
-
save_page file
|
|
954
|
+
save_cache
|
|
772
955
|
end
|
|
773
956
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
##
|
|
778
|
-
# Writes the cache file for this store
|
|
957
|
+
##
|
|
958
|
+
# Writes the cache file for this store
|
|
779
959
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
960
|
+
def save_cache
|
|
961
|
+
clean_cache_collection @cache[:ancestors]
|
|
962
|
+
clean_cache_collection @cache[:attributes]
|
|
963
|
+
clean_cache_collection @cache[:class_methods]
|
|
964
|
+
clean_cache_collection @cache[:instance_methods]
|
|
785
965
|
|
|
786
|
-
|
|
787
|
-
|
|
966
|
+
@cache[:modules].uniq!
|
|
967
|
+
@cache[:modules].sort!
|
|
788
968
|
|
|
789
|
-
|
|
790
|
-
|
|
969
|
+
@cache[:pages].uniq!
|
|
970
|
+
@cache[:pages].sort!
|
|
791
971
|
|
|
792
|
-
|
|
972
|
+
@cache[:encoding] = @encoding # this gets set twice due to assert_cache
|
|
793
973
|
|
|
794
|
-
|
|
795
|
-
|
|
974
|
+
@cache[:c_class_variables].merge! @c_class_variables
|
|
975
|
+
@cache[:c_singleton_class_variables].merge! @c_singleton_class_variables
|
|
796
976
|
|
|
797
|
-
|
|
977
|
+
return if @dry_run
|
|
798
978
|
|
|
799
|
-
|
|
800
|
-
|
|
979
|
+
File.open cache_path, 'wb' do |io|
|
|
980
|
+
Marshal.dump @cache, io
|
|
981
|
+
end
|
|
801
982
|
end
|
|
802
|
-
end
|
|
803
983
|
|
|
804
|
-
|
|
805
|
-
|
|
984
|
+
##
|
|
985
|
+
# Writes the ri data for +klass+ (or module)
|
|
806
986
|
|
|
807
|
-
|
|
808
|
-
|
|
987
|
+
def save_class(klass)
|
|
988
|
+
full_name = klass.full_name
|
|
809
989
|
|
|
810
|
-
|
|
990
|
+
FileUtils.mkdir_p class_path(full_name) unless @dry_run
|
|
811
991
|
|
|
812
|
-
|
|
992
|
+
@cache[:modules] << full_name
|
|
813
993
|
|
|
814
|
-
|
|
994
|
+
path = class_file full_name
|
|
815
995
|
|
|
816
|
-
|
|
817
|
-
|
|
996
|
+
begin
|
|
997
|
+
disk_klass = load_class full_name
|
|
818
998
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
999
|
+
klass = disk_klass.merge klass
|
|
1000
|
+
rescue MissingFileError
|
|
1001
|
+
end
|
|
822
1002
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
1003
|
+
# BasicObject has no ancestors
|
|
1004
|
+
ancestors = klass.direct_ancestors.compact.map do |ancestor|
|
|
1005
|
+
# HACK for classes we don't know about (class X < RuntimeError)
|
|
1006
|
+
String === ancestor ? ancestor : ancestor.full_name
|
|
1007
|
+
end
|
|
828
1008
|
|
|
829
|
-
|
|
830
|
-
|
|
1009
|
+
@cache[:ancestors][full_name] ||= []
|
|
1010
|
+
@cache[:ancestors][full_name].concat ancestors
|
|
831
1011
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
1012
|
+
attribute_definitions = klass.attributes.map do |attribute|
|
|
1013
|
+
"#{attribute.definition} #{attribute.name}"
|
|
1014
|
+
end
|
|
835
1015
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
1016
|
+
unless attribute_definitions.empty?
|
|
1017
|
+
@cache[:attributes][full_name] ||= []
|
|
1018
|
+
@cache[:attributes][full_name].concat attribute_definitions
|
|
1019
|
+
end
|
|
840
1020
|
|
|
841
|
-
|
|
1021
|
+
to_delete = []
|
|
842
1022
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
1023
|
+
unless klass.method_list.empty?
|
|
1024
|
+
@cache[:class_methods][full_name] ||= []
|
|
1025
|
+
@cache[:instance_methods][full_name] ||= []
|
|
846
1026
|
|
|
847
|
-
|
|
848
|
-
|
|
1027
|
+
class_methods, instance_methods =
|
|
1028
|
+
klass.method_list.partition { |meth| meth.singleton }
|
|
849
1029
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1030
|
+
class_methods = class_methods. map { |method| method.name }
|
|
1031
|
+
instance_methods = instance_methods.map { |method| method.name }
|
|
1032
|
+
attribute_names = klass.attributes.map { |attr| attr.name }
|
|
853
1033
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1034
|
+
old = @cache[:class_methods][full_name] - class_methods
|
|
1035
|
+
to_delete.concat old.map { |method|
|
|
1036
|
+
method_file full_name, "#{full_name}::#{method}"
|
|
1037
|
+
}
|
|
858
1038
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
1039
|
+
old = @cache[:instance_methods][full_name] -
|
|
1040
|
+
instance_methods - attribute_names
|
|
1041
|
+
to_delete.concat old.map { |method|
|
|
1042
|
+
method_file full_name, "#{full_name}##{method}"
|
|
1043
|
+
}
|
|
864
1044
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1045
|
+
@cache[:class_methods][full_name] = class_methods
|
|
1046
|
+
@cache[:instance_methods][full_name] = instance_methods
|
|
1047
|
+
end
|
|
868
1048
|
|
|
869
|
-
|
|
1049
|
+
return if @dry_run
|
|
870
1050
|
|
|
871
|
-
|
|
1051
|
+
FileUtils.rm_f to_delete
|
|
872
1052
|
|
|
873
|
-
|
|
874
|
-
|
|
1053
|
+
File.open path, 'wb' do |io|
|
|
1054
|
+
Marshal.dump klass, io
|
|
1055
|
+
end
|
|
875
1056
|
end
|
|
876
|
-
end
|
|
877
1057
|
|
|
878
|
-
|
|
879
|
-
|
|
1058
|
+
##
|
|
1059
|
+
# Writes the ri data for +method+ on +klass+
|
|
880
1060
|
|
|
881
|
-
|
|
882
|
-
|
|
1061
|
+
def save_method(klass, method)
|
|
1062
|
+
full_name = klass.full_name
|
|
883
1063
|
|
|
884
|
-
|
|
1064
|
+
FileUtils.mkdir_p class_path(full_name) unless @dry_run
|
|
885
1065
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
1066
|
+
cache = if method.singleton
|
|
1067
|
+
@cache[:class_methods]
|
|
1068
|
+
else
|
|
1069
|
+
@cache[:instance_methods]
|
|
1070
|
+
end
|
|
1071
|
+
cache[full_name] ||= []
|
|
1072
|
+
cache[full_name] << method.name
|
|
893
1073
|
|
|
894
|
-
|
|
1074
|
+
return if @dry_run
|
|
895
1075
|
|
|
896
|
-
|
|
897
|
-
|
|
1076
|
+
File.open method_file(full_name, method.full_name), 'wb' do |io|
|
|
1077
|
+
Marshal.dump method, io
|
|
1078
|
+
end
|
|
898
1079
|
end
|
|
899
|
-
end
|
|
900
1080
|
|
|
901
|
-
|
|
902
|
-
|
|
1081
|
+
##
|
|
1082
|
+
# Writes the ri data for +page+
|
|
903
1083
|
|
|
904
|
-
|
|
905
|
-
|
|
1084
|
+
def save_page(page)
|
|
1085
|
+
return unless page.text?
|
|
906
1086
|
|
|
907
|
-
|
|
1087
|
+
path = page_file page.full_name
|
|
908
1088
|
|
|
909
|
-
|
|
1089
|
+
FileUtils.mkdir_p File.dirname(path) unless @dry_run
|
|
910
1090
|
|
|
911
|
-
|
|
912
|
-
|
|
1091
|
+
cache[:pages] ||= []
|
|
1092
|
+
cache[:pages] << page.full_name
|
|
913
1093
|
|
|
914
|
-
|
|
1094
|
+
return if @dry_run
|
|
915
1095
|
|
|
916
|
-
|
|
917
|
-
|
|
1096
|
+
File.open path, 'wb' do |io|
|
|
1097
|
+
Marshal.dump page, io
|
|
1098
|
+
end
|
|
918
1099
|
end
|
|
919
|
-
end
|
|
920
1100
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1101
|
+
##
|
|
1102
|
+
# Source of the contents of this store.
|
|
1103
|
+
#
|
|
1104
|
+
# For a store from a gem the source is the gem name. For a store from the
|
|
1105
|
+
# home directory the source is "home". For system ri store (the standard
|
|
1106
|
+
# library documentation) the source is"ruby". For a store from the site
|
|
1107
|
+
# ri directory the store is "site". For other stores the source is the
|
|
1108
|
+
# #path.
|
|
1109
|
+
|
|
1110
|
+
def source
|
|
1111
|
+
case type
|
|
1112
|
+
when :gem then File.basename File.expand_path '..', @path
|
|
1113
|
+
when :home then 'home'
|
|
1114
|
+
when :site then 'site'
|
|
1115
|
+
when :system then 'ruby'
|
|
1116
|
+
else @path
|
|
1117
|
+
end
|
|
937
1118
|
end
|
|
938
|
-
end
|
|
939
1119
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1120
|
+
##
|
|
1121
|
+
# Gets the title for this RDoc store. This is used as the title in each
|
|
1122
|
+
# page on the RDoc server
|
|
943
1123
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
1124
|
+
def title
|
|
1125
|
+
@cache[:title]
|
|
1126
|
+
end
|
|
947
1127
|
|
|
948
|
-
|
|
949
|
-
|
|
1128
|
+
##
|
|
1129
|
+
# Sets the title page for this RDoc store.
|
|
950
1130
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1131
|
+
def title=(title)
|
|
1132
|
+
@cache[:title] = title
|
|
1133
|
+
end
|
|
954
1134
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1135
|
+
##
|
|
1136
|
+
# Returns the unique classes discovered by RDoc.
|
|
1137
|
+
#
|
|
1138
|
+
# ::complete must have been called prior to using this method.
|
|
959
1139
|
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1140
|
+
def unique_classes
|
|
1141
|
+
@unique_classes
|
|
1142
|
+
end
|
|
963
1143
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1144
|
+
##
|
|
1145
|
+
# Returns the unique classes and modules discovered by RDoc.
|
|
1146
|
+
# ::complete must have been called prior to using this method.
|
|
967
1147
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1148
|
+
def unique_classes_and_modules
|
|
1149
|
+
@unique_classes + @unique_modules
|
|
1150
|
+
end
|
|
971
1151
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1152
|
+
##
|
|
1153
|
+
# Returns the unique modules discovered by RDoc.
|
|
1154
|
+
# ::complete must have been called prior to using this method.
|
|
975
1155
|
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1156
|
+
def unique_modules
|
|
1157
|
+
@unique_modules
|
|
1158
|
+
end
|
|
979
1159
|
|
|
980
1160
|
private
|
|
981
|
-
def marshal_load(file)
|
|
982
|
-
File.open(file, 'rb') {|io| Marshal.load(io, MarshalFilter)}
|
|
983
|
-
end
|
|
984
1161
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1162
|
+
def remove_classes_and_modules(cms)
|
|
1163
|
+
cms.each do |cm|
|
|
1164
|
+
remove_classes_and_modules(cm.classes_and_modules)
|
|
1165
|
+
|
|
1166
|
+
if cm.is_a?(NormalModule)
|
|
1167
|
+
@modules_hash.delete(cm.full_name)
|
|
1168
|
+
else
|
|
1169
|
+
@classes_hash.delete(cm.full_name)
|
|
1170
|
+
end
|
|
991
1171
|
end
|
|
992
1172
|
end
|
|
993
|
-
obj
|
|
994
|
-
end
|
|
995
|
-
private_constant :MarshalFilter
|
|
996
1173
|
|
|
1174
|
+
def marshal_load(file)
|
|
1175
|
+
File.open(file, 'rb') {|io| Marshal.load(io, MarshalFilter)}
|
|
1176
|
+
end
|
|
1177
|
+
|
|
1178
|
+
MarshalFilter = proc do |obj|
|
|
1179
|
+
case obj
|
|
1180
|
+
when true, false, nil, Array, Class, ::Encoding, Hash, Integer, String, Symbol, Text
|
|
1181
|
+
else
|
|
1182
|
+
unless obj.class.name.start_with?("RDoc::")
|
|
1183
|
+
raise TypeError, "not permitted class: #{obj.class.name}"
|
|
1184
|
+
end
|
|
1185
|
+
end
|
|
1186
|
+
obj
|
|
1187
|
+
end
|
|
1188
|
+
private_constant :MarshalFilter
|
|
1189
|
+
|
|
1190
|
+
end
|
|
997
1191
|
end
|