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.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +1 -3
  3. data/RI.md +75 -75
  4. data/exe/rdoc +2 -2
  5. data/lib/rdoc/code_object/alias.rb +71 -69
  6. data/lib/rdoc/code_object/any_method.rb +305 -303
  7. data/lib/rdoc/code_object/attr.rb +150 -148
  8. data/lib/rdoc/code_object/class_module.rb +798 -792
  9. data/lib/rdoc/code_object/constant.rb +175 -173
  10. data/lib/rdoc/code_object/context/section.rb +142 -138
  11. data/lib/rdoc/code_object/context.rb +926 -958
  12. data/lib/rdoc/code_object/extend.rb +7 -5
  13. data/lib/rdoc/code_object/include.rb +7 -5
  14. data/lib/rdoc/code_object/method_attr.rb +326 -319
  15. data/lib/rdoc/code_object/mixin.rb +97 -95
  16. data/lib/rdoc/code_object/normal_class.rb +77 -78
  17. data/lib/rdoc/code_object/normal_module.rb +61 -59
  18. data/lib/rdoc/code_object/require.rb +23 -39
  19. data/lib/rdoc/code_object/single_class.rb +21 -19
  20. data/lib/rdoc/code_object/top_level.rb +212 -219
  21. data/lib/rdoc/code_object.rb +305 -303
  22. data/lib/rdoc/comment.rb +275 -273
  23. data/lib/rdoc/cross_reference.rb +192 -190
  24. data/lib/rdoc/encoding.rb +105 -103
  25. data/lib/rdoc/erb_partial.rb +13 -11
  26. data/lib/rdoc/erbio.rb +29 -27
  27. data/lib/rdoc/generator/aliki.rb +161 -153
  28. data/lib/rdoc/generator/darkfish.rb +645 -635
  29. data/lib/rdoc/generator/json_index.rb +233 -229
  30. data/lib/rdoc/generator/markup.rb +164 -146
  31. data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
  32. data/lib/rdoc/generator/pot/po.rb +52 -51
  33. data/lib/rdoc/generator/pot/po_entry.rb +138 -132
  34. data/lib/rdoc/generator/pot.rb +85 -81
  35. data/lib/rdoc/generator/ri.rb +23 -19
  36. data/lib/rdoc/generator/template/aliki/DESIGN.md +6 -4
  37. data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
  38. data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
  39. data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
  40. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
  41. data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
  42. data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
  43. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
  44. data/lib/rdoc/generator.rb +48 -46
  45. data/lib/rdoc/i18n/locale.rb +99 -95
  46. data/lib/rdoc/i18n/text.rb +109 -105
  47. data/lib/rdoc/i18n.rb +7 -5
  48. data/lib/rdoc/markdown/byte_runtime.rb +80 -0
  49. data/lib/rdoc/markdown.kpeg +15 -11
  50. data/lib/rdoc/markdown.rb +40 -47
  51. data/lib/rdoc/markup/block_quote.rb +12 -8
  52. data/lib/rdoc/markup/document.rb +127 -123
  53. data/lib/rdoc/markup/formatter.rb +219 -215
  54. data/lib/rdoc/markup/include.rb +33 -29
  55. data/lib/rdoc/markup/indented_paragraph.rb +37 -33
  56. data/lib/rdoc/markup/inline_parser.rb +281 -277
  57. data/lib/rdoc/markup/list.rb +80 -88
  58. data/lib/rdoc/markup/list_item.rb +73 -85
  59. data/lib/rdoc/markup/paragraph.rb +23 -19
  60. data/lib/rdoc/markup/parser.rb +501 -497
  61. data/lib/rdoc/markup/pre_process.rb +283 -279
  62. data/lib/rdoc/markup/raw.rb +2 -2
  63. data/lib/rdoc/markup/rule.rb +16 -12
  64. data/lib/rdoc/markup/to_ansi.rb +143 -139
  65. data/lib/rdoc/markup/to_bs.rb +72 -68
  66. data/lib/rdoc/markup/to_html.rb +594 -565
  67. data/lib/rdoc/markup/to_html_crossref.rb +234 -230
  68. data/lib/rdoc/markup/to_html_snippet.rb +232 -227
  69. data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
  70. data/lib/rdoc/markup/to_label.rb +63 -59
  71. data/lib/rdoc/markup/to_markdown.rb +212 -208
  72. data/lib/rdoc/markup/to_rdoc.rb +336 -332
  73. data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
  74. data/lib/rdoc/markup/to_test.rb +60 -56
  75. data/lib/rdoc/markup/to_tt_only.rb +84 -80
  76. data/lib/rdoc/markup/verbatim.rb +62 -58
  77. data/lib/rdoc/markup.rb +198 -196
  78. data/lib/rdoc/options.rb +1063 -1061
  79. data/lib/rdoc/parser/c.rb +1039 -1037
  80. data/lib/rdoc/parser/changelog.rb +319 -315
  81. data/lib/rdoc/parser/markdown.rb +17 -13
  82. data/lib/rdoc/parser/rbs.rb +239 -235
  83. data/lib/rdoc/parser/rd.rb +17 -13
  84. data/lib/rdoc/parser/ruby.rb +1245 -1124
  85. data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
  86. data/lib/rdoc/parser/simple.rb +31 -27
  87. data/lib/rdoc/parser/text.rb +12 -8
  88. data/lib/rdoc/parser.rb +228 -220
  89. data/lib/rdoc/rbs_helper.rb +1 -1
  90. data/lib/rdoc/rd/inline.rb +57 -53
  91. data/lib/rdoc/rd.rb +90 -88
  92. data/lib/rdoc/rdoc.rb +500 -491
  93. data/lib/rdoc/ri/driver.rb +1140 -1135
  94. data/lib/rdoc/ri/formatter.rb +7 -3
  95. data/lib/rdoc/ri/paths.rb +140 -136
  96. data/lib/rdoc/ri/servlet.rb +354 -350
  97. data/lib/rdoc/ri/store.rb +4 -2
  98. data/lib/rdoc/ri/task.rb +55 -51
  99. data/lib/rdoc/ri.rb +14 -12
  100. data/lib/rdoc/rubygems_hook.rb +183 -181
  101. data/lib/rdoc/server.rb +349 -347
  102. data/lib/rdoc/stats/normal.rb +46 -42
  103. data/lib/rdoc/stats/quiet.rb +39 -35
  104. data/lib/rdoc/stats/verbose.rb +35 -31
  105. data/lib/rdoc/stats.rb +365 -363
  106. data/lib/rdoc/store.rb +888 -902
  107. data/lib/rdoc/task.rb +260 -256
  108. data/lib/rdoc/text.rb +135 -133
  109. data/lib/rdoc/token_stream.rb +101 -93
  110. data/lib/rdoc/tom_doc.rb +203 -201
  111. data/lib/rdoc/version.rb +1 -1
  112. metadata +4 -5
  113. data/lib/rdoc/markdown/literals.kpeg +0 -21
  114. data/lib/rdoc/markdown/literals.rb +0 -454
@@ -1,969 +1,975 @@
1
1
  # frozen_string_literal: true
