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
data/lib/rdoc/parser/c.rb CHANGED
@@ -1,1227 +1,1229 @@
1
1
  # frozen_string_literal: true
2
2
  require 'tsort'
3
3
 
4
- ##
5
- # RDoc::Parser::C attempts to parse C extension files. It looks for
6
- # the standard patterns that you find in extensions: +rb_define_class+,
7
- # +rb_define_method+ and so on. It tries to find the corresponding
8
- # C source for the methods and extract comments, but if we fail
9
- # we don't worry too much.
10
- #
11
- # The comments associated with a Ruby method are extracted from the C
12
- # comment block associated with the routine that _implements_ that
13
- # method, that is to say the method whose name is given in the
14
- # +rb_define_method+ call. For example, you might write:
15
- #
16
- # /*
17
- # * Returns a new array that is a one-dimensional flattening of this
18
- # * array (recursively). That is, for every element that is an array,
19
- # * extract its elements into the new array.
20
- # *
21
- # * s = [ 1, 2, 3 ] #=> [1, 2, 3]
22
- # * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
23
- # * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
24
- # * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
25
- # */
26
- # static VALUE
27
- # rb_ary_flatten(VALUE ary)
28
- # {
29
- # ary = rb_obj_dup(ary);
30
- # rb_ary_flatten_bang(ary);
31
- # return ary;
32
- # }
33
- #
34
- # ...
35
- #
36
- # void
37
- # Init_Array(void)
38
- # {
39
- # ...
40
- # rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
41
- #
42
- # Here RDoc will determine from the +rb_define_method+ line that there's a
43
- # method called "flatten" in class Array, and will look for the implementation
44
- # in the method +rb_ary_flatten+. It will then use the comment from that
45
- # method in the HTML output. This method must be in the same source file
46
- # as the +rb_define_method+.
47
- #
48
- # The comment blocks may include special directives:
49
- #
50
- # [Document-class: +name+]
51
- # Documentation for the named class.
52
- #
53
- # [Document-module: +name+]
54
- # Documentation for the named module.
55
- #
56
- # [Document-const: +name+]
57
- # Documentation for the named +rb_define_const+.
58
- #
59
- # Constant values can be supplied on the first line of the comment like so:
60
- #
61
- # /* 300: The highest possible score in bowling */
62
- # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
63
- #
64
- # The value can contain internal colons so long as they are escaped with a \
65
- #
66
- # [Document-global: +name+]
67
- # Documentation for the named +rb_define_global_const+
68
- #
69
- # [Document-variable: +name+]
70
- # Documentation for the named +rb_define_variable+
71
- #
72
- # [Document-method\: +method_name+]
73
- # Documentation for the named method. Use this when the method name is
74
- # unambiguous.
75
- #
76
- # [Document-method\: <tt>ClassName::method_name</tt>]
77
- # Documentation for a singleton method in the given class. Use this when
78
- # the method name alone is ambiguous.
79
- #
80
- # [Document-method\: <tt>ClassName#method_name</tt>]
81
- # Documentation for a instance method in the given class. Use this when the
82
- # method name alone is ambiguous.
83
- #
84
- # [Document-attr: +name+]
85
- # Documentation for the named attribute.
86
- #
87
- # [call-seq: <i>text up to an empty line</i>]
88
- # Because C source doesn't give descriptive names to Ruby-level parameters,
89
- # you need to document the calling sequence explicitly
90
- #
91
- # In addition, RDoc assumes by default that the C method implementing a
92
- # Ruby function is in the same source file as the rb_define_method call.
93
- # If this isn't the case, add the comment:
94
- #
95
- # rb_define_method(....); // in filename
96
- #
97
- # As an example, we might have an extension that defines multiple classes
98
- # in its Init_xxx method. We could document them using
99
- #
100
- # /*
101
- # * Document-class: MyClass
102
- # *
103
- # * Encapsulate the writing and reading of the configuration
104
- # * file. ...
105
- # */
106
- #
107
- # /*
108
- # * Document-method: read_value
109
- # *
110
- # * call-seq:
111
- # * cfg.read_value(key) -> value
112
- # * cfg.read_value(key} { |key| } -> value
113
- # *
114
- # * Return the value corresponding to +key+ from the configuration.
115
- # * In the second form, if the key isn't found, invoke the
116
- # * block and return its value.
117
- # */
118
-
119
- class RDoc::Parser::C < RDoc::Parser
120
-
121
- parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)
122
-
123
- include RDoc::Text
124
-
125
- # :stopdoc:
126
- BOOL_ARG_PATTERN = /\s*+\b([01]|Q?(?:true|false)|TRUE|FALSE)\b\s*/
127
- TRUE_VALUES = ['1', 'TRUE', 'true', 'Qtrue'].freeze
128
- # :startdoc:
129
-
130
- ##
131
- # Maps C variable names to names of Ruby classes or modules
132
-
133
- attr_reader :classes
134
-
135
- ##
136
- # C file the parser is parsing
137
-
138
- attr_accessor :content
139
-
140
- ##
141
- # Dependencies from a missing enclosing class to the classes in
142
- # missing_dependencies that depend upon it.
143
-
144
- attr_reader :enclosure_dependencies
145
-
146
- ##
147
- # Maps C variable names to names of Ruby classes (and singleton classes)
148
-
149
- attr_reader :known_classes
150
-
151
- ##
152
- # Classes found while parsing the C file that were not yet registered due to
153
- # a missing enclosing class. These are processed by do_missing
154
-
155
- attr_reader :missing_dependencies
156
-
157
- ##
158
- # Maps C variable names to names of Ruby singleton classes
159
-
160
- attr_reader :singleton_classes
161
-
162
- ##
163
- # The TopLevel items in the parsed file belong to
164
-
165
- attr_reader :top_level
166
-
167
- ##
168
- # Prepares for parsing a C file. See RDoc::Parser#initialize for details on
169
- # the arguments.
170
-
171
- def initialize(top_level, content, options, stats)
172
- super
173
-
174
- @known_classes = RDoc::KNOWN_CLASSES.dup
175
- @content = handle_tab_width handle_ifdefs_in @content
176
- @file_dir = File.dirname @file_name
4
+ module RDoc
5
+ class Parser
6
+ ##
7
+ # RDoc::Parser::C attempts to parse C extension files. It looks for
8
+ # the standard patterns that you find in extensions: +rb_define_class+,
9
+ # +rb_define_method+ and so on. It tries to find the corresponding
10
+ # C source for the methods and extract comments, but if we fail
11
+ # we don't worry too much.
12
+ #
13
+ # The comments associated with a Ruby method are extracted from the C
14
+ # comment block associated with the routine that _implements_ that
15
+ # method, that is to say the method whose name is given in the
16
+ # +rb_define_method+ call. For example, you might write:
17
+ #
18
+ # /*
19
+ # * Returns a new array that is a one-dimensional flattening of this
20
+ # * array (recursively). That is, for every element that is an array,
21
+ # * extract its elements into the new array.
22
+ # *
23
+ # * s = [ 1, 2, 3 ] #=> [1, 2, 3]
24
+ # * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
25
+ # * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
26
+ # * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
27
+ # */
28
+ # static VALUE
29
+ # rb_ary_flatten(VALUE ary)
30
+ # {
31
+ # ary = rb_obj_dup(ary);
32
+ # rb_ary_flatten_bang(ary);
33
+ # return ary;
34
+ # }
35
+ #
36
+ # ...
37
+ #
38
+ # void
39
+ # Init_Array(void)
40
+ # {
41
+ # ...
42
+ # rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
43
+ #
44
+ # Here RDoc will determine from the +rb_define_method+ line that there's a
45
+ # method called "flatten" in class Array, and will look for the implementation
46
+ # in the method +rb_ary_flatten+. It will then use the comment from that
47
+ # method in the HTML output. This method must be in the same source file
48
+ # as the +rb_define_method+.
49
+ #
50
+ # The comment blocks may include special directives:
51
+ #
52
+ # [Document-class: +name+]
53
+ # Documentation for the named class.
54
+ #
55
+ # [Document-module: +name+]
56
+ # Documentation for the named module.
57
+ #
58
+ # [Document-const: +name+]
59
+ # Documentation for the named +rb_define_const+.
60
+ #
61
+ # Constant values can be supplied on the first line of the comment like so:
62
+ #
63
+ # /* 300: The highest possible score in bowling */
64
+ # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
65
+ #
66
+ # The value can contain internal colons so long as they are escaped with a \
67
+ #
68
+ # [Document-global: +name+]
69
+ # Documentation for the named +rb_define_global_const+
70
+ #
71
+ # [Document-variable: +name+]
72
+ # Documentation for the named +rb_define_variable+
73
+ #
74
+ # [Document-method\: +method_name+]
75
+ # Documentation for the named method. Use this when the method name is
76
+ # unambiguous.
77
+ #
78
+ # [Document-method\: <tt>ClassName::method_name</tt>]
79
+ # Documentation for a singleton method in the given class. Use this when
80
+ # the method name alone is ambiguous.
81
+ #
82
+ # [Document-method\: <tt>ClassName#method_name</tt>]
83
+ # Documentation for a instance method in the given class. Use this when the
84
+ # method name alone is ambiguous.
85
+ #
86
+ # [Document-attr: +name+]
87
+ # Documentation for the named attribute.
88
+ #
89
+ # [call-seq: <i>text up to an empty line</i>]
90
+ # Because C source doesn't give descriptive names to Ruby-level parameters,
91
+ # you need to document the calling sequence explicitly
92
+ #
93
+ # In addition, RDoc assumes by default that the C method implementing a
94
+ # Ruby function is in the same source file as the rb_define_method call.
95
+ # If this isn't the case, add the comment:
96
+ #
97
+ # rb_define_method(....); // in filename
98
+ #
99
+ # As an example, we might have an extension that defines multiple classes
100
+ # in its Init_xxx method. We could document them using
101
+ #
102
+ # /*
103
+ # * Document-class: MyClass
104
+ # *
105
+ # * Encapsulate the writing and reading of the configuration
106
+ # * file. ...
107
+ # */
108
+ #
109
+ # /*
110
+ # * Document-method: read_value
111
+ # *
112
+ # * call-seq:
113
+ # * cfg.read_value(key) -> value
114
+ # * cfg.read_value(key} { |key| } -> value
115
+ # *
116
+ # * Return the value corresponding to +key+ from the configuration.
117
+ # * In the second form, if the key isn't found, invoke the
118
+ # * block and return its value.
119
+ # */
120
+
121
+ class C < Parser
122
+
123
+ parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)
124
+
125
+ include ::RDoc::Text
126
+
127
+ # :stopdoc:
128
+ BOOL_ARG_PATTERN = /\s*+\b([01]|Q?(?:true|false)|TRUE|FALSE)\b\s*/
129
+ TRUE_VALUES = ['1', 'TRUE', 'true', 'Qtrue'].freeze
130
+ # :startdoc:
131
+
132
+ ##
133
+ # Maps C variable names to names of Ruby classes or modules
134
+
135
+ attr_reader :classes
136
+
137
+ ##
138
+ # C file the parser is parsing
139
+
140
+ attr_accessor :content
141
+
142
+ ##
143
+ # Dependencies from a missing enclosing class to the classes in
144
+ # missing_dependencies that depend upon it.
145
+
146
+ attr_reader :enclosure_dependencies
147
+
148
+ ##
149
+ # Maps C variable names to names of Ruby classes (and singleton classes)
150
+
151
+ attr_reader :known_classes
152
+
153
+ ##
154
+ # Classes found while parsing the C file that were not yet registered due to
155
+ # a missing enclosing class. These are processed by do_missing
156
+
157
+ attr_reader :missing_dependencies
158
+
159
+ ##
160
+ # Maps C variable names to names of Ruby singleton classes
161
+
162
+ attr_reader :singleton_classes
163
+
164
+ ##
165
+ # The TopLevel items in the parsed file belong to
166
+
167
+ attr_reader :top_level
168
+
169
+ ##
170
+ # Prepares for parsing a C file. See RDoc::Parser#initialize for details on
171
+ # the arguments.
172
+
173
+ def initialize(top_level, content, options, stats)
174
+ super
175
+
176
+ @known_classes = KNOWN_CLASSES.dup
177
+ @content = handle_tab_width handle_ifdefs_in @content
178
+ @file_dir = File.dirname @file_name
177
179
 
