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