2
- ##
3
- # ClassModule is the base class for objects representing either a class or a
4
- # module.
5
-
6
- class RDoc::ClassModule < RDoc::Context
7
-
8
- ##
9
- # 1::
10
- # RDoc 3.7
11
- # * Added visibility, singleton and file to attributes
12
- # * Added file to constants
13
- # * Added file to includes
14
- # * Added file to methods
15
- # 2::
16
- # RDoc 3.13
17
- # * Added extends
18
- # 3::
19
- # RDoc 4.0
20
- # * Added sections
21
- # * Added in_files
22
- # * Added parent name
23
- # * Complete Constant dump
24
-
25
- MARSHAL_VERSION = 3 # :nodoc:
26
-
27
- ##
28
- # Constants that are aliases for this class or module
29
-
30
- attr_accessor :constant_aliases
2
+ module RDoc
3
+ ##
4
+ # ClassModule is the base class for objects representing either a class or a
5
+ # module.
6
+
7
+ class ClassModule < ::RDoc::Context
8
+
9
+ ##
10
+ # 1::
11
+ # RDoc 3.7
12
+ # * Added visibility, singleton and file to attributes
13
+ # * Added file to constants
14
+ # * Added file to includes
15
+ # * Added file to methods
16
+ # 2::
17
+ # RDoc 3.13
18
+ # * Added extends
19
+ # 3::
20
+ # RDoc 4.0
21
+ # * Added sections
22
+ # * Added in_files
23
+ # * Added parent name
24
+ # * Complete Constant dump
25
+
26
+ MARSHAL_VERSION = 3 # :nodoc:
27
+
28
+ ##
29
+ # Constants that are aliases for this class or module
30
+
31
+ attr_accessor :constant_aliases
32
+
33
+ ##
34
+ # A hash of <tt>{ location => [comments] }</tt> documenting this class/module.
35
+ # Use #add_comment to add comments.
36
+ #
37
+ # Ruby hashes maintain insertion order, so comments render in the order
38
+ # they were first added. Each location maps to an array of comments,
39
+ # allowing a class reopened in the same file to accumulate multiple comments.
40
+ #
41
+ # Before marshalling:
42
+ # - +location+ is an RDoc::TopLevel
43
+ # - +comments+ are Strings
44
+ #
45
+ # After unmarshalling:
46
+ # - +location+ is a filename String
47
+ # - +comments+ are RDoc::Markup::Documents
48
+
49
+ attr_accessor :comment_location
50
+
51
+ ##
52
+ # Class or module this constant is an alias for
53
+
54
+ attr_accessor :is_alias_for
55
+
56
+ ##
57
+ # Return a RDoc::ClassModule of class +class_type+ that is a copy
58
+ # of module +module+. Used to promote modules to classes.
59
+ #--
60
+ # TODO move to RDoc::NormalClass (I think)
61
+
62
+ def self.from_module(class_type, mod)
63
+ klass = class_type.new mod.name
64
+
65
+ mod.comment_location.each do |location, comments|
66
+ comments.each { |comment| klass.add_comment comment, location }
67
+ end
31
68
 
32
- ##
33
- # A hash of <tt>{ location => [comments] }</tt> documenting this class/module.
34
- # Use #add_comment to add comments.
35
- #
36
- # Ruby hashes maintain insertion order, so comments render in the order
37
- # they were first added. Each location maps to an array of comments,
38
- # allowing a class reopened in the same file to accumulate multiple comments.
39
- #
40
- # Before marshalling:
41
- # - +location+ is an RDoc::TopLevel
42
- # - +comments+ are Strings
43
- #
44
- # After unmarshalling:
45
- # - +location+ is a filename String
46
- # - +comments+ are RDoc::Markup::Documents
47
-
48
- attr_accessor :comment_location
69
+ klass.parent = mod.parent
70
+ klass.section = mod.section
71
+
72
+ klass.attributes.concat mod.attributes
73
+ klass.method_list.concat mod.method_list
74
+ klass.aliases.concat mod.aliases
75
+ klass.external_aliases.concat mod.external_aliases
76
+ klass.constants.concat mod.constants
77
+ klass.includes.concat mod.includes
78
+ klass.extends.concat mod.extends
79
+
80
+ klass.methods_hash.update mod.methods_hash
81
+ klass.constants_hash.update mod.constants_hash
82
+
83
+ klass.current_section = mod.current_section
84
+ klass.in_files.concat mod.in_files
85
+ klass.sections.concat mod.sections
86
+ klass.unmatched_alias_lists = mod.unmatched_alias_lists
87
+ klass.current_section = mod.current_section
88
+ klass.classes_hash.update mod.classes_hash
89
+ klass.modules_hash.update mod.modules_hash
90
+ klass.metadata.update mod.metadata
91
+
92
+ klass.document_self = mod.received_nodoc ? nil : mod.document_self
93
+ klass.document_children = mod.document_children
94
+ klass.force_documentation = mod.force_documentation
95
+ klass.done_documenting = mod.done_documenting
96
+
97
+ # update the parent of all children
98
+
99
+ (klass.attributes +
100
+ klass.method_list +
101
+ klass.aliases +
102
+ klass.external_aliases +
103
+ klass.constants +
104
+ klass.includes +
105
+ klass.extends +
106
+ klass.classes +
107
+ klass.modules).each do |obj|
108
+ obj.parent = klass
109
+ obj.full_name = nil
110
+ end
49
111
 
50
- ##
51
- # Class or module this constant is an alias for
112
+ klass
113
+ end
52
114
 
53
- attr_accessor :is_alias_for
115
+ ##
116
+ # Creates a new ClassModule with +name+ with optional +superclass+
117
+ #
118
+ # This is a constructor for subclasses, and must never be called directly.
54
119
 
55
- ##
56
- # Return a RDoc::ClassModule of class +class_type+ that is a copy
57
- # of module +module+. Used to promote modules to classes.
58
- #--
59
- # TODO move to RDoc::NormalClass (I think)
60
-
61
- def self.from_module(class_type, mod)
62
- klass = class_type.new mod.name
63
-
64
- mod.comment_location.each do |location, comments|
65
- comments.each { |comment| klass.add_comment comment, location }
66
- end
67
-
68
- klass.parent = mod.parent
69
- klass.section = mod.section
70
-
71
- klass.attributes.concat mod.attributes
72
- klass.method_list.concat mod.method_list
73
- klass.aliases.concat mod.aliases
74
- klass.external_aliases.concat mod.external_aliases
75
- klass.constants.concat mod.constants
76
- klass.includes.concat mod.includes
77
- klass.extends.concat mod.extends
78
-
79
- klass.methods_hash.update mod.methods_hash
80
- klass.constants_hash.update mod.constants_hash
81
-
82
- klass.current_section = mod.current_section
83
- klass.in_files.concat mod.in_files
84
- klass.sections.concat mod.sections
85
- klass.unmatched_alias_lists = mod.unmatched_alias_lists
86
- klass.current_section = mod.current_section
87
- klass.visibility = mod.visibility
88
-
89
- klass.classes_hash.update mod.classes_hash
90
- klass.modules_hash.update mod.modules_hash
91
- klass.metadata.update mod.metadata
92
-
93
- klass.document_self = mod.received_nodoc ? nil : mod.document_self
94
- klass.document_children = mod.document_children
95
- klass.force_documentation = mod.force_documentation
96
- klass.done_documenting = mod.done_documenting
97
-
98
- # update the parent of all children
99
-
100
- (klass.attributes +
101
- klass.method_list +
102
- klass.aliases +
103
- klass.external_aliases +
104
- klass.constants +
105
- klass.includes +
106
- klass.extends +
107
- klass.classes +
108
- klass.modules).each do |obj|
109
- obj.parent = klass
110
- obj.full_name = nil
111
- end
112
-
113
- klass
114
- end
120
+ def initialize(name, superclass = nil)
121
+ @constant_aliases = []
122
+ @is_alias_for = nil
123
+ @name = name
124
+ @superclass = superclass
125
+ @comment_location = {} # Hash of { location => [comments] }
115
126
 
116
- ##
117
- # Creates a new ClassModule with +name+ with optional +superclass+
118
- #
119
- # This is a constructor for subclasses, and must never be called directly.
120
-
121
- def initialize(name, superclass = nil)
122
- @constant_aliases = []
123
- @is_alias_for = nil
124
- @name = name
125
- @superclass = superclass
126
- @comment_location = {} # Hash of { location => [comments] }
127
-
128
- super()
129
- end
127
+ super()
128
+ end
130
129
 
131
- ##
132
- # Adds +comment+ to this ClassModule's list of comments at +location+. This
133
- # method is preferred over #comment= since it allows ri data to be updated
134
- # across multiple runs.
130
+ ##
131
+ # Adds +comment+ to this ClassModule's list of comments at +location+. This
132
+ # method is preferred over #comment= since it allows ri data to be updated
133
+ # across multiple runs.
135
134
 
136
- def add_comment(comment, location)
137
- return unless document_self
135
+ def add_comment(comment, location)
136
+ return unless document_self
138
137
 
139
- original = comment
138
+ original = comment
140
139
 
141
- comment = case comment
142
- when RDoc::Comment then
143
- comment.normalize
144
- else
145
- normalize_comment comment
146
- end
140
+ comment = case comment
141
+ when Comment
142
+ comment.normalize
143
+ else
144
+ normalize_comment comment
145
+ end
147
146
 