178
- @classes = load_variable_map :c_class_variables
179
- @singleton_classes = load_variable_map :c_singleton_class_variables
180
+ @classes = load_variable_map :c_class_variables
181
+ @singleton_classes = load_variable_map :c_singleton_class_variables
180
182
 
181
- @markup = @options.markup
183
+ @markup = @options.markup
182
184
 
183
- # class_variable => { function => [method, ...] }
184
- @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }
185
+ # class_variable => { function => [method, ...] }
186
+ @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }
185
187
 
186
- # missing variable => [handle_class_module arguments]
187
- @missing_dependencies = {}
188
+ # missing variable => [handle_class_module arguments]
189
+ @missing_dependencies = {}
188
190
 
189
- # missing enclosure variable => [dependent handle_class_module arguments]
190
- @enclosure_dependencies = Hash.new { |h, k| h[k] = [] }
191
- @enclosure_dependencies.instance_variable_set :@missing_dependencies,
192
- @missing_dependencies
191
+ # missing enclosure variable => [dependent handle_class_module arguments]
192
+ @enclosure_dependencies = Hash.new { |h, k| h[k] = [] }
193
+ @enclosure_dependencies.instance_variable_set :@missing_dependencies,
194
+ @missing_dependencies
193
195
 
194
- @enclosure_dependencies.extend TSort
196
+ @enclosure_dependencies.extend TSort
195
197
 
196
- def @enclosure_dependencies.tsort_each_node(&block)
197
- each_key(&block)
198
- rescue TSort::Cyclic => e
199
- cycle_vars = e.message.scan(/"(.*?)"/).flatten
198
+ def @enclosure_dependencies.tsort_each_node(&block)
199
+ each_key(&block)
200
+ rescue TSort::Cyclic => e
201
+ cycle_vars = e.message.scan(/"(.*?)"/).flatten
200
202
 
201
- cycle = cycle_vars.sort.map do |var_name|
202
- delete var_name
203
+ cycle = cycle_vars.sort.map do |var_name|
204
+ delete var_name
203
205
 
204
- var_name, type, mod_name, = @missing_dependencies[var_name]
206
+ var_name, type, mod_name, = @missing_dependencies[var_name]
205
207
 
206
- "#{type} #{mod_name} (#{var_name})"
207
- end.join ', '
208
+ "#{type} #{mod_name} (#{var_name})"
209
+ end.join ', '
208
210
 
209
- warn "Unable to create #{cycle} due to a cyclic class or module creation"
211
+ warn "Unable to create #{cycle} due to a cyclic class or module creation"
210
212
 
211
- retry
212
- end
213
-
214
- def @enclosure_dependencies.tsort_each_child(node, &block)
215
- fetch(node, []).each(&block)
216
- end
217
- end
213
+ retry
214
+ end
218
215
 
219
- ##
220
- # Scans #content for rb_define_alias
221
-
222
- def do_aliases
223
- @content.scan(/rb_define_alias\s*\(
224
- \s*(\w+),
225
- \s*"(.+?)",
226
- \s*"(.+?)"
227
- \s*\)/xm) do |var_name, new_name, old_name|
228
- class_name = @known_classes[var_name]
229
-
230
- unless class_name then
231
- @options.warn "Enclosing class or module %p for alias %s %s is not known" % [
232
- var_name, new_name, old_name]
233
- next
216
+ def @enclosure_dependencies.tsort_each_child(node, &block)
217
+ fetch(node, []).each(&block)
218
+ end
234
219
  end
235
220
 
236
- class_obj = find_class var_name, class_name
237
- comment = find_alias_comment var_name, new_name, old_name
238
- comment.normalize
239
- if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name}
240
- comment = existing_method.comment
221
+ ##
222
+ # Scans #content for rb_define_alias
223
+
224
+ def do_aliases
225
+ @content.scan(/rb_define_alias\s*\(
226
+ \s*(\w+),
227
+ \s*"(.+?)",
228
+ \s*"(.+?)"
229
+ \s*\)/xm) do |var_name, new_name, old_name|
230
+ class_name = @known_classes[var_name]
231
+
232
+ unless class_name
233
+ @options.warn "Enclosing class or module %p for alias %s %s is not known" % [
234
+ var_name, new_name, old_name]
235
+ next
236
+ end
237
+
238
+ class_obj = find_class var_name, class_name
239
+ comment = find_alias_comment var_name, new_name, old_name
240
+ comment.normalize
241
+ if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name}
242
+ comment = existing_method.comment
243
+ end
244
+ add_alias(var_name, class_obj, old_name, new_name, comment, singleton: @singleton_classes.key?(var_name))
245
+ end
241
246
  end
242
- add_alias(var_name, class_obj, old_name, new_name, comment)
243
- end
244
- end
245
247
 
246
- ##
247
- # Add alias, either from a direct alias definition, or from two
248
- # method that reference the same function.
248
+ ##
249
+ # Add alias, either from a direct alias definition, or from two
250
+ # method that reference the same function.
249
251
 
250
- def add_alias(var_name, class_obj, old_name, new_name, comment)
251
- al = RDoc::Alias.new old_name, new_name, comment, singleton: @singleton_classes.key?(var_name)
252
- al.record_location @top_level
253
- class_obj.add_alias al
254
- @stats.add_alias al
255
- al
256
- end
252
+ def add_alias(var_name, class_obj, old_name, new_name, comment, singleton:)
253
+ al = Alias.new old_name, new_name, comment, singleton: singleton
254
+ al.record_location @top_level
255
+ class_obj.add_alias al
256
+ @stats.add_alias al
257
+ al
258
+ end
257
259
 
