rdoc 7.2.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +4 -7
  3. data/LICENSE.rdoc +4 -0
  4. data/README.md +43 -2
  5. data/RI.md +75 -75
  6. data/doc/markup_reference/markdown.md +104 -3
  7. data/exe/rdoc +2 -2
  8. data/lib/rdoc/code_object/alias.rb +70 -74
  9. data/lib/rdoc/code_object/any_method.rb +305 -298
  10. data/lib/rdoc/code_object/attr.rb +150 -143
  11. data/lib/rdoc/code_object/class_module.rb +801 -765
  12. data/lib/rdoc/code_object/constant.rb +178 -150
  13. data/lib/rdoc/code_object/context/section.rb +133 -160
  14. data/lib/rdoc/code_object/context.rb +925 -952
  15. data/lib/rdoc/code_object/extend.rb +7 -5
  16. data/lib/rdoc/code_object/include.rb +7 -5
  17. data/lib/rdoc/code_object/method_attr.rb +325 -324
  18. data/lib/rdoc/code_object/mixin.rb +97 -95
  19. data/lib/rdoc/code_object/normal_class.rb +77 -78
  20. data/lib/rdoc/code_object/normal_module.rb +61 -59
  21. data/lib/rdoc/code_object/require.rb +23 -39
  22. data/lib/rdoc/code_object/single_class.rb +21 -19
  23. data/lib/rdoc/code_object/top_level.rb +212 -213
  24. data/lib/rdoc/code_object.rb +305 -305
  25. data/lib/rdoc/comment.rb +274 -337
  26. data/lib/rdoc/cross_reference.rb +194 -212
  27. data/lib/rdoc/encoding.rb +105 -103
  28. data/lib/rdoc/erb_partial.rb +13 -11
  29. data/lib/rdoc/erbio.rb +29 -27
  30. data/lib/rdoc/generator/aliki.rb +165 -140
  31. data/lib/rdoc/generator/darkfish.rb +647 -631
  32. data/lib/rdoc/generator/json_index.rb +233 -229
  33. data/lib/rdoc/generator/markup.rb +165 -122
  34. data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
  35. data/lib/rdoc/generator/pot/po.rb +52 -51
  36. data/lib/rdoc/generator/pot/po_entry.rb +138 -132
  37. data/lib/rdoc/generator/pot.rb +85 -81
  38. data/lib/rdoc/generator/ri.rb +23 -19
  39. data/lib/rdoc/generator/template/aliki/DESIGN.md +538 -0
  40. data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +1 -1
  41. data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
  42. data/lib/rdoc/generator/template/aliki/_head.rhtml +11 -11
  43. data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
  44. data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +8 -6
  45. data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +8 -6
  46. data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +1 -1
  47. data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +2 -2
  48. data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
  49. data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +1 -1
  50. data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +1 -1
  51. data/lib/rdoc/generator/template/aliki/class.rhtml +56 -46
  52. data/lib/rdoc/generator/template/aliki/css/rdoc.css +538 -283
  53. data/lib/rdoc/generator/template/aliki/index.rhtml +1 -1
  54. data/lib/rdoc/generator/template/aliki/js/aliki.js +80 -102
  55. data/lib/rdoc/generator/template/aliki/page.rhtml +1 -1
  56. data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +1 -1
  57. data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +2 -2
  58. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
  59. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -6
  60. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -6
  61. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +1 -1
  62. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
  63. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +1 -1
  64. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +5 -5
  65. data/lib/rdoc/generator/template/darkfish/class.rhtml +18 -21
  66. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +0 -1
  67. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +3 -3
  68. data/lib/rdoc/generator.rb +48 -46
  69. data/lib/rdoc/i18n/locale.rb +99 -95
  70. data/lib/rdoc/i18n/text.rb +109 -105
  71. data/lib/rdoc/i18n.rb +7 -5
  72. data/lib/rdoc/markdown/byte_runtime.rb +80 -0
  73. data/lib/rdoc/markdown.kpeg +30 -21
  74. data/lib/rdoc/markdown.rb +329 -151
  75. data/lib/rdoc/markup/block_quote.rb +12 -8
  76. data/lib/rdoc/markup/document.rb +127 -123
  77. data/lib/rdoc/markup/formatter.rb +215 -221
  78. data/lib/rdoc/markup/heading.rb +1 -4
  79. data/lib/rdoc/markup/include.rb +33 -29
  80. data/lib/rdoc/markup/indented_paragraph.rb +37 -33
  81. data/lib/rdoc/markup/inline_parser.rb +281 -277
  82. data/lib/rdoc/markup/list.rb +80 -88
  83. data/lib/rdoc/markup/list_item.rb +73 -85
  84. data/lib/rdoc/markup/paragraph.rb +23 -19
  85. data/lib/rdoc/markup/parser.rb +501 -497
  86. data/lib/rdoc/markup/pre_process.rb +284 -305
  87. data/lib/rdoc/markup/raw.rb +2 -2
  88. data/lib/rdoc/markup/rule.rb +16 -12
  89. data/lib/rdoc/markup/to_ansi.rb +143 -139
  90. data/lib/rdoc/markup/to_bs.rb +72 -68
  91. data/lib/rdoc/markup/to_html.rb +600 -493
  92. data/lib/rdoc/markup/to_html_crossref.rb +221 -191
  93. data/lib/rdoc/markup/to_html_snippet.rb +232 -227
  94. data/lib/rdoc/markup/to_joined_paragraph.rb +40 -41
  95. data/lib/rdoc/markup/to_label.rb +63 -59
  96. data/lib/rdoc/markup/to_markdown.rb +212 -208
  97. data/lib/rdoc/markup/to_rdoc.rb +336 -332
  98. data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
  99. data/lib/rdoc/markup/to_test.rb +60 -56
  100. data/lib/rdoc/markup/to_tt_only.rb +83 -86
  101. data/lib/rdoc/markup/verbatim.rb +62 -58
  102. data/lib/rdoc/markup.rb +198 -196
  103. data/lib/rdoc/options.rb +1063 -1076
  104. data/lib/rdoc/parser/c.rb +1039 -1036
  105. data/lib/rdoc/parser/changelog.rb +319 -315
  106. data/lib/rdoc/parser/markdown.rb +17 -13
  107. data/lib/rdoc/parser/rbs.rb +279 -0
  108. data/lib/rdoc/parser/rd.rb +17 -13
  109. data/lib/rdoc/parser/ruby.rb +1231 -2222
  110. data/lib/rdoc/parser/ruby_colorizer.rb +303 -0
  111. data/lib/rdoc/parser/simple.rb +31 -27
  112. data/lib/rdoc/parser/text.rb +12 -8
  113. data/lib/rdoc/parser.rb +230 -221
  114. data/lib/rdoc/rbs_helper.rb +186 -0
  115. data/lib/rdoc/rd/inline.rb +57 -53
  116. data/lib/rdoc/rd.rb +90 -88
  117. data/lib/rdoc/rdoc.rb +547 -366
  118. data/lib/rdoc/ri/driver.rb +1141 -1130
  119. data/lib/rdoc/ri/formatter.rb +7 -3
  120. data/lib/rdoc/ri/paths.rb +140 -136
  121. data/lib/rdoc/ri/servlet.rb +456 -0
  122. data/lib/rdoc/ri/store.rb +4 -2
  123. data/lib/rdoc/ri/task.rb +55 -51
  124. data/lib/rdoc/ri.rb +14 -11
  125. data/lib/rdoc/rubygems_hook.rb +194 -192
  126. data/lib/rdoc/server.rb +462 -0
  127. data/lib/rdoc/stats/normal.rb +46 -42
  128. data/lib/rdoc/stats/quiet.rb +39 -35
  129. data/lib/rdoc/stats/verbose.rb +35 -31
  130. data/lib/rdoc/stats.rb +363 -338
  131. data/lib/rdoc/store.rb +919 -725
  132. data/lib/rdoc/task.rb +260 -255
  133. data/lib/rdoc/text.rb +130 -245
  134. data/lib/rdoc/token_stream.rb +101 -115
  135. data/lib/rdoc/tom_doc.rb +203 -201
  136. data/lib/rdoc/version.rb +1 -1
  137. data/lib/rdoc.rb +35 -7
  138. data/lib/rubygems_plugin.rb +2 -11
  139. data/rdoc-logo.svg +43 -0
  140. data/rdoc.gemspec +6 -4
  141. metadata +36 -20
  142. data/lib/rdoc/code_object/anon_class.rb +0 -10
  143. data/lib/rdoc/code_object/ghost_method.rb +0 -6
  144. data/lib/rdoc/code_object/meta_method.rb +0 -6
  145. data/lib/rdoc/markdown/literals.kpeg +0 -21
  146. data/lib/rdoc/markdown/literals.rb +0 -454
  147. data/lib/rdoc/parser/prism_ruby.rb +0 -1112
  148. data/lib/rdoc/parser/ripper_state_lex.rb +0 -302
  149. data/lib/rdoc/parser/ruby_tools.rb +0 -163
  150. data/lib/rdoc/servlet.rb +0 -452
