rdoc 3.1 → 6.3.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rdoc might be problematic. Click here for more details.

Files changed (247) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.rdoc +220 -0
  3. data/CVE-2013-0256.rdoc +49 -0
  4. data/ExampleMarkdown.md +37 -0
  5. data/ExampleRDoc.rdoc +208 -0
  6. data/Gemfile +12 -0
  7. data/History.rdoc +1666 -0
  8. data/LEGAL.rdoc +50 -0
  9. data/LICENSE.rdoc +57 -0
  10. data/README.rdoc +129 -0
  11. data/RI.rdoc +57 -0
  12. data/Rakefile +84 -81
  13. data/TODO.rdoc +59 -0
  14. data/bin/console +7 -0
  15. data/bin/setup +6 -0
  16. data/{bin → exe}/rdoc +11 -2
  17. data/exe/ri +12 -0
  18. data/lib/rdoc/alias.rb +1 -2
  19. data/lib/rdoc/anon_class.rb +3 -2
  20. data/lib/rdoc/any_method.rb +234 -40
  21. data/lib/rdoc/attr.rb +79 -11
  22. data/lib/rdoc/class_module.rb +443 -71
  23. data/lib/rdoc/code_object.rb +216 -20
  24. data/lib/rdoc/code_objects.rb +4 -21
  25. data/lib/rdoc/comment.rb +250 -0
  26. data/lib/rdoc/constant.rb +110 -9
  27. data/lib/rdoc/context/section.rb +232 -0
  28. data/lib/rdoc/context.rb +392 -172
  29. data/lib/rdoc/cross_reference.rb +202 -0
  30. data/lib/rdoc/encoding.rb +83 -28
  31. data/lib/rdoc/erb_partial.rb +19 -0
  32. data/lib/rdoc/erbio.rb +8 -3
  33. data/lib/rdoc/extend.rb +10 -0
  34. data/lib/rdoc/generator/darkfish.rb +507 -84
  35. data/lib/rdoc/generator/json_index.rb +300 -0
  36. data/lib/rdoc/generator/markup.rb +27 -74
  37. data/lib/rdoc/generator/pot/message_extractor.rb +68 -0
  38. data/lib/rdoc/generator/pot/po.rb +84 -0
  39. data/lib/rdoc/generator/pot/po_entry.rb +141 -0
  40. data/lib/rdoc/generator/pot.rb +98 -0
  41. data/lib/rdoc/generator/ri.rb +8 -62
  42. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
  43. data/lib/rdoc/generator/template/darkfish/_head.rhtml +22 -0
  44. data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +19 -0
  45. data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +9 -0
  46. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +15 -0
  47. data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +9 -0
  48. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +15 -0
  49. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +15 -0
  50. data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +12 -0
  51. data/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
  52. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +12 -0
  53. data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +11 -0
  54. data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +14 -0
  55. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
  56. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +18 -0
  57. data/lib/rdoc/generator/template/darkfish/class.rhtml +172 -0
  58. data/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
  59. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +639 -0
  60. data/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
  61. data/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
  62. data/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
  63. data/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
  64. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
  65. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
  66. data/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
  67. data/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
  68. data/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
  69. data/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
  70. data/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
  71. data/lib/rdoc/generator/template/darkfish/index.rhtml +18 -60
  72. data/lib/rdoc/generator/template/darkfish/js/darkfish.js +51 -83
  73. data/lib/rdoc/generator/template/darkfish/js/search.js +110 -0
  74. data/lib/rdoc/generator/template/darkfish/page.rhtml +18 -0
  75. data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +18 -0
  76. data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +62 -0
  77. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +58 -0
  78. data/lib/rdoc/generator/template/json_index/.document +1 -0
  79. data/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
  80. data/lib/rdoc/generator/template/json_index/js/searcher.js +229 -0
  81. data/lib/rdoc/generator.rb +24 -13
  82. data/lib/rdoc/ghost_method.rb +1 -2
  83. data/lib/rdoc/i18n/locale.rb +102 -0
  84. data/lib/rdoc/i18n/text.rb +126 -0
  85. data/lib/rdoc/i18n.rb +10 -0
  86. data/lib/rdoc/include.rb +5 -95
  87. data/lib/rdoc/known_classes.rb +5 -2
  88. data/lib/rdoc/markdown/entities.rb +2132 -0
  89. data/lib/rdoc/markdown/literals.kpeg +23 -0
  90. data/lib/rdoc/markdown/literals.rb +416 -0
  91. data/lib/rdoc/markdown.kpeg +1237 -0
  92. data/lib/rdoc/markdown.rb +16684 -0
  93. data/lib/rdoc/markup/attr_changer.rb +23 -0
  94. data/lib/rdoc/markup/attr_span.rb +36 -0
  95. data/lib/rdoc/markup/attribute_manager.rb +135 -62
  96. data/lib/rdoc/markup/attributes.rb +71 -0
  97. data/lib/rdoc/markup/blank_line.rb +1 -0
  98. data/lib/rdoc/markup/block_quote.rb +15 -0
  99. data/lib/rdoc/markup/document.rb +96 -9
  100. data/lib/rdoc/markup/formatter.rb +138 -25
  101. data/lib/rdoc/markup/hard_break.rb +32 -0
  102. data/lib/rdoc/markup/heading.rb +61 -2
  103. data/lib/rdoc/markup/include.rb +43 -0
  104. data/lib/rdoc/markup/indented_paragraph.rb +48 -0
  105. data/lib/rdoc/markup/list.rb +25 -4
  106. data/lib/rdoc/markup/list_item.rb +18 -4
  107. data/lib/rdoc/markup/paragraph.rb +15 -0
  108. data/lib/rdoc/markup/parser.rb +180 -88
  109. data/lib/rdoc/markup/pre_process.rb +183 -38
  110. data/lib/rdoc/markup/raw.rb +6 -5
  111. data/lib/rdoc/markup/regexp_handling.rb +41 -0
  112. data/lib/rdoc/markup/rule.rb +1 -0
  113. data/lib/rdoc/markup/table.rb +47 -0
  114. data/lib/rdoc/markup/to_ansi.rb +17 -7
  115. data/lib/rdoc/markup/to_bs.rb +5 -8
  116. data/lib/rdoc/markup/to_html.rb +238 -137
  117. data/lib/rdoc/markup/to_html_crossref.rb +125 -152
  118. data/lib/rdoc/markup/to_html_snippet.rb +285 -0
  119. data/lib/rdoc/markup/to_joined_paragraph.rb +47 -0
  120. data/lib/rdoc/markup/to_label.rb +75 -0
  121. data/lib/rdoc/markup/to_markdown.rb +192 -0
  122. data/lib/rdoc/markup/to_rdoc.rb +85 -15
  123. data/lib/rdoc/markup/to_table_of_contents.rb +89 -0
  124. data/lib/rdoc/markup/to_test.rb +2 -4
  125. data/lib/rdoc/markup/to_tt_only.rb +121 -0
  126. data/lib/rdoc/markup/verbatim.rb +39 -0
  127. data/lib/rdoc/markup.rb +388 -110
  128. data/lib/rdoc/meta_method.rb +1 -2
  129. data/lib/rdoc/method_attr.rb +87 -21
  130. data/lib/rdoc/mixin.rb +121 -0
  131. data/lib/rdoc/normal_class.rb +39 -10
  132. data/lib/rdoc/normal_module.rb +22 -7
  133. data/lib/rdoc/options.rb +613 -73
  134. data/lib/rdoc/parser/c.rb +621 -287
  135. data/lib/rdoc/parser/changelog.rb +335 -0
  136. data/lib/rdoc/parser/markdown.rb +24 -0
  137. data/lib/rdoc/parser/rd.rb +23 -0
  138. data/lib/rdoc/parser/ripper_state_lex.rb +590 -0
  139. data/lib/rdoc/parser/ruby.rb +1368 -762
  140. data/lib/rdoc/parser/ruby_tools.rb +42 -35
  141. data/lib/rdoc/parser/simple.rb +23 -11
  142. data/lib/rdoc/parser/text.rb +12 -0
  143. data/lib/rdoc/parser.rb +162 -89
  144. data/lib/rdoc/rd/block_parser.rb +1056 -0
  145. data/lib/rdoc/rd/block_parser.ry +639 -0
  146. data/lib/rdoc/rd/inline.rb +72 -0
  147. data/lib/rdoc/rd/inline_parser.rb +1208 -0
  148. data/lib/rdoc/rd/inline_parser.ry +593 -0
  149. data/lib/rdoc/rd.rb +100 -0
  150. data/lib/rdoc/rdoc.rb +208 -115
  151. data/lib/rdoc/require.rb +1 -2
  152. data/lib/rdoc/ri/driver.rb +734 -239
  153. data/lib/rdoc/ri/formatter.rb +1 -0
  154. data/lib/rdoc/ri/paths.rb +91 -48
  155. data/lib/rdoc/ri/store.rb +3 -261
  156. data/lib/rdoc/ri/task.rb +71 -0
  157. data/lib/rdoc/ri.rb +5 -2
  158. data/lib/rdoc/rubygems_hook.rb +246 -0
  159. data/lib/rdoc/servlet.rb +451 -0
  160. data/lib/rdoc/single_class.rb +14 -2
  161. data/lib/rdoc/stats/normal.rb +19 -12
  162. data/lib/rdoc/stats/quiet.rb +1 -0
  163. data/lib/rdoc/stats/verbose.rb +1 -0
  164. data/lib/rdoc/stats.rb +262 -104
  165. data/lib/rdoc/store.rb +979 -0
  166. data/lib/rdoc/task.rb +84 -44
  167. data/lib/rdoc/text.rb +117 -72
  168. data/lib/rdoc/token_stream.rb +73 -4
  169. data/lib/rdoc/tom_doc.rb +263 -0
  170. data/lib/rdoc/top_level.rb +111 -261
  171. data/lib/rdoc/version.rb +8 -0
  172. data/lib/rdoc.rb +127 -64
  173. data/man/ri.1 +247 -0
  174. data/rdoc.gemspec +249 -0
  175. metadata +171 -291
  176. data/.autotest +0 -16
  177. data/.document +0 -5
  178. data/History.txt +0 -594
  179. data/LICENSE.txt +0 -57
  180. data/Manifest.txt +0 -158
  181. data/README.txt +0 -45
  182. data/RI.txt +0 -58
  183. data/bin/ri +0 -5
  184. data/lib/rdoc/gauntlet.rb +0 -52
  185. data/lib/rdoc/generator/template/darkfish/classpage.rhtml +0 -296
  186. data/lib/rdoc/generator/template/darkfish/filepage.rhtml +0 -124
  187. data/lib/rdoc/generator/template/darkfish/js/jquery.js +0 -32
  188. data/lib/rdoc/generator/template/darkfish/js/quicksearch.js +0 -114
  189. data/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js +0 -10
  190. data/lib/rdoc/generator/template/darkfish/rdoc.css +0 -706
  191. data/lib/rdoc/markup/formatter_test_case.rb +0 -689
  192. data/lib/rdoc/markup/inline.rb +0 -137
  193. data/lib/rdoc/markup/text_formatter_test_case.rb +0 -116
  194. data/lib/rdoc/ruby_lex.rb +0 -1291
  195. data/lib/rdoc/ruby_token.rb +0 -416
  196. data/test/README +0 -1
  197. data/test/binary.dat +0 -0
  198. data/test/hidden.zip.txt +0 -1
  199. data/test/test.ja.rdoc +0 -10
  200. data/test/test.ja.txt +0 -8
  201. data/test/test.txt +0 -1
  202. data/test/test_attribute_manager.rb +0 -120
  203. data/test/test_rdoc_alias.rb +0 -13
  204. data/test/test_rdoc_any_method.rb +0 -126
  205. data/test/test_rdoc_attr.rb +0 -61
  206. data/test/test_rdoc_class_module.rb +0 -233
  207. data/test/test_rdoc_code_object.rb +0 -165
  208. data/test/test_rdoc_constant.rb +0 -15
  209. data/test/test_rdoc_context.rb +0 -370
  210. data/test/test_rdoc_encoding.rb +0 -166
  211. data/test/test_rdoc_generator_darkfish.rb +0 -119
  212. data/test/test_rdoc_generator_ri.rb +0 -76
  213. data/test/test_rdoc_include.rb +0 -96
  214. data/test/test_rdoc_markup.rb +0 -37
  215. data/test/test_rdoc_markup_attribute_manager.rb +0 -240
  216. data/test/test_rdoc_markup_document.rb +0 -51
  217. data/test/test_rdoc_markup_paragraph.rb +0 -9
  218. data/test/test_rdoc_markup_parser.rb +0 -1395
  219. data/test/test_rdoc_markup_pre_process.rb +0 -185
  220. data/test/test_rdoc_markup_raw.rb +0 -27
  221. data/test/test_rdoc_markup_to_ansi.rb +0 -328
  222. data/test/test_rdoc_markup_to_bs.rb +0 -341
  223. data/test/test_rdoc_markup_to_html.rb +0 -335
  224. data/test/test_rdoc_markup_to_html_crossref.rb +0 -169
  225. data/test/test_rdoc_markup_to_rdoc.rb +0 -327
  226. data/test/test_rdoc_method_attr.rb +0 -122
  227. data/test/test_rdoc_normal_class.rb +0 -17
  228. data/test/test_rdoc_normal_module.rb +0 -31
  229. data/test/test_rdoc_options.rb +0 -342
  230. data/test/test_rdoc_parser.rb +0 -83
  231. data/test/test_rdoc_parser_c.rb +0 -912
  232. data/test/test_rdoc_parser_ruby.rb +0 -1754
  233. data/test/test_rdoc_parser_simple.rb +0 -99
  234. data/test/test_rdoc_rdoc.rb +0 -164
  235. data/test/test_rdoc_require.rb +0 -25
  236. data/test/test_rdoc_ri_driver.rb +0 -846
  237. data/test/test_rdoc_ri_paths.rb +0 -43
  238. data/test/test_rdoc_ri_store.rb +0 -352
  239. data/test/test_rdoc_ruby_lex.rb +0 -23
  240. data/test/test_rdoc_stats.rb +0 -38
  241. data/test/test_rdoc_task.rb +0 -92
  242. data/test/test_rdoc_text.rb +0 -251
  243. data/test/test_rdoc_top_level.rb +0 -120
  244. data/test/xref_data.rb +0 -62
  245. data/test/xref_test_case.rb +0 -61
  246. data.tar.gz.sig +0 -3
  247. metadata.gz.sig +0 -0