148
- (@comment_location[location] ||= []) << comment
147
+ (@comment_location[location] ||= []) << comment
149
148
 
150
- self.comment = original
151
- end
149
+ self.comment = original
150
+ end
152
151
 
153
- def add_things(my_things, other_things) # :nodoc:
154
- other_things.each do |group, things|
155
- my_things[group].each { |thing| yield false, thing } if
156
- my_things.include? group
152
+ def add_things(my_things, other_things) # :nodoc:
153
+ other_things.each do |group, things|
154
+ my_things[group].each { |thing| yield false, thing } if
155
+ my_things.include? group
157
156
 
158
- things.each do |thing|
159
- yield true, thing
157
+ things.each do |thing|
158
+ yield true, thing
159
+ end
160
160
  end
161
161
  end
162
- end
163
-
164
- ##
165
- # Ancestors list for this ClassModule: the list of included modules
166
- # (classes will add their superclass if any).
167
- #
168
- # Returns the included classes or modules, not the includes
169
- # themselves. The returned values are either String or
170
- # RDoc::NormalModule instances (see RDoc::Include#module).
171
- #
172
- # The values are returned in reverse order of their inclusion,
173
- # which is the order suitable for searching methods/attributes
174
- # in the ancestors. The superclass, if any, comes last.
175
-
176
- def ancestors
177
- includes.map { |i| i.module }.reverse
178
- end
179
-
180
- def aref_prefix # :nodoc:
181
- raise NotImplementedError, "missing aref_prefix for #{self.class}"
182
- end
183
162
 
184
- ##
185
- # HTML fragment reference for this module or class using GitHub-style
186
- # anchor format (lowercase, :: replaced with -).
187
- #
188
- # Examples:
189
- # Foo -> class-foo
190
- # Foo::Bar -> class-foo-bar
191
-
192
- def aref
193
- "#{aref_prefix}-#{full_name.downcase.gsub('::', '-')}"
194
- end
163
+ ##
164
+ # Ancestors list for this ClassModule: the list of included modules
165
+ # (classes will add their superclass if any).
166
+ #
167
+ # Returns the included classes or modules, not the includes
168
+ # themselves. The returned values are either String or
169
+ # RDoc::NormalModule instances (see RDoc::Include#module).
170
+ #
171
+ # The values are returned in reverse order of their inclusion,
172
+ # which is the order suitable for searching methods/attributes
173
+ # in the ancestors. The superclass, if any, comes last.
195
174
 
196
- ##
197
- # Legacy HTML fragment reference for backward compatibility.
198
- # Returns the old RDoc-style anchor format.
199
- #
200
- # Examples:
201
- # Foo -> class-Foo
202
- # Foo::Bar -> class-Foo::Bar
203
-
204
- def legacy_aref
205
- "#{aref_prefix}-#{full_name}"
206
- end
207
-
208
- ##
209
- # Ancestors of this class or module only
175
+ def ancestors
176
+ included_ancestors
177
+ end
210
178
 
211
- alias direct_ancestors ancestors
179
+ def included_ancestors # :nodoc:
180
+ includes.map { |i| i.module }.reverse
181
+ end
212
182
 
213
- ##
214
- # Clears the comment. Used by the Ruby parser.
183
+ def aref_prefix # :nodoc:
184
+ raise NotImplementedError, "missing aref_prefix for #{self.class}"
185
+ end
215
186
 
216
- def clear_comment
217
- @comment = ''
218
- end
187
+ ##
188
+ # HTML fragment reference for this module or class using GitHub-style
189
+ # anchor format (lowercase, :: replaced with -).
190
+ #
191
+ # Examples:
192
+ # Foo -> class-foo
193
+ # Foo::Bar -> class-foo-bar
219
194
 
220
- ##
221
- # This method is deprecated, use #add_comment instead.
222
- #
223
- # Appends +comment+ to the current comment, but separated by a rule. Works
224
- # more like <tt>+=</tt>.
225
-
226
- def comment=(comment) # :nodoc:
227
- comment = case comment
228
- when RDoc::Comment then
229
- comment.normalize
230
- else
231
- normalize_comment comment
232
- end
195
+ def aref
196
+ "#{aref_prefix}-#{full_name.downcase.gsub('::', '-')}"
197
+ end
233
198
 
234
- comment = "#{@comment.to_s}\n---\n#{comment.to_s}" unless @comment.empty?
199
+ ##
200
+ # Legacy HTML fragment reference for backward compatibility.
201
+ # Returns the old RDoc-style anchor format.
202
+ #
203
+ # Examples:
204
+ # Foo -> class-Foo
205
+ # Foo::Bar -> class-Foo::Bar
235
206
 
236
- super comment
237
- end
207
+ def legacy_aref
208
+ "#{aref_prefix}-#{full_name}"
209
+ end
238
210
 
239
- ##
240
- # Prepares this ClassModule for use by a generator.
241
- #
242
- # See RDoc::Store#complete
243
-
244
- def complete(min_visibility)
245
- update_aliases
246
- remove_nodoc_children
247
- embed_mixins
248
- update_includes
249
- update_extends
250
- remove_invisible min_visibility
251
- end
211
+ ##
212
+ # Ancestors of this class or module only
252
213
 
253
- ##
254
- # Does this ClassModule or any of its methods have document_self set?
214
+ alias direct_ancestors ancestors
255
215
 
256
- def document_self_or_methods
257
- document_self || method_list.any?{ |m| m.document_self }
258
- end
216
+ ##
217
+ # Clears the comment. Used by the Ruby parser.
259
218
 
260
- ##
261
- # Does this class or module have a comment with content or is
262
- # #received_nodoc true?
219
+ def clear_comment
220
+ @comment = ''
221
+ end
263
222
 
264
- def documented?
265
- return true if @received_nodoc
266
- return false if @comment_location.empty?
267
- @comment_location.each_value.any? { |comments| comments.any? { |c| not c.empty? } }
268
- end
223
+ ##
224
+ # This method is deprecated, use #add_comment instead.
225
+ #
226
+ # Appends +comment+ to the current comment, but separated by a rule. Works
227
+ # more like <tt>+=</tt>.
269
228
 
270
- ##
271
- # Iterates the ancestors of this class or module for which an
272
- # RDoc::ClassModule exists.
229
+ def comment=(comment) # :nodoc:
230
+ comment = case comment
231
+ when Comment
232
+ comment.normalize
233
+ else
234
+ normalize_comment comment
235
+ end
273
236
 
274
- def each_ancestor # :yields: module
275
- return enum_for __method__ unless block_given?
237
+ comment = "#{@comment.to_s}\n---\n#{comment.to_s}" unless @comment.empty?
276
238
 
277
- ancestors.each do |mod|
278
- next if String === mod
279
- next if self == mod
280
- yield mod
239
+ super comment
281
240
  end
282
- end
283
241
 
284
- ##
285
- # Looks for a symbol in the #ancestors. See Context#find_local_symbol.
242
+ ##
243
+ # Prepares this ClassModule for use by a generator.
244
+ #
245
+ # See RDoc::Store#complete
286
246
 
287
- def find_ancestor_local_symbol(symbol)
288
- each_ancestor do |m|
289
- res = m.find_local_symbol(symbol)
290
- return res if res
247
+ def complete(min_visibility)
248
+ update_aliases
249
+ remove_nodoc_children
250
+ embed_mixins
251
+ update_includes
252
+ update_extends
253
+ remove_invisible min_visibility
291
254
  end
292
255
 
293
- nil
294
- end
256
+ ##
257
+ # Does this ClassModule or any of its methods have document_self set?
295
258
 
296
- ##
297
- # Finds a class or module with +name+ in this namespace or its descendants
259
+ def document_self_or_methods
260
+ document_self || method_list.any?{ |m| m.document_self }
261
+ end
298
262
 
299
- def find_class_named(name)
300
- return self if full_name == name
301
- return self if @name == name
263
+ ##
264
+ # Does this class or module have a comment with content or is
265
+ # #received_nodoc true?
302
266
 