data/lib/rdoc/parser/c.rb CHANGED
@@ -1,1226 +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
- @classes[raw_name] = container
687
- end
688
- @classes[raw_name]
689
- end
690
-
691
- ##
692
- # Look for class or module documentation above Init_+class_name+(void),
693
- # in a Document-class +class_name+ (or module) comment or above an
694
- # rb_define_class (or module). If a comment is supplied above a matching
695
- # Init_ and a rb_define_class the Init_ comment is used.
696
- #
697
- # /*
698
- # * This is a comment for Foo
699
- # */
700
- # Init_Foo(void) {
701
- # VALUE cFoo = rb_define_class("Foo", rb_cObject);
702
- # }
703
- #
704
- # /*
705
- # * Document-class: Foo
706
- # * This is a comment for Foo
707
- # */
708
- # Init_foo(void) {
709
- # VALUE cFoo = rb_define_class("Foo", rb_cObject);
710
- # }
711
- #
712
- # /*
713
- # * This is a comment for Foo
714
- # */
715
- # VALUE cFoo = rb_define_class("Foo", rb_cObject);
716
-
717
- def find_class_comment(class_name, class_mod)
718
- comment = nil
719
-
720
- if @content =~ %r%
721
- ((?>/\*.*?\*/\s+))
722
- (static\s+)?
723
- void\s+
724
- Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm then
725
- comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
726
- elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
727
- (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
728
- comment = "/*\n#{$1}"
729
- elsif @content =~ %r%((?>/\*.*?\*/\s+))
730
- ([\w\.\s]+\s* = \s+)?rb_define_(class|module)[\t (]*?"(#{class_name})"%xm then
731
- comment = $1
732
- elsif @content =~ %r%((?>/\*.*?\*/\s+))
733
- ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
734
- comment = $1
735
- else
736
- comment = ''
737
- end
738
-
739
- 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
740
741
 
741
- look_for_directives_in class_mod, comment
742
+ comment = new_comment comment, @top_level, :c
742
743
 
743
- class_mod.add_comment comment, @top_level
744
- end
744
+ look_for_directives_in class_mod, comment
745
745
 
746
- ##
747
- # Generate a const table
748
-
749
- def gen_const_table(file_content)
750
- table = {}
751
- @content.scan(%r{
752
- (?<doc>(?>^\s*/\*.*?\*/\s+))
753
- rb_define_(?<type>\w+)\(\s*(?:\w+),\s*
754
- "(?<name>\w+)"\s*,
755
- .*?\)\s*;
756
- | (?<doc>(?>^\s*/\*.*?\*/\s+))
757
- rb_define_global_(?<type>const)\(\s*
758
- "(?<name>\w+)"\s*,
759
- .*?\)\s*;
760
- | (?<doc>(?>^\s*/\*.*?\*/\s+))
761
- rb_file_(?<type>const)\(\s*
762
- "(?<name>\w+)"\s*,
763
- .*?\)\s*;
764
- | (?<doc>(?>^\s*/\*.*?\*/\s+))
765
- rb_curses_define_(?<type>const)\(\s*
766
- (?<name>\w+)
767
- \s*\)\s*;
768
- | Document-(?:const|global|variable):\s
769
- (?<name>(?:\w+::)*\w+)
770
- \s*?\n(?<doc>(?>.*?\*/))
771
- }mxi) do
772
- name, doc, type = $~.values_at(:name, :doc, :type)
773
- if type
774
- table[[type, name]] = doc
775
- else
776
- table[name] = "/*\n" + doc
746
+ class_mod.add_comment comment, @top_level
777
747
  end
778
- end
779
- table
780
- end
781
-
782
- ##
783
- # Finds a comment matching +type+ and +const_name+ either above the
784
- # comment or in the matching Document- section.
785
-
786
- def find_const_comment(type, const_name, class_name = nil)
787
- @const_table ||= {}
788
- @const_table[@content] ||= gen_const_table @content
789
- table = @const_table[@content]
790
-
791
- comment =
792
- table[[type, const_name]] ||
793
- (class_name && table[class_name + "::" + const_name]) ||
794
- table[const_name] ||
795
- ''
796
-
797
- new_comment comment, @top_level, :c
798
- end
799
-
800
- ##
801
- # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
802
748
 
803
- def find_modifiers(comment, meth_obj)
804
- look_for_directives_in meth_obj, comment
805
- end
806
-
807
- ##
808
- # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
809
-
810
- def find_override_comment(class_name, meth_obj)
811
- name = Regexp.escape meth_obj.name
812
- 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
813
784
 
814
- comment = if @content =~ %r%Document-method:
815
- \s+#{class_name}#{prefix}#{name}
816
- \s*?\n((?>.*?\*/))%xm then
817
- "/*\n#{$1}"
818
- elsif @content =~ %r%Document-method:
819
- \s#{name}\s*?\n((?>.*?\*/))%xm then
820
- "/*\n#{$1}"
821
- end
785
+ ##
786
+ # Finds a comment matching +type+ and +const_name+ either above the
787
+ # comment or in the matching Document- section.
822
788
 
823
- 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]
824
793
 
825
- new_comment comment, @top_level, :c
826
- end
794
+ comment =
795
+ table[[type, const_name]] ||
796
+ (class_name && table[class_name + "::" + const_name]) ||
797
+ table[const_name] ||
798
+ ''
827
799
 
828
- ##
829
- # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
830
- # +read+, +write+ or both
800
+ new_comment comment, @top_level, :c
801
+ end
831
802
 
832
- def handle_attr(var_name, attr_name, read, write)
833
- rw = ''
834
- rw += 'R' if TRUE_VALUES.include?(read)
835
- rw += 'W' if TRUE_VALUES.include?(write)
803
+ ##
804
+ # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
836
805
 
837
- class_name = @known_classes[var_name]
806
+ def find_modifiers(comment, meth_obj)
807
+ look_for_directives_in meth_obj, comment
808
+ end
838
809
 
839
- return unless class_name
810
+ ##
811
+ # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
840
812
 
841
- 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
842
816
 
843
- 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
844
825
 
845
- comment = find_attr_comment var_name, attr_name
846
- comment.normalize
826
+ return unless comment
847
827
 
848
- name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
828
+ new_comment comment, @top_level, :c
829
+ end
849
830
 
850
- 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
851
834
 
852
- attr.record_location @top_level
853
- class_obj.add_attribute attr
854
- @stats.add_attribute attr
855
- 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)
856
839
 