258
- ##
259
- # Scans #content for rb_attr and rb_define_attr
260
-
261
- def do_attrs
262
- @content.scan(/rb_attr\s*\(
263
- \s*(\w+),
264
- \s*([\w"()]+),
265
- #{BOOL_ARG_PATTERN},
266
- #{BOOL_ARG_PATTERN},
267
- \s*\w+\);/xmo) do |var_name, attr_name, read, write|
268
- handle_attr var_name, attr_name, read, write
269
- end
260
+ ##
261
+ # Scans #content for rb_attr and rb_define_attr
262
+
263
+ def do_attrs
264
+ @content.scan(/rb_attr\s*\(
265
+ \s*(\w+),
266
+ \s*([\w"()]+),
267
+ #{BOOL_ARG_PATTERN},
268
+ #{BOOL_ARG_PATTERN},
269
+ \s*\w+\);/xmo) do |var_name, attr_name, read, write|
270
+ handle_attr var_name, attr_name, read, write
271
+ end
270
272
 
271
- @content.scan(%r%rb_define_attr\(
272
- \s*([\w\.]+),
273
- \s*"([^"]+)",
274
- #{BOOL_ARG_PATTERN},
275
- #{BOOL_ARG_PATTERN}\);
276
- %xmo) do |var_name, attr_name, read, write|
277
- handle_attr var_name, attr_name, read, write
278
- end
279
- end
273
+ @content.scan(%r%rb_define_attr\(
274
+ \s*([\w\.]+),
275
+ \s*"([^"]+)",
276
+ #{BOOL_ARG_PATTERN},
277
+ #{BOOL_ARG_PATTERN}\);
278
+ %xmo) do |var_name, attr_name, read, write|
279
+ handle_attr var_name, attr_name, read, write
280
+ end
281
+ end
280
282
 
281
- ##
282
- # Scans #content for boot_defclass
283
+ ##
284
+ # Scans #content for boot_defclass
283
285
 
284
- def do_boot_defclass
285
- @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
286
- |var_name, class_name, parent|
287
- parent = nil if parent == "0"
288
- handle_class_module(var_name, :class, class_name, parent, nil)
289
- end
290
- end
286
+ def do_boot_defclass
287
+ @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
288
+ |var_name, class_name, parent|
289
+ parent = nil if parent == "0"
290
+ handle_class_module(var_name, :class, class_name, parent, nil)
291
+ end
292
+ end
291
293
 
292
- ##
293
- # Scans #content for rb_define_class, boot_defclass, rb_define_class_under
294
- # and rb_singleton_class
295
-
296
- def do_classes_and_modules
297
- do_boot_defclass if @file_name == "class.c"
298
-
299
- @content.scan(
300
- %r(
301
- (?<open>\s*\(\s*) {0}
302
- (?<close>\s*\)\s*) {0}
303
- (?<name>\s*"(?<class_name>\w+)") {0}
304
- (?<parent>\s*(?:
305
- (?<parent_name>[\w\*\s\(\)\.\->]+) |
306
- rb_path2class\s*\(\s*"(?<path>[\w:]+)"\s*\)
307
- )) {0}
308
- (?<under>\w+) {0}
309
-
310
- (?<var_name>[\w\.]+)\s* =
311
- \s*rb_(?:
312
- define_(?:
313
- class(?: # rb_define_class(name, parent_name)
314
- \(\s*
294
+ ##
295
+ # Scans #content for rb_define_class, boot_defclass, rb_define_class_under
296
+ # and rb_singleton_class
297
+
298
+ def do_classes_and_modules
299
+ do_boot_defclass if @file_name == "class.c"
300
+
301
+ @content.scan(
302
+ %r(
303
+ (?<open>\s*\(\s*) {0}
304
+ (?<close>\s*\)\s*) {0}
305
+ (?<name>\s*"(?<class_name>\w+)") {0}
306
+ (?<parent>\s*(?:
307
+ (?<parent_name>[\w\*\s\(\)\.\->]+) |
308
+ rb_path2class\s*\(\s*"(?<path>[\w:]+)"\s*\)
309
+ )) {0}
310
+ (?<under>\w+) {0}
311
+
312
+ (?<var_name>[\w\.]+)\s* =
313
+ \s*rb_(?:
314
+ define_(?:
315
+ class(?: # rb_define_class(name, parent_name)
316
+ \(\s*
317
+ \g<name>,
318
+ \g<parent>
319
+ \s*\)
320
+ |
321
+ _under\g<open> # rb_define_class_under(under, name, parent_name...)
322
+ \g<under>,
323
+ \g<name>,
324
+ \g<parent>
325
+ \g<close>
326
+ )
327
+ |
328
+ (?<module>)
329
+ module(?: # rb_define_module(name)
330
+ \g<open>
331
+ \g<name>
332
+ \g<close>
333
+ |
334
+ _under\g<open> # rb_define_module_under(under, name)
335
+ \g<under>,
336
+ \g<name>
337
+ \g<close>
338
+ )
339
+ )
340
+ |
341
+ (?<attributes>(?:\s*"\w+",)*\s*NULL\s*) {0}
342
+ struct_define(?:
343
+ \g<open> # rb_struct_define(name, ...)
315
344
  \g<name>,
316
- \g<parent>
317
- \s*\)
318
345
  |
319
- _under\g<open> # rb_define_class_under(under, name, parent_name...)
346
+ _under\g<open> # rb_struct_define_under(under, name, ...)
320
347
  \g<under>,
321
348
  \g<name>,
322
- \g<parent>
323
- \g<close>
324
- )
325
- |
326
- (?<module>)
327
- module(?: # rb_define_module(name)
328
- \g<open>
329
- \g<name>
330
- \g<close>
331
349
  |
332
- _under\g<open> # rb_define_module_under(under, name)
333
- \g<under>,
334
- \g<name>
335
- \g<close>
350
+ _without_accessor(?:
351
+ \g<open> # rb_struct_define_without_accessor(name, parent_name, ...)
352
+ |
353
+ _under\g<open> # rb_struct_define_without_accessor_under(under, name, parent_name, ...)
354
+ \g<under>,
355
+ )
356
+ \g<name>,
357
+ \g<parent>,
358
+ \s*\w+, # Allocation function
336
359
  )
337
- )
338
- |
339
- (?<attributes>(?:\s*"\w+",)*\s*NULL\s*) {0}
340
- struct_define(?:
341
- \g<open> # rb_struct_define(name, ...)
342
- \g<name>,
343
- |
344
- _under\g<open> # rb_struct_define_under(under, name, ...)
345
- \g<under>,
346
- \g<name>,
347
- |
348
- _without_accessor(?:
349
- \g<open> # rb_struct_define_without_accessor(name, parent_name, ...)
360
+ \g<attributes>
361
+ \g<close>
350
362
  |
351
- _under\g<open> # rb_struct_define_without_accessor_under(under, name, parent_name, ...)
352
- \g<under>,
353
- )
354
- \g<name>,
355
- \g<parent>,
356
- \s*\w+, # Allocation function
357
- )
358
- \g<attributes>
359
- \g<close>
360
- |
361
- singleton_class\g<open> # rb_singleton_class(target_class_name)
362
- (?<target_class_name>\w+)
363
- \g<close>
364
- )
365
- )mx
366
- ) do
367
- if target_class_name = $~[:target_class_name]
368
- # rb_singleton_class(target_class_name)
369
- handle_singleton $~[:var_name], target_class_name
370
- next
363
+ singleton_class\g<open> # rb_singleton_class(target_class_name)
364
+ (?<target_class_name>\w+)
365
+ \g<close>
366
+ )
367
+ )mx
368
+ ) do
369
+ if target_class_name = $~[:target_class_name]
370
+ # rb_singleton_class(target_class_name)
371
+ handle_singleton $~[:var_name], target_class_name
372
+ next
373
+ end
374
+
375
+ var_name = $~[:var_name]
376
+ type = $~[:module] ? :module : :class
377
+ class_name = $~[:class_name]
378
+ parent_name = $~[:parent_name] || $~[:path]
379
+ under = $~[:under]
380
+ attributes = $~[:attributes]
381
+
382
+ handle_class_module(var_name, type, class_name, parent_name, under)
383
+ if attributes and !parent_name # rb_struct_define *not* without_accessor
384
+ true_flag = 'Qtrue'
385
+ attributes.scan(/"\K\w+(?=")/) do |attr_name|
386
+ handle_attr var_name, attr_name, true_flag, true_flag
387
+ end
388
+ end
389
+ end
371
390
  end
372
391
 
373
- var_name = $~[:var_name]
374
- type = $~[:module] ? :module : :class
375
- class_name = $~[:class_name]
376
- parent_name = $~[:parent_name] || $~[:path]
377
- under = $~[:under]
378
- attributes = $~[:attributes]
379
-
380
- handle_class_module(var_name, type, class_name, parent_name, under)
381
- if attributes and !parent_name # rb_struct_define *not* without_accessor
382
- true_flag = 'Qtrue'
383
- attributes.scan(/"\K\w+(?=")/) do |attr_name|
384
- handle_attr var_name, attr_name, true_flag, true_flag
392
+ ##
393
+ # Scans #content for rb_define_variable, rb_define_readonly_variable,
394
+ # rb_define_const and rb_define_global_const
395
+
396
+ def do_constants
397
+ @content.scan(%r%\Wrb_define_
398
+ ( variable |
399
+ readonly_variable |
400
+ const |
401
+ global_const )
402
+ \s*\(
403
+ (?:\s*(\w+),)?
404
+ \s*"(\w+)",
405
+ \s*(.*?)\s*\)\s*;
406
+ %xm) do |type, var_name, const_name, definition|
407
+ var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
408
+ type = "const" if type == "global_const"
409
+ handle_constants type, var_name, const_name, definition
385
410
  end
386
- end
387
- end
388
- end
389
411
 
390
- ##
391
- # Scans #content for rb_define_variable, rb_define_readonly_variable,
392
- # rb_define_const and rb_define_global_const
393
-
394
- def do_constants
395
- @content.scan(%r%\Wrb_define_
396
- ( variable |
397
- readonly_variable |
398
- const |
399
- global_const )
400
- \s*\(
401
- (?:\s*(\w+),)?
402
- \s*"(\w+)",
403
- \s*(.*?)\s*\)\s*;
404
- %xm) do |type, var_name, const_name, definition|
405
- var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
406
- type = "const" if type == "global_const"
407
- handle_constants type, var_name, const_name, definition
408
- end
412
+ @content.scan(%r%
413
+ \Wrb_curses_define_const
414
+ \s*\(
415
+ \s*
416
+ (\w+)
417
+ \s*
418
+ \)
419
+ \s*;%xm) do |consts|
420
+ const = consts.first
421
+
422
+ handle_constants 'const', 'mCurses', const, "UINT2NUM(#{const})"
423
+ end
409
424
 
410
- @content.scan(%r%
411
- \Wrb_curses_define_const
412
- \s*\(
413
- \s*
414
- (\w+)
415
- \s*
416
- \)
417
- \s*;%xm) do |consts|
418
- const = consts.first
419
-
420
- handle_constants 'const', 'mCurses', const, "UINT2NUM(#{const})"
421
- end
425
+ @content.scan(%r%
426
+ \Wrb_file_const
427
+ \s*\(
428
+ \s*
429
+ "([^"]+)",
430
+ \s*
431
+ (.*?)
432
+ \s*
433
+ \)
434
+ \s*;%xm) do |name, value|
435
+ handle_constants 'const', 'rb_mFConst', name, value
436
+ end
437
+ end
422
438
 
423
- @content.scan(%r%
424
- \Wrb_file_const
425
- \s*\(
426
- \s*
427
- "([^"]+)",
428
- \s*
429
- (.*?)
430
- \s*
431
- \)
432
- \s*;%xm) do |name, value|
433
- handle_constants 'const', 'rb_mFConst', name, value
434
- end
435
- end
436
439
 
440
+ ##
441
+ # Scans #content for rb_include_module
437
442
 
438
- ##
439
- # Scans #content for rb_include_module
443
+ def do_includes
444
+ @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c, m|
445
+ next unless cls = @classes[c]
446
+ m = @known_classes[m] || m
440
447
 