303
- @classes.values.find do |klass|
304
- next if klass == self
305
- klass.find_class_named name
267
+ def documented?
268
+ return true if @received_nodoc
269
+ return false if @comment_location.empty?
270
+ @comment_location.each_value.any? { |comments| comments.any? { |c| not c.empty? } }
306
271
  end
307
- end
308
272
 
309
- ##
310
- # Return the fully qualified name of this class or module
311
-
312
- def full_name
313
- @full_name ||= if RDoc::ClassModule === parent then
314
- "#{parent.full_name}::#{@name}"
315
- else
316
- @name
317
- end
318
- end
273
+ ##
274
+ # Iterates the ancestors of this class or module for which an
275
+ # RDoc::ClassModule exists.
319
276
 
320
- ##
321
- # Return array of full_name splitted by +::+.
277
+ def each_ancestor # :yields: module
278
+ return enum_for __method__ unless block_given?
322
279
 
323
- def nesting_namespaces
324
- @namespaces ||= full_name.split("::").reject(&:empty?)
325
- end
280
+ ancestors.each do |mod|
281
+ next if String === mod
282
+ next if self == mod
283
+ yield mod
284
+ end
285
+ end
326
286
 
327
- ##
328
- # Return array of fully qualified nesting namespaces.
329
- #
330
- # For example, if full_name is +A::B::C+, this method returns <code>["A", "A::B", "A::B::C"]</code>
287
+ ##
288
+ # Looks for a symbol in the #ancestors. See Context#find_local_symbol.
331
289
 
332
- def fully_qualified_nesting_namespaces
333
- return nesting_namespaces if nesting_namespaces.length < 2
334
- @fqns ||= nesting_namespaces.inject([]) do |list, n|
335
- list << (list.empty? ? n : "#{list.last}::#{n}")
290
+ def find_ancestor_local_symbol(symbol)
291
+ each_ancestor do |m|
292
+ res = m.find_local_symbol(symbol)
293
+ return res if res
294
+ end
295
+
296
+ nil
336
297
  end
337
- end
338
298
 
339
- ##
340
- # TODO: filter included items by #display?
299
+ ##
300
+ # Finds a class or module with +name+ in this namespace or its descendants
341
301
 
342
- def marshal_dump # :nodoc:
343
- attrs = attributes.sort.map do |attr|
344
- next unless attr.display?
345
- [ attr.name, attr.rw,
346
- attr.visibility, attr.singleton, attr.file_name,
347
- ]
348
- end.compact
349
-
350
- method_types = methods_by_type.map do |type, visibilities|
351
- visibilities = visibilities.map do |visibility, methods|
352
- method_names = methods.map do |method|
353
- next unless method.display?
354
- [method.name, method.file_name]
355
- end.compact
356
-
357
- [visibility, method_names.uniq]
358
- end
359
-
360
- [type, visibilities]
361
- end
362
-
363
- [ MARSHAL_VERSION,
364
- @name,
365
- full_name,
366
- @superclass,
367
- parse(@comment_location),
368
- attrs,
369
- constants.select { |constant| constant.display? },
370
- includes.map do |incl|
371
- next unless incl.display?
372
- [incl.name, parse(incl.comment), incl.file_name]
373
- end.compact,
374
- method_types,
375
- extends.map do |ext|
376
- next unless ext.display?
377
- [ext.name, parse(ext.comment), ext.file_name]
378
- end.compact,
379
- @sections.values,
380
- @in_files.map do |tl|
381
- tl.relative_name
382
- end,
383
- parent.full_name,
384
- parent.class,
385
- ]
386
- end
302
+ def find_class_named(name)
303
+ return self if full_name == name
304
+ return self if @name == name
387
305
 
388
- def marshal_load(array) # :nodoc:
389
- initialize_visibility
390
- initialize_methods_etc
391
- @current_section = nil
392
- @document_self = true
393
- @done_documenting = false
394
- @parent = nil
395
- @temporary_section = nil
396
- @visibility = nil
397
- @classes = {}
398
- @modules = {}
399
-
400
- @name = array[1]
401
- @full_name = array[2]
402
- @superclass = array[3]
403
- document = array[4]
404
-
405
- @comment = RDoc::Comment.from_document document
406
-
407
- @comment_location = if document.parts.first.is_a?(RDoc::Markup::Document)
408
- document.parts.group_by(&:file)
409
- else
410
- { document.file => [document] }
411
- end
412
-
413
- array[5].each do |name, rw, visibility, singleton, file|
414
- singleton ||= false
415
- visibility ||= :public
416
-
417
- attr = RDoc::Attr.new name, rw, nil, singleton: singleton
418
-
419
- add_attribute attr
420
- attr.visibility = visibility
421
- attr.record_location RDoc::TopLevel.new file
422
- end
423
-
424
- array[6].each do |constant, document, file|
425
- case constant
426
- when RDoc::Constant then
427
- add_constant constant
428
- else
429
- constant = add_constant RDoc::Constant.new(constant, nil, RDoc::Comment.from_document(document))
430
- constant.record_location RDoc::TopLevel.new file
306
+ @classes.values.find do |klass|
307
+ next if klass == self
308
+ klass.find_class_named name
431
309
  end
432
310
  end
433
311
 
434
- array[7].each do |name, document, file|
435
- incl = add_include RDoc::Include.new(name, RDoc::Comment.from_document(document))
436
- incl.record_location RDoc::TopLevel.new file
312
+ ##
313
+ # Return the fully qualified name of this class or module
314
+
315
+ def full_name
316
+ @full_name ||= if ClassModule === parent
317
+ "#{parent.full_name}::#{@name}"
318
+ else
319
+ @name
320
+ end
437
321
  end
438
322
 
439
- array[8].each do |type, visibilities|
440
- visibilities.each do |visibility, methods|
441
- @visibility = visibility
323
+ ##
324
+ # Return array of full_name splitted by +::+.
442
325
 
443
- methods.each do |name, file|
444
- method = RDoc::AnyMethod.new name, singleton: type == 'class'
445
- method.record_location RDoc::TopLevel.new file
446
- add_method method
447
- end
448
- end
326
+ def nesting_namespaces
327
+ @namespaces ||= full_name.split("::").reject(&:empty?)
449
328
  end
450
329
 
451
- array[9].each do |name, document, file|
452
- ext = add_extend RDoc::Extend.new(name, RDoc::Comment.from_document(document))
453
- ext.record_location RDoc::TopLevel.new file
454
- end if array[9] # Support Marshal version 1
330
+ ##
331
+ # Return array of fully qualified nesting namespaces.
332
+ #
333
+ # For example, if full_name is +A::B::C+, this method returns <code>["A", "A::B", "A::B::C"]</code>
455
334
 
456
- sections = (array[10] || []).map do |section|
457
- [section.title, section]
335
+ def fully_qualified_nesting_namespaces
336
+ return nesting_namespaces if nesting_namespaces.length < 2
337
+ @fqns ||= nesting_namespaces.inject([]) do |list, n|
338
+ list << (list.empty? ? n : "#{list.last}::#{n}")
339
+ end
458
340
  end
459
341
 
460
- @sections = Hash[*sections.flatten]
461
- @current_section = add_section nil
342
+ ##
343
+ # TODO: filter included items by #display?
462
344
 
463
- @in_files = []
345
+ def marshal_dump # :nodoc:
346
+ attrs = attributes.sort.map do |attr|
347
+ next unless attr.display?
348
+ [ attr.name, attr.rw,
349
+ attr.visibility, attr.singleton, attr.file_name,
350
+ ]
351
+ end.compact
464
352
 
465
- (array[11] || []).each do |filename|
466
- record_location RDoc::TopLevel.new filename
467
- end
468
-
469
- @parent_name = array[12]
470
- @parent_class = array[13]
471
- end
353
+ method_types = methods_by_type.map do |type, visibilities|
354
+ visibilities = visibilities.map do |visibility, methods|
355
+ method_names = methods.map do |method|
356
+ next unless method.display?
357
+ [method.name, method.file_name]
358
+ end.compact
472
359
 
473
- ##
474
- # Merges +class_module+ into this ClassModule.
475
- #
476
- # The data in +class_module+ is preferred over the receiver.
360
+ [visibility, method_names.uniq]
361
+ end
477
362
 
478
- def merge(class_module)
479
- @parent = class_module.parent
480
- @parent_name = class_module.parent_name
363
+ [type, visibilities]
364
+ end
481
365
 