857
- ##
858
- # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
859
- # named +class_name+ in +parent+ which was assigned to the C +var_name+.
840
+ class_name = @known_classes[var_name]
860
841
 
861
- def handle_class_module(var_name, type, class_name, parent, in_module)
862
- parent_name = @known_classes[parent] || parent
842
+ return unless class_name
863
843
 
864
- if in_module then
865
- enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
844
+ class_obj = find_class var_name, class_name
866
845
 
867
- if enclosure.nil? and enclosure = @known_classes[in_module] then
868
- enc_type = /^rb_m/ =~ in_module ? :module : :class
869
- handle_class_module in_module, enc_type, enclosure, nil, nil
870
- enclosure = @classes[in_module]
871
- end
846
+ return unless class_obj
872
847
 
873
- unless enclosure then
874
- @enclosure_dependencies[in_module] << var_name
875
- @missing_dependencies[var_name] =
876
- [var_name, type, class_name, parent, in_module]
848
+ comment = find_attr_comment var_name, attr_name
849
+ comment.normalize
877
850
 
878
- return
879
- end
880
- else
881
- enclosure = @top_level
882
- end
851
+ name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
883
852
 
884
- if type == :class then
885
- full_name = if RDoc::ClassModule === enclosure then
886
- enclosure.full_name + "::#{class_name}"
887
- else
888
- class_name
889
- end
853
+ attr = Attr.new name, rw, comment
890
854
 