441
- def do_includes
442
- @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c, m|
443
- next unless cls = @classes[c]
444
- m = @known_classes[m] || m
448
+ comment = new_comment '', @top_level, :c
449
+ incl = cls.add_include Include.new(m, comment)
450
+ incl.record_location @top_level
451
+ end
452
+ end
445
453
 
446
- comment = new_comment '', @top_level, :c
447
- incl = cls.add_include RDoc::Include.new(m, comment)
448
- incl.record_location @top_level
449
- end
450
- end
454
+ ##
455
+ # Scans #content for rb_define_method, rb_define_singleton_method,
456
+ # rb_define_module_function, rb_define_private_method,
457
+ # rb_define_global_function and define_filetest_function
458
+
459
+ def do_methods
460
+ @content.scan(%r%rb_define_
461
+ (
462
+ singleton_method |
463
+ method |
464
+ module_function |
465
+ private_method
466
+ )
467
+ \s*\(\s*([\w\.]+),
468
+ \s*"([^"]+)",
469
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\(|\(METHOD\))?(\w+)\)?,
470
+ \s*(-?\w+)\s*\)
471
+ (?:;\s*/[*/]\s+in\s+(\w+?\.(?:cpp|c|y)))?
472
+ %xm) do |type, var_name, meth_name, function, param_count, source_file|
473
+
474
+ # Ignore top-object and weird struct.c dynamic stuff
475
+ next if var_name == "ruby_top_self"
476
+ next if var_name == "nstr"
477
+
478
+ var_name = "rb_cObject" if var_name == "rb_mKernel"
479
+ handle_method(type, var_name, meth_name, function, param_count,
480
+ source_file)
481
+ end
451
482
 
452
- ##
453
- # Scans #content for rb_define_method, rb_define_singleton_method,
454
- # rb_define_module_function, rb_define_private_method,
455
- # rb_define_global_function and define_filetest_function
456
-
457
- def do_methods
458
- @content.scan(%r%rb_define_
459
- (
460
- singleton_method |
461
- method |
462
- module_function |
463
- private_method
464
- )
465
- \s*\(\s*([\w\.]+),
466
- \s*"([^"]+)",
467
- \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\(|\(METHOD\))?(\w+)\)?,
468
- \s*(-?\w+)\s*\)
469
- (?:;\s*/[*/]\s+in\s+(\w+?\.(?:cpp|c|y)))?
470
- %xm) do |type, var_name, meth_name, function, param_count, source_file|
471
-
472
- # Ignore top-object and weird struct.c dynamic stuff
473
- next if var_name == "ruby_top_self"
474
- next if var_name == "nstr"
475
-
476
- var_name = "rb_cObject" if var_name == "rb_mKernel"
477
- handle_method(type, var_name, meth_name, function, param_count,
478
- source_file)
479
- end
483
+ @content.scan(%r%rb_define_global_function\s*\(
484
+ \s*"([^"]+)",
485
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
486
+ \s*(-?\w+)\s*\)
487
+ (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
488
+ %xm) do |meth_name, function, param_count, source_file|
489
+ handle_method("method", "rb_mKernel", meth_name, function, param_count,
490
+ source_file)
491
+ end
480
492
 
481
- @content.scan(%r%rb_define_global_function\s*\(
482
- \s*"([^"]+)",
483
- \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
484
- \s*(-?\w+)\s*\)
485
- (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
486
- %xm) do |meth_name, function, param_count, source_file|
487
- handle_method("method", "rb_mKernel", meth_name, function, param_count,
488
- source_file)
489
- end
493
+ @content.scan(/define_filetest_function\s*\(
494
+ \s*"([^"]+)",
495
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
496
+ \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count|
490
497
 
491
- @content.scan(/define_filetest_function\s*\(
492
- \s*"([^"]+)",
493
- \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
494
- \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count|
498
+ handle_method("method", "rb_mFileTest", meth_name, function, param_count)
499
+ handle_method("singleton_method", "rb_cFile", meth_name, function,
500
+ param_count)
501
+ end
502
+ end
495
503
 
496
- handle_method("method", "rb_mFileTest", meth_name, function, param_count)
497
- handle_method("singleton_method", "rb_cFile", meth_name, function,
498
- param_count)
499
- end
500
- end
504
+ ##
505
+ # Creates classes and module that were missing were defined due to the file
506
+ # order being different than the declaration order.
501
507
 
502
- ##
503
- # Creates classes and module that were missing were defined due to the file
504
- # order being different than the declaration order.
508
+ def do_missing
509
+ return if @missing_dependencies.empty?
505
510
 
506
- def do_missing
507
- return if @missing_dependencies.empty?
511
+ @enclosure_dependencies.tsort.each do |in_module|
512
+ arguments = @missing_dependencies.delete in_module
508
513
 
509
- @enclosure_dependencies.tsort.each do |in_module|
510
- arguments = @missing_dependencies.delete in_module
514
+ next unless arguments # dependency on existing class
511
515
 
512
- next unless arguments # dependency on existing class
516
+ handle_class_module(*arguments)
517
+ end
518
+ end
513
519
 
514
- handle_class_module(*arguments)
515
- end
516
- end
520
+ ##
521
+ # Finds the comment for an alias on +class_name+ from +new_name+ to
522
+ # +old_name+
517
523
 
518
- ##
519
- # Finds the comment for an alias on +class_name+ from +new_name+ to
520
- # +old_name+
524
+ def find_alias_comment(class_name, new_name, old_name)
525
+ content =~ %r%((?>/\*.*?\*/\s+))
526
+ rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
527
+ \s*"#{Regexp.escape new_name}"\s*,
528
+ \s*"#{Regexp.escape old_name}"\s*\);%xm
521
529
 
522
- def find_alias_comment(class_name, new_name, old_name)
523
- content =~ %r%((?>/\*.*?\*/\s+))
524
- rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
525
- \s*"#{Regexp.escape new_name}"\s*,
526
- \s*"#{Regexp.escape old_name}"\s*\);%xm
530
+ new_comment($1 || '', @top_level, :c)
531
+ end
527
532
 
528
- new_comment($1 || '', @top_level, :c)
529
- end
533
+ ##
534
+ # Finds a comment for rb_define_attr, rb_attr or Document-attr.
535
+ #
536
+ # +var_name+ is the C class variable the attribute is defined on.
537
+ # +attr_name+ is the attribute's name.
538
+ #
539
+ # +read+ and +write+ are the read/write flags ('1' or '0'). Either both or
540
+ # neither must be provided.
541
+
542
+ def find_attr_comment(var_name, attr_name, read = nil, write = nil)
543
+ attr_name = Regexp.escape attr_name
544
+
545
+ rw = if read and write
546
+ /\s*#{read}\s*,\s*#{write}\s*/xm
547
+ else
548
+ /.*?/m
549
+ end
550
+
551
+ comment = if @content =~ %r%((?>/\*.*?\*/\s+))
552
+ rb_define_attr\((?:\s*#{var_name},)?\s*
553
+ "#{attr_name}"\s*,
554
+ #{rw}\)\s*;%xm
555
+ $1
556
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
557
+ rb_attr\(\s*#{var_name}\s*,
558
+ \s*#{attr_name}\s*,
559
+ #{rw},.*?\)\s*;%xm
560
+ $1
561
+ elsif @content =~ %r%(/\*.*?(?:\s*\*\s*)?)
562
+ Document-attr:\s#{attr_name}\s*?\n
563
+ ((?>(.|\n)*?\*/))%x
564
+ "#{$1}\n#{$2}"
565
+ else
566
+ ''
567
+ end
530
568
 
531
- ##
532
- # Finds a comment for rb_define_attr, rb_attr or Document-attr.
533
- #
534
- # +var_name+ is the C class variable the attribute is defined on.
535
- # +attr_name+ is the attribute's name.
536
- #
537
- # +read+ and +write+ are the read/write flags ('1' or '0'). Either both or
538
- # neither must be provided.
539
-
540
- def find_attr_comment(var_name, attr_name, read = nil, write = nil)
541
- attr_name = Regexp.escape attr_name
542
-
543
- rw = if read and write then
544
- /\s*#{read}\s*,\s*#{write}\s*/xm
545
- else
546
- /.*?/m
547
- end
548
-
549
- comment = if @content =~ %r%((?>/\*.*?\*/\s+))
550
- rb_define_attr\((?:\s*#{var_name},)?\s*
551
- "#{attr_name}"\s*,
552
- #{rw}\)\s*;%xm then
553
- $1
554
- elsif @content =~ %r%((?>/\*.*?\*/\s+))
555
- rb_attr\(\s*#{var_name}\s*,
556
- \s*#{attr_name}\s*,
557
- #{rw},.*?\)\s*;%xm then
558
- $1
559
- elsif @content =~ %r%(/\*.*?(?:\s*\*\s*)?)
560
- Document-attr:\s#{attr_name}\s*?\n
561
- ((?>(.|\n)*?\*/))%x then
562
- "#{$1}\n#{$2}"
563
- else
564
- ''
565
- end
566
-
567
- new_comment comment, @top_level, :c
568
- end
569
+ new_comment comment, @top_level, :c
570
+ end
569
571
 
570
- ##
571
- # Generate a Ruby-method table
572
-
573
- def gen_body_table(file_content)
574
- table = {}
575
- file_content.scan(%r{
576
- ((?>/\*.*?\*/\s*)?)
577
- ((?:\w+\s+){0,2} VALUE\s+(\w+)
578
- \s*(?:\([^\)]*\))(?:[^\);]|$))
579
- | ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+))
580
- | ^\s*\#\s*define\s+(\w+)\s+(\w+)
581
- }xm) do
582
- case
583
- when name = $3
584
- table[name] = [:func_def, $1, $2, $~.offset(2)] if !(t = table[name]) || t[0] != :func_def
585
- when name = $6
586
- table[name] = [:macro_def, $4, $5, $~.offset(5), $7] if !(t = table[name]) || t[0] == :macro_alias
587
- when name = $8
588
- table[name] ||= [:macro_alias, $9]
572
+ ##
573
+ # Generate a Ruby-method table
574
+
575
+ def gen_body_table(file_content)
576
+ table = {}
577
+ file_content.scan(%r{
578
+ ((?>/\*.*?\*/\s*)?)
579
+ ((?:\w+\s+){0,2} VALUE\s+(\w+)
580
+ \s*(?:\([^\)]*\))(?:[^\);]|$))
581
+ | ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+))
582
+ | ^\s*\#\s*define\s+(\w+)\s+(\w+)
583
+ }xm) do
584
+ case
585
+ when name = $3
586
+ table[name] = [:func_def, $1, $2, $~.offset(2)] if !(t = table[name]) || t[0] != :func_def
587
+ when name = $6
588
+ table[name] = [:macro_def, $4, $5, $~.offset(5), $7] if !(t = table[name]) || t[0] == :macro_alias
589
+ when name = $8
590
+ table[name] ||= [:macro_alias, $9]
591
+ end
592
+ end
593
+ table
589
594
  end