482
- other_document = parse class_module.comment_location
366
+ [ MARSHAL_VERSION,
367
+ @name,
368
+ full_name,
369
+ @superclass,
370
+ parse(@comment_location),
371
+ attrs,
372
+ constants.select { |constant| constant.display? },
373
+ includes.map do |incl|
374
+ next unless incl.display?
375
+ [incl.name, parse(incl.comment), incl.file_name]
376
+ end.compact,
377
+ method_types,
378
+ extends.map do |ext|
379
+ next unless ext.display?
380
+ [ext.name, parse(ext.comment), ext.file_name]
381
+ end.compact,
382
+ @sections.values,
383
+ @in_files.map do |tl|
384
+ tl.relative_name
385
+ end,
386
+ parent.full_name,
387
+ parent.class,
388
+ ]
389
+ end
483
390
 
484
- if other_document then
485
- document = parse @comment_location
391
+ def marshal_load(array) # :nodoc:
392
+ initialize_visibility
393
+ initialize_methods_etc
394
+ @current_section = nil
395
+ @document_self = true
396
+ @done_documenting = false
397
+ @parent = nil
398
+ @temporary_section = nil
399
+ @classes = {}
400
+ @modules = {}
486
401
 
487
- document = document.merge other_document
402
+ @name = array[1]
403
+ @full_name = array[2]
404
+ @superclass = array[3]
405
+ document = array[4]
488
406
 
489
- @comment = RDoc::Comment.from_document(document)
407
+ @comment = Comment.from_document document
490
408
 
491
- @comment_location = if document.parts.first.is_a?(RDoc::Markup::Document)
409
+ @comment_location = if document.parts.first.is_a?(Markup::Document)
492
410
  document.parts.group_by(&:file)
493
411
  else
494
412
  { document.file => [document] }
495
413
  end
496
- end
497
414
 
498
- cm = class_module
499
- other_files = cm.in_files
415
+ array[5].each do |name, rw, visibility, singleton, file|
416
+ singleton ||= false
417
+ visibility ||= :public
418
+
419
+ attr = Attr.new name, rw, nil, singleton: singleton
500
420
 
501
- merge_collections attributes, cm.attributes, other_files do |add, attr|
502
- if add then
503
421
  add_attribute attr
504
- else
505
- @attributes.delete attr
506
- @methods_hash.delete attr.pretty_name
422
+ attr.visibility = visibility
423
+ attr.record_location TopLevel.new file
507
424
  end
508
- end
509
425
 
510
- merge_collections constants, cm.constants, other_files do |add, const|
511
- if add then
512
- add_constant const
513
- else
514
- @constants.delete const
515
- @constants_hash.delete const.name
426
+ array[6].each do |constant, document, file|
427
+ case constant
428
+ when Constant
429
+ add_constant constant
430
+ else
431
+ constant = add_constant Constant.new(constant, nil, Comment.from_document(document))
432
+ constant.record_location TopLevel.new file
433
+ end
516
434
  end
517
- end
518
435
 
519
- merge_collections includes, cm.includes, other_files do |add, incl|
520
- if add then
521
- add_include incl
522
- else
523
- @includes.delete incl
436
+ array[7].each do |name, document, file|
437
+ incl = add_include Include.new(name, Comment.from_document(document))
438
+ incl.record_location TopLevel.new file
524
439
  end
525
- end
526
440
 
527
- @includes.uniq! # clean up
441
+ array[8].each do |type, visibilities|
442
+ visibilities.each do |visibility, methods|
443
+ methods.each do |name, file|
444
+ method = AnyMethod.new name, singleton: type == 'class'
445
+ method.record_location TopLevel.new file
446
+ method.visibility = visibility
447
+ add_method method
448
+ end
449
+ end
450
+ end
528
451
 
529
- merge_collections extends, cm.extends, other_files do |add, ext|
530
- if add then
531
- add_extend ext
532
- else
533
- @extends.delete ext
452
+ array[9].each do |name, document, file|
453
+ ext = add_extend Extend.new(name, Comment.from_document(document))
454
+ ext.record_location TopLevel.new file
455
+ end if array[9] # Support Marshal version 1
456
+
457
+ sections = (array[10] || []).map do |section|
458
+ [section.title, section]
534
459
  end
535
- end
536
460
 
537
- @extends.uniq! # clean up
461
+ @sections = Hash[*sections.flatten]
462
+ @current_section = add_section nil
538
463
 
539
- merge_collections method_list, cm.method_list, other_files do |add, meth|
540
- if add then
541
- add_method meth
542
- else
543
- @method_list.delete meth
544
- @methods_hash.delete meth.pretty_name
464
+ @in_files = []
465
+
466
+ (array[11] || []).each do |filename|
467
+ record_location TopLevel.new filename
545
468
  end
469
+
470
+ @parent_name = array[12]
471
+ @parent_class = array[13]
546
472
  end
547
473
 
548
- merge_sections cm
474
+ ##
475
+ # Merges +class_module+ into this ClassModule.
476
+ #
477
+ # The data in +class_module+ is preferred over the receiver.
549
478
 
550
- self
551
- end
479
+ def merge(class_module)
480
+ @parent = class_module.parent
481
+ @parent_name = class_module.parent_name
552
482
 
553
- ##
554
- # Merges collection +mine+ with +other+ preferring other. +other_files+ is
555
- # used to help determine which items should be deleted.
556
- #
557
- # Yields whether the item should be added or removed (true or false) and the
558
- # item to be added or removed.
559
- #
560
- # merge_collections things, other.things, other.in_files do |add, thing|
561
- # if add then
562
- # # add the thing
563
- # else
564
- # # remove the thing
565
- # end
566
- # end
567
-
568
- def merge_collections(mine, other, other_files, &block) # :nodoc:
569
- my_things = mine. group_by { |thing| thing.file }
570
- other_things = other.group_by { |thing| thing.file }
571
-
572
- remove_things my_things, other_files, &block
573
- add_things my_things, other_things, &block
574
- end
483
+ other_document = parse class_module.comment_location
575
484
 
576
- ##
577
- # Merges the comments in this ClassModule with the comments in the other
578
- # ClassModule +cm+.
485
+ if other_document
486
+ document = parse @comment_location
579
487
 
580
- def merge_sections(cm) # :nodoc:
581
- my_sections = sections.group_by { |section| section.title }
582
- other_sections = cm.sections.group_by { |section| section.title }
488
+ document = document.merge other_document
583
489
 
584
- other_files = cm.in_files
490
+ @comment = Comment.from_document(document)
585
491
 
586
- remove_things my_sections, other_files do |_, section|
587
- @sections.delete section.title
588
- end
492
+ @comment_location = if document.parts.first.is_a?(Markup::Document)
493
+ document.parts.group_by(&:file)
494
+ else
495
+ { document.file => [document] }
496
+ end
497
+ end
589
498
 
590
- other_sections.each do |group, sections|
591
- if my_sections.include? group
592
- my_sections[group].each do |my_section|
593
- other_section = cm.sections_hash[group]
499
+ cm = class_module
500
+ other_files = cm.in_files
594
501
 
595
- my_comments = my_section.comments
596
- other_comments = other_section.comments
502
+ merge_collections attributes, cm.attributes, other_files do |add, attr|
503
+ if add
504
+ add_attribute attr
505
+ else
506
+ @attributes.delete attr
507
+ @methods_hash.delete attr.pretty_name
508
+ end
509
+ end
597
510
 
598
- other_files = other_section.in_files
511
+ merge_collections constants, cm.constants, other_files do |add, const|
512
+ if add
513
+ add_constant const
514
+ else
515
+ @constants.delete const
516
+ @constants_hash.delete const.name
517
+ end
518
+ end
599
519
 
600
- merge_collections my_comments, other_comments, other_files do |add, comment|
601
- if add then
602
- my_section.add_comment comment
603
- else
604
- my_section.remove_comment comment
605
- end
606
- end
520
+ merge_collections includes, cm.includes, other_files do |add, incl|
521
+ if add
522
+ add_include incl
523
+ else
524
+ @includes.delete incl
607
525
  end