data/lib/rdoc/store.rb ADDED
@@ -0,0 +1,979 @@
1
+ # frozen_string_literal: true
2
+ require 'fileutils'
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
+
27
+ ##
28
+ # Errors raised from loading or saving the store
29
+
30
+ class Error < RDoc::Error
31
+ end
32
+
33
+ ##
34
+ # Raised when a stored file for a class, module, page or method is missing.
35
+
36
+ class MissingFileError < Error
37
+
38
+ ##
39
+ # The store the file should exist in
40
+
41
+ attr_reader :store
42
+
43
+ ##
44
+ # The file the #name should be saved as
45
+
46
+ attr_reader :file
47
+
48
+ ##
49
+ # The name of the object the #file would be loaded from
50
+
51
+ attr_reader :name
52
+
53
+ ##
54
+ # Creates a new MissingFileError for the missing +file+ for the given
55
+ # +name+ that should have been in the +store+.
56
+
57
+ def initialize store, file, name
58
+ @store = store
59
+ @file = file
60
+ @name = name
61
+ end
62
+
63
+ def message # :nodoc:
64
+ "store at #{@store.path} missing file #{@file} for #{@name}"
65
+ end
66
+
67
+ end
68
+
69
+ ##
70
+ # Stores the name of the C variable a class belongs to. This helps wire up
71
+ # classes defined from C across files.
72
+
73
+ attr_reader :c_enclosure_classes # :nodoc:
74
+
75
+ attr_reader :c_enclosure_names # :nodoc:
76
+
77
+ ##
78
+ # Maps C variables to class or module names for each parsed C file.
79
+
80
+ attr_reader :c_class_variables
81
+
82
+ ##
83
+ # Maps C variables to singleton class names for each parsed C file.
84
+
85
+ attr_reader :c_singleton_class_variables
86
+
87
+ ##
88
+ # If true this Store will not write any files
89
+
90
+ attr_accessor :dry_run
91
+
92
+ ##
93
+ # Path this store reads or writes
94
+
95
+ attr_accessor :path
96
+
97
+ ##
98
+ # The RDoc::RDoc driver for this parse tree. This allows classes consulting
99
+ # the documentation tree to access user-set options, for example.
100
+
101
+ attr_accessor :rdoc
102
+
103
+ ##
104
+ # Type of ri datastore this was loaded from. See RDoc::RI::Driver,
105
+ # RDoc::RI::Paths.
106
+
107
+ attr_accessor :type
108
+
109
+ ##
110
+ # The contents of the Store
111
+
112
+ attr_reader :cache
113
+
114
+ ##
115
+ # The encoding of the contents in the Store
116
+
117
+ attr_accessor :encoding
118
+
119
+ ##
120
+ # The lazy constants alias will be discovered in passing
121
+
122
+ attr_reader :unmatched_constant_alias
123
+
124
+ ##
125
+ # Creates a new Store of +type+ that will load or save to +path+
126
+
127
+ def initialize path = nil, type = nil
128
+ @dry_run = false
129
+ @encoding = nil
130
+ @path = path
131
+ @rdoc = nil
132
+ @type = type
133
+
134
+ @cache = {
135
+ :ancestors => {},
136
+ :attributes => {},
137
+ :class_methods => {},
138
+ :c_class_variables => {},
139
+ :c_singleton_class_variables => {},
140
+ :encoding => @encoding,
141
+ :instance_methods => {},
142
+ :main => nil,
143
+ :modules => [],
144
+ :pages => [],
145
+ :title => nil,
146
+ }
147
+
148
+ @classes_hash = {}
149
+ @modules_hash = {}
150
+ @files_hash = {}
151
+ @text_files_hash = {}
152
+
153
+ @c_enclosure_classes = {}
154
+ @c_enclosure_names = {}
155
+
156
+ @c_class_variables = {}
157
+ @c_singleton_class_variables = {}
158
+
159
+ @unique_classes = nil
160
+ @unique_modules = nil
161
+
162
+ @unmatched_constant_alias = {}
163
+ end
164
+
165
+ ##
166
+ # Adds +module+ as an enclosure (namespace) for the given +variable+ for C
167
+ # files.
168
+
169
+ def add_c_enclosure variable, namespace
170
+ @c_enclosure_classes[variable] = namespace
171
+ end
172
+
173
+ ##
174
+ # Adds C variables from an RDoc::Parser::C
175
+
176
+ def add_c_variables c_parser
177
+ filename = c_parser.top_level.relative_name
178
+
179
+ @c_class_variables[filename] = make_variable_map c_parser.classes
180
+
181
+ @c_singleton_class_variables[filename] = c_parser.singleton_classes
182
+ end
183
+
184
+ ##
185
+ # Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the
186
+ # created RDoc::TopLevel.
187
+
188
+ def add_file absolute_name, relative_name: absolute_name, parser: nil
189
+ unless top_level = @files_hash[relative_name] then
190
+ top_level = RDoc::TopLevel.new absolute_name, relative_name
191
+ top_level.parser = parser if parser
192
+ top_level.store = self
193
+ @files_hash[relative_name] = top_level
194
+ @text_files_hash[relative_name] = top_level if top_level.text?
195
+ end
196
+
197
+ top_level
198
+ end
199
+
200
+ def update_parser_of_file(absolute_name, parser)
201
+ if top_level = @files_hash[absolute_name] then
202
+ @text_files_hash[absolute_name] = top_level if top_level.text?
203
+ end
204
+ end
205
+
206
+ ##
207
+ # Returns all classes discovered by RDoc
208
+
209
+ def all_classes
210
+ @classes_hash.values
211
+ end
212
+
213
+ ##
214
+ # Returns all classes and modules discovered by RDoc
215
+
216
+ def all_classes_and_modules
217
+ @classes_hash.values + @modules_hash.values
218
+ end
219
+
220
+ ##
221
+ # All TopLevels known to RDoc
222
+
223
+ def all_files
224
+ @files_hash.values
225
+ end
226
+
227
+ ##
228
+ # Returns all modules discovered by RDoc
229
+
230
+ def all_modules
231
+ modules_hash.values
232
+ end
233
+
234
+ ##
235
+ # Ancestors cache accessor. Maps a klass name to an Array of its ancestors
236
+ # in this store. If Foo in this store inherits from Object, Kernel won't be
237
+ # listed (it will be included from ruby's ri store).
238
+
239
+ def ancestors
240
+ @cache[:ancestors]
241
+ end
242
+
243
+ ##
244
+ # Attributes cache accessor. Maps a class to an Array of its attributes.
245
+
246
+ def attributes
247
+ @cache[:attributes]
248
+ end
249
+
250
+ ##
251
+ # Path to the cache file
252
+
253
+ def cache_path
254
+ File.join @path, 'cache.ri'
255
+ end
256
+
257
+ ##
258
+ # Path to the ri data for +klass_name+
259
+
260
+ def class_file klass_name
261
+ name = klass_name.split('::').last
262
+ File.join class_path(klass_name), "cdesc-#{name}.ri"
263
+ end
264
+
265
+ ##
266
+ # Class methods cache accessor. Maps a class to an Array of its class
267
+ # methods (not full name).
268
+
269
+ def class_methods
270
+ @cache[:class_methods]
271
+ end
272
+
273
+ ##
274
+ # Path where data for +klass_name+ will be stored (methods or class data)
275
+
276
+ def class_path klass_name
277
+ File.join @path, *klass_name.split('::')
278
+ end
279
+
280
+ ##
281
+ # Hash of all classes known to RDoc
282
+
283
+ def classes_hash
284
+ @classes_hash
285
+ end
286
+
287
+ ##
288
+ # Removes empty items and ensures item in each collection are unique and
289
+ # sorted
290
+
291
+ def clean_cache_collection collection # :nodoc:
292
+ collection.each do |name, item|
293
+ if item.empty? then
294
+ collection.delete name
295
+ else
296
+ # HACK mongrel-1.1.5 documents its files twice
297
+ item.uniq!
298
+ item.sort!
299
+ end
300
+ end
301
+ end
302
+
303
+ ##
304
+ # Prepares the RDoc code object tree for use by a generator.
305
+ #
306
+ # It finds unique classes/modules defined, and replaces classes/modules that
307
+ # are aliases for another one by a copy with RDoc::ClassModule#is_alias_for
308
+ # set.
309
+ #
310
+ # It updates the RDoc::ClassModule#constant_aliases attribute of "real"
311
+ # classes or modules.
312
+ #
313
+ # It also completely removes the classes and modules that should be removed
314
+ # from the documentation and the methods that have a visibility below
315
+ # +min_visibility+, which is the <tt>--visibility</tt> option.
316
+ #
317
+ # See also RDoc::Context#remove_from_documentation?
318
+
319
+ def complete min_visibility
320
+ fix_basic_object_inheritance
321
+
322
+ # cache included modules before they are removed from the documentation
323
+ all_classes_and_modules.each { |cm| cm.ancestors }
324
+
325
+ unless min_visibility == :nodoc then
326
+ remove_nodoc @classes_hash
327
+ remove_nodoc @modules_hash
328
+ end
329
+
330
+ @unique_classes = find_unique @classes_hash
331
+ @unique_modules = find_unique @modules_hash
332
+
333
+ unique_classes_and_modules.each do |cm|
334
+ cm.complete min_visibility
335
+ end
336
+
337
+ @files_hash.each_key do |file_name|
338
+ tl = @files_hash[file_name]
339
+
340
+ unless tl.text? then
341
+ tl.modules_hash.clear
342
+ tl.classes_hash.clear
343
+
344
+ tl.classes_or_modules.each do |cm|
345
+ name = cm.full_name
346
+ if cm.type == 'class' then
347
+ tl.classes_hash[name] = cm if @classes_hash[name]
348
+ else
349
+ tl.modules_hash[name] = cm if @modules_hash[name]
350
+ end
351
+ end
352
+ end
353
+ end
354
+ end
355
+
356
+ ##
357
+ # Hash of all files known to RDoc
358
+
359
+ def files_hash
360
+ @files_hash
361
+ end
362
+
363
+ ##
364
+ # Finds the enclosure (namespace) for the given C +variable+.
365
+
366
+ def find_c_enclosure variable
367
+ @c_enclosure_classes.fetch variable do
368
+ break unless name = @c_enclosure_names[variable]
369
+
370
+ mod = find_class_or_module name
371
+
372
+ unless mod then
373
+ loaded_mod = load_class_data name
374
+
375
+ file = loaded_mod.in_files.first
376
+
377
+ return unless file # legacy data source
378
+
379
+ file.store = self
380
+
381
+ mod = file.add_module RDoc::NormalModule, name
382
+ end
383
+
384
+ @c_enclosure_classes[variable] = mod
385
+ end
386
+ end
387
+
388
+ ##
389
+ # Finds the class with +name+ in all discovered classes
390
+
391
+ def find_class_named name
392
+ @classes_hash[name]
393
+ end
394
+
395
+ ##
396
+ # Finds the class with +name+ starting in namespace +from+
397
+
398
+ def find_class_named_from name, from
399
+ from = find_class_named from unless RDoc::Context === from
400
+
401
+ until RDoc::TopLevel === from do
402
+ return nil unless from
403
+
404
+ klass = from.find_class_named name
405
+ return klass if klass
406
+
407
+ from = from.parent
408
+ end
409
+
410
+ find_class_named name
411
+ end
412
+
413
+ ##
414
+ # Finds the class or module with +name+
415
+
416
+ def find_class_or_module name
417
+ name = $' if name =~ /^::/
418
+ @classes_hash[name] || @modules_hash[name]
419
+ end
420
+
421
+ ##
422
+ # Finds the file with +name+ in all discovered files
423
+
424
+ def find_file_named name
425
+ @files_hash[name]
426
+ end
427
+
428
+ ##
429
+ # Finds the module with +name+ in all discovered modules
430
+
431
+ def find_module_named name
432
+ @modules_hash[name]
433
+ end
434
+
435
+ ##
436
+ # Returns the RDoc::TopLevel that is a text file and has the given
437
+ # +file_name+
438
+
439
+ def find_text_page file_name
440
+ @text_files_hash.each_value.find do |file|
441
+ file.full_name == file_name
442
+ end
443
+ end
444
+
445
+ ##
446
+ # Finds unique classes/modules defined in +all_hash+,
447
+ # and returns them as an array. Performs the alias
448
+ # updates in +all_hash+: see ::complete.
449
+ #--
450
+ # TODO aliases should be registered by Context#add_module_alias
451
+
452
+ def find_unique all_hash
453
+ unique = []
454
+
455
+ all_hash.each_pair do |full_name, cm|
456
+ unique << cm if full_name == cm.full_name
457
+ end
458
+
459
+ unique
460
+ end
461
+
462
+ ##
463
+ # Fixes the erroneous <tt>BasicObject < Object</tt> in 1.9.
464
+ #
465
+ # Because we assumed all classes without a stated superclass
466
+ # inherit from Object, we have the above wrong inheritance.
467
+ #
468
+ # We fix BasicObject right away if we are running in a Ruby
469
+ # version >= 1.9.
470
+
471
+ def fix_basic_object_inheritance
472
+ basic = classes_hash['BasicObject']
473
+ return unless basic
474
+ basic.superclass = nil
475
+ end
476
+
477
+ ##
478
+ # Friendly rendition of #path
479
+
480
+ def friendly_path
481
+ case type
482
+ when :gem then
483
+ parent = File.expand_path '..', @path
484
+ "gem #{File.basename parent}"
485
+ when :home then RDoc.home
486
+ when :site then 'ruby site'
487
+ when :system then 'ruby core'
488
+ else @path
489
+ end
490
+ end
491
+
492
+ def inspect # :nodoc:
493
+ "#<%s:0x%x %s %p>" % [self.class, object_id, @path, module_names.sort]
494
+ end
495
+
496
+ ##
497
+ # Instance methods cache accessor. Maps a class to an Array of its
498
+ # instance methods (not full name).
499
+
500
+ def instance_methods
501
+ @cache[:instance_methods]
502
+ end
503
+
504
+ ##
505
+ # Loads all items from this store into memory. This recreates a
506
+ # documentation tree for use by a generator
507
+
508
+ def load_all
509
+ load_cache
510
+
511
+ module_names.each do |module_name|
512
+ mod = find_class_or_module(module_name) || load_class(module_name)
513
+
514
+ # load method documentation since the loaded class/module does not have
515
+ # it
516
+ loaded_methods = mod.method_list.map do |method|
517
+ load_method module_name, method.full_name
518
+ end
519
+
520
+ mod.method_list.replace loaded_methods
521
+
522
+ loaded_attributes = mod.attributes.map do |attribute|
523
+ load_method module_name, attribute.full_name
524
+ end
525
+
526
+ mod.attributes.replace loaded_attributes
527
+ end
528
+
529
+ all_classes_and_modules.each do |mod|
530
+ descendent_re = /^#{mod.full_name}::[^:]+$/
531
+
532
+ module_names.each do |name|
533
+ next unless name =~ descendent_re
534
+
535
+ descendent = find_class_or_module name
536
+
537
+ case descendent
538
+ when RDoc::NormalClass then
539
+ mod.classes_hash[name] = descendent
540
+ when RDoc::NormalModule then
541
+ mod.modules_hash[name] = descendent
542
+ end
543
+ end
544
+ end
545
+
546
+ @cache[:pages].each do |page_name|
547
+ page = load_page page_name
548
+ @files_hash[page_name] = page
549
+ @text_files_hash[page_name] = page if page.text?
550
+ end
551
+ end
552
+
553
+ ##
554
+ # Loads cache file for this store
555
+
556
+ def load_cache
557
+ #orig_enc = @encoding
558
+
559
+ File.open cache_path, 'rb' do |io|
560
+ @cache = Marshal.load io.read
561
+ end
562
+
563
+ load_enc = @cache[:encoding]
564
+
565
+ # TODO this feature will be time-consuming to add:
566
+ # a) Encodings may be incompatible but transcodeable
567
+ # b) Need to warn in the appropriate spots, wherever they may be
568
+ # c) Need to handle cross-cache differences in encodings
569
+ # d) Need to warn when generating into a cache with different encodings
570
+ #
571
+ #if orig_enc and load_enc != orig_enc then
572
+ # warn "Cached encoding #{load_enc} is incompatible with #{orig_enc}\n" \
573
+ # "from #{path}/cache.ri" unless
574
+ # Encoding.compatible? orig_enc, load_enc
575
+ #end
576
+
577
+ @encoding = load_enc unless @encoding
578
+
579
+ @cache[:pages] ||= []
580
+ @cache[:main] ||= nil
581
+ @cache[:c_class_variables] ||= {}
582
+ @cache[:c_singleton_class_variables] ||= {}
583
+
584
+ @cache[:c_class_variables].each do |_, map|
585
+ map.each do |variable, name|
586
+ @c_enclosure_names[variable] = name
587
+ end
588
+ end
589
+
590
+ @cache
591
+ rescue Errno::ENOENT
592
+ end
593
+
594
+ ##
595
+ # Loads ri data for +klass_name+ and hooks it up to this store.
596
+
597
+ def load_class klass_name
598
+ obj = load_class_data klass_name
599
+
600
+ obj.store = self
601
+
602
+ case obj
603
+ when RDoc::NormalClass then
604
+ @classes_hash[klass_name] = obj
605
+ when RDoc::SingleClass then
606
+ @classes_hash[klass_name] = obj
607
+ when RDoc::NormalModule then
608
+ @modules_hash[klass_name] = obj
609
+ end
610
+ end
611
+
612
+ ##
613
+ # Loads ri data for +klass_name+
614
+
615
+ def load_class_data klass_name
616
+ file = class_file klass_name
617
+
618
+ File.open file, 'rb' do |io|
619
+ Marshal.load io.read
620
+ end
621
+ rescue Errno::ENOENT => e
622
+ error = MissingFileError.new(self, file, klass_name)
623
+ error.set_backtrace e.backtrace
624
+ raise error
625
+ end
626
+
627
+ ##
628
+ # Loads ri data for +method_name+ in +klass_name+
629
+
630
+ def load_method klass_name, method_name
631
+ file = method_file klass_name, method_name
632
+
633
+ File.open file, 'rb' do |io|
634
+ obj = Marshal.load io.read
635
+ obj.store = self
636
+ obj.parent =
637
+ find_class_or_module(klass_name) || load_class(klass_name) unless
638
+ obj.parent
639
+ obj
640
+ end
641
+ rescue Errno::ENOENT => e
642
+ error = MissingFileError.new(self, file, klass_name + method_name)
643
+ error.set_backtrace e.backtrace
644
+ raise error
645
+ end
646
+
647
+ ##
648
+ # Loads ri data for +page_name+
649
+
650
+ def load_page page_name
651
+ file = page_file page_name
652
+
653
+ File.open file, 'rb' do |io|
654
+ obj = Marshal.load io.read
655
+ obj.store = self
656
+ obj
657
+ end
658
+ rescue Errno::ENOENT => e
659
+ error = MissingFileError.new(self, file, page_name)
660
+ error.set_backtrace e.backtrace
661
+ raise error
662
+ end
663
+
664
+ ##
665
+ # Gets the main page for this RDoc store. This page is used as the root of
666
+ # the RDoc server.
667
+
668
+ def main
669
+ @cache[:main]
670
+ end
671
+
672
+ ##
673
+ # Sets the main page for this RDoc store.
674
+
675
+ def main= page
676
+ @cache[:main] = page
677
+ end
678
+
679
+ ##
680
+ # Converts the variable => ClassModule map +variables+ from a C parser into
681
+ # a variable => class name map.
682
+
683
+ def make_variable_map variables
684
+ map = {}
685
+
686
+ variables.each { |variable, class_module|
687
+ map[variable] = class_module.full_name
688
+ }
689
+
690
+ map
691
+ end
692
+
693
+ ##
694
+ # Path to the ri data for +method_name+ in +klass_name+
695
+
696
+ def method_file klass_name, method_name
697
+ method_name = method_name.split('::').last
698
+ method_name =~ /#(.*)/
699
+ method_type = $1 ? 'i' : 'c'
700
+ method_name = $1 if $1
701
+ method_name = method_name.gsub(/\W/) { "%%%02x" % $&[0].ord }
702
+
703
+ File.join class_path(klass_name), "#{method_name}-#{method_type}.ri"
704
+ end
705
+
706
+ ##
707
+ # Modules cache accessor. An Array of all the module (and class) names in
708
+ # the store.
709
+
710
+ def module_names
711
+ @cache[:modules]
712
+ end
713
+
714
+ ##
715
+ # Hash of all modules known to RDoc
716
+
717
+ def modules_hash
718
+ @modules_hash
719
+ end
720
+
721
+ ##
722
+ # Returns the RDoc::TopLevel that is a text file and has the given +name+
723
+
724
+ def page name
725
+ @text_files_hash.each_value.find do |file|
726
+ file.page_name == name or file.base_name == name
727
+ end
728
+ end
729
+
730
+ ##
731
+ # Path to the ri data for +page_name+
732
+
733
+ def page_file page_name
734
+ file_name = File.basename(page_name).gsub('.', '_')
735
+
736
+ File.join @path, File.dirname(page_name), "page-#{file_name}.ri"
737
+ end
738
+
739
+ ##
740
+ # Removes from +all_hash+ the contexts that are nodoc or have no content.
741
+ #
742
+ # See RDoc::Context#remove_from_documentation?
743
+
744
+ def remove_nodoc all_hash
745
+ all_hash.keys.each do |name|
746
+ context = all_hash[name]
747
+ all_hash.delete(name) if context.remove_from_documentation?
748
+ end
749
+ end
750
+
751
+ ##
752
+ # Saves all entries in the store
753
+
754
+ def save
755
+ load_cache
756
+
757
+ all_classes_and_modules.each do |klass|
758
+ save_class klass
759
+
760
+ klass.each_method do |method|
761
+ save_method klass, method
762
+ end
763
+
764
+ klass.each_attribute do |attribute|
765
+ save_method klass, attribute
766
+ end
767
+ end
768
+
769
+ all_files.each do |file|
770
+ save_page file
771
+ end
772
+
773
+ save_cache
774
+ end
775
+
776
+ ##
777
+ # Writes the cache file for this store
778
+
779
+ def save_cache
780
+ clean_cache_collection @cache[:ancestors]
781
+ clean_cache_collection @cache[:attributes]
782
+ clean_cache_collection @cache[:class_methods]
783
+ clean_cache_collection @cache[:instance_methods]
784
+
785
+ @cache[:modules].uniq!
786
+ @cache[:modules].sort!
787
+
788
+ @cache[:pages].uniq!
789
+ @cache[:pages].sort!
790
+
791
+ @cache[:encoding] = @encoding # this gets set twice due to assert_cache
792
+
793
+ @cache[:c_class_variables].merge! @c_class_variables
794
+ @cache[:c_singleton_class_variables].merge! @c_singleton_class_variables
795
+
796
+ return if @dry_run
797
+
798
+ File.open cache_path, 'wb' do |io|
799
+ Marshal.dump @cache, io
800
+ end
801
+ end
802
+
803
+ ##
804
+ # Writes the ri data for +klass+ (or module)
805
+
806
+ def save_class klass
807
+ full_name = klass.full_name
808
+
809
+ FileUtils.mkdir_p class_path(full_name) unless @dry_run
810
+
811
+ @cache[:modules] << full_name
812
+
813
+ path = class_file full_name
814
+
815
+ begin
816
+ disk_klass = load_class full_name
817
+
818
+ klass = disk_klass.merge klass
819
+ rescue MissingFileError
820
+ end
821
+
822
+ # BasicObject has no ancestors
823
+ ancestors = klass.direct_ancestors.compact.map do |ancestor|
824
+ # HACK for classes we don't know about (class X < RuntimeError)
825
+ String === ancestor ? ancestor : ancestor.full_name
826
+ end
827
+
828
+ @cache[:ancestors][full_name] ||= []
829
+ @cache[:ancestors][full_name].concat ancestors
830
+
831
+ attribute_definitions = klass.attributes.map do |attribute|
832
+ "#{attribute.definition} #{attribute.name}"
833
+ end
834
+
835
+ unless attribute_definitions.empty? then
836
+ @cache[:attributes][full_name] ||= []
837
+ @cache[:attributes][full_name].concat attribute_definitions
838
+ end
839
+
840
+ to_delete = []
841
+
842
+ unless klass.method_list.empty? then
843
+ @cache[:class_methods][full_name] ||= []
844
+ @cache[:instance_methods][full_name] ||= []
845
+
846
+ class_methods, instance_methods =
847
+ klass.method_list.partition { |meth| meth.singleton }
848
+
849
+ class_methods = class_methods. map { |method| method.name }
850
+ instance_methods = instance_methods.map { |method| method.name }
851
+ attribute_names = klass.attributes.map { |attr| attr.name }
852
+
853
+ old = @cache[:class_methods][full_name] - class_methods
854
+ to_delete.concat old.map { |method|
855
+ method_file full_name, "#{full_name}::#{method}"
856
+ }
857
+
858
+ old = @cache[:instance_methods][full_name] -
859
+ instance_methods - attribute_names
860
+ to_delete.concat old.map { |method|
861
+ method_file full_name, "#{full_name}##{method}"
862
+ }
863
+
864
+ @cache[:class_methods][full_name] = class_methods
865
+ @cache[:instance_methods][full_name] = instance_methods
866
+ end
867
+
868
+ return if @dry_run
869
+
870
+ FileUtils.rm_f to_delete
871
+
872
+ File.open path, 'wb' do |io|
873
+ Marshal.dump klass, io
874
+ end
875
+ end
876
+
877
+ ##
878
+ # Writes the ri data for +method+ on +klass+
879
+
880
+ def save_method klass, method
881
+ full_name = klass.full_name
882
+
883
+ FileUtils.mkdir_p class_path(full_name) unless @dry_run
884
+
885
+ cache = if method.singleton then
886
+ @cache[:class_methods]
887
+ else
888
+ @cache[:instance_methods]
889
+ end
890
+ cache[full_name] ||= []
891
+ cache[full_name] << method.name
892
+
893
+ return if @dry_run
894
+
895
+ File.open method_file(full_name, method.full_name), 'wb' do |io|
896
+ Marshal.dump method, io
897
+ end
898
+ end
899
+
900
+ ##
901
+ # Writes the ri data for +page+
902
+
903
+ def save_page page
904
+ return unless page.text?
905
+
906
+ path = page_file page.full_name
907
+
908
+ FileUtils.mkdir_p File.dirname(path) unless @dry_run
909
+
910
+ cache[:pages] ||= []
911
+ cache[:pages] << page.full_name
912
+
913
+ return if @dry_run
914
+
915
+ File.open path, 'wb' do |io|
916
+ Marshal.dump page, io
917
+ end
918
+ end
919
+
920
+ ##
921
+ # Source of the contents of this store.
922
+ #
923
+ # For a store from a gem the source is the gem name. For a store from the
924
+ # home directory the source is "home". For system ri store (the standard
925
+ # library documentation) the source is"ruby". For a store from the site
926
+ # ri directory the store is "site". For other stores the source is the
927
+ # #path.
928
+
929
+ def source
930
+ case type
931
+ when :gem then File.basename File.expand_path '..', @path
932
+ when :home then 'home'
933
+ when :site then 'site'
934
+ when :system then 'ruby'
935
+ else @path
936
+ end
937
+ end
938
+
939
+ ##
940
+ # Gets the title for this RDoc store. This is used as the title in each
941
+ # page on the RDoc server
942
+
943
+ def title
944
+ @cache[:title]
945
+ end
946
+
947
+ ##
948
+ # Sets the title page for this RDoc store.
949
+
950
+ def title= title
951
+ @cache[:title] = title
952
+ end
953
+
954
+ ##
955
+ # Returns the unique classes discovered by RDoc.
956
+ #
957
+ # ::complete must have been called prior to using this method.
958
+
959
+ def unique_classes
960
+ @unique_classes
961
+ end
962
+
963
+ ##
964
+ # Returns the unique classes and modules discovered by RDoc.
965
+ # ::complete must have been called prior to using this method.
966
+
967
+ def unique_classes_and_modules
968
+ @unique_classes + @unique_modules
969
+ end
970
+
971
+ ##
972
+ # Returns the unique modules discovered by RDoc.
973
+ # ::complete must have been called prior to using this method.
974
+
975
+ def unique_modules
976
+ @unique_modules
977
+ end
978
+
979
+ end