891
- if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)% then
892
- parent_name = $1
855
+ attr.record_location @top_level
856
+ class_obj.add_attribute attr
857
+ @stats.add_attribute attr
893
858
  end
894
859
 
895
- cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name
896
- else
897
- cm = enclosure.add_module RDoc::NormalModule, class_name
898
- 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+.
899
863
 
900
- cm.record_location enclosure.top_level
901
-
902
- find_class_comment cm.full_name, cm
903
-
904
- case cm
905
- when RDoc::NormalClass
906
- @stats.add_class cm
907
- when RDoc::NormalModule
908
- @stats.add_module cm
909
- end
910
-
911
- @classes[var_name] = cm
912
- @known_classes[var_name] = cm.full_name
913
- @store.add_c_enclosure var_name, cm
914
- end
864
+ def handle_class_module(var_name, type, class_name, parent, in_module)
865
+ parent_name = @known_classes[parent] || parent
915
866
 
916
- ##
917
- # Adds constants. By providing some_value: at the start of the comment you
918
- # can override the C value of the comment to give a friendly definition.
919
- #
920
- # /* 300: The perfect score in bowling */
921
- # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
922
- #
923
- # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
924
- # RDoc. Values may include quotes and escaped colons (\:).
867
+ if in_module
868
+ enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
925
869
 
