rdoc 8.0.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 +1 -3
- data/RI.md +75 -75
- data/exe/rdoc +2 -2
- data/lib/rdoc/code_object/alias.rb +71 -69
- data/lib/rdoc/code_object/any_method.rb +305 -303
- data/lib/rdoc/code_object/attr.rb +150 -148
- data/lib/rdoc/code_object/class_module.rb +798 -792
- data/lib/rdoc/code_object/constant.rb +175 -173
- data/lib/rdoc/code_object/context/section.rb +142 -138
- data/lib/rdoc/code_object/context.rb +926 -958
- 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 +326 -319
- 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 -219
- data/lib/rdoc/code_object.rb +305 -303
- data/lib/rdoc/comment.rb +275 -273
- data/lib/rdoc/cross_reference.rb +192 -190
- 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 +161 -153
- data/lib/rdoc/generator/darkfish.rb +645 -635
- data/lib/rdoc/generator/json_index.rb +233 -229
- data/lib/rdoc/generator/markup.rb +164 -146
- 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 +6 -4
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
- data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
- data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
- 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 +15 -11
- data/lib/rdoc/markdown.rb +40 -47
- data/lib/rdoc/markup/block_quote.rb +12 -8
- data/lib/rdoc/markup/document.rb +127 -123
- data/lib/rdoc/markup/formatter.rb +219 -215
- 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 +283 -279
- 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 +594 -565
- data/lib/rdoc/markup/to_html_crossref.rb +234 -230
- data/lib/rdoc/markup/to_html_snippet.rb +232 -227
- data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
- 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 +84 -80
- data/lib/rdoc/markup/verbatim.rb +62 -58
- data/lib/rdoc/markup.rb +198 -196
- data/lib/rdoc/options.rb +1063 -1061
- data/lib/rdoc/parser/c.rb +1039 -1037
- data/lib/rdoc/parser/changelog.rb +319 -315
- data/lib/rdoc/parser/markdown.rb +17 -13
- data/lib/rdoc/parser/rbs.rb +239 -235
- data/lib/rdoc/parser/rd.rb +17 -13
- data/lib/rdoc/parser/ruby.rb +1245 -1124
- data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
- data/lib/rdoc/parser/simple.rb +31 -27
- data/lib/rdoc/parser/text.rb +12 -8
- data/lib/rdoc/parser.rb +228 -220
- data/lib/rdoc/rbs_helper.rb +1 -1
- data/lib/rdoc/rd/inline.rb +57 -53
- data/lib/rdoc/rd.rb +90 -88
- data/lib/rdoc/rdoc.rb +500 -491
- data/lib/rdoc/ri/driver.rb +1140 -1135
- data/lib/rdoc/ri/formatter.rb +7 -3
- data/lib/rdoc/ri/paths.rb +140 -136
- data/lib/rdoc/ri/servlet.rb +354 -350
- data/lib/rdoc/ri/store.rb +4 -2
- data/lib/rdoc/ri/task.rb +55 -51
- data/lib/rdoc/ri.rb +14 -12
- data/lib/rdoc/rubygems_hook.rb +183 -181
- data/lib/rdoc/server.rb +349 -347
- 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 +365 -363
- data/lib/rdoc/store.rb +888 -902
- data/lib/rdoc/task.rb +260 -256
- data/lib/rdoc/text.rb +135 -133
- data/lib/rdoc/token_stream.rb +101 -93
- data/lib/rdoc/tom_doc.rb +203 -201
- data/lib/rdoc/version.rb +1 -1
- metadata +4 -5
- data/lib/rdoc/markdown/literals.kpeg +0 -21
- data/lib/rdoc/markdown/literals.rb +0 -454
data/lib/rdoc/store.rb
CHANGED
|
@@ -1,270 +1,296 @@
|
|
|
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
|
-
# created RDoc::TopLevel.
|
|
170
|
+
@c_singleton_class_variables[filename] = c_parser.singleton_classes
|
|
171
|
+
end
|
|
183
172
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
@files_hash[relative_name]
|
|
190
|
-
|
|
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
|
|
185
|
+
|
|
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
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
|
215
250
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
cm.methods_hash.clear
|
|
234
|
-
cm.method_list.each { |m| cm.methods_hash[m.pretty_name] = m }
|
|
235
|
-
cm.attributes.each { |a| cm.methods_hash[a.pretty_name] = a }
|
|
236
|
-
|
|
237
|
-
# Remove constants contributed by this file
|
|
238
|
-
cm.constants.reject! { |c| c.file == top_level }
|
|
239
|
-
cm.constants_hash.clear
|
|
240
|
-
cm.constants.each { |c| cm.constants_hash[c.name] = c }
|
|
241
|
-
|
|
242
|
-
# Remove includes, extends, and aliases from this file
|
|
243
|
-
cm.includes.reject! { |i| i.file == top_level }
|
|
244
|
-
cm.extends.reject! { |e| e.file == top_level }
|
|
245
|
-
cm.aliases.reject! { |a| a.file == top_level }
|
|
246
|
-
cm.external_aliases.reject! { |a| a.file == top_level }
|
|
247
|
-
|
|
248
|
-
# Clear or remove comment entries from this file
|
|
249
|
-
if cm.is_a?(RDoc::ClassModule)
|
|
250
|
-
if keep_position
|
|
251
|
-
cm.comment_location[top_level] = [] if cm.comment_location.key?(top_level)
|
|
252
|
-
else
|
|
253
|
-
cm.comment_location.delete(top_level)
|
|
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
|
|
254
268
|
end
|
|
255
|
-
cm.rebuild_comment_from_location
|
|
256
269
|
end
|
|
257
270
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
# Clear the TopLevel's class/module list to prevent duplicates
|
|
272
|
+
top_level.classes_or_modules.clear
|
|
273
|
+
end
|
|
274
|
+
|
|
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 } }
|
|
261
291
|
|
|
262
|
-
# If no files contribute to this class/module anymore, remove it
|
|
263
|
-
# from the store entirely. This handles file deletion correctly
|
|
264
|
-
# for classes that are only defined in the deleted file, while
|
|
265
|
-
# preserving classes that span multiple files.
|
|
266
292
|
if cm.in_files.empty?
|
|
267
|
-
if cm.is_a?(
|
|
293
|
+
if cm.is_a?(NormalModule)
|
|
268
294
|
@modules_hash.delete(cm.full_name)
|
|
269
295
|
else
|
|
270
296
|
@classes_hash.delete(cm.full_name)
|
|
@@ -275,931 +301,891 @@ class RDoc::Store
|
|
|
275
301
|
end
|
|
276
302
|
end
|
|
277
303
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
304
|
+
##
|
|
305
|
+
# Make sure any references to C variable names are resolved to the corresponding class.
|
|
306
|
+
#
|
|
281
307
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
# +comment_location+ and a stale +in_files+ reference. Call this after
|
|
287
|
-
# all re-parsing is complete.
|
|
288
|
-
|
|
289
|
-
def cleanup_stale_contributions
|
|
290
|
-
all_classes_and_modules.each do |cm|
|
|
291
|
-
cm.comment_location.delete_if { |_, comments| comments.empty? }
|
|
292
|
-
cm.rebuild_comment_from_location
|
|
293
|
-
|
|
294
|
-
cm.in_files.select! { |tl| cm.comment_location.key?(tl) ||
|
|
295
|
-
cm.method_list.any? { |m| m.file == tl } ||
|
|
296
|
-
cm.attributes.any? { |a| a.file == tl } ||
|
|
297
|
-
cm.constants.any? { |c| c.file == tl } }
|
|
298
|
-
|
|
299
|
-
if cm.in_files.empty?
|
|
300
|
-
if cm.is_a?(RDoc::NormalModule)
|
|
301
|
-
@modules_hash.delete(cm.full_name)
|
|
302
|
-
else
|
|
303
|
-
@classes_hash.delete(cm.full_name)
|
|
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
|
|
304
312
|
end
|
|
305
|
-
cm.parent&.classes_hash&.delete(cm.name)
|
|
306
|
-
cm.parent&.modules_hash&.delete(cm.name)
|
|
307
313
|
end
|
|
308
314
|
end
|
|
309
|
-
end
|
|
310
315
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
#
|
|
316
|
+
##
|
|
317
|
+
# Returns all classes discovered by RDoc
|
|
314
318
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if klass.superclass.is_a?(String) && (candidate = find_c_enclosure(klass.superclass))
|
|
318
|
-
klass.superclass = candidate
|
|
319
|
-
end
|
|
319
|
+
def all_classes
|
|
320
|
+
@classes_hash.values
|
|
320
321
|
end
|
|
321
|
-
end
|
|
322
322
|
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
##
|
|
324
|
+
# Returns all classes and modules discovered by RDoc
|
|
325
325
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
@text_files_hash[relative_name] = top_level if top_level.text?
|
|
326
|
+
def all_classes_and_modules
|
|
327
|
+
@classes_hash.values + @modules_hash.values
|
|
329
328
|
end
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
##
|
|
333
|
-
# Returns all classes discovered by RDoc
|
|
334
|
-
|
|
335
|
-
def all_classes
|
|
336
|
-
@classes_hash.values
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
##
|
|
340
|
-
# Returns all classes and modules discovered by RDoc
|
|
341
|
-
|
|
342
|
-
def all_classes_and_modules
|
|
343
|
-
@classes_hash.values + @modules_hash.values
|
|
344
|
-
end
|
|
345
329
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
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.
|
|
352
336
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
337
|
+
##
|
|
338
|
+
# Invalidates the cached type name lookup. Server mode calls this after
|
|
339
|
+
# re-parsing changes the set of classes and modules.
|
|
356
340
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
341
|
+
def invalidate_type_name_lookup # :nodoc:
|
|
342
|
+
@type_name_lookup = nil
|
|
343
|
+
end
|
|
360
344
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
|
377
362
|
end
|
|
363
|
+
lookup.merge!(unqualified_names)
|
|
378
364
|
end
|
|
379
|
-
lookup.merge!(unqualified_names)
|
|
380
365
|
end
|
|
381
|
-
end
|
|
382
366
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
def merge_rbs_signatures(signatures)
|
|
390
|
-
@rbs_signatures = signatures
|
|
391
|
-
end
|
|
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.
|
|
392
372
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
# canonical method for aliases, and handles +initialize+ -> +.new+
|
|
397
|
-
# singleton mapping.
|
|
373
|
+
def merge_rbs_signatures(signatures)
|
|
374
|
+
@rbs_signatures = signatures
|
|
375
|
+
end
|
|
398
376
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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
|
|
403
395
|
|
|
404
|
-
|
|
405
|
-
|
|
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
|
|
406
402
|
|
|
407
|
-
|
|
408
|
-
if !sig && method_attr.name == 'new' && method_attr.singleton
|
|
409
|
-
sig = @rbs_signatures["#{cm.full_name}#initialize"]
|
|
403
|
+
sig
|
|
410
404
|
end
|
|
411
405
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if !sig && method_attr.is_alias_for
|
|
415
|
-
canonical = method_attr.is_alias_for
|
|
416
|
-
sig = canonical.type_signature_lines || rbs_signature_for(canonical)
|
|
406
|
+
def clear_rbs_signatures # :nodoc:
|
|
407
|
+
@rbs_signatures = nil
|
|
417
408
|
end
|
|
418
409
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
def clear_rbs_signatures # :nodoc:
|
|
423
|
-
@rbs_signatures = nil
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
##
|
|
427
|
-
# All TopLevels known to RDoc
|
|
410
|
+
##
|
|
411
|
+
# All TopLevels known to RDoc
|
|
428
412
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
413
|
+
def all_files
|
|
414
|
+
@files_hash.values
|
|
415
|
+
end
|
|
432
416
|
|
|
433
|
-
|
|
434
|
-
|
|
417
|
+
##
|
|
418
|
+
# Returns all modules discovered by RDoc
|
|
435
419
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
420
|
+
def all_modules
|
|
421
|
+
modules_hash.values
|
|
422
|
+
end
|
|
439
423
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
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).
|
|
444
428
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
429
|
+
def ancestors
|
|
430
|
+
@cache[:ancestors]
|
|
431
|
+
end
|
|
448
432
|
|
|
449
|
-
|
|
450
|
-
|
|
433
|
+
##
|
|
434
|
+
# Attributes cache accessor. Maps a class to an Array of its attributes.
|
|
451
435
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
436
|
+
def attributes
|
|
437
|
+
@cache[:attributes]
|
|
438
|
+
end
|
|
455
439
|
|
|
456
|
-
|
|
457
|
-
|
|
440
|
+
##
|
|
441
|
+
# Path to the cache file
|
|
458
442
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
443
|
+
def cache_path
|
|
444
|
+
File.join @path, 'cache.ri'
|
|
445
|
+
end
|
|
462
446
|
|
|
463
|
-
|
|
464
|
-
|
|
447
|
+
##
|
|
448
|
+
# Path to the ri data for +klass_name+
|
|
465
449
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
450
|
+
def class_file(klass_name)
|
|
451
|
+
name = klass_name.split('::').last
|
|
452
|
+
File.join class_path(klass_name), "cdesc-#{name}.ri"
|
|
453
|
+
end
|
|
470
454
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
455
|
+
##
|
|
456
|
+
# Class methods cache accessor. Maps a class to an Array of its class
|
|
457
|
+
# methods (not full name).
|
|
474
458
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
459
|
+
def class_methods
|
|
460
|
+
@cache[:class_methods]
|
|
461
|
+
end
|
|
478
462
|
|
|
479
|
-
|
|
480
|
-
|
|
463
|
+
##
|
|
464
|
+
# Path where data for +klass_name+ will be stored (methods or class data)
|
|
481
465
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
466
|
+
def class_path(klass_name)
|
|
467
|
+
File.join @path, *klass_name.split('::')
|
|
468
|
+
end
|
|
485
469
|
|
|
486
|
-
|
|
487
|
-
|
|
470
|
+
##
|
|
471
|
+
# Hash of all classes known to RDoc
|
|
488
472
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
473
|
+
def classes_hash
|
|
474
|
+
@classes_hash
|
|
475
|
+
end
|
|
492
476
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
477
|
+
##
|
|
478
|
+
# Removes empty items and ensures item in each collection are unique and
|
|
479
|
+
# sorted
|
|
496
480
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
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!
|
|
489
|
+
end
|
|
505
490
|
end
|
|
506
491
|
end
|
|
507
|
-
end
|
|
508
492
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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?
|
|
524
508
|
|
|
525
|
-
|
|
526
|
-
|
|
509
|
+
def complete(min_visibility)
|
|
510
|
+
fix_basic_object_inheritance
|
|
527
511
|
|
|
528
|
-
|
|
529
|
-
|
|
512
|
+
# cache included modules before they are removed from the documentation
|
|
513
|
+
all_classes_and_modules.each { |cm| cm.ancestors }
|
|
530
514
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
515
|
+
unless min_visibility == :nodoc
|
|
516
|
+
remove_nodoc @classes_hash
|
|
517
|
+
remove_nodoc @modules_hash
|
|
518
|
+
end
|
|
535
519
|
|
|
536
|
-
|
|
537
|
-
|
|
520
|
+
@unique_classes = find_unique @classes_hash
|
|
521
|
+
@unique_modules = find_unique @modules_hash
|
|
538
522
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
523
|
+
unique_classes_and_modules.each do |cm|
|
|
524
|
+
cm.complete min_visibility
|
|
525
|
+
end
|
|
542
526
|
|
|
543
|
-
|
|
544
|
-
|
|
527
|
+
@files_hash.each_key do |file_name|
|
|
528
|
+
tl = @files_hash[file_name]
|
|
545
529
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
530
|
+
unless tl.text?
|
|
531
|
+
tl.modules_hash.clear
|
|
532
|
+
tl.classes_hash.clear
|
|
549
533
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
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
|
|
556
541
|
end
|
|
557
542
|
end
|
|
558
543
|
end
|
|
559
544
|
end
|
|
560
|
-
end
|
|
561
545
|
|
|
562
|
-
|
|
563
|
-
|
|
546
|
+
##
|
|
547
|
+
# Hash of all files known to RDoc
|
|
564
548
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
549
|
+
def files_hash
|
|
550
|
+
@files_hash
|
|
551
|
+
end
|
|
568
552
|
|
|
569
|
-
|
|
570
|
-
|
|
553
|
+
##
|
|
554
|
+
# Finds the enclosure (namespace) for the given C +variable+.
|
|
571
555
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
556
|
+
def find_c_enclosure(variable)
|
|
557
|
+
@c_enclosure_classes.fetch variable do
|
|
558
|
+
break unless name = @c_enclosure_names[variable]
|
|
575
559
|
|
|
576
|
-
|
|
560
|
+
mod = find_class_or_module name
|
|
577
561
|
|
|
578
|
-
|
|
579
|
-
|
|
562
|
+
unless mod
|
|
563
|
+
loaded_mod = load_class_data name
|
|
580
564
|
|
|
581
|
-
|
|
565
|
+
file = loaded_mod.in_files.first
|
|
582
566
|
|
|
583
|
-
|
|
567
|
+
return unless file # legacy data source
|
|
584
568
|
|
|
585
|
-
|
|
569
|
+
file.store = self
|
|
586
570
|
|
|
587
|
-
|
|
588
|
-
|
|
571
|
+
mod = file.add_module NormalModule, name
|
|
572
|
+
end
|
|
589
573
|
|
|
590
|
-
|
|
574
|
+
@c_enclosure_classes[variable] = mod
|
|
575
|
+
end
|
|
591
576
|
end
|
|
592
|
-
end
|
|
593
577
|
|
|
594
|
-
|
|
595
|
-
|
|
578
|
+
##
|
|
579
|
+
# Finds the class with +name+ in all discovered classes
|
|
596
580
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
581
|
+
def find_class_named(name)
|
|
582
|
+
@classes_hash[name]
|
|
583
|
+
end
|
|
600
584
|
|
|
601
|
-
|
|
602
|
-
|
|
585
|
+
##
|
|
586
|
+
# Finds the class with +name+ starting in namespace +from+
|
|
603
587
|
|
|
604
|
-
|
|
605
|
-
|
|
588
|
+
def find_class_named_from(name, from)
|
|
589
|
+
from = find_class_named from unless Context === from
|
|
606
590
|
|
|
607
|
-
|
|
608
|
-
|
|
591
|
+
until TopLevel === from do
|
|
592
|
+
return nil unless from
|
|
609
593
|
|
|
610
|
-
|
|
611
|
-
|
|
594
|
+
klass = from.find_class_named name
|
|
595
|
+
return klass if klass
|
|
612
596
|
|
|
613
|
-
|
|
614
|
-
|
|
597
|
+
from = from.parent
|
|
598
|
+
end
|
|
615
599
|
|
|
616
|
-
|
|
617
|
-
|
|
600
|
+
find_class_named name
|
|
601
|
+
end
|
|
618
602
|
|
|
619
|
-
|
|
620
|
-
|
|
603
|
+
##
|
|
604
|
+
# Finds the class or module with +name+
|
|
621
605
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
606
|
+
def find_class_or_module(name)
|
|
607
|
+
name = $' if name =~ /^::/
|
|
608
|
+
@classes_hash[name] || @modules_hash[name]
|
|
609
|
+
end
|
|
626
610
|
|
|
627
|
-
|
|
628
|
-
|
|
611
|
+
##
|
|
612
|
+
# Finds the file with +name+ in all discovered files
|
|
629
613
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
614
|
+
def find_file_named(name)
|
|
615
|
+
@files_hash[name]
|
|
616
|
+
end
|
|
633
617
|
|
|
634
|
-
|
|
635
|
-
|
|
618
|
+
##
|
|
619
|
+
# Finds the module with +name+ in all discovered modules
|
|
636
620
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
621
|
+
def find_module_named(name)
|
|
622
|
+
@modules_hash[name]
|
|
623
|
+
end
|
|
640
624
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
625
|
+
##
|
|
626
|
+
# Returns the RDoc::TopLevel that is a text file and has the given
|
|
627
|
+
# +file_name+
|
|
644
628
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
629
|
+
def find_text_page(file_name)
|
|
630
|
+
page = @files_hash[file_name]
|
|
631
|
+
page if page&.text?
|
|
648
632
|
end
|
|
649
|
-
end
|
|
650
633
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
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
|
|
640
|
+
|
|
641
|
+
def find_unique(all_hash)
|
|
642
|
+
unique = []
|
|
657
643
|
|
|
658
|
-
|
|
659
|
-
|
|
644
|
+
all_hash.each_pair do |full_name, cm|
|
|
645
|
+
unique << cm if full_name == cm.full_name
|
|
646
|
+
end
|
|
660
647
|
|
|
661
|
-
|
|
662
|
-
unique << cm if full_name == cm.full_name
|
|
648
|
+
unique
|
|
663
649
|
end
|
|
664
650
|
|
|
665
|
-
|
|
666
|
-
|
|
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.
|
|
667
659
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
#
|
|
674
|
-
# We fix BasicObject right away if we are running in a Ruby
|
|
675
|
-
# version >= 1.9.
|
|
660
|
+
def fix_basic_object_inheritance
|
|
661
|
+
basic = classes_hash['BasicObject']
|
|
662
|
+
return unless basic
|
|
663
|
+
basic.superclass = nil
|
|
664
|
+
end
|
|
676
665
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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
|
|
678
|
+
end
|
|
679
|
+
end
|
|
682
680
|
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
def friendly_path
|
|
687
|
-
case type
|
|
688
|
-
when :gem then
|
|
689
|
-
parent = File.expand_path '..', @path
|
|
690
|
-
"gem #{File.basename parent}"
|
|
691
|
-
when :home then RDoc.home
|
|
692
|
-
when :site then 'ruby site'
|
|
693
|
-
when :system then 'ruby core'
|
|
694
|
-
else @path
|
|
681
|
+
def inspect # :nodoc:
|
|
682
|
+
"#<%s:0x%x %s %p>" % [self.class, object_id, @path, module_names.sort]
|
|
695
683
|
end
|
|
696
|
-
end
|
|
697
684
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
685
|
+
##
|
|
686
|
+
# Instance methods cache accessor. Maps a class to an Array of its
|
|
687
|
+
# instance methods (not full name).
|
|
701
688
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
689
|
+
def instance_methods
|
|
690
|
+
@cache[:instance_methods]
|
|
691
|
+
end
|
|
705
692
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
693
|
+
##
|
|
694
|
+
# Loads all items from this store into memory. This recreates a
|
|
695
|
+
# documentation tree for use by a generator
|
|
709
696
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
# documentation tree for use by a generator
|
|
697
|
+
def load_all
|
|
698
|
+
load_cache
|
|
713
699
|
|
|
714
|
-
|
|
715
|
-
|
|
700
|
+
module_names.each do |module_name|
|
|
701
|
+
mod = find_class_or_module(module_name) || load_class(module_name)
|
|
716
702
|
|
|
717
|
-
|
|
718
|
-
|
|
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
|
|
719
708
|
|
|
720
|
-
|
|
721
|
-
# it
|
|
722
|
-
loaded_methods = mod.method_list.map do |method|
|
|
723
|
-
load_method module_name, method.full_name
|
|
724
|
-
end
|
|
709
|
+
mod.method_list.replace loaded_methods
|
|
725
710
|
|
|
726
|
-
|
|
711
|
+
loaded_attributes = mod.attributes.map do |attribute|
|
|
712
|
+
load_method module_name, attribute.full_name
|
|
713
|
+
end
|
|
727
714
|
|
|
728
|
-
|
|
729
|
-
load_method module_name, attribute.full_name
|
|
715
|
+
mod.attributes.replace loaded_attributes
|
|
730
716
|
end
|
|
731
717
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
all_classes_and_modules.each do |mod|
|
|
736
|
-
descendent_re = /^#{mod.full_name}::[^:]+$/
|
|
718
|
+
all_classes_and_modules.each do |mod|
|
|
719
|
+
descendent_re = /^#{mod.full_name}::[^:]+$/
|
|
737
720
|
|
|
738
|
-
|
|
739
|
-
|
|
721
|
+
module_names.each do |name|
|
|
722
|
+
next unless name =~ descendent_re
|
|
740
723
|
|
|
741
|
-
|
|
724
|
+
descendent = find_class_or_module name
|
|
742
725
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
726
|
+
case descendent
|
|
727
|
+
when NormalClass
|
|
728
|
+
mod.classes_hash[name] = descendent
|
|
729
|
+
when NormalModule
|
|
730
|
+
mod.modules_hash[name] = descendent
|
|
731
|
+
end
|
|
748
732
|
end
|
|
749
733
|
end
|
|
750
|
-
end
|
|
751
734
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
735
|
+
@page_index = nil
|
|
736
|
+
@cache[:pages].each do |page_name|
|
|
737
|
+
@files_hash[page_name] = load_page(page_name)
|
|
738
|
+
end
|
|
756
739
|
end
|
|
757
|
-
end
|
|
758
740
|
|
|
759
|
-
|
|
760
|
-
|
|
741
|
+
##
|
|
742
|
+
# Loads cache file for this store
|
|
761
743
|
|
|
762
|
-
|
|
763
|
-
|
|
744
|
+
def load_cache
|
|
745
|
+
#orig_enc = @encoding
|
|
764
746
|
|
|
765
|
-
|
|
747
|
+
@cache = marshal_load(cache_path)
|
|
766
748
|
|
|
767
|
-
|
|
749
|
+
load_enc = @cache[:encoding]
|
|
768
750
|
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
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
|
|
762
|
+
|
|
763
|
+
@encoding = load_enc unless @encoding
|
|
764
|
+
|
|
765
|
+
@cache[:pages] ||= []
|
|
766
|
+
@cache[:main] ||= nil
|
|
767
|
+
@cache[:c_class_variables] ||= {}
|
|
768
|
+
@cache[:c_singleton_class_variables] ||= {}
|
|
769
|
+
|
|
770
|
+
@cache[:c_class_variables].each do |_, map|
|
|
771
|
+
map.each do |variable, name|
|
|
772
|
+
@c_enclosure_names[variable] = name
|
|
773
|
+
end
|
|
791
774
|
end
|
|
792
|
-
end
|
|
793
775
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
776
|
+
@cache
|
|
777
|
+
rescue Errno::ENOENT
|
|
778
|
+
end
|
|
797
779
|
|
|
798
|
-
|
|
799
|
-
|
|
780
|
+
##
|
|
781
|
+
# Loads ri data for +klass_name+ and hooks it up to this store.
|
|
800
782
|
|
|
801
|
-
|
|
802
|
-
|
|
783
|
+
def load_class(klass_name)
|
|
784
|
+
obj = load_class_data klass_name
|
|
803
785
|
|
|
804
|
-
|
|
786
|
+
obj.store = self
|
|
805
787
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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
|
|
813
796
|
end
|
|
814
|
-
end
|
|
815
797
|
|
|
816
|
-
|
|
817
|
-
|
|
798
|
+
##
|
|
799
|
+
# Loads ri data for +klass_name+
|
|
818
800
|
|
|
819
|
-
|
|
820
|
-
|
|
801
|
+
def load_class_data(klass_name)
|
|
802
|
+
file = class_file klass_name
|
|
821
803
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
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
|
|
828
810
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
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
|
|
844
826
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
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
|
|
859
841
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
842
|
+
##
|
|
843
|
+
# Gets the main page for this RDoc store. This page is used as the root of
|
|
844
|
+
# the RDoc server.
|
|
863
845
|
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
846
|
+
def main
|
|
847
|
+
@cache[:main]
|
|
848
|
+
end
|
|
867
849
|
|
|
868
|
-
|
|
869
|
-
|
|
850
|
+
##
|
|
851
|
+
# Sets the main page for this RDoc store.
|
|
870
852
|
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
853
|
+
def main=(page)
|
|
854
|
+
@cache[:main] = page
|
|
855
|
+
end
|
|
874
856
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
857
|
+
##
|
|
858
|
+
# Converts the variable => ClassModule map +variables+ from a C parser into
|
|
859
|
+
# a variable => class name map.
|
|
878
860
|
|
|
879
|
-
|
|
880
|
-
|
|
861
|
+
def make_variable_map(variables)
|
|
862
|
+
map = {}
|
|
881
863
|
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
864
|
+
variables.each { |variable, class_module|
|
|
865
|
+
map[variable] = class_module.full_name
|
|
866
|
+
}
|
|
885
867
|
|
|
886
|
-
|
|
887
|
-
|
|
868
|
+
map
|
|
869
|
+
end
|
|
888
870
|
|
|
889
|
-
|
|
890
|
-
|
|
871
|
+
##
|
|
872
|
+
# Path to the ri data for +method_name+ in +klass_name+
|
|
891
873
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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 }
|
|
898
880
|
|
|
899
|
-
|
|
900
|
-
|
|
881
|
+
File.join class_path(klass_name), "#{method_name}-#{method_type}.ri"
|
|
882
|
+
end
|
|
901
883
|
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
884
|
+
##
|
|
885
|
+
# Modules cache accessor. An Array of all the module (and class) names in
|
|
886
|
+
# the store.
|
|
905
887
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
888
|
+
def module_names
|
|
889
|
+
@cache[:modules]
|
|
890
|
+
end
|
|
909
891
|
|
|
910
|
-
|
|
911
|
-
|
|
892
|
+
##
|
|
893
|
+
# Hash of all modules known to RDoc
|
|
912
894
|
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
895
|
+
def modules_hash
|
|
896
|
+
@modules_hash
|
|
897
|
+
end
|
|
916
898
|
|
|
917
|
-
|
|
918
|
-
|
|
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
|
|
919
907
|
|
|
920
|
-
|
|
921
|
-
@files_hash.each_value.find do |file|
|
|
922
|
-
file.page_name == name or file.base_name == name
|
|
908
|
+
@page_index[name]
|
|
923
909
|
end
|
|
924
|
-
end
|
|
925
910
|
|
|
926
|
-
|
|
927
|
-
|
|
911
|
+
##
|
|
912
|
+
# Path to the ri data for +page_name+
|
|
928
913
|
|
|
929
|
-
|
|
930
|
-
|
|
914
|
+
def page_file(page_name)
|
|
915
|
+
file_name = File.basename(page_name).gsub('.', '_')
|
|
931
916
|
|
|
932
|
-
|
|
933
|
-
|
|
917
|
+
File.join @path, File.dirname(page_name), "page-#{file_name}.ri"
|
|
918
|
+
end
|
|
934
919
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
920
|
+
##
|
|
921
|
+
# Removes from +all_hash+ the contexts that are nodoc or have no content.
|
|
922
|
+
#
|
|
923
|
+
# See RDoc::Context#remove_from_documentation?
|
|
939
924
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
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
|
|
944
930
|
end
|
|
945
|
-
end
|
|
946
931
|
|
|
947
|
-
|
|
948
|
-
|
|
932
|
+
##
|
|
933
|
+
# Saves all entries in the store
|
|
934
|
+
|
|
935
|
+
def save
|
|
936
|
+
load_cache
|
|
949
937
|
|
|
950
|
-
|
|
951
|
-
|
|
938
|
+
all_classes_and_modules.each do |klass|
|
|
939
|
+
save_class klass
|
|
952
940
|
|
|
953
|
-
|
|
954
|
-
|
|
941
|
+
klass.each_method do |method|
|
|
942
|
+
save_method klass, method
|
|
943
|
+
end
|
|
955
944
|
|
|
956
|
-
|
|
957
|
-
|
|
945
|
+
klass.attributes.each do |attribute|
|
|
946
|
+
save_method klass, attribute
|
|
947
|
+
end
|
|
958
948
|
end
|
|
959
949
|
|
|
960
|
-
|
|
961
|
-
|
|
950
|
+
all_files.each do |file|
|
|
951
|
+
save_page file
|
|
962
952
|
end
|
|
963
|
-
end
|
|
964
953
|
|
|
965
|
-
|
|
966
|
-
save_page file
|
|
954
|
+
save_cache
|
|
967
955
|
end
|
|
968
956
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
##
|
|
973
|
-
# Writes the cache file for this store
|
|
957
|
+
##
|
|
958
|
+
# Writes the cache file for this store
|
|
974
959
|
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
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]
|
|
980
965
|
|
|
981
|
-
|
|
982
|
-
|
|
966
|
+
@cache[:modules].uniq!
|
|
967
|
+
@cache[:modules].sort!
|
|
983
968
|
|
|
984
|
-
|
|
985
|
-
|
|
969
|
+
@cache[:pages].uniq!
|
|
970
|
+
@cache[:pages].sort!
|
|
986
971
|
|
|
987
|
-
|
|
972
|
+
@cache[:encoding] = @encoding # this gets set twice due to assert_cache
|
|
988
973
|
|
|
989
|
-
|
|
990
|
-
|
|
974
|
+
@cache[:c_class_variables].merge! @c_class_variables
|
|
975
|
+
@cache[:c_singleton_class_variables].merge! @c_singleton_class_variables
|
|
991
976
|
|
|
992
|
-
|
|
977
|
+
return if @dry_run
|
|
993
978
|
|
|
994
|
-
|
|
995
|
-
|
|
979
|
+
File.open cache_path, 'wb' do |io|
|
|
980
|
+
Marshal.dump @cache, io
|
|
981
|
+
end
|
|
996
982
|
end
|
|
997
|
-
end
|
|
998
983
|
|
|
999
|
-
|
|
1000
|
-
|
|
984
|
+
##
|
|
985
|
+
# Writes the ri data for +klass+ (or module)
|
|
1001
986
|
|
|
1002
|
-
|
|
1003
|
-
|
|
987
|
+
def save_class(klass)
|
|
988
|
+
full_name = klass.full_name
|
|
1004
989
|
|
|
1005
|
-
|
|
990
|
+
FileUtils.mkdir_p class_path(full_name) unless @dry_run
|
|
1006
991
|
|
|
1007
|
-
|
|
992
|
+
@cache[:modules] << full_name
|
|
1008
993
|
|
|
1009
|
-
|
|
994
|
+
path = class_file full_name
|
|
1010
995
|
|
|
1011
|
-
|
|
1012
|
-
|
|
996
|
+
begin
|
|
997
|
+
disk_klass = load_class full_name
|
|
1013
998
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
999
|
+
klass = disk_klass.merge klass
|
|
1000
|
+
rescue MissingFileError
|
|
1001
|
+
end
|
|
1017
1002
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
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
|
|
1023
1008
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1009
|
+
@cache[:ancestors][full_name] ||= []
|
|
1010
|
+
@cache[:ancestors][full_name].concat ancestors
|
|
1026
1011
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1012
|
+
attribute_definitions = klass.attributes.map do |attribute|
|
|
1013
|
+
"#{attribute.definition} #{attribute.name}"
|
|
1014
|
+
end
|
|
1030
1015
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1016
|
+
unless attribute_definitions.empty?
|
|
1017
|
+
@cache[:attributes][full_name] ||= []
|
|
1018
|
+
@cache[:attributes][full_name].concat attribute_definitions
|
|
1019
|
+
end
|
|
1035
1020
|
|
|
1036
|
-
|
|
1021
|
+
to_delete = []
|
|
1037
1022
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1023
|
+
unless klass.method_list.empty?
|
|
1024
|
+
@cache[:class_methods][full_name] ||= []
|
|
1025
|
+
@cache[:instance_methods][full_name] ||= []
|
|
1041
1026
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1027
|
+
class_methods, instance_methods =
|
|
1028
|
+
klass.method_list.partition { |meth| meth.singleton }
|
|
1044
1029
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
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 }
|
|
1048
1033
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
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
|
+
}
|
|
1053
1038
|
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
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
|
+
}
|
|
1059
1044
|
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1045
|
+
@cache[:class_methods][full_name] = class_methods
|
|
1046
|
+
@cache[:instance_methods][full_name] = instance_methods
|
|
1047
|
+
end
|
|
1063
1048
|
|
|
1064
|
-
|
|
1049
|
+
return if @dry_run
|
|
1065
1050
|
|
|
1066
|
-
|
|
1051
|
+
FileUtils.rm_f to_delete
|
|
1067
1052
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1053
|
+
File.open path, 'wb' do |io|
|
|
1054
|
+
Marshal.dump klass, io
|
|
1055
|
+
end
|
|
1070
1056
|
end
|
|
1071
|
-
end
|
|
1072
1057
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1058
|
+
##
|
|
1059
|
+
# Writes the ri data for +method+ on +klass+
|
|
1075
1060
|
|
|
1076
|
-
|
|
1077
|
-
|
|
1061
|
+
def save_method(klass, method)
|
|
1062
|
+
full_name = klass.full_name
|
|
1078
1063
|
|
|
1079
|
-
|
|
1064
|
+
FileUtils.mkdir_p class_path(full_name) unless @dry_run
|
|
1080
1065
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
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
|
|
1088
1073
|
|
|
1089
|
-
|
|
1074
|
+
return if @dry_run
|
|
1090
1075
|
|
|
1091
|
-
|
|
1092
|
-
|
|
1076
|
+
File.open method_file(full_name, method.full_name), 'wb' do |io|
|
|
1077
|
+
Marshal.dump method, io
|
|
1078
|
+
end
|
|
1093
1079
|
end
|
|
1094
|
-
end
|
|
1095
1080
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1081
|
+
##
|
|
1082
|
+
# Writes the ri data for +page+
|
|
1098
1083
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1084
|
+
def save_page(page)
|
|
1085
|
+
return unless page.text?
|
|
1101
1086
|
|
|
1102
|
-
|
|
1087
|
+
path = page_file page.full_name
|
|
1103
1088
|
|
|
1104
|
-
|
|
1089
|
+
FileUtils.mkdir_p File.dirname(path) unless @dry_run
|
|
1105
1090
|
|
|
1106
|
-
|
|
1107
|
-
|
|
1091
|
+
cache[:pages] ||= []
|
|
1092
|
+
cache[:pages] << page.full_name
|
|
1108
1093
|
|
|
1109
|
-
|
|
1094
|
+
return if @dry_run
|
|
1110
1095
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1096
|
+
File.open path, 'wb' do |io|
|
|
1097
|
+
Marshal.dump page, io
|
|
1098
|
+
end
|
|
1113
1099
|
end
|
|
1114
|
-
end
|
|
1115
1100
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
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
|
|
1132
1118
|
end
|
|
1133
|
-
end
|
|
1134
1119
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1120
|
+
##
|
|
1121
|
+
# Gets the title for this RDoc store. This is used as the title in each
|
|
1122
|
+
# page on the RDoc server
|
|
1138
1123
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1124
|
+
def title
|
|
1125
|
+
@cache[:title]
|
|
1126
|
+
end
|
|
1142
1127
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1128
|
+
##
|
|
1129
|
+
# Sets the title page for this RDoc store.
|
|
1145
1130
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1131
|
+
def title=(title)
|
|
1132
|
+
@cache[:title] = title
|
|
1133
|
+
end
|
|
1149
1134
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1135
|
+
##
|
|
1136
|
+
# Returns the unique classes discovered by RDoc.
|
|
1137
|
+
#
|
|
1138
|
+
# ::complete must have been called prior to using this method.
|
|
1154
1139
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1140
|
+
def unique_classes
|
|
1141
|
+
@unique_classes
|
|
1142
|
+
end
|
|
1158
1143
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1144
|
+
##
|
|
1145
|
+
# Returns the unique classes and modules discovered by RDoc.
|
|
1146
|
+
# ::complete must have been called prior to using this method.
|
|
1162
1147
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1148
|
+
def unique_classes_and_modules
|
|
1149
|
+
@unique_classes + @unique_modules
|
|
1150
|
+
end
|
|
1166
1151
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1152
|
+
##
|
|
1153
|
+
# Returns the unique modules discovered by RDoc.
|
|
1154
|
+
# ::complete must have been called prior to using this method.
|
|
1170
1155
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1156
|
+
def unique_modules
|
|
1157
|
+
@unique_modules
|
|
1158
|
+
end
|
|
1174
1159
|
|
|
1175
1160
|
private
|
|
1176
1161
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1162
|
+
def remove_classes_and_modules(cms)
|
|
1163
|
+
cms.each do |cm|
|
|
1164
|
+
remove_classes_and_modules(cm.classes_and_modules)
|
|
1180
1165
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1166
|
+
if cm.is_a?(NormalModule)
|
|
1167
|
+
@modules_hash.delete(cm.full_name)
|
|
1168
|
+
else
|
|
1169
|
+
@classes_hash.delete(cm.full_name)
|
|
1170
|
+
end
|
|
1185
1171
|
end
|
|
1186
1172
|
end
|
|
1187
|
-
end
|
|
1188
1173
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1174
|
+
def marshal_load(file)
|
|
1175
|
+
File.open(file, 'rb') {|io| Marshal.load(io, MarshalFilter)}
|
|
1176
|
+
end
|
|
1192
1177
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
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
|
|
1199
1185
|
end
|
|
1186
|
+
obj
|
|
1200
1187
|
end
|
|
1201
|
-
|
|
1202
|
-
end
|
|
1203
|
-
private_constant :MarshalFilter
|
|
1188
|
+
private_constant :MarshalFilter
|
|
1204
1189
|
|
|
1190
|
+
end
|
|
1205
1191
|
end
|