608
- else
609
- sections.each do |section|
610
- add_section group, section.comments
526
+ end
527
+
528
+ @includes.uniq! # clean up
529
+
530
+ merge_collections extends, cm.extends, other_files do |add, ext|
531
+ if add
532
+ add_extend ext
533
+ else
534
+ @extends.delete ext
611
535
  end
612
536
  end
613
- end
614
- end
615
537
 
616
- ##
617
- # Does this object represent a module?
538
+ @extends.uniq! # clean up
618
539
 
619
- def module?
620
- false
621
- end
540
+ merge_collections method_list, cm.method_list, other_files do |add, meth|
541
+ if add
542
+ add_method meth
543
+ else
544
+ @method_list.delete meth
545
+ @methods_hash.delete meth.pretty_name
546
+ end
547
+ end
622
548
 
623
- ##
624
- # Allows overriding the initial name.
625
- #
626
- # Used for modules and classes that are constant aliases.
549
+ merge_sections cm
627
550
 
628
- def name=(new_name)
629
- @name = new_name
630
- end
551
+ self
552
+ end
631
553
 
632
- ##
633
- # Parses +comment_location+ into an RDoc::Markup::Document composed of
634
- # multiple RDoc::Markup::Documents with their file set.
554
+ ##
555
+ # Merges collection +mine+ with +other+ preferring other. +other_files+ is
556
+ # used to help determine which items should be deleted.
557
+ #
558
+ # Yields whether the item should be added or removed (true or false) and the
559
+ # item to be added or removed.
560
+ #
561
+ # merge_collections things, other.things, other.in_files do |add, thing|
562
+ # if add
563
+ # # add the thing
564
+ # else
565
+ # # remove the thing
566
+ # end
567
+ # end
635
568
 
636
- def parse(comment_location)
637
- case comment_location
638
- when String then
639
- super
640
- when Hash then
641
- docs = comment_location.flat_map do |location, comments|
642
- comments.map do |comment|
643
- doc = super comment
644
- doc.file = location
645
- doc
646
- end
647
- end
569
+ def merge_collections(mine, other, other_files, &block) # :nodoc:
570
+ my_things = mine. group_by { |thing| thing.file }
571
+ other_things = other.group_by { |thing| thing.file }
648
572
 
649
- RDoc::Markup::Document.new(*docs)
650
- when RDoc::Comment then
651
- doc = super comment_location.text, comment_location.format
652
- doc.file = comment_location.location
653
- doc
654
- when RDoc::Markup::Document then
655
- return comment_location
656
- else
657
- raise ArgumentError, "unknown comment class #{comment_location.class}"
573
+ remove_things my_things, other_files, &block
574
+ add_things my_things, other_things, &block
658
575
  end
659
- end
660
576
 
661
- ##
662
- # Path to this class or module for use with HTML generator output.
577
+ ##
578
+ # Merges the comments in this ClassModule with the comments in the other
579
+ # ClassModule +cm+.
663
580
 
664
- def path
665
- prefix = options.class_module_path_prefix
666
- return http_url unless prefix
667
- File.join(prefix, http_url)
668
- end
581
+ def merge_sections(cm) # :nodoc:
582
+ my_sections = sections.group_by { |section| section.title }
583
+ other_sections = cm.sections.group_by { |section| section.title }
669
584
 
670
- ##
671
- # Name to use to generate the url:
672
- # modules and classes that are aliases for another
673
- # module or class return the name of the latter.
585
+ other_files = cm.in_files
674
586
 
675
- def name_for_path
676
- is_alias_for ? is_alias_for.name_for_path : full_name
677
- end
587
+ remove_things my_sections, other_files do |_, section|
588
+ @sections.delete section.title
589
+ end
678
590
 
679
- ##
680
- # Returns the classes and modules that are not constants
681
- # aliasing another class or module. For use by formatters
682
- # only (caches its result).
591
+ other_sections.each do |group, sections|
592
+ if my_sections.include? group
593
+ my_sections[group].each do |my_section|
594
+ other_section = cm.sections_hash[group]
683
595
 
684
- def non_aliases
685
- @non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for }
686
- end
596
+ my_comments = my_section.comments
597
+ other_comments = other_section.comments
687
598
 
688
- ##
689
- # Updates the child modules or classes of class/module +parent+ by
690
- # deleting the ones that have been removed from the documentation.
691
- #
692
- # +parent_hash+ is either <tt>parent.modules_hash</tt> or
693
- # <tt>parent.classes_hash</tt> and +all_hash+ is ::all_modules_hash or
694
- # ::all_classes_hash.
599
+ other_files = other_section.in_files
600
+
601
+ merge_collections my_comments, other_comments, other_files do |add, comment|
602
+ if add
603
+ my_section.add_comment comment
604
+ else
605
+ my_section.remove_comment comment
606
+ end
607
+ end
608
+ end
609
+ else
610
+ sections.each do |section|
611
+ add_section group, section.comments
612
+ end
613
+ end
614
+ end
615
+ end
695
616
 
696
- def remove_nodoc_children
697
- prefix = self.full_name + '::'
617
+ ##
618
+ # Does this object represent a module?
698
619
 
699
- modules_hash.each_key do |name|
700
- full_name = prefix + name
701
- modules_hash.delete name unless @store.modules_hash[full_name]
620
+ def module?
621
+ false
702
622
  end
703
623
 
704
- classes_hash.each_key do |name|
705
- full_name = prefix + name
706
- classes_hash.delete name unless @store.classes_hash[full_name]
624
+ ##
625
+ # Allows overriding the initial name.
626
+ #
627
+ # Used for modules and classes that are constant aliases.
628
+
629
+ def name=(new_name)
630
+ @name = new_name
707
631
  end
708
- end
709
632
 
710
- def remove_things(my_things, other_files) # :nodoc:
711
- my_things.delete_if do |file, things|
712
- next false unless other_files.include? file
633
+ ##
634
+ # Parses +comment_location+ into an RDoc::Markup::Document composed of
635
+ # multiple RDoc::Markup::Documents with their file set.
636
+
637
+ def parse(comment_location)
638
+ case comment_location
639
+ when String
640
+ super
641
+ when Hash
642
+ docs = comment_location.flat_map do |location, comments|
643
+ comments.map do |comment|
644
+ doc = super comment
645
+ doc.file = location
646
+ doc
647
+ end
648
+ end
713
649
 
714
- things.each do |thing|
715
- yield false, thing
650
+ Markup::Document.new(*docs)
651
+ when Comment
652
+ doc = super comment_location.text, comment_location.format
653
+ doc.file = comment_location.location
654
+ doc
655
+ when Markup::Document
656
+ return comment_location
657
+ else
658
+ raise ArgumentError, "unknown comment class #{comment_location.class}"
716
659
  end
660
+ end
717
661
 
718
- true
662
+ ##
663
+ # Path to this class or module for use with HTML generator output.
664
+
665
+ def path
666
+ prefix = options.class_module_path_prefix
667
+ return http_url unless prefix
668
+ File.join(prefix, http_url)
719
669
  end
720
- end
721
670
 
722
- ##
723
- # Search record used by RDoc::Generator::JsonIndex
724
- #
725
- # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator.
726
- # Use #search_snippet instead for getting documentation snippets.
727
-
728
- def search_record
729
- [
730
- name,
731
- full_name,
732
- full_name,
733
- '',
734
- path,
735
- '',
736
- snippet(@comment_location),
737
- ]
738
- end
671
+ ##
672
+ # Name to use to generate the url:
673
+ # modules and classes that are aliases for another
674
+ # module or class return the name of the latter.
739
675
 
740
- ##
741
- # Returns an HTML snippet of the first comment for search results.
676
+ def name_for_path
677
+ is_alias_for ? is_alias_for.name_for_path : full_name
678
+ end
742
679
 
743
- def search_snippet
744
- first_comment = @comment_location.each_value.first&.first
745
- return '' unless first_comment && !first_comment.empty?
680
+ ##
681
+ # Returns the classes and modules that are not constants
682
+ # aliasing another class or module. For use by formatters
683
+ # only (caches its result).
746
684
 
747
- snippet(first_comment)
748
- end
685
+ def non_aliases
686
+ @non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for }
687
+ end
749
688
 