926
- def handle_constants(type, var_name, const_name, definition)
927
- 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
928
875
 
929
- 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]
930
880
 
931
- class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/]
932
-
933
- unless class_obj then
934
- @options.warn 'Enclosing class or module %p is not known' % [const_name]
935
- return
936
- end
881
+ return
882
+ end
883
+ else
884
+ enclosure = @top_level
885
+ end
937
886
 
938
- comment = find_const_comment type, const_name, class_name
939
- 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
940
893
 
941
- # In the case of rb_define_const, the definition and comment are in
942
- # "/* definition: comment */" form. The literal ':' and '\' characters
943
- # can be escaped with a backslash.
944
- if type.downcase == 'const' then
945
- if /\A(.+?)?:(?!\S)/ =~ comment.text
946
- new_definition, new_comment = $1, $'
894
+ if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)%
895
+ parent_name = $1
896
+ end
947
897
 
948
- if !new_definition # Default to literal C definition
949
- new_definition = definition
898
+ cm = enclosure.add_class NormalClass, class_name, parent_name
950
899
  else
951
- new_definition = new_definition.gsub(/\\([\\:])/, '\1')
900
+ cm = enclosure.add_module NormalModule, class_name
952
901
  end
953
902
 
954
- new_definition.sub!(/\A(\s+)/, '')
903
+ cm.record_location enclosure.top_level
904
+ enclosure.top_level.add_to_classes_or_modules cm
955
905
 
956
- new_comment = "#{$1}#{new_comment.lstrip}"
906
+ find_class_comment cm.full_name, cm
957
907
 
958
- 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
959
914
 
960
- con = RDoc::Constant.new const_name, new_definition, new_comment
961
- else
962
- 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
963
918
  end
964
- else
965
- con = RDoc::Constant.new const_name, definition, comment
966
- end
967
919
 
968
- con.record_location @top_level
969
- @stats.add_constant con
970
- class_obj.add_constant con
971
- 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 (\:).
972
929
 
973
- ##
974
- # Removes #ifdefs that would otherwise confuse us
930
+ def handle_constants(type, var_name, const_name, definition)
931
+ class_name = @known_classes[var_name]
975
932
 
976
- def handle_ifdefs_in(body)
977
- body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
978
- end
933
+ return unless class_name
979
934
 
980
- ##
981
- # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
982
- # to +var_name+. +type+ is the type of method definition function used.
983
- # +singleton_method+ and +module_function+ create a singleton method.
935
+ class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/]
984
936
 
985
- def handle_method(type, var_name, meth_name, function, param_count,
986
- source_file = nil)
987
- class_name = @known_classes[var_name]
988
- 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
989
941
 
990
- @methods[var_name][function] << meth_name
942
+ comment = find_const_comment type, const_name, class_name
943
+ comment.normalize
991
944
 
992
- 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, $'
993
951
 
994
- 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
995
957
 
996
- if existing_method = class_obj.method_list.find { |m| m.c_function == function }
997
- add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
998
- end
958
+ new_definition.sub!(/\A(\s+)/, '')
999
959
 
1000
- if class_obj then
1001
- if meth_name == 'initialize' then
1002
- meth_name = 'new'
1003
- singleton = true
1004
- type = 'method' # force public
1005
- end
960
+ new_comment = "#{$1}#{new_comment.lstrip}"
1006
961
 
1007
- singleton = singleton || %w[singleton_method module_function].include?(type)
1008
- meth_obj = RDoc::AnyMethod.new '', meth_name, singleton: singleton
1009
- meth_obj.c_function = function
962
+ new_comment = self.new_comment(new_comment, @top_level, :c)
1010
963
 