590
- end
591
- table
592
- end
593
595
 
594
- ##
595
- # Find the C code corresponding to a Ruby method
596
+ ##
597
+ # Find the C code corresponding to a Ruby method
596
598
 
597
- def find_body(class_name, meth_name, meth_obj, file_content, quiet = false)
598
- if file_content
599
- @body_table ||= {}
600
- @body_table[file_content] ||= gen_body_table file_content
601
- type, *args = @body_table[file_content][meth_name]
602
- end
599
+ def find_body(class_name, meth_name, meth_obj, file_content, quiet = false)
600
+ if file_content
601
+ @body_table ||= {}
602
+ @body_table[file_content] ||= gen_body_table file_content
603
+ type, *args = @body_table[file_content][meth_name]
604
+ end
603
605
 
604
- case type
605
- when :func_def
606
- comment = new_comment args[0], @top_level, :c
607
- body = args[1]
608
- offset, = args[2]
606
+ case type
607
+ when :func_def
608
+ comment = new_comment args[0], @top_level, :c
609
+ body = args[1]
610
+ offset, = args[2]
609
611
 
610
- # try to find the whole body
611
- body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
612
+ # try to find the whole body
613
+ body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
612
614
 
613
- # The comment block may have been overridden with a 'Document-method'
614
- # block. This happens in the interpreter when multiple methods are
615
- # vectored through to the same C method but those methods are logically
616
- # distinct (for example Kernel.hash and Kernel.object_id share the same
617
- # implementation
615
+ # The comment block may have been overridden with a 'Document-method'
616
+ # block. This happens in the interpreter when multiple methods are
617
+ # vectored through to the same C method but those methods are logically
618
+ # distinct (for example Kernel.hash and Kernel.object_id share the same
619
+ # implementation
618
620
 
619
- override_comment = find_override_comment class_name, meth_obj
620
- comment = override_comment if override_comment
621
+ override_comment = find_override_comment class_name, meth_obj
622
+ comment = override_comment if override_comment
621
623
 
622
- find_modifiers comment, meth_obj if comment
624
+ find_modifiers comment, meth_obj if comment
623
625
 
624
- #meth_obj.params = params
625
- meth_obj.start_collecting_tokens(:c)
626
- tk = { :line_no => 1, :char_no => 1, :text => body }
627
- meth_obj.add_token tk
628
- meth_obj.comment = comment
629
- meth_obj.line = file_content[0, offset].count("\n") + 1
626
+ #meth_obj.params = params
627
+ meth_obj.start_collecting_tokens(:c)
628
+ tk = { :line_no => 1, :char_no => 1, :text => body }
629
+ meth_obj.add_token tk
630
+ meth_obj.comment = comment
631
+ meth_obj.line = file_content[0, offset].count("\n") + 1
630
632
 
631
- body
632
- when :macro_def
633
- comment = new_comment args[0], @top_level, :c
634
- body = args[1]
635
- offset, = args[2]
633
+ body
634
+ when :macro_def
635
+ comment = new_comment args[0], @top_level, :c
636
+ body = args[1]
637
+ offset, = args[2]
636
638
 
637
- find_body class_name, args[3], meth_obj, file_content, true
639
+ find_body class_name, args[3], meth_obj, file_content, true
638
640
 
639
- find_modifiers comment, meth_obj
641
+ find_modifiers comment, meth_obj
640
642
 
641
- meth_obj.start_collecting_tokens(:c)
642
- tk = { :line_no => 1, :char_no => 1, :text => body }
643
- meth_obj.add_token tk
644
- meth_obj.comment = comment
645
- meth_obj.line = file_content[0, offset].count("\n") + 1
643
+ meth_obj.start_collecting_tokens(:c)
644
+ tk = { :line_no => 1, :char_no => 1, :text => body }
645
+ meth_obj.add_token tk
646
+ meth_obj.comment = comment
647
+ meth_obj.line = file_content[0, offset].count("\n") + 1
646
648
 
647
- body
648
- when :macro_alias
649
- # with no comment we hope the aliased definition has it and use it's
650
- # definition
649
+ body
650
+ when :macro_alias
651
+ # with no comment we hope the aliased definition has it and use it's
652
+ # definition
651
653
 
652
- body = find_body(class_name, args[0], meth_obj, file_content, true)
654
+ body = find_body(class_name, args[0], meth_obj, file_content, true)
653
655
 
654
- return body if body
656
+ return body if body
655
657
 
656
- @options.warn "No definition for #{meth_name}"
657
- false
658
- else # No body, but might still have an override comment
659
- comment = find_override_comment class_name, meth_obj
658
+ @options.warn "No definition for #{meth_name}"
659
+ false
660
+ else # No body, but might still have an override comment
661
+ comment = find_override_comment class_name, meth_obj
660
662
 
661
- if comment then
662
- find_modifiers comment, meth_obj
663
- meth_obj.comment = comment
663
+ if comment
664
+ find_modifiers comment, meth_obj
665
+ meth_obj.comment = comment
664
666
 
665
- ''
666
- else
667
- @options.warn "No definition for #{meth_name}"
668
- false
667
+ ''
668
+ else
669
+ @options.warn "No definition for #{meth_name}"
670
+ false
671
+ end
672
+ end
669
673
  end
670
- end
671
- end
672
674
 
673
- ##
674
- # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+
675
-
676
- def find_class(raw_name, name, base_name = nil)
677
- unless @classes[raw_name]
678
- if raw_name =~ /^rb_m/
679
- container = @top_level.add_module RDoc::NormalModule, name
680
- else
681
- container = @top_level.add_class RDoc::NormalClass, name
675
+ ##
676
+ # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+
677
+
678
+ def find_class(raw_name, name, base_name = nil)
679
+ unless @classes[raw_name]
680
+ if raw_name =~ /^rb_m/
681
+ container = @top_level.add_module NormalModule, name
682
+ else
683
+ container = @top_level.add_class NormalClass, name
684
+ end
685
+ container.name = base_name if base_name
686
+
687
+ container.record_location @top_level
688
+ @top_level.add_to_classes_or_modules container
689
+ @classes[raw_name] = container
690
+ end
691
+ @classes[raw_name]
682
692
  end
683
- container.name = base_name if base_name
684
693
 