750
- ##
751
- # Rebuilds +@comment+ from the current +@comment_location+ entries,
752
- # skipping any empty placeholders.
753
-
754
- def rebuild_comment_from_location
755
- texts = @comment_location.each_value.flat_map { |comments|
756
- comments.filter_map { |c| c.to_s unless c.empty? }
757
- }
758
- merged = texts.join("\n---\n")
759
- @comment = merged.empty? ? '' : RDoc::Comment.new(merged)
760
- end
689
+ ##
690
+ # Updates the child modules or classes of class/module +parent+ by
691
+ # deleting the ones that have been removed from the documentation.
692
+ #
693
+ # +parent_hash+ is either <tt>parent.modules_hash</tt> or
694
+ # <tt>parent.classes_hash</tt> and +all_hash+ is ::all_modules_hash or
695
+ # ::all_classes_hash.
761
696
 
762
- ##
763
- # Sets the store for this class or module and its contained code objects.
697
+ def remove_nodoc_children
698
+ prefix = self.full_name + '::'
764
699
 
765
- def store=(store)
766
- super
700
+ modules_hash.each_key do |name|
701
+ full_name = prefix + name
702
+ modules_hash.delete name unless @store.modules_hash[full_name]
703
+ end
767
704
 
768
- @attributes .each do |attr| attr.store = store end
769
- @constants .each do |const| const.store = store end
770
- @includes .each do |incl| incl.store = store end
771
- @extends .each do |ext| ext.store = store end
772
- @method_list.each do |meth| meth.store = store end
773
- end
705
+ classes_hash.each_key do |name|
706
+ full_name = prefix + name
707
+ classes_hash.delete name unless @store.classes_hash[full_name]
708
+ end
709
+ end
774
710
 
775
- ##
776
- # Get the superclass of this class. Attempts to retrieve the superclass
777
- # object, returns the name if it is not known.
711
+ def remove_things(my_things, other_files) # :nodoc:
712
+ my_things.delete_if do |file, things|
713
+ next false unless other_files.include? file
778
714
 
779
- def superclass
780
- @store.find_class_named(@superclass) || @superclass
781
- end
715
+ things.each do |thing|
716
+ yield false, thing
717
+ end
782
718
 
783
- ##
784
- # Set the superclass of this class to +superclass+
785
- #
786
- # where +superclass+ is one of:
787
- #
788
- # - +nil+
789
- # - a String containing the full name of the superclass
790
- # - the RDoc::ClassModule representing the superclass
791
-
792
- def superclass=(superclass)
793
- raise NoMethodError, "#{full_name} is a module" if module?
794
- case superclass
795
- when RDoc::ClassModule
796
- @superclass = superclass.full_name
797
- when nil, String
798
- @superclass = superclass
799
- else
800
- raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}"
719
+ true
720
+ end
801
721
  end
802
- end
803
722
 
804
- ##
805
- # Get all super classes of this class in an array. The last element might be
806
- # a string if the name is unknown.
723
+ ##
724
+ # Search record used by RDoc::Generator::JsonIndex
725
+ #
726
+ # TODO: Remove this method after dropping the darkfish theme and JsonIndex generator.
727
+ # Use #search_snippet instead for getting documentation snippets.
728
+
729
+ def search_record
730
+ [
731
+ name,
732
+ full_name,
733
+ full_name,
734
+ '',
735
+ path,
736
+ '',
737
+ snippet(@comment_location),
738
+ ]
739
+ end
807
740
 
808
- def super_classes
809
- result = []
810
- parent = self
811
- while parent = parent.superclass
812
- result << parent
813
- return result if parent.is_a?(String)
741
+ ##
742
+ # Returns an HTML snippet of the first comment for search results.
743
+
744
+ def search_snippet
745
+ first_comment = @comment_location.each_value.first&.first
746
+ return '' unless first_comment && !first_comment.empty?
747
+
748
+ snippet(first_comment)
814
749
  end
815
- result
816
- end
817
750
 
818
- def to_s # :nodoc:
819
- if is_alias_for then
820
- "#{self.class.name} #{self.full_name} -> #{is_alias_for}"
821
- else
822
- super
751
+ ##
752
+ # Rebuilds +@comment+ from the current +@comment_location+ entries,
753
+ # skipping any empty placeholders.
754
+
755
+ def rebuild_comment_from_location
756
+ texts = @comment_location.each_value.flat_map { |comments|
757
+ comments.filter_map { |c| c.to_s unless c.empty? }
758
+ }
759
+ merged = texts.join("\n---\n")
760
+ @comment = merged.empty? ? '' : Comment.new(merged)
823
761
  end
824
- end
825
762
 
826
- ##
827
- # 'module' or 'class'
763
+ ##
764
+ # Sets the store for this class or module and its contained code objects.
828
765
 
829
- def type
830
- module? ? 'module' : 'class'
831
- end
766
+ def store=(store)
767
+ super
832
768
 
833
- ##
834
- # Updates the child modules & classes by replacing the ones that are
835
- # aliases through a constant.
836
- #
837
- # The aliased module/class is replaced in the children and in
838
- # RDoc::Store#modules_hash or RDoc::Store#classes_hash
839
- # by a copy that has <tt>RDoc::ClassModule#is_alias_for</tt> set to
840
- # the aliased module/class, and this copy is added to <tt>#aliases</tt>
841
- # of the aliased module/class.
842
- #
843
- # Formatters can use the #non_aliases method to retrieve children that
844
- # are not aliases, for instance to list the namespace content, since
845
- # the aliased modules are included in the constants of the class/module,
846
- # that are listed separately.
847
-
848
- def update_aliases
849
- constants.each do |const|
850
- cm = const.is_alias_for
851
- cm ||= const.resolved_alias_target if const.is_a?(RDoc::Constant)
852
- next unless cm
853
-
854
- # Resolve chained aliases (A = B = C) to the real class/module.
855
- cm = @store.find_class_or_module(cm.full_name) || cm
856
- while (target = cm.is_alias_for)
857
- cm = target
858
- end
859
-
860
- cm_alias = cm.dup
861
- cm_alias.name = const.name
862
-
863
- if full_name == 'Object'
864
- # Don't move top-level aliases under Object, they look ugly there
865
- cm_alias.parent = top_level
769
+ @attributes .each do |attr| attr.store = store end
770
+ @constants .each do |const| const.store = store end
771
+ @includes .each do |incl| incl.store = store end
772
+ @extends .each do |ext| ext.store = store end
773
+ @method_list.each do |meth| meth.store = store end
774
+ end
775
+
776
+ ##
777
+ # Get the superclass of this class. Attempts to retrieve the superclass
778
+ # object, returns the name if it is not known.
779
+
780
+ def superclass
781
+ @store.find_class_named(@superclass) || @superclass
782
+ end
783
+
784
+ ##
785
+ # Set the superclass of this class to +superclass+
786
+ #
787
+ # where +superclass+ is one of:
788
+ #
789
+ # - +nil+
790
+ # - a String containing the full name of the superclass
791
+ # - the RDoc::ClassModule representing the superclass
792
+
793
+ def superclass=(superclass)
794
+ raise NoMethodError, "#{full_name} is a module" if module?
795
+ case superclass
796
+ when ClassModule
797
+ @superclass = superclass.full_name
798
+ when nil, String
799
+ @superclass = superclass
866
800
  else
867
- cm_alias.parent = self
801
+ raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}"
868
802
  end
869
- cm_alias.full_name = nil # force update for new parent
870
-
871
- # Don't clobber a real (non-alias) class/module already living at this
872
- # name. Mirrors the BasicObject = BlankSlate guard in
873
- # Context#add_module_alias. Existing alias copies (set by
874
- # add_module_alias or a previous update_aliases pass) carry is_alias_for,
875
- # so they're still overwritable here.
876
- existing = @store.find_class_or_module(cm_alias.full_name)
877
- next if existing && !existing.is_alias_for
803
+ end
878
804
 
879
- # Persist a lazy-resolved target so Stats#report_constants and
880
- # Constant#marshal_dump observe the alias relationship. Skipped
881
- # aliases (above) intentionally leave the constant unmarked.
882
- const.is_alias_for ||= cm
805
+ ##
806
+ # Get all super classes of this class in an array. The last element might be
807
+ # a string if the name is unknown.
883
808
 