1011
- p_count = Integer(param_count) rescue -1
1012
-
1013
- if source_file then
1014
- file_name = File.join @file_dir, source_file
1015
-
1016
- if File.exist? file_name then
1017
- file_content = File.read file_name
964
+ con = Constant.new const_name, new_definition, new_comment
965
+ else
966
+ con = Constant.new const_name, definition, comment
967
+ end
1018
968
  else
1019
- @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
969
+ con = Constant.new const_name, definition, comment
1020
970
  end
1021
- else
1022
- 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')
1023
982
  end
1024
983
 
1025
- 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)
1026
993
 
1027
- if body and meth_obj.document_self then
1028
- meth_obj.params = if p_count < -1 then # -2 is Array
1029
- '(*args)'
1030
- elsif p_count == -1 then # argc, argv
1031
- rb_scan_args body
1032
- else
1033
- args = (1..p_count).map { |i| "p#{i}" }
1034
- "(#{args.join ', '})"
1035
- end
994
+ @methods[var_name][function] << meth_name
1036
995
 
996
+ return unless class_name
1037
997
 
1038
- meth_obj.record_location @top_level
998
+ class_obj = find_class var_name, class_name
1039
999
 
1040
- if meth_obj.section_title
1041
- 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)
1042
1002
  end
1043
- class_obj.add_method meth_obj
1044
1003
 
1045
- @stats.add_method meth_obj
1046
- 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
1047
1051
  end
1048
- end
1049
- end
1050
1052
 
1051
- ##
1052
- # 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+
1053
1055
 
1054
- def handle_singleton(sclass_var, class_var)
1055
- if (klass = @classes[class_var])
1056
- @classes[sclass_var] = klass
1057
- end
1058
- if (class_name = @known_classes[class_var])
1059
- @known_classes[sclass_var] = class_name
1060
- @singleton_classes[sclass_var] = class_name
1061
- end
1062
- 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
1063
1065
 
1064
- ##
1065
- # Loads the variable map with the given +name+ from the RDoc::Store, if
1066
- # present.
1066
+ ##
1067
+ # Loads the variable map with the given +name+ from the RDoc::Store, if
1068
+ # present.
1067
1069
 
1068
- def load_variable_map(map_name)
1069
- return {} unless files = @store.cache[map_name]
1070
- 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]
1071
1073
 
1072
- class_map = {}
1074
+ class_map = {}
1073
1075
 
1074
- name_map.each do |variable, name|
1075
- 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)
1076
1078
 
1077
- class_map[variable] = if map_name == :c_class_variables then
1078
- mod
1079
- else
1080
- name
1081
- end
1082
- @known_classes[variable] = name
1083
- 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
1084
1086
 
1085
- class_map
1086
- end
1087
+ class_map
1088
+ end
1087
1089
 
1088
- ##
1089
- # Look for directives in a normal comment block:
1090
- #
1091
- # /*
1092
- # * :title: My Awesome Project
1093
- # */
1094
- #
1095
- # This method modifies the +comment+
1096
- # Both :main: and :title: directives are deprecated and will be removed in RDoc 7.
1097
-
1098
- def look_for_directives_in(context, comment)
1099
- comment.text, format = @preprocess.run_pre_processes(comment.text, context, comment.line || 1, :c)
1100
- comment.format = format if format
1101
- @preprocess.run_post_processes(comment, context)
1102
- comment.normalized = true
1103
- comment
1104
- 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
1105
1106
 
1106
- ##
1107
- # Extracts parameters from the +method_body+ and returns a method
1108
- # 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
1109
1110
 
1110
- def rb_scan_args(method_body)
1111
- method_body =~ /rb_scan_args\((.*?)\)/m
1112
- return '(*args)' unless $1
1111
+ def rb_scan_args(method_body)
1112
+ method_body =~ /rb_scan_args\((.*?)\)/m
1113
+ return '(*args)' unless $1
1113
1114
 