685
- container.record_location @top_level
686
- @top_level.add_to_classes_or_modules container
687
- @classes[raw_name] = container
688
- end
689
- @classes[raw_name]
690
- end
691
-
692
- ##
693
- # Look for class or module documentation above Init_+class_name+(void),
694
- # in a Document-class +class_name+ (or module) comment or above an
695
- # rb_define_class (or module). If a comment is supplied above a matching
696
- # Init_ and a rb_define_class the Init_ comment is used.
697
- #
698
- # /*
699
- # * This is a comment for Foo
700
- # */
701
- # Init_Foo(void) {
702
- # VALUE cFoo = rb_define_class("Foo", rb_cObject);
703
- # }
704
- #
705
- # /*
706
- # * Document-class: Foo
707
- # * This is a comment for Foo
708
- # */
709
- # Init_foo(void) {
710
- # VALUE cFoo = rb_define_class("Foo", rb_cObject);
711
- # }
712
- #
713
- # /*
714
- # * This is a comment for Foo
715
- # */
716
- # VALUE cFoo = rb_define_class("Foo", rb_cObject);
717
-
718
- def find_class_comment(class_name, class_mod)
719
- comment = nil
720
-
721
- if @content =~ %r%
722
- ((?>/\*.*?\*/\s+))
723
- (static\s+)?
724
- void\s+
725
- Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm then
726
- comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
727
- elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
728
- (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
729
- comment = "/*\n#{$1}"
730
- elsif @content =~ %r%((?>/\*.*?\*/\s+))
731
- ([\w\.\s]+\s* = \s+)?rb_define_(class|module)[\t (]*?"(#{class_name})"%xm then
732
- comment = $1
733
- elsif @content =~ %r%((?>/\*.*?\*/\s+))
734
- ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
735
- comment = $1
736
- else
737
- comment = ''
738
- end
739
-
740
- comment = new_comment comment, @top_level, :c
694
+ ##
695
+ # Look for class or module documentation above Init_+class_name+(void),
696
+ # in a Document-class +class_name+ (or module) comment or above an
697
+ # rb_define_class (or module). If a comment is supplied above a matching
698
+ # Init_ and a rb_define_class the Init_ comment is used.
699
+ #
700
+ # /*
701
+ # * This is a comment for Foo
702
+ # */
703
+ # Init_Foo(void) {
704
+ # VALUE cFoo = rb_define_class("Foo", rb_cObject);
705
+ # }
706
+ #
707
+ # /*
708
+ # * Document-class: Foo
709
+ # * This is a comment for Foo
710
+ # */
711
+ # Init_foo(void) {
712
+ # VALUE cFoo = rb_define_class("Foo", rb_cObject);
713
+ # }
714
+ #
715
+ # /*
716
+ # * This is a comment for Foo
717
+ # */
718
+ # VALUE cFoo = rb_define_class("Foo", rb_cObject);
719
+
720
+ def find_class_comment(class_name, class_mod)
721
+ comment = nil
722
+
723
+ if @content =~ %r%
724
+ ((?>/\*.*?\*/\s+))
725
+ (static\s+)?
726
+ void\s+
727
+ Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm
728
+ comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
729
+ elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
730
+ (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm
731
+ comment = "/*\n#{$1}"
732
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
733
+ ([\w\.\s]+\s* = \s+)?rb_define_(class|module)[\t (]*?"(#{class_name})"%xm
734
+ comment = $1
735
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
736
+ ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm
737
+ comment = $1
738
+ else
739
+ comment = ''
740
+ end
741
741
 
742
- look_for_directives_in class_mod, comment
742
+ comment = new_comment comment, @top_level, :c
743
743
 
744
- class_mod.add_comment comment, @top_level
745
- end
744
+ look_for_directives_in class_mod, comment
746
745
 
747
- ##
748
- # Generate a const table
749
-
750
- def gen_const_table(file_content)
751
- table = {}
752
- @content.scan(%r{
753
- (?<doc>(?>^\s*/\*.*?\*/\s+))
754
- rb_define_(?<type>\w+)\(\s*(?:\w+),\s*
755
- "(?<name>\w+)"\s*,
756
- .*?\)\s*;
757
- | (?<doc>(?>^\s*/\*.*?\*/\s+))
758
- rb_define_global_(?<type>const)\(\s*
759
- "(?<name>\w+)"\s*,
760
- .*?\)\s*;
761
- | (?<doc>(?>^\s*/\*.*?\*/\s+))
762
- rb_file_(?<type>const)\(\s*
763
- "(?<name>\w+)"\s*,
764
- .*?\)\s*;
765
- | (?<doc>(?>^\s*/\*.*?\*/\s+))
766
- rb_curses_define_(?<type>const)\(\s*
767
- (?<name>\w+)
768
- \s*\)\s*;
769
- | Document-(?:const|global|variable):\s
770
- (?<name>(?:\w+::)*\w+)
771
- \s*?\n(?<doc>(?>.*?\*/))
772
- }mxi) do
773
- name, doc, type = $~.values_at(:name, :doc, :type)
774
- if type
775
- table[[type, name]] = doc
776
- else
777
- table[name] = "/*\n" + doc
746
+ class_mod.add_comment comment, @top_level
778
747
  end
779
- end
780
- table
781
- end
782
-
783
- ##
784
- # Finds a comment matching +type+ and +const_name+ either above the
785
- # comment or in the matching Document- section.
786
-
787
- def find_const_comment(type, const_name, class_name = nil)
788
- @const_table ||= {}
789
- @const_table[@content] ||= gen_const_table @content
790
- table = @const_table[@content]
791
-
792
- comment =
793
- table[[type, const_name]] ||
794
- (class_name && table[class_name + "::" + const_name]) ||
795
- table[const_name] ||
796
- ''
797
-
798
- new_comment comment, @top_level, :c
799
- end
800
-
801
- ##
802
- # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
803
748
 
804
- def find_modifiers(comment, meth_obj)
805
- look_for_directives_in meth_obj, comment
806
- end
807
-
808
- ##
809
- # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
810
-
811
- def find_override_comment(class_name, meth_obj)
812
- name = Regexp.escape meth_obj.name
813
- prefix = Regexp.escape meth_obj.name_prefix
749
+ ##
750
+ # Generate a const table
751
+
752
+ def gen_const_table(file_content)
753
+ table = {}
754
+ @content.scan(%r{
755
+ (?<doc>(?>^\s*/\*.*?\*/\s+))
756
+ rb_define_(?<type>\w+)\(\s*(?:\w+),\s*
757
+ "(?<name>\w+)"\s*,
758
+ .*?\)\s*;
759
+ | (?<doc>(?>^\s*/\*.*?\*/\s+))
760
+ rb_define_global_(?<type>const)\(\s*
761
+ "(?<name>\w+)"\s*,
762
+ .*?\)\s*;
763
+ | (?<doc>(?>^\s*/\*.*?\*/\s+))
764
+ rb_file_(?<type>const)\(\s*
765
+ "(?<name>\w+)"\s*,
766
+ .*?\)\s*;
767
+ | (?<doc>(?>^\s*/\*.*?\*/\s+))
768
+ rb_curses_define_(?<type>const)\(\s*
769
+ (?<name>\w+)
770
+ \s*\)\s*;
771
+ | Document-(?:const|global|variable):\s
772
+ (?<name>(?:\w+::)*\w+)
773
+ \s*?\n(?<doc>(?>.*?\*/))
774
+ }mxi) do
775
+ name, doc, type = $~.values_at(:name, :doc, :type)
776
+ if type
777
+ table[[type, name]] = doc
778
+ else
779
+ table[name] = "/*\n" + doc
780
+ end
781
+ end
782
+ table
783
+ end
814
784
 
815
- comment = if @content =~ %r%Document-method:
816
- \s+#{class_name}#{prefix}#{name}
817
- \s*?\n((?>.*?\*/))%xm then
818
- "/*\n#{$1}"
819
- elsif @content =~ %r%Document-method:
820
- \s#{name}\s*?\n((?>.*?\*/))%xm then
821
- "/*\n#{$1}"
822
- end
785
+ ##
786
+ # Finds a comment matching +type+ and +const_name+ either above the
787
+ # comment or in the matching Document- section.
823
788
 
824
- return unless comment
789
+ def find_const_comment(type, const_name, class_name = nil)
790
+ @const_table ||= {}
791
+ @const_table[@content] ||= gen_const_table @content
792
+ table = @const_table[@content]
825
793
 
826
- new_comment comment, @top_level, :c
827
- end
794
+ comment =
795
+ table[[type, const_name]] ||
796
+ (class_name && table[class_name + "::" + const_name]) ||
797
+ table[const_name] ||
798
+ ''
828
799
 
829
- ##
830
- # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
831
- # +read+, +write+ or both
800
+ new_comment comment, @top_level, :c
801
+ end
832
802
 
833
- def handle_attr(var_name, attr_name, read, write)
834
- rw = ''
835
- rw += 'R' if TRUE_VALUES.include?(read)
836
- rw += 'W' if TRUE_VALUES.include?(write)
803
+ ##
804
+ # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
837
805
 
838
- class_name = @known_classes[var_name]
806
+ def find_modifiers(comment, meth_obj)
807
+ look_for_directives_in meth_obj, comment
808
+ end
839
809
 
840
- return unless class_name
810
+ ##
811
+ # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
841
812
 
842
- class_obj = find_class var_name, class_name
813
+ def find_override_comment(class_name, meth_obj)
814
+ name = Regexp.escape meth_obj.name
815
+ prefix = Regexp.escape meth_obj.name_prefix
843
816
 
844
- return unless class_obj
817
+ comment = if @content =~ %r%Document-method:
818
+ \s+#{class_name}#{prefix}#{name}
819
+ \s*?\n((?>.*?\*/))%xm
820
+ "/*\n#{$1}"
821
+ elsif @content =~ %r%Document-method:
822
+ \s#{name}\s*?\n((?>.*?\*/))%xm
823
+ "/*\n#{$1}"
824
+ end
845
825
 
846
- comment = find_attr_comment var_name, attr_name
847
- comment.normalize
826
+ return unless comment
848
827
 
849
- name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
828
+ new_comment comment, @top_level, :c
829
+ end
850
830
 
851
- attr = RDoc::Attr.new name, rw, comment
831
+ ##
832
+ # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
833
+ # +read+, +write+ or both
852
834
 
853
- attr.record_location @top_level
854
- class_obj.add_attribute attr
855
- @stats.add_attribute attr
856
- end
835
+ def handle_attr(var_name, attr_name, read, write)
836
+ rw = ''
837
+ rw += 'R' if TRUE_VALUES.include?(read)
838
+ rw += 'W' if TRUE_VALUES.include?(write)
857
839
 
858
- ##
859
- # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
860
- # named +class_name+ in +parent+ which was assigned to the C +var_name+.
840
+ class_name = @known_classes[var_name]
861
841
 
862
- def handle_class_module(var_name, type, class_name, parent, in_module)
863
- parent_name = @known_classes[parent] || parent
842
+ return unless class_name
864
843
 
865
- if in_module then
866
- enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
844
+ class_obj = find_class var_name, class_name
867
845
 
868
- if enclosure.nil? and enclosure = @known_classes[in_module] then
869
- enc_type = /^rb_m/ =~ in_module ? :module : :class
870
- handle_class_module in_module, enc_type, enclosure, nil, nil
871
- enclosure = @classes[in_module]
872
- end
846
+ return unless class_obj
873
847
 
874
- unless enclosure then
875
- @enclosure_dependencies[in_module] << var_name
876
- @missing_dependencies[var_name] =
877
- [var_name, type, class_name, parent, in_module]
848
+ comment = find_attr_comment var_name, attr_name
849
+ comment.normalize
878
850
 
879
- return
880
- end
881
- else
882
- enclosure = @top_level
883
- end
851
+ name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
884
852
 
885
- if type == :class then
886
- full_name = if RDoc::ClassModule === enclosure then
887
- enclosure.full_name + "::#{class_name}"
888
- else
889
- class_name
890
- end
853
+ attr = Attr.new name, rw, comment
891
854
 
892
- if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)% then
893
- parent_name = $1
855
+ attr.record_location @top_level
856
+ class_obj.add_attribute attr
857
+ @stats.add_attribute attr
894
858
  end
895
859
 
896
- cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name
897
- else
898
- cm = enclosure.add_module RDoc::NormalModule, class_name
899
- end
860
+ ##
861
+ # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
862
+ # named +class_name+ in +parent+ which was assigned to the C +var_name+.
900
863
 
901
- cm.record_location enclosure.top_level
902
- enclosure.top_level.add_to_classes_or_modules cm
903
-
904
- find_class_comment cm.full_name, cm
905
-
906
- case cm
907
- when RDoc::NormalClass
908
- @stats.add_class cm
909
- when RDoc::NormalModule
910
- @stats.add_module cm
911
- end
912
-
913
- @classes[var_name] = cm
914
- @known_classes[var_name] = cm.full_name
915
- @store.add_c_enclosure var_name, cm
916
- end
864
+ def handle_class_module(var_name, type, class_name, parent, in_module)
865
+ parent_name = @known_classes[parent] || parent
917
866
 
918
- ##
919
- # Adds constants. By providing some_value: at the start of the comment you
920
- # can override the C value of the comment to give a friendly definition.
921
- #
922
- # /* 300: The perfect score in bowling */
923
- # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
924
- #
925
- # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
926
- # RDoc. Values may include quotes and escaped colons (\:).
867
+ if in_module
868
+ enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
927
869
 
928
- def handle_constants(type, var_name, const_name, definition)
929
- class_name = @known_classes[var_name]
870
+ if enclosure.nil? and enclosure = @known_classes[in_module]
871
+ enc_type = /^rb_m/ =~ in_module ? :module : :class
872
+ handle_class_module in_module, enc_type, enclosure, nil, nil
873
+ enclosure = @classes[in_module]
874
+ end
930
875
 
931
- return unless class_name
876
+ unless enclosure
877
+ @enclosure_dependencies[in_module] << var_name
878
+ @missing_dependencies[var_name] =
879
+ [var_name, type, class_name, parent, in_module]
932
880
 
933
- class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/]
934
-
935
- unless class_obj then
936
- @options.warn 'Enclosing class or module %p is not known' % [const_name]
937
- return
938
- end
881
+ return
882
+ end
883
+ else
884
+ enclosure = @top_level
885
+ end
939
886
 
940
- comment = find_const_comment type, const_name, class_name
941
- comment.normalize
887
+ if type == :class
888
+ full_name = if ClassModule === enclosure
889
+ enclosure.full_name + "::#{class_name}"
890
+ else
891
+ class_name
892
+ end
942
893
 
943
- # In the case of rb_define_const, the definition and comment are in
944
- # "/* definition: comment */" form. The literal ':' and '\' characters
945
- # can be escaped with a backslash.
946
- if type.downcase == 'const' then
947
- if /\A(.+?)?:(?!\S)/ =~ comment.text
948
- new_definition, new_comment = $1, $'
894
+ if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)%
895
+ parent_name = $1
896
+ end
949
897
 
950
- if !new_definition # Default to literal C definition
951
- new_definition = definition
898
+ cm = enclosure.add_class NormalClass, class_name, parent_name
952
899
  else
953
- new_definition = new_definition.gsub(/\\([\\:])/, '\1')
900
+ cm = enclosure.add_module NormalModule, class_name
954
901
  end
955
902
 
956
- new_definition.sub!(/\A(\s+)/, '')
903
+ cm.record_location enclosure.top_level
904
+ enclosure.top_level.add_to_classes_or_modules cm
957
905
 
958
- new_comment = "#{$1}#{new_comment.lstrip}"
906
+ find_class_comment cm.full_name, cm
959
907
 
960
- new_comment = self.new_comment(new_comment, @top_level, :c)
908
+ case cm
909
+ when NormalClass
910
+ @stats.add_class cm
911
+ when NormalModule
912
+ @stats.add_module cm
913
+ end
961
914
 
962
- con = RDoc::Constant.new const_name, new_definition, new_comment
963
- else
964
- con = RDoc::Constant.new const_name, definition, comment
915
+ @classes[var_name] = cm
916
+ @known_classes[var_name] = cm.full_name
917
+ @store.add_c_enclosure var_name, cm
965
918
  end
966
- else
967
- con = RDoc::Constant.new const_name, definition, comment
968
- end
969
919
 
970
- con.record_location @top_level
971
- @stats.add_constant con
972
- class_obj.add_constant con
973
- end
920
+ ##
921
+ # Adds constants. By providing some_value: at the start of the comment you
922
+ # can override the C value of the comment to give a friendly definition.
923
+ #
924
+ # /* 300: The perfect score in bowling */
925
+ # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
926
+ #
927
+ # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
928
+ # RDoc. Values may include quotes and escaped colons (\:).
974
929
 
975
- ##
976
- # Removes #ifdefs that would otherwise confuse us
930
+ def handle_constants(type, var_name, const_name, definition)
931
+ class_name = @known_classes[var_name]
977
932
 
978
- def handle_ifdefs_in(body)
979
- body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
980
- end
933
+ return unless class_name
981
934
 
982
- ##
983
- # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
984
- # to +var_name+. +type+ is the type of method definition function used.
985
- # +singleton_method+ and +module_function+ create a singleton method.
935
+ class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/]
986
936
 