884
- cm_alias.aliases.clear
885
- cm_alias.is_alias_for = cm
809
+ def super_classes
810
+ result = []
811
+ # Degenerate input can produce a cyclic superclass chain
812
+ visited = [full_name]
813
+ parent = self
814
+ while parent = parent.superclass
815
+ if parent.is_a?(String)
816
+ result << parent
817
+ break
818
+ end
819
+ break if visited.include?(parent.full_name)
820
+ visited << parent.full_name
821
+ result << parent
822
+ end
823
+ result
824
+ end
886
825
 
887
- if cm.module? then
888
- @store.modules_hash[cm_alias.full_name] = cm_alias
889
- modules_hash[const.name] = cm_alias
826
+ def to_s # :nodoc:
827
+ if is_alias_for
828
+ "#{self.class.name} #{self.full_name} -> #{is_alias_for}"
890
829
  else
891
- @store.classes_hash[cm_alias.full_name] = cm_alias
892
- classes_hash[const.name] = cm_alias
830
+ super
893
831
  end
894
-
895
- cm.aliases << cm_alias
896
832
  end
897
- end
898
833
 
899
- ##
900
- # Deletes from #includes those whose module has been removed from the
901
- # documentation.
902
- #--
903
- # FIXME: includes are not reliably removed, see _possible_bug test case
834
+ ##
835
+ # 'module' or 'class'
836
+
837
+ def type
838
+ module? ? 'module' : 'class'
839
+ end
840
+
841
+ ##
842
+ # Updates the child modules & classes by replacing the ones that are
843
+ # aliases through a constant.
844
+ #
845
+ # The aliased module/class is replaced in the children and in
846
+ # RDoc::Store#modules_hash or RDoc::Store#classes_hash
847
+ # by a copy that has <tt>RDoc::ClassModule#is_alias_for</tt> set to
848
+ # the aliased module/class, and this copy is added to <tt>#aliases</tt>
849
+ # of the aliased module/class.
850
+ #
851
+ # Formatters can use the #non_aliases method to retrieve children that
852
+ # are not aliases, for instance to list the namespace content, since
853
+ # the aliased modules are included in the constants of the class/module,
854
+ # that are listed separately.
855
+
856
+ def update_aliases
857
+ constants.each do |const|
858
+ cm = const.is_alias_for
859
+ cm ||= const.resolved_alias_target if const.is_a?(Constant)
860
+ next unless cm
861
+
862
+ # Resolve chained aliases (A = B = C) to the real class/module.
863
+ cm = @store.find_class_or_module(cm.full_name) || cm
864
+ while (target = cm.is_alias_for)
865
+ cm = target
866
+ end
904
867
 
905
- def update_includes
906
- includes.reject! do |include|
907
- mod = include.module
908
- !(String === mod) && @store.modules_hash[mod.full_name].nil?
909
- end
868
+ cm_alias = cm.dup
869
+ cm_alias.name = const.name
910
870
 
911
- includes.uniq!
912
- end
871
+ if full_name == 'Object'
872
+ # Don't move top-level aliases under Object, they look ugly there
873
+ cm_alias.parent = top_level
874
+ else
875
+ cm_alias.parent = self
876
+ end
877
+ cm_alias.full_name = nil # force update for new parent
878
+
879
+ # Don't clobber a real (non-alias) class/module already living at this
880
+ # name. Mirrors the BasicObject = BlankSlate guard in
881
+ # Context#add_module_alias. Existing alias copies (set by
882
+ # add_module_alias or a previous update_aliases pass) carry is_alias_for,
883
+ # so they're still overwritable here.
884
+ existing = @store.find_class_or_module(cm_alias.full_name)
885
+ next if existing && !existing.is_alias_for
886
+
887
+ # Persist a lazy-resolved target so Stats#report_constants and
888
+ # Constant#marshal_dump observe the alias relationship. Skipped
889
+ # aliases (above) intentionally leave the constant unmarked.
890
+ const.is_alias_for ||= cm
891
+
892
+ cm_alias.aliases.clear
893
+ cm_alias.is_alias_for = cm
894
+
895
+ if cm.module?
896
+ @store.modules_hash[cm_alias.full_name] = cm_alias
897
+ modules_hash[const.name] = cm_alias
898
+ else
899
+ @store.classes_hash[cm_alias.full_name] = cm_alias
900
+ classes_hash[const.name] = cm_alias
901
+ end
913
902
 
914
- ##
915
- # Deletes from #extends those whose module has been removed from the
916
- # documentation.
917
- #--
918
- # FIXME: like update_includes, extends are not reliably removed
903
+ cm.aliases << cm_alias
904
+ end
905
+ end
906
+
907
+ ##
908
+ # Deletes from #includes those whose module has been removed from the
909
+ # documentation.
910
+ #--
911
+ # FIXME: includes are not reliably removed, see _possible_bug test case
919
912
 
920
- def update_extends
921
- extends.reject! do |ext|
922
- mod = ext.module
913
+ def update_includes
914
+ includes.reject! do |include|
915
+ mod = include.module
916
+ !(String === mod) && @store.modules_hash[mod.full_name].nil?
917
+ end
923
918
 
924
- !(String === mod) && @store.modules_hash[mod.full_name].nil?
919
+ includes.uniq!
925
920
  end
926
921
 
927
- extends.uniq!
928
- end
922
+ ##
923
+ # Deletes from #extends those whose module has been removed from the
924
+ # documentation.
925
+ #--
926
+ # FIXME: like update_includes, extends are not reliably removed
929
927
 
930
- def embed_mixins
931
- return unless options.embed_mixins
928
+ def update_extends
929
+ extends.reject! do |ext|
930
+ mod = ext.module
932
931
 
933
- includes.each do |include|
934
- next if String === include.module
935
- include.module.method_list.each do |code_object|
936
- add_method(prepare_to_embed(code_object))
937
- end
938
- include.module.constants.each do |code_object|
939
- add_constant(prepare_to_embed(code_object))
940
- end
941
- include.module.attributes.each do |code_object|
942
- add_attribute(prepare_to_embed(code_object))
932
+ !(String === mod) && @store.modules_hash[mod.full_name].nil?
943
933
  end
934
+
935
+ extends.uniq!
944
936
  end
945
937
 
946
- extends.each do |ext|
947
- next if String === ext.module
948
- ext.module.method_list.each do |code_object|
949
- add_method(prepare_to_embed(code_object, true))
938
+ def embed_mixins
939
+ return unless options.embed_mixins
940
+
941
+ includes.each do |include|
942
+ next if String === include.module
943
+ include.module.method_list.each do |code_object|
944
+ add_method(prepare_to_embed(code_object))
945
+ end
946
+ include.module.constants.each do |code_object|
947
+ add_constant(prepare_to_embed(code_object))
948
+ end
949
+ include.module.attributes.each do |code_object|
950
+ add_attribute(prepare_to_embed(code_object))
951
+ end
950
952
  end
951
- ext.module.attributes.each do |code_object|
952
- add_attribute(prepare_to_embed(code_object, true))
953
+
954
+ extends.each do |ext|
955
+ next if String === ext.module
956
+ ext.module.method_list.each do |code_object|
957
+ add_method(prepare_to_embed(code_object, true))
958
+ end
959
+ ext.module.attributes.each do |code_object|
960
+ add_attribute(prepare_to_embed(code_object, true))
961
+ end
953
962
  end
954
963
  end
955
- end
956
964
 
957
965
  private
958
966
 
959
- def prepare_to_embed(code_object, singleton=false)
960
- code_object = code_object.dup
961
- code_object.mixin_from = code_object.parent
962
- code_object.singleton = true if singleton
963
- set_current_section(code_object.section.title, code_object.section.comment)
964
- # add_method and add_attribute will reassign self's visibility back to the method/attribute
965
- # so we need to sync self's visibility with the object's to properly retain that information
966
- self.visibility = code_object.visibility
967
- code_object
967
+ def prepare_to_embed(code_object, singleton=false)
968
+ code_object = code_object.dup
969
+ code_object.mixin_from = code_object.parent
970
+ code_object.singleton = true if singleton
971
+ set_current_section(code_object.section.title, code_object.section.comment)
972
+ code_object
973
+ end
968
974
  end
969
975
  end