1114
- $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
1115
- format = $1.split(//)
1115
+ $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
1116
+ format = $1.split(//)
1116
1117
 
1117
- lead = opt = trail = 0
1118
+ lead = opt = trail = 0
1118
1119
 
1119
- if format.first =~ /\d/ then
1120
- lead = $&.to_i
1121
- format.shift
1122
- if format.first =~ /\d/ then
1123
- opt = $&.to_i
1124
- format.shift
1125
- if format.first =~ /\d/ then
1126
- trail = $&.to_i
1120
+ if format.first =~ /\d/
1121
+ lead = $&.to_i
1127
1122
  format.shift
1128
- 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
1129
1132
  end
1130
- end
1131
- end
1132
1133
 
1133
- if format.first == '*' and not block_arg then
1134
- var = true
1135
- format.shift
1136
- if format.first =~ /\d/ then
1137
- trail = $&.to_i
1138
- format.shift
1139
- end
1140
- 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
1141
1142
 
1142
- if format.first == ':' then
1143
- hash = true
1144
- format.shift
1145
- end
1143
+ if format.first == ':'
1144
+ hash = true
1145
+ format.shift
1146
+ end
1146
1147
 
1147
- if format.first == '&' then
1148
- block = true
1149
- format.shift
1150
- end
1148
+ if format.first == '&'
1149
+ block = true
1150
+ format.shift
1151
+ end
1151
1152
 
1152
- # 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
1153
1154
 
1154
- args = []
1155
- position = 1
1155
+ args = []
1156
+ position = 1
1156
1157
 
1157
- (1...(position + lead)).each do |index|
1158
- args << "p#{index}"
1159
- end
1158
+ (1...(position + lead)).each do |index|
1159
+ args << "p#{index}"
1160
+ end
1160
1161
 
1161
- position += lead
1162
+ position += lead
1162
1163
 
1163
- (position...(position + opt)).each do |index|
1164
- args << "p#{index} = v#{index}"
1165
- end
1164
+ (position...(position + opt)).each do |index|
1165
+ args << "p#{index} = v#{index}"
1166
+ end
1166
1167
 
1167
- position += opt
1168
+ position += opt
1168
1169
 
1169
- if var then
1170
- args << '*args'
1171
- position += 1
1172
- end
1170
+ if var
1171
+ args << '*args'
1172
+ position += 1
1173
+ end
1173
1174
 
1174
- (position...(position + trail)).each do |index|
1175
- args << "p#{index}"
1176
- end
1175
+ (position...(position + trail)).each do |index|
1176
+ args << "p#{index}"
1177
+ end
1177
1178
 
1178
- position += trail
1179
+ position += trail
1179
1180
 
1180
- if hash then
1181
- args << "p#{position} = {}"
1182
- end
1181
+ if hash
1182
+ args << "p#{position} = {}"
1183
+ end
1183
1184
 
1184
- args << '&block' if block
1185
+ args << '&block' if block
1185
1186
 
1186
- "(#{args.join ', '})"
1187
- end
1187
+ "(#{args.join ', '})"
1188
+ end
1188
1189
 
1189
- ##
1190
- # Removes lines that are commented out that might otherwise get picked up
1191
- # 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
1192
1193
 
1193
- def remove_commented_out_lines
1194
- @content = @content.gsub(%r%//.*rb_define_%, '//')
1195
- end
1194
+ def remove_commented_out_lines
1195
+ @content = @content.gsub(%r%//.*rb_define_%, '//')
1196
+ end
1196
1197
 
1197
- ##
1198
- # Extracts the classes, modules, methods, attributes, constants and aliases
1199
- # 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
1200
1201
 
1201
- def scan
1202
- remove_commented_out_lines
1202
+ def scan
1203
+ remove_commented_out_lines
1203
1204
 
1204
- do_classes_and_modules
1205
- do_missing
1205
+ do_classes_and_modules
1206
+ do_missing
1206
1207
 
1207
- do_constants
1208
- do_methods
1209
- do_includes
1210
- do_aliases
1211
- do_attrs
1208
+ do_constants
1209
+ do_methods
1210
+ do_includes
1211
+ do_aliases
1212
+ do_attrs
1212
1213
 
1213
- @store.add_c_variables self
1214
+ @store.add_c_variables self
1214
1215
 
1215
- @top_level
1216
- end
1216
+ @top_level
1217
+ end
1217
1218
 
1218
- ##
1219
- # Creates a RDoc::Comment instance.
1219
+ ##
1220
+ # Creates a RDoc::Comment instance.
1220
1221
 
1221
- def new_comment(text = nil, location = nil, language = nil)
1222
- RDoc::Comment.new(text, location, language).tap do |comment|
1223
- 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
1224
1227
  end
1225
1228
  end
1226
1229
  end