987
- def handle_method(type, var_name, meth_name, function, param_count,
988
- source_file = nil)
989
- class_name = @known_classes[var_name]
990
- singleton = @singleton_classes.key? var_name
937
+ unless class_obj
938
+ @options.warn 'Enclosing class or module %p is not known' % [const_name]
939
+ return
940
+ end
991
941
 
992
- @methods[var_name][function] << meth_name
942
+ comment = find_const_comment type, const_name, class_name
943
+ comment.normalize
993
944
 
994
- return unless class_name
945
+ # In the case of rb_define_const, the definition and comment are in
946
+ # "/* definition: comment */" form. The literal ':' and '\' characters
947
+ # can be escaped with a backslash.
948
+ if type.downcase == 'const'
949
+ if /\A(.+?)?:(?!\S)/ =~ comment.text
950
+ new_definition, new_comment = $1, $'
995
951
 
996
- class_obj = find_class var_name, class_name
952
+ if !new_definition # Default to literal C definition
953
+ new_definition = definition
954
+ else
955
+ new_definition = new_definition.gsub(/\\([\\:])/, '\1')
956
+ end
997
957
 
998
- if existing_method = class_obj.method_list.find { |m| m.c_function == function }
999
- add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
1000
- end
958
+ new_definition.sub!(/\A(\s+)/, '')
1001
959
 
1002
- if class_obj then
1003
- if meth_name == 'initialize' then
1004
- meth_name = 'new'
1005
- singleton = true
1006
- type = 'method' # force public
1007
- end
960
+ new_comment = "#{$1}#{new_comment.lstrip}"
1008
961
 
1009
- singleton = singleton || %w[singleton_method module_function].include?(type)
1010
- meth_obj = RDoc::AnyMethod.new meth_name, singleton: singleton
1011
- meth_obj.c_function = function
962
+ new_comment = self.new_comment(new_comment, @top_level, :c)
1012
963
 
1013
- p_count = Integer(param_count) rescue -1
1014
-
1015
- if source_file then
1016
- file_name = File.join @file_dir, source_file
1017
-
1018
- if File.exist? file_name then
1019
- file_content = RDoc::Encoding.read_file file_name, @options.encoding
964
+ con = Constant.new const_name, new_definition, new_comment
965
+ else
966
+ con = Constant.new const_name, definition, comment
967
+ end
1020
968
  else
1021
- @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
969
+ con = Constant.new const_name, definition, comment
1022
970
  end
1023
- else
1024
- file_content = @content
971
+
972
+ con.record_location @top_level
973
+ @stats.add_constant con
974
+ class_obj.add_constant con
975
+ end
976
+
977
+ ##
978
+ # Removes #ifdefs that would otherwise confuse us
979
+
980
+ def handle_ifdefs_in(body)
981
+ body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
1025
982
  end
1026
983
 
1027
- body = find_body class_name, function, meth_obj, file_content
984
+ ##
985
+ # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
986
+ # to +var_name+. +type+ is the type of method definition function used.
987
+ # +singleton_method+ and +module_function+ create a singleton method.
988
+
989
+ def handle_method(type, var_name, meth_name, function, param_count,
990
+ source_file = nil)
991
+ class_name = @known_classes[var_name]
992
+ singleton = @singleton_classes.key?(var_name) || %w[singleton_method module_function].include?(type)
1028
993
 
1029
- if body and meth_obj.document_self then
1030
- meth_obj.params = if p_count < -1 then # -2 is Array
1031
- '(*args)'
1032
- elsif p_count == -1 then # argc, argv
1033
- rb_scan_args body
1034
- else
1035
- args = (1..p_count).map { |i| "p#{i}" }
1036
- "(#{args.join ', '})"
1037
- end
994
+ @methods[var_name][function] << meth_name
1038
995
 
996
+ return unless class_name
1039
997
 
1040
- meth_obj.record_location @top_level
998
+ class_obj = find_class var_name, class_name
1041
999
 
1042
- if meth_obj.section_title
1043
- class_obj.temporary_section = class_obj.add_section(meth_obj.section_title)
1000
+ if existing_method = class_obj.method_list.find { |m| m.c_function == function && m.singleton == singleton }
1001
+ add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment, singleton: singleton)
1044
1002
  end
1045
- class_obj.add_method meth_obj
1046
1003
 
1047
- @stats.add_method meth_obj
1048
- meth_obj.visibility = :private if 'private_method' == type
1004
+ if class_obj
1005
+ if meth_name == 'initialize'
1006
+ meth_name = 'new'
1007
+ singleton = true
1008
+ type = 'method' # force public
1009
+ end
1010
+
1011
+ meth_obj = AnyMethod.new meth_name, singleton: singleton
1012
+ meth_obj.c_function = function
1013
+
1014
+ p_count = Integer(param_count) rescue -1
1015
+
1016
+ if source_file
1017
+ file_name = File.join @file_dir, source_file
1018
+
1019
+ if File.exist? file_name
1020
+ file_content = Encoding.read_file file_name, @options.encoding
1021
+ else
1022
+ @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
1023
+ end
1024
+ else
1025
+ file_content = @content
1026
+ end
1027
+
1028
+ body = find_body class_name, function, meth_obj, file_content
1029
+
1030
+ if body and meth_obj.document_self
1031
+ meth_obj.params = if p_count < -1 # -2 is Array
1032
+ '(*args)'
1033
+ elsif p_count == -1 # argc, argv
1034
+ rb_scan_args body
1035
+ else
1036
+ args = (1..p_count).map { |i| "p#{i}" }
1037
+ "(#{args.join ', '})"
1038
+ end
1039
+
1040
+
1041
+ meth_obj.record_location @top_level
1042
+
1043
+ if meth_obj.section_title
1044
+ class_obj.temporary_section = class_obj.add_section(meth_obj.section_title)
1045
+ end
1046
+ meth_obj.visibility = type == 'private_method' ? :private : :public
1047
+ class_obj.add_method meth_obj
1048
+ @stats.add_method meth_obj
1049
+ end
1050
+ end
1049
1051
  end
1050
- end
1051
- end
1052
1052
 
1053
- ##
1054
- # Registers a singleton class +sclass_var+ as a singleton of +class_var+
1053
+ ##
1054
+ # Registers a singleton class +sclass_var+ as a singleton of +class_var+
1055
1055
 
1056
- def handle_singleton(sclass_var, class_var)
1057
- if (klass = @classes[class_var])
1058
- @classes[sclass_var] = klass
1059
- end
1060
- if (class_name = @known_classes[class_var])
1061
- @known_classes[sclass_var] = class_name
1062
- @singleton_classes[sclass_var] = class_name
1063
- end
1064
- end
1056
+ def handle_singleton(sclass_var, class_var)
1057
+ if (klass = @classes[class_var])
1058
+ @classes[sclass_var] = klass
1059
+ end
1060
+ if (class_name = @known_classes[class_var])
1061
+ @known_classes[sclass_var] = class_name
1062
+ @singleton_classes[sclass_var] = class_name
1063
+ end
1064
+ end
1065
1065
 
1066
- ##
1067
- # Loads the variable map with the given +name+ from the RDoc::Store, if
1068
- # present.
1066
+ ##
1067
+ # Loads the variable map with the given +name+ from the RDoc::Store, if
1068
+ # present.
1069
1069
 
1070
- def load_variable_map(map_name)
1071
- return {} unless files = @store.cache[map_name]
1072
- return {} unless name_map = files[@file_name]
1070
+ def load_variable_map(map_name)
1071
+ return {} unless files = @store.cache[map_name]
1072
+ return {} unless name_map = files[@file_name]
1073
1073
 
1074
- class_map = {}
1074
+ class_map = {}
1075
1075
 
1076
- name_map.each do |variable, name|
1077
- next unless mod = @store.find_class_or_module(name)
1076
+ name_map.each do |variable, name|
1077
+ next unless mod = @store.find_class_or_module(name)
1078
1078
 
1079
- class_map[variable] = if map_name == :c_class_variables then
1080
- mod
1081
- else
1082
- name
1083
- end
1084
- @known_classes[variable] = name
1085
- end
1079
+ class_map[variable] = if map_name == :c_class_variables
1080
+ mod
1081
+ else
1082
+ name
1083
+ end
1084
+ @known_classes[variable] = name
1085
+ end
1086
1086
 
1087
- class_map
1088
- end
1087
+ class_map
1088
+ end
1089
1089
 
1090
- ##
1091
- # Look for directives in a normal comment block:
1092
- #
1093
- # /*
1094
- # * :nodoc:
1095
- # */
1096
- #
1097
- # This method modifies the +comment+
1098
-
1099
- def look_for_directives_in(context, comment)
1100
- comment.text, format = @preprocess.run_pre_processes(comment.text, context, comment.line || 1, :c)
1101
- comment.format = format if format
1102
- @preprocess.run_post_processes(comment, context)
1103
- comment.normalized = true
1104
- comment
1105
- end
1090
+ ##
1091
+ # Look for directives in a normal comment block:
1092
+ #
1093
+ # /*
1094
+ # * :nodoc:
1095
+ # */
1096
+ #
1097
+ # This method modifies the +comment+
1098
+
1099
+ def look_for_directives_in(context, comment)
1100
+ comment.text, format = @preprocess.run_pre_processes(comment.text, context, comment.line || 1, :c)
1101
+ comment.format = format if format
1102
+ @preprocess.run_post_processes(comment, context)
1103
+ comment.normalized = true
1104
+ comment
1105
+ end
1106
1106
 
1107
- ##
1108
- # Extracts parameters from the +method_body+ and returns a method
1109
- # parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT
1107
+ ##
1108
+ # Extracts parameters from the +method_body+ and returns a method
1109
+ # parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT
1110
1110
 
1111
- def rb_scan_args(method_body)
1112
- method_body =~ /rb_scan_args\((.*?)\)/m
1113
- return '(*args)' unless $1
1111
+ def rb_scan_args(method_body)
1112
+ method_body =~ /rb_scan_args\((.*?)\)/m
1113
+ return '(*args)' unless $1
1114
1114
 
1115
- $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
1116
- format = $1.split(//)
1115
+ $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
1116
+ format = $1.split(//)
1117
1117
 
1118
- lead = opt = trail = 0
1118
+ lead = opt = trail = 0
1119
1119
 
1120
- if format.first =~ /\d/ then
1121
- lead = $&.to_i
1122
- format.shift
1123
- if format.first =~ /\d/ then
1124
- opt = $&.to_i
1125
- format.shift
1126
- if format.first =~ /\d/ then
1127
- trail = $&.to_i
1120
+ if format.first =~ /\d/
1121
+ lead = $&.to_i
1128
1122
  format.shift
1129
- block_arg = true
1123
+ if format.first =~ /\d/
1124
+ opt = $&.to_i
1125
+ format.shift
1126
+ if format.first =~ /\d/
1127
+ trail = $&.to_i
1128
+ format.shift
1129
+ block_arg = true
1130
+ end
1131
+ end
1130
1132
  end
1131
- end
1132
- end
1133
1133
 
1134
- if format.first == '*' and not block_arg then
1135
- var = true
1136
- format.shift
1137
- if format.first =~ /\d/ then
1138
- trail = $&.to_i
1139
- format.shift
1140
- end
1141
- end
1134
+ if format.first == '*' and not block_arg
1135
+ var = true
1136
+ format.shift
1137
+ if format.first =~ /\d/
1138
+ trail = $&.to_i
1139
+ format.shift
1140
+ end
1141
+ end
1142
1142
 
1143
- if format.first == ':' then
1144
- hash = true
1145
- format.shift
1146
- end
1143
+ if format.first == ':'
1144
+ hash = true
1145
+ format.shift
1146
+ end
1147
1147
 
1148
- if format.first == '&' then
1149
- block = true
1150
- format.shift
1151
- end
1148
+ if format.first == '&'
1149
+ block = true
1150
+ format.shift
1151
+ end
1152
1152
 
1153
- # if the format string is not empty there's a bug in the C code, ignore it
1153
+ # if the format string is not empty there's a bug in the C code, ignore it
1154
1154
 
1155
- args = []
1156
- position = 1
1155
+ args = []
1156
+ position = 1
1157
1157
 
1158
- (1...(position + lead)).each do |index|
1159
- args << "p#{index}"
1160
- end
1158
+ (1...(position + lead)).each do |index|
1159
+ args << "p#{index}"
1160
+ end
1161
1161
 
1162
- position += lead
1162
+ position += lead
1163
1163
 
1164
- (position...(position + opt)).each do |index|
1165
- args << "p#{index} = v#{index}"
1166
- end
1164
+ (position...(position + opt)).each do |index|
1165
+ args << "p#{index} = v#{index}"
1166
+ end
1167
1167
 
1168
- position += opt
1168
+ position += opt
1169
1169
 
1170
- if var then
1171
- args << '*args'
1172
- position += 1
1173
- end
1170
+ if var
1171
+ args << '*args'
1172
+ position += 1
1173
+ end
1174
1174
 
1175
- (position...(position + trail)).each do |index|
1176
- args << "p#{index}"
1177
- end
1175
+ (position...(position + trail)).each do |index|
1176
+ args << "p#{index}"
1177
+ end
1178
1178
 
1179
- position += trail
1179
+ position += trail
1180
1180
 
1181
- if hash then
1182
- args << "p#{position} = {}"
1183
- end
1181
+ if hash
1182
+ args << "p#{position} = {}"
1183
+ end
1184
1184
 
1185
- args << '&block' if block
1185
+ args << '&block' if block
1186
1186
 
1187
- "(#{args.join ', '})"
1188
- end
1187
+ "(#{args.join ', '})"
1188
+ end
1189
1189
 
1190
- ##
1191
- # Removes lines that are commented out that might otherwise get picked up
1192
- # when scanning for classes and methods
1190
+ ##
1191
+ # Removes lines that are commented out that might otherwise get picked up
1192
+ # when scanning for classes and methods
1193
1193
 
1194
- def remove_commented_out_lines
1195
- @content = @content.gsub(%r%//.*rb_define_%, '//')
1196
- end
1194
+ def remove_commented_out_lines
1195
+ @content = @content.gsub(%r%//.*rb_define_%, '//')
1196
+ end
1197
1197
 
1198
- ##
1199
- # Extracts the classes, modules, methods, attributes, constants and aliases
1200
- # from a C file and returns an RDoc::TopLevel for this file
1198
+ ##
1199
+ # Extracts the classes, modules, methods, attributes, constants and aliases
1200
+ # from a C file and returns an RDoc::TopLevel for this file
1201
1201
 
1202
- def scan
1203
- remove_commented_out_lines
1202
+ def scan
1203
+ remove_commented_out_lines
1204
1204
 
1205
- do_classes_and_modules
1206
- do_missing
1205
+ do_classes_and_modules
1206
+ do_missing
1207
1207
 
1208
- do_constants
1209
- do_methods
1210
- do_includes
1211
- do_aliases
1212
- do_attrs
1208
+ do_constants
1209
+ do_methods
1210
+ do_includes
1211
+ do_aliases
1212
+ do_attrs
1213
1213
 
1214
- @store.add_c_variables self
1214
+ @store.add_c_variables self
1215
1215
 
1216
- @top_level
1217
- end
1216
+ @top_level
1217
+ end
1218
1218
 
1219
- ##
1220
- # Creates a RDoc::Comment instance.
1219
+ ##
1220
+ # Creates a RDoc::Comment instance.
1221
1221
 
1222
- def new_comment(text = nil, location = nil, language = nil)
1223
- RDoc::Comment.new(text, location, language).tap do |comment|
1224
- comment.format = @markup
1222
+ def new_comment(text = nil, location = nil, language = nil)
1223
+ Comment.new(text, location, language).tap do |comment|
1224
+ comment.format = @markup
1225
+ end
1226
+ end
1225
1227
  end
1226
1228
  end
1227
1229
  end