rdoc 3.1 → 6.3.3

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

Potentially problematic release.


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

Files changed (247) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTING.rdoc +220 -0
  3. data/CVE-2013-0256.rdoc +49 -0
  4. data/ExampleMarkdown.md +37 -0
  5. data/ExampleRDoc.rdoc +208 -0
  6. data/Gemfile +12 -0
  7. data/History.rdoc +1666 -0
  8. data/LEGAL.rdoc +50 -0
  9. data/LICENSE.rdoc +57 -0
  10. data/README.rdoc +129 -0
  11. data/RI.rdoc +57 -0
  12. data/Rakefile +84 -81
  13. data/TODO.rdoc +59 -0
  14. data/bin/console +7 -0
  15. data/bin/setup +6 -0
  16. data/{bin → exe}/rdoc +11 -2
  17. data/exe/ri +12 -0
  18. data/lib/rdoc/alias.rb +1 -2
  19. data/lib/rdoc/anon_class.rb +3 -2
  20. data/lib/rdoc/any_method.rb +234 -40
  21. data/lib/rdoc/attr.rb +79 -11
  22. data/lib/rdoc/class_module.rb +443 -71
  23. data/lib/rdoc/code_object.rb +216 -20
  24. data/lib/rdoc/code_objects.rb +4 -21
  25. data/lib/rdoc/comment.rb +250 -0
  26. data/lib/rdoc/constant.rb +110 -9
  27. data/lib/rdoc/context/section.rb +232 -0
  28. data/lib/rdoc/context.rb +392 -172
  29. data/lib/rdoc/cross_reference.rb +202 -0
  30. data/lib/rdoc/encoding.rb +83 -28
  31. data/lib/rdoc/erb_partial.rb +19 -0
  32. data/lib/rdoc/erbio.rb +8 -3
  33. data/lib/rdoc/extend.rb +10 -0
  34. data/lib/rdoc/generator/darkfish.rb +507 -84
  35. data/lib/rdoc/generator/json_index.rb +300 -0
  36. data/lib/rdoc/generator/markup.rb +27 -74
  37. data/lib/rdoc/generator/pot/message_extractor.rb +68 -0
  38. data/lib/rdoc/generator/pot/po.rb +84 -0
  39. data/lib/rdoc/generator/pot/po_entry.rb +141 -0
  40. data/lib/rdoc/generator/pot.rb +98 -0
  41. data/lib/rdoc/generator/ri.rb +8 -62
  42. data/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
  43. data/lib/rdoc/generator/template/darkfish/_head.rhtml +22 -0
  44. data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +19 -0
  45. data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +9 -0
  46. data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +15 -0
  47. data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +9 -0
  48. data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +15 -0
  49. data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +15 -0
  50. data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +12 -0
  51. data/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
  52. data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +12 -0
  53. data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +11 -0
  54. data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +14 -0
  55. data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
  56. data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +18 -0
  57. data/lib/rdoc/generator/template/darkfish/class.rhtml +172 -0
  58. data/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
  59. data/lib/rdoc/generator/template/darkfish/css/rdoc.css +639 -0
  60. data/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
  61. data/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
  62. data/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
  63. data/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
  64. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
  65. data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
  66. data/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
  67. data/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
  68. data/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
  69. data/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
  70. data/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
  71. data/lib/rdoc/generator/template/darkfish/index.rhtml +18 -60
  72. data/lib/rdoc/generator/template/darkfish/js/darkfish.js +51 -83
  73. data/lib/rdoc/generator/template/darkfish/js/search.js +110 -0
  74. data/lib/rdoc/generator/template/darkfish/page.rhtml +18 -0
  75. data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +18 -0
  76. data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +62 -0
  77. data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +58 -0
  78. data/lib/rdoc/generator/template/json_index/.document +1 -0
  79. data/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
  80. data/lib/rdoc/generator/template/json_index/js/searcher.js +229 -0
  81. data/lib/rdoc/generator.rb +24 -13
  82. data/lib/rdoc/ghost_method.rb +1 -2
  83. data/lib/rdoc/i18n/locale.rb +102 -0
  84. data/lib/rdoc/i18n/text.rb +126 -0
  85. data/lib/rdoc/i18n.rb +10 -0
  86. data/lib/rdoc/include.rb +5 -95
  87. data/lib/rdoc/known_classes.rb +5 -2
  88. data/lib/rdoc/markdown/entities.rb +2132 -0
  89. data/lib/rdoc/markdown/literals.kpeg +23 -0
  90. data/lib/rdoc/markdown/literals.rb +416 -0
  91. data/lib/rdoc/markdown.kpeg +1237 -0
  92. data/lib/rdoc/markdown.rb +16684 -0
  93. data/lib/rdoc/markup/attr_changer.rb +23 -0
  94. data/lib/rdoc/markup/attr_span.rb +36 -0
  95. data/lib/rdoc/markup/attribute_manager.rb +135 -62
  96. data/lib/rdoc/markup/attributes.rb +71 -0
  97. data/lib/rdoc/markup/blank_line.rb +1 -0
  98. data/lib/rdoc/markup/block_quote.rb +15 -0
  99. data/lib/rdoc/markup/document.rb +96 -9
  100. data/lib/rdoc/markup/formatter.rb +138 -25
  101. data/lib/rdoc/markup/hard_break.rb +32 -0
  102. data/lib/rdoc/markup/heading.rb +61 -2
  103. data/lib/rdoc/markup/include.rb +43 -0
  104. data/lib/rdoc/markup/indented_paragraph.rb +48 -0
  105. data/lib/rdoc/markup/list.rb +25 -4
  106. data/lib/rdoc/markup/list_item.rb +18 -4
  107. data/lib/rdoc/markup/paragraph.rb +15 -0
  108. data/lib/rdoc/markup/parser.rb +180 -88
  109. data/lib/rdoc/markup/pre_process.rb +183 -38
  110. data/lib/rdoc/markup/raw.rb +6 -5
  111. data/lib/rdoc/markup/regexp_handling.rb +41 -0
  112. data/lib/rdoc/markup/rule.rb +1 -0
  113. data/lib/rdoc/markup/table.rb +47 -0
  114. data/lib/rdoc/markup/to_ansi.rb +17 -7
  115. data/lib/rdoc/markup/to_bs.rb +5 -8
  116. data/lib/rdoc/markup/to_html.rb +238 -137
  117. data/lib/rdoc/markup/to_html_crossref.rb +125 -152
  118. data/lib/rdoc/markup/to_html_snippet.rb +285 -0
  119. data/lib/rdoc/markup/to_joined_paragraph.rb +47 -0
  120. data/lib/rdoc/markup/to_label.rb +75 -0
  121. data/lib/rdoc/markup/to_markdown.rb +192 -0
  122. data/lib/rdoc/markup/to_rdoc.rb +85 -15
  123. data/lib/rdoc/markup/to_table_of_contents.rb +89 -0
  124. data/lib/rdoc/markup/to_test.rb +2 -4
  125. data/lib/rdoc/markup/to_tt_only.rb +121 -0
  126. data/lib/rdoc/markup/verbatim.rb +39 -0
  127. data/lib/rdoc/markup.rb +388 -110
  128. data/lib/rdoc/meta_method.rb +1 -2
  129. data/lib/rdoc/method_attr.rb +87 -21
  130. data/lib/rdoc/mixin.rb +121 -0
  131. data/lib/rdoc/normal_class.rb +39 -10
  132. data/lib/rdoc/normal_module.rb +22 -7
  133. data/lib/rdoc/options.rb +613 -73
  134. data/lib/rdoc/parser/c.rb +621 -287
  135. data/lib/rdoc/parser/changelog.rb +335 -0
  136. data/lib/rdoc/parser/markdown.rb +24 -0
  137. data/lib/rdoc/parser/rd.rb +23 -0
  138. data/lib/rdoc/parser/ripper_state_lex.rb +590 -0
  139. data/lib/rdoc/parser/ruby.rb +1368 -762
  140. data/lib/rdoc/parser/ruby_tools.rb +42 -35
  141. data/lib/rdoc/parser/simple.rb +23 -11
  142. data/lib/rdoc/parser/text.rb +12 -0
  143. data/lib/rdoc/parser.rb +162 -89
  144. data/lib/rdoc/rd/block_parser.rb +1056 -0
  145. data/lib/rdoc/rd/block_parser.ry +639 -0
  146. data/lib/rdoc/rd/inline.rb +72 -0
  147. data/lib/rdoc/rd/inline_parser.rb +1208 -0
  148. data/lib/rdoc/rd/inline_parser.ry +593 -0
  149. data/lib/rdoc/rd.rb +100 -0
  150. data/lib/rdoc/rdoc.rb +208 -115
  151. data/lib/rdoc/require.rb +1 -2
  152. data/lib/rdoc/ri/driver.rb +734 -239
  153. data/lib/rdoc/ri/formatter.rb +1 -0
  154. data/lib/rdoc/ri/paths.rb +91 -48
  155. data/lib/rdoc/ri/store.rb +3 -261
  156. data/lib/rdoc/ri/task.rb +71 -0
  157. data/lib/rdoc/ri.rb +5 -2
  158. data/lib/rdoc/rubygems_hook.rb +246 -0
  159. data/lib/rdoc/servlet.rb +451 -0
  160. data/lib/rdoc/single_class.rb +14 -2
  161. data/lib/rdoc/stats/normal.rb +19 -12
  162. data/lib/rdoc/stats/quiet.rb +1 -0
  163. data/lib/rdoc/stats/verbose.rb +1 -0
  164. data/lib/rdoc/stats.rb +262 -104
  165. data/lib/rdoc/store.rb +979 -0
  166. data/lib/rdoc/task.rb +84 -44
  167. data/lib/rdoc/text.rb +117 -72
  168. data/lib/rdoc/token_stream.rb +73 -4
  169. data/lib/rdoc/tom_doc.rb +263 -0
  170. data/lib/rdoc/top_level.rb +111 -261
  171. data/lib/rdoc/version.rb +8 -0
  172. data/lib/rdoc.rb +127 -64
  173. data/man/ri.1 +247 -0
  174. data/rdoc.gemspec +249 -0
  175. metadata +171 -291
  176. data/.autotest +0 -16
  177. data/.document +0 -5
  178. data/History.txt +0 -594
  179. data/LICENSE.txt +0 -57
  180. data/Manifest.txt +0 -158
  181. data/README.txt +0 -45
  182. data/RI.txt +0 -58
  183. data/bin/ri +0 -5
  184. data/lib/rdoc/gauntlet.rb +0 -52
  185. data/lib/rdoc/generator/template/darkfish/classpage.rhtml +0 -296
  186. data/lib/rdoc/generator/template/darkfish/filepage.rhtml +0 -124
  187. data/lib/rdoc/generator/template/darkfish/js/jquery.js +0 -32
  188. data/lib/rdoc/generator/template/darkfish/js/quicksearch.js +0 -114
  189. data/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js +0 -10
  190. data/lib/rdoc/generator/template/darkfish/rdoc.css +0 -706
  191. data/lib/rdoc/markup/formatter_test_case.rb +0 -689
  192. data/lib/rdoc/markup/inline.rb +0 -137
  193. data/lib/rdoc/markup/text_formatter_test_case.rb +0 -116
  194. data/lib/rdoc/ruby_lex.rb +0 -1291
  195. data/lib/rdoc/ruby_token.rb +0 -416
  196. data/test/README +0 -1
  197. data/test/binary.dat +0 -0
  198. data/test/hidden.zip.txt +0 -1
  199. data/test/test.ja.rdoc +0 -10
  200. data/test/test.ja.txt +0 -8
  201. data/test/test.txt +0 -1
  202. data/test/test_attribute_manager.rb +0 -120
  203. data/test/test_rdoc_alias.rb +0 -13
  204. data/test/test_rdoc_any_method.rb +0 -126
  205. data/test/test_rdoc_attr.rb +0 -61
  206. data/test/test_rdoc_class_module.rb +0 -233
  207. data/test/test_rdoc_code_object.rb +0 -165
  208. data/test/test_rdoc_constant.rb +0 -15
  209. data/test/test_rdoc_context.rb +0 -370
  210. data/test/test_rdoc_encoding.rb +0 -166
  211. data/test/test_rdoc_generator_darkfish.rb +0 -119
  212. data/test/test_rdoc_generator_ri.rb +0 -76
  213. data/test/test_rdoc_include.rb +0 -96
  214. data/test/test_rdoc_markup.rb +0 -37
  215. data/test/test_rdoc_markup_attribute_manager.rb +0 -240
  216. data/test/test_rdoc_markup_document.rb +0 -51
  217. data/test/test_rdoc_markup_paragraph.rb +0 -9
  218. data/test/test_rdoc_markup_parser.rb +0 -1395
  219. data/test/test_rdoc_markup_pre_process.rb +0 -185
  220. data/test/test_rdoc_markup_raw.rb +0 -27
  221. data/test/test_rdoc_markup_to_ansi.rb +0 -328
  222. data/test/test_rdoc_markup_to_bs.rb +0 -341
  223. data/test/test_rdoc_markup_to_html.rb +0 -335
  224. data/test/test_rdoc_markup_to_html_crossref.rb +0 -169
  225. data/test/test_rdoc_markup_to_rdoc.rb +0 -327
  226. data/test/test_rdoc_method_attr.rb +0 -122
  227. data/test/test_rdoc_normal_class.rb +0 -17
  228. data/test/test_rdoc_normal_module.rb +0 -31
  229. data/test/test_rdoc_options.rb +0 -342
  230. data/test/test_rdoc_parser.rb +0 -83
  231. data/test/test_rdoc_parser_c.rb +0 -912
  232. data/test/test_rdoc_parser_ruby.rb +0 -1754
  233. data/test/test_rdoc_parser_simple.rb +0 -99
  234. data/test/test_rdoc_rdoc.rb +0 -164
  235. data/test/test_rdoc_require.rb +0 -25
  236. data/test/test_rdoc_ri_driver.rb +0 -846
  237. data/test/test_rdoc_ri_paths.rb +0 -43
  238. data/test/test_rdoc_ri_store.rb +0 -352
  239. data/test/test_rdoc_ruby_lex.rb +0 -23
  240. data/test/test_rdoc_stats.rb +0 -38
  241. data/test/test_rdoc_task.rb +0 -92
  242. data/test/test_rdoc_text.rb +0 -251
  243. data/test/test_rdoc_top_level.rb +0 -120
  244. data/test/xref_data.rb +0 -62
  245. data/test/xref_test_case.rb +0 -61
  246. data.tar.gz.sig +0 -3
  247. metadata.gz.sig +0 -0
data/lib/rdoc/parser/c.rb CHANGED
@@ -1,18 +1,17 @@
1
- require 'rdoc/parser'
2
- require 'rdoc/parser/ruby'
3
- require 'rdoc/known_classes'
1
+ # frozen_string_literal: true
2
+ require 'tsort'
4
3
 
5
4
  ##
6
5
  # RDoc::Parser::C attempts to parse C extension files. It looks for
7
- # the standard patterns that you find in extensions: <tt>rb_define_class,
8
- # rb_define_method</tt> and so on. It tries to find the corresponding
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
9
8
  # C source for the methods and extract comments, but if we fail
10
9
  # we don't worry too much.
11
10
  #
12
11
  # The comments associated with a Ruby method are extracted from the C
13
12
  # comment block associated with the routine that _implements_ that
14
13
  # method, that is to say the method whose name is given in the
15
- # <tt>rb_define_method</tt> call. For example, you might write:
14
+ # +rb_define_method+ call. For example, you might write:
16
15
  #
17
16
  # /*
18
17
  # * Returns a new array that is a one-dimensional flattening of this
@@ -25,8 +24,7 @@ require 'rdoc/known_classes'
25
24
  # * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
26
25
  # */
27
26
  # static VALUE
28
- # rb_ary_flatten(ary)
29
- # VALUE ary;
27
+ # rb_ary_flatten(VALUE ary)
30
28
  # {
31
29
  # ary = rb_obj_dup(ary);
32
30
  # rb_ary_flatten_bang(ary);
@@ -36,16 +34,16 @@ require 'rdoc/known_classes'
36
34
  # ...
37
35
  #
38
36
  # void
39
- # Init_Array()
37
+ # Init_Array(void)
40
38
  # {
41
39
  # ...
42
40
  # rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
43
41
  #
44
- # Here RDoc will determine from the rb_define_method line that there's a
42
+ # Here RDoc will determine from the +rb_define_method+ line that there's a
45
43
  # 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
44
+ # in the method +rb_ary_flatten+. It will then use the comment from that
47
45
  # method in the HTML output. This method must be in the same source file
48
- # as the rb_define_method.
46
+ # as the +rb_define_method+.
49
47
  #
50
48
  # The comment blocks may include special directives:
51
49
  #
@@ -58,20 +56,36 @@ require 'rdoc/known_classes'
58
56
  # [Document-const: +name+]
59
57
  # Documentation for the named +rb_define_const+.
60
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
+ #
61
66
  # [Document-global: +name+]
62
67
  # Documentation for the named +rb_define_global_const+
63
68
  #
64
69
  # [Document-variable: +name+]
65
70
  # Documentation for the named +rb_define_variable+
66
71
  #
67
- # [Document-method: +name+]
68
- # Documentation for the named method.
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.
69
83
  #
70
84
  # [Document-attr: +name+]
71
85
  # Documentation for the named attribute.
72
86
  #
73
87
  # [call-seq: <i>text up to an empty line</i>]
74
- # Because C source doesn't give descripive names to Ruby-level parameters,
88
+ # Because C source doesn't give descriptive names to Ruby-level parameters,
75
89
  # you need to document the calling sequence explicitly
76
90
  #
77
91
  # In addition, RDoc assumes by default that the C method implementing a
@@ -108,33 +122,91 @@ class RDoc::Parser::C < RDoc::Parser
108
122
 
109
123
  include RDoc::Text
110
124
 
125
+ ##
126
+ # Maps C variable names to names of Ruby classes or modules
127
+
128
+ attr_reader :classes
129
+
111
130
  ##
112
131
  # C file the parser is parsing
113
132
 
114
133
  attr_accessor :content
115
134
 
116
135
  ##
117
- # Resets cross-file state. Call when parsing different projects that need
118
- # separate documentation.
136
+ # Dependencies from a missing enclosing class to the classes in
137
+ # missing_dependencies that depend upon it.
119
138
 
120
- def self.reset
121
- @@enclosure_classes = {}
122
- @@known_bodies = {}
123
- end
139
+ attr_reader :enclosure_dependencies
140
+
141
+ ##
142
+ # Maps C variable names to names of Ruby classes (and singleton classes)
143
+
144
+ attr_reader :known_classes
124
145
 
125
- reset
146
+ ##
147
+ # Classes found while parsing the C file that were not yet registered due to
148
+ # a missing enclosing class. These are processed by do_missing
149
+
150
+ attr_reader :missing_dependencies
151
+
152
+ ##
153
+ # Maps C variable names to names of Ruby singleton classes
154
+
155
+ attr_reader :singleton_classes
156
+
157
+ ##
158
+ # The TopLevel items in the parsed file belong to
159
+
160
+ attr_reader :top_level
126
161
 
127
162
  ##
128
- # Prepare to parse a C file
163
+ # Prepares for parsing a C file. See RDoc::Parser#initialize for details on
164
+ # the arguments.
129
165
 
130
- def initialize(top_level, file_name, content, options, stats)
166
+ def initialize top_level, file_name, content, options, stats
131
167
  super
132
168
 
133
169
  @known_classes = RDoc::KNOWN_CLASSES.dup
134
- @content = handle_tab_width handle_ifdefs_in(@content)
135
- @classes = Hash.new
136
- @singleton_classes = Hash.new
137
- @file_dir = File.dirname(@file_name)
170
+ @content = handle_tab_width handle_ifdefs_in @content
171
+ @file_dir = File.dirname @file_name
172
+
173
+ @classes = load_variable_map :c_class_variables
174
+ @singleton_classes = load_variable_map :c_singleton_class_variables
175
+
176
+ # class_variable => { function => [method, ...] }
177
+ @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }
178
+
179
+ # missing variable => [handle_class_module arguments]
180
+ @missing_dependencies = {}
181
+
182
+ # missing enclosure variable => [dependent handle_class_module arguments]
183
+ @enclosure_dependencies = Hash.new { |h, k| h[k] = [] }
184
+ @enclosure_dependencies.instance_variable_set :@missing_dependencies,
185
+ @missing_dependencies
186
+
187
+ @enclosure_dependencies.extend TSort
188
+
189
+ def @enclosure_dependencies.tsort_each_node &block
190
+ each_key(&block)
191
+ rescue TSort::Cyclic => e
192
+ cycle_vars = e.message.scan(/"(.*?)"/).flatten
193
+
194
+ cycle = cycle_vars.sort.map do |var_name|
195
+ delete var_name
196
+
197
+ var_name, type, mod_name, = @missing_dependencies[var_name]
198
+
199
+ "#{type} #{mod_name} (#{var_name})"
200
+ end.join ', '
201
+
202
+ warn "Unable to create #{cycle} due to a cyclic class or module creation"
203
+
204
+ retry
205
+ end
206
+
207
+ def @enclosure_dependencies.tsort_each_child node, &block
208
+ fetch(node, []).each(&block)
209
+ end
138
210
  end
139
211
 
140
212
  ##
@@ -146,21 +218,38 @@ class RDoc::Parser::C < RDoc::Parser
146
218
  \s*"(.+?)",
147
219
  \s*"(.+?)"
148
220
  \s*\)/xm) do |var_name, new_name, old_name|
149
- class_name = @known_classes[var_name] || var_name
150
- class_obj = find_class var_name, class_name
221
+ class_name = @known_classes[var_name]
151
222
 
152
- al = RDoc::Alias.new '', old_name, new_name, ''
153
- al.singleton = @singleton_classes.key?(var_name)
223
+ unless class_name then
224
+ @options.warn "Enclosing class or module %p for alias %s %s is not known" % [
225
+ var_name, new_name, old_name]
226
+ next
227
+ end
154
228
 
229
+ class_obj = find_class var_name, class_name
155
230
  comment = find_alias_comment var_name, new_name, old_name
156
- comment = strip_stars comment
157
- al.comment = comment
158
-
159
- class_obj.add_alias al
160
- @stats.add_alias al
231
+ comment.normalize
232
+ if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name}
233
+ comment = existing_method.comment
234
+ end
235
+ add_alias(var_name, class_obj, old_name, new_name, comment)
161
236
  end
162
237
  end
163
238
 
239
+ ##
240
+ # Add alias, either from a direct alias definition, or from two
241
+ # method that reference the same function.
242
+
243
+ def add_alias(var_name, class_obj, old_name, new_name, comment)
244
+ al = RDoc::Alias.new '', old_name, new_name, ''
245
+ al.singleton = @singleton_classes.key? var_name
246
+ al.comment = comment
247
+ al.record_location @top_level
248
+ class_obj.add_alias al
249
+ @stats.add_alias al
250
+ al
251
+ end
252
+
164
253
  ##
165
254
  # Scans #content for rb_attr and rb_define_attr
166
255
 
@@ -185,52 +274,113 @@ class RDoc::Parser::C < RDoc::Parser
185
274
  end
186
275
 
187
276
  ##
188
- # Scans #content for rb_define_module, rb_define_class, boot_defclass,
189
- # rb_define_module_under, rb_define_class_under and rb_singleton_class
190
-
191
- def do_classes
192
- @content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
193
- |var_name, class_name|
194
- handle_class_module(var_name, "module", class_name, nil, nil)
195
- end
196
-
197
- # The '.' lets us handle SWIG-generated files
198
- @content.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
199
- \(
200
- \s*"(\w+)",
201
- \s*(\w+)\s*
202
- \)/mx) do |var_name, class_name, parent|
203
- handle_class_module(var_name, "class", class_name, parent, nil)
204
- end
277
+ # Scans #content for boot_defclass
205
278
 
279
+ def do_boot_defclass
206
280
  @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
207
281
  |var_name, class_name, parent|
208
282
  parent = nil if parent == "0"
209
- handle_class_module(var_name, "class", class_name, parent, nil)
210
- end
211
-
212
- @content.scan(/(\w+)\s* = \s*rb_define_module_under\s*
213
- \(
214
- \s*(\w+),
215
- \s*"(\w+)"
216
- \s*\)/mx) do |var_name, in_module, class_name|
217
- handle_class_module(var_name, "module", class_name, nil, in_module)
283
+ handle_class_module(var_name, :class, class_name, parent, nil)
218
284
  end
285
+ end
219
286
 
220
- @content.scan(/([\w\.]+)\s* = \s*rb_define_class_under\s*
221
- \(
222
- \s*(\w+),
223
- \s*"(\w+)",
224
- \s*([\w\*\s\(\)\.\->]+)\s* # for SWIG
225
- \s*\)/mx) do |var_name, in_module, class_name, parent|
226
- handle_class_module(var_name, "class", class_name, parent, in_module)
227
- end
287
+ ##
288
+ # Scans #content for rb_define_class, boot_defclass, rb_define_class_under
289
+ # and rb_singleton_class
290
+
291
+ def do_classes_and_modules
292
+ do_boot_defclass if @file_name == "class.c"
293
+
294
+ @content.scan(
295
+ %r(
296
+ (?<var_name>[\w\.]+)\s* =
297
+ \s*rb_(?:
298
+ define_(?:
299
+ class(?: # rb_define_class(class_name_1, parent_name_1)
300
+ \s*\(
301
+ \s*"(?<class_name_1>\w+)",
302
+ \s*(?<parent_name_1>\w+)\s*
303
+ \)
304
+ |
305
+ _under\s*\( # rb_define_class_under(class_under, class_name2, parent_name2...)
306
+ \s* (?<class_under>\w+),
307
+ \s* "(?<class_name_2>\w+)",
308
+ \s*
309
+ (?:
310
+ (?<parent_name_2>[\w\*\s\(\)\.\->]+) |
311
+ rb_path2class\("(?<path>[\w:]+)"\)
312
+ )
313
+ \s*\)
314
+ )
315
+ |
316
+ module(?: # rb_define_module(module_name_1)
317
+ \s*\(
318
+ \s*"(?<module_name_1>\w+)"\s*
319
+ \)
320
+ |
321
+ _under\s*\( # rb_define_module_under(module_under, module_name_2)
322
+ \s*(?<module_under>\w+),
323
+ \s*"(?<module_name_2>\w+)"
324
+ \s*\)
325
+ )
326
+ )
327
+ |
328
+ struct_define_without_accessor\s*\( # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...)
329
+ \s*"(?<class_name_3>\w+)",
330
+ \s*(?<parent_name_3>\w+),
331
+ \s*\w+, # Allocation function
332
+ (?:\s*"\w+",)* # Attributes
333
+ \s*NULL
334
+ \)
335
+ |
336
+ singleton_class\s*\( # rb_singleton_class(target_class_name)
337
+ \s*(?<target_class_name>\w+)
338
+ \)
339
+ )
340
+ )mx
341
+ ) do
342
+ class_name = $~[:class_name_1]
343
+ type = :class
344
+ if class_name
345
+ # rb_define_class(class_name_1, parent_name_1)
346
+ parent_name = $~[:parent_name_1]
347
+ #under = nil
348
+ else
349
+ class_name = $~[:class_name_2]
350
+ if class_name
351
+ # rb_define_class_under(class_under, class_name2, parent_name2...)
352
+ parent_name = $~[:parent_name_2] || $~[:path]
353
+ under = $~[:class_under]
354
+ else
355
+ class_name = $~[:class_name_3]
356
+ if class_name
357
+ # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...)
358
+ parent_name = $~[:parent_name_3]
359
+ #under = nil
360
+ else
361
+ type = :module
362
+ class_name = $~[:module_name_1]
363
+ #parent_name = nil
364
+ if class_name
365
+ # rb_define_module(module_name_1)
366
+ #under = nil
367
+ else
368
+ class_name = $~[:module_name_2]
369
+ if class_name
370
+ # rb_define_module_under(module_under, module_name_1)
371
+ under = $~[:module_under]
372
+ else
373
+ # rb_singleton_class(target_class_name)
374
+ target_class_name = $~[:target_class_name]
375
+ handle_singleton $~[:var_name], target_class_name
376
+ next
377
+ end
378
+ end
379
+ end
380
+ end
381
+ end
228
382
 
229
- @content.scan(/([\w\.]+)\s* = \s*rb_singleton_class\s*
230
- \(
231
- \s*(\w+)
232
- \s*\)/mx) do |sclass_var, class_var|
233
- handle_singleton sclass_var, class_var
383
+ handle_class_module($~[:var_name], type, class_name, parent_name, under)
234
384
  end
235
385
  end
236
386
 
@@ -252,17 +402,46 @@ class RDoc::Parser::C < RDoc::Parser
252
402
  var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
253
403
  handle_constants type, var_name, const_name, definition
254
404
  end
405
+
406
+ @content.scan(%r%
407
+ \Wrb_curses_define_const
408
+ \s*\(
409
+ \s*
410
+ (\w+)
411
+ \s*
412
+ \)
413
+ \s*;%xm) do |consts|
414
+ const = consts.first
415
+
416
+ handle_constants 'const', 'mCurses', const, "UINT2NUM(#{const})"
417
+ end
418
+
419
+ @content.scan(%r%
420
+ \Wrb_file_const
421
+ \s*\(
422
+ \s*
423
+ "([^"]+)",
424
+ \s*
425
+ (.*?)
426
+ \s*
427
+ \)
428
+ \s*;%xm) do |name, value|
429
+ handle_constants 'const', 'rb_mFConst', name, value
430
+ end
255
431
  end
256
432
 
433
+
257
434
  ##
258
435
  # Scans #content for rb_include_module
259
436
 
260
437
  def do_includes
261
438
  @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
262
- if cls = @classes[c]
263
- m = @known_classes[m] || m
264
- cls.add_include RDoc::Include.new(m, "")
265
- end
439
+ next unless cls = @classes[c]
440
+ m = @known_classes[m] || m
441
+
442
+ comment = RDoc::Comment.new '', @top_level, :c
443
+ incl = cls.add_include RDoc::Include.new(m, comment)
444
+ incl.record_location @top_level
266
445
  end
267
446
  end
268
447
 
@@ -281,19 +460,17 @@ class RDoc::Parser::C < RDoc::Parser
281
460
  )
282
461
  \s*\(\s*([\w\.]+),
283
462
  \s*"([^"]+)",
284
- \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
463
+ \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\(|\(METHOD\))?(\w+)\)?,
285
464
  \s*(-?\w+)\s*\)
286
- (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
287
- %xm) do |type, var_name, meth_name, meth_body, param_count, source_file|
465
+ (?:;\s*/[*/]\s+in\s+(\w+?\.(?:cpp|c|y)))?
466
+ %xm) do |type, var_name, meth_name, function, param_count, source_file|
288
467
 
289
468
  # Ignore top-object and weird struct.c dynamic stuff
290
469
  next if var_name == "ruby_top_self"
291
470
  next if var_name == "nstr"
292
- next if var_name == "envtbl"
293
- next if var_name == "argf" # it'd be nice to handle this one
294
471
 
295
472
  var_name = "rb_cObject" if var_name == "rb_mKernel"
296
- handle_method(type, var_name, meth_name, meth_body, param_count,
473
+ handle_method(type, var_name, meth_name, function, param_count,
297
474
  source_file)
298
475
  end
299
476
 
@@ -302,18 +479,35 @@ class RDoc::Parser::C < RDoc::Parser
302
479
  \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
303
480
  \s*(-?\w+)\s*\)
304
481
  (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
305
- %xm) do |meth_name, meth_body, param_count, source_file|
306
- handle_method("method", "rb_mKernel", meth_name,
307
- meth_body, param_count, source_file)
482
+ %xm) do |meth_name, function, param_count, source_file|
483
+ handle_method("method", "rb_mKernel", meth_name, function, param_count,
484
+ source_file)
308
485
  end
309
486
 
310
487
  @content.scan(/define_filetest_function\s*\(
311
488
  \s*"([^"]+)",
312
489
  \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
313
- \s*(-?\w+)\s*\)/xm) do |meth_name, meth_body, param_count|
490
+ \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count|
491
+
492
+ handle_method("method", "rb_mFileTest", meth_name, function, param_count)
493
+ handle_method("singleton_method", "rb_cFile", meth_name, function,
494
+ param_count)
495
+ end
496
+ end
314
497
 
315
- handle_method("method", "rb_mFileTest", meth_name, meth_body, param_count)
316
- handle_method("singleton_method", "rb_cFile", meth_name, meth_body, param_count)
498
+ ##
499
+ # Creates classes and module that were missing were defined due to the file
500
+ # order being different than the declaration order.
501
+
502
+ def do_missing
503
+ return if @missing_dependencies.empty?
504
+
505
+ @enclosure_dependencies.tsort.each do |in_module|
506
+ arguments = @missing_dependencies.delete in_module
507
+
508
+ next unless arguments # dependency on existing class
509
+
510
+ handle_class_module(*arguments)
317
511
  end
318
512
  end
319
513
 
@@ -327,7 +521,7 @@ class RDoc::Parser::C < RDoc::Parser
327
521
  \s*"#{Regexp.escape new_name}"\s*,
328
522
  \s*"#{Regexp.escape old_name}"\s*\);%xm
329
523
 
330
- $1 || ''
524
+ RDoc::Comment.new($1 || '', @top_level, :c)
331
525
  end
332
526
 
333
527
  ##
@@ -348,42 +542,72 @@ class RDoc::Parser::C < RDoc::Parser
348
542
  /.*?/m
349
543
  end
350
544
 
351
- if @content =~ %r%((?>/\*.*?\*/\s+))
352
- rb_define_attr\((?:\s*#{var_name},)?\s*
353
- "#{attr_name}"\s*,
354
- #{rw}\)\s*;%xm then
355
- $1
356
- elsif @content =~ %r%((?>/\*.*?\*/\s+))
357
- rb_attr\(\s*#{var_name}\s*,
358
- \s*#{attr_name}\s*,
359
- #{rw},.*?\)\s*;%xm then
360
- $1
361
- elsif @content =~ %r%Document-attr:\s#{attr_name}\s*?\n
362
- ((?>.*?\*/))%xm then
363
- $1
364
- else
365
- ''
545
+ comment = if @content =~ %r%((?>/\*.*?\*/\s+))
546
+ rb_define_attr\((?:\s*#{var_name},)?\s*
547
+ "#{attr_name}"\s*,
548
+ #{rw}\)\s*;%xm then
549
+ $1
550
+ elsif @content =~ %r%((?>/\*.*?\*/\s+))
551
+ rb_attr\(\s*#{var_name}\s*,
552
+ \s*#{attr_name}\s*,
553
+ #{rw},.*?\)\s*;%xm then
554
+ $1
555
+ elsif @content =~ %r%(/\*.*?(?:\s*\*\s*)?)
556
+ Document-attr:\s#{attr_name}\s*?\n
557
+ ((?>(.|\n)*?\*/))%x then
558
+ "#{$1}\n#{$2}"
559
+ else
560
+ ''
561
+ end
562
+
563
+ RDoc::Comment.new comment, @top_level, :c
564
+ end
565
+
566
+ ##
567
+ # Generate a Ruby-method table
568
+
569
+ def gen_body_table file_content
570
+ table = {}
571
+ file_content.scan(%r{
572
+ ((?>/\*.*?\*/\s*)?)
573
+ ((?:(?:\w+)\s+)?
574
+ (?:intern\s+)?VALUE\s+(\w+)
575
+ \s*(?:\([^)]*\))(?:[^\);]|$))
576
+ | ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+))
577
+ | ^\s*\#\s*define\s+(\w+)\s+(\w+)
578
+ }xm) do
579
+ case
580
+ when $1
581
+ table[$3] = [:func_def, $1, $2, $~.offset(2)] if !table[$3] || table[$3][0] != :func_def
582
+ when $4
583
+ table[$6] = [:macro_def, $4, $5, $~.offset(5), $7] if !table[$6] || table[$6][0] == :macro_alias
584
+ when $8
585
+ table[$8] ||= [:macro_alias, $9]
586
+ end
366
587
  end
588
+ table
367
589
  end
368
590
 
369
591
  ##
370
592
  # Find the C code corresponding to a Ruby method
371
593
 
372
- def find_body(class_name, meth_name, meth_obj, body, quiet = false)
373
- case body
374
- when %r%((?>/\*.*?\*/\s*)?)
375
- ((?:(?:static|SWIGINTERN)\s+)?
376
- (?:intern\s+)?VALUE\s+#{meth_name}
377
- \s*(\([^)]*\))([^;]|$))%xm then
378
- comment = $1
379
- body_text = $2
594
+ def find_body class_name, meth_name, meth_obj, file_content, quiet = false
595
+ if file_content
596
+ @body_table ||= {}
597
+ @body_table[file_content] ||= gen_body_table file_content
598
+ type, *args = @body_table[file_content][meth_name]
599
+ end
380
600
 
381
- remove_private_comments comment if comment
601
+ case type
602
+ when :func_def
603
+ comment = RDoc::Comment.new args[0], @top_level, :c
604
+ body = args[1]
605
+ offset, = args[2]
382
606
 
383
- # see if we can find the whole body
607
+ comment.remove_private if comment
384
608
 
385
- re = Regexp.escape(body_text) + '[^(]*^\{.*?^\}'
386
- body_text = $& if /#{re}/m =~ body
609
+ # try to find the whole body
610
+ body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
387
611
 
388
612
  # The comment block may have been overridden with a 'Document-method'
389
613
  # block. This happens in the interpreter when multiple methods are
@@ -391,46 +615,61 @@ class RDoc::Parser::C < RDoc::Parser
391
615
  # distinct (for example Kernel.hash and Kernel.object_id share the same
392
616
  # implementation
393
617
 
394
- override_comment = find_override_comment class_name, meth_obj.name
618
+ override_comment = find_override_comment class_name, meth_obj
395
619
  comment = override_comment if override_comment
396
620
 
621
+ comment.normalize
397
622
  find_modifiers comment, meth_obj if comment
398
623
 
399
624
  #meth_obj.params = params
400
625
  meth_obj.start_collecting_tokens
401
- tk = RDoc::RubyToken::Token.new nil, 1, 1
402
- tk.set_text body_text
626
+ tk = { :line_no => 1, :char_no => 1, :text => body }
403
627
  meth_obj.add_token tk
404
- meth_obj.comment = strip_stars comment
405
- when %r%((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))%m
406
- comment = $1
407
- body_text = $2
408
- find_body class_name, $3, meth_obj, body, true
628
+ meth_obj.comment = comment
629
+ meth_obj.line = file_content[0, offset].count("\n") + 1
630
+
631
+ body
632
+ when :macro_def
633
+ comment = RDoc::Comment.new args[0], @top_level, :c
634
+ body = args[1]
635
+ offset, = args[2]
636
+
637
+ find_body class_name, args[3], meth_obj, file_content, true
638
+
639
+ comment.normalize
409
640
  find_modifiers comment, meth_obj
410
641
 
411
642
  meth_obj.start_collecting_tokens
412
- tk = RDoc::RubyToken::Token.new nil, 1, 1
413
- tk.set_text body_text
643
+ tk = { :line_no => 1, :char_no => 1, :text => body }
414
644
  meth_obj.add_token tk
415
- meth_obj.comment = strip_stars(comment) + meth_obj.comment.to_s
416
- when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m
417
- unless find_body(class_name, $1, meth_obj, body, true)
418
- warn "No definition for #{meth_name}" if @options.verbosity > 1
419
- return false
420
- end
645
+ meth_obj.comment = comment
646
+ meth_obj.line = file_content[0, offset].count("\n") + 1
647
+
648
+ body
649
+ when :macro_alias
650
+ # with no comment we hope the aliased definition has it and use it's
651
+ # definition
652
+
653
+ body = find_body(class_name, args[0], meth_obj, file_content, true)
654
+
655
+ return body if body
656
+
657
+ @options.warn "No definition for #{meth_name}"
658
+ false
421
659
  else # No body, but might still have an override comment
422
- comment = find_override_comment class_name, meth_obj.name
660
+ comment = find_override_comment class_name, meth_obj
423
661
 
424
- if comment
662
+ if comment then
663
+ comment.normalize
425
664
  find_modifiers comment, meth_obj
426
- meth_obj.comment = strip_stars comment
665
+ meth_obj.comment = comment
666
+
667
+ ''
427
668
  else
428
- warn "No definition for #{meth_name}" if @options.verbosity > 1
429
- return false
669
+ @options.warn "No definition for #{meth_name}"
670
+ false
430
671
  end
431
672
  end
432
-
433
- true
434
673
  end
435
674
 
436
675
  ##
@@ -476,7 +715,7 @@ class RDoc::Parser::C < RDoc::Parser
476
715
  # */
477
716
  # VALUE cFoo = rb_define_class("Foo", rb_cObject);
478
717
 
479
- def find_class_comment(class_name, class_mod)
718
+ def find_class_comment class_name, class_mod
480
719
  comment = nil
481
720
 
482
721
  if @content =~ %r%
@@ -487,111 +726,94 @@ class RDoc::Parser::C < RDoc::Parser
487
726
  comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
488
727
  elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
489
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
490
732
  comment = $1
491
733
  elsif @content =~ %r%((?>/\*.*?\*/\s+))
492
- ([\w\.\s]+\s* = \s+)?rb_define_(class|module).*?"(#{class_name})"%xm then
734
+ ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
493
735
  comment = $1
736
+ else
737
+ comment = ''
494
738
  end
495
739
 
496
- return unless comment
740
+ comment = RDoc::Comment.new comment, @top_level, :c
741
+ comment.normalize
497
742
 
498
- comment = strip_stars comment
743
+ look_for_directives_in class_mod, comment
499
744
 
500
- comment = look_for_directives_in class_mod, comment
745
+ class_mod.add_comment comment, @top_level
746
+ end
501
747
 
502
- class_mod.comment = comment
748
+ ##
749
+ # Generate a const table
750
+
751
+ def gen_const_table file_content
752
+ table = {}
753
+ @content.scan(%r{
754
+ ((?>^\s*/\*.*?\*/\s+))
755
+ rb_define_(\w+)\((?:\s*(?:\w+),)?\s*
756
+ "(\w+)"\s*,
757
+ .*?\)\s*;
758
+ | Document-(?:const|global|variable):\s
759
+ ((?:\w+::)*\w+)
760
+ \s*?\n((?>.*?\*/))
761
+ }mxi) do
762
+ case
763
+ when $1 then table[[$2, $3]] = $1
764
+ when $4 then table[$4] = "/*\n" + $5
765
+ end
766
+ end
767
+ table
503
768
  end
504
769
 
505
770
  ##
506
771
  # Finds a comment matching +type+ and +const_name+ either above the
507
772
  # comment or in the matching Document- section.
508
773
 
509
- def find_const_comment(type, const_name)
510
- if @content =~ %r%((?>^\s*/\*.*?\*/\s+))
511
- rb_define_#{type}\((?:\s*(\w+),)?\s*
512
- "#{const_name}"\s*,
513
- .*?\)\s*;%xmi then
514
- $1
515
- elsif @content =~ %r%Document-(?:const|global|variable):\s#{const_name}
516
- \s*?\n((?>.*?\*/))%xm
517
- $1
518
- else
774
+ def find_const_comment(type, const_name, class_name = nil)
775
+ @const_table ||= {}
776
+ @const_table[@content] ||= gen_const_table @content
777
+ table = @const_table[@content]
778
+
779
+ comment =
780
+ table[[type, const_name]] ||
781
+ (class_name && table[class_name + "::" + const_name]) ||
782
+ table[const_name] ||
519
783
  ''
520
- end
784
+
785
+ RDoc::Comment.new comment, @top_level, :c
521
786
  end
522
787
 
523
788
  ##
524
789
  # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
525
- #
526
- # If <tt>:nodoc:</tt> is found, documentation on +meth_obj+ is suppressed.
527
- #
528
- # If <tt>:yields:</tt> is followed by an argument list it is used for the
529
- # #block_params of +meth_obj+.
530
- #
531
- # If the comment block contains a <tt>call-seq:</tt> section like:
532
- #
533
- # call-seq:
534
- # ARGF.readlines(sep=$/) -> array
535
- # ARGF.readlines(limit) -> array
536
- # ARGF.readlines(sep, limit) -> array
537
- #
538
- # ARGF.to_a(sep=$/) -> array
539
- # ARGF.to_a(limit) -> array
540
- # ARGF.to_a(sep, limit) -> array
541
- #
542
- # it is used for the parameters of +meth_obj+.
543
790
 
544
791
  def find_modifiers comment, meth_obj
545
- # we must handle situations like the above followed by an unindented first
546
- # comment. The difficulty is to make sure not to match lines starting
547
- # with ARGF at the same indent, but that are after the first description
548
- # paragraph.
549
-
550
- if comment =~ /call-seq:(.*?(?:\S|\*\/?).*?)^\s*(?:\*\/?)?\s*$/m then
551
- all_start, all_stop = $~.offset(0)
552
- seq_start, seq_stop = $~.offset(1)
553
-
554
- # we get the following lines that start with the leading word at the
555
- # same indent, even if they have blank lines before
556
- if $1 =~ /(^\s*\*?\s*\n)+^(\s*\*?\s*\w+)/m then
557
- leading = $2 # ' * ARGF' in the example above
558
- re = %r%
559
- \A(
560
- (^\s*\*?\s*\n)+
561
- (^#{Regexp.escape leading}.*?\n)+
562
- )+
563
- ^\s*\*?\s*$
564
- %xm
565
- if comment[seq_stop..-1] =~ re then
566
- all_stop = seq_stop + $~.offset(0).last
567
- seq_stop = seq_stop + $~.offset(1).last
568
- end
569
- end
792
+ comment.normalize
793
+ comment.extract_call_seq meth_obj
570
794
 
571
- seq = comment[seq_start..seq_stop]
572
- seq.gsub!(/^(\s*\*?\s*?)(\S|\n)/m, '\2')
573
- comment.slice! all_start...all_stop
574
- meth_obj.call_seq = seq
575
- elsif comment.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') then
576
- meth_obj.call_seq = $1.strip
577
- end
578
-
579
- if comment.sub!(/\s*:(nodoc|doc|yields?|args?):\s*(.*)/, '') then
580
- RDoc::Parser.process_directive meth_obj, $1, $2
581
- end
795
+ look_for_directives_in meth_obj, comment
582
796
  end
583
797
 
584
798
  ##
585
- # Finds a <tt>Document-method</tt> override for +meth_name+ in +class_name+
799
+ # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
586
800
 
587
- def find_override_comment(class_name, meth_name)
588
- name = Regexp.escape(meth_name)
801
+ def find_override_comment class_name, meth_obj
802
+ name = Regexp.escape meth_obj.name
803
+ prefix = Regexp.escape meth_obj.name_prefix
589
804
 
590
- if @content =~ %r%Document-method:\s+#{class_name}(?:\.|::|#)#{name}\s*?\n((?>.*?\*/))%m then
591
- $1
592
- elsif @content =~ %r%Document-method:\s#{name}\s*?\n((?>.*?\*/))%m then
593
- $1
594
- end
805
+ comment = if @content =~ %r%Document-method:
806
+ \s+#{class_name}#{prefix}#{name}
807
+ \s*?\n((?>.*?\*/))%xm then
808
+ "/*#{$1}"
809
+ elsif @content =~ %r%Document-method:
810
+ \s#{name}\s*?\n((?>.*?\*/))%xm then
811
+ "/*#{$1}"
812
+ end
813
+
814
+ return unless comment
815
+
816
+ RDoc::Comment.new comment, @top_level, :c
595
817
  end
596
818
 
597
819
  ##
@@ -600,8 +822,8 @@ class RDoc::Parser::C < RDoc::Parser
600
822
 
601
823
  def handle_attr(var_name, attr_name, read, write)
602
824
  rw = ''
603
- rw << 'R' if '1' == read
604
- rw << 'W' if '1' == write
825
+ rw += 'R' if '1' == read
826
+ rw += 'W' if '1' == write
605
827
 
606
828
  class_name = @known_classes[var_name]
607
829
 
@@ -612,12 +834,13 @@ class RDoc::Parser::C < RDoc::Parser
612
834
  return unless class_obj
613
835
 
614
836
  comment = find_attr_comment var_name, attr_name
615
- comment = strip_stars comment
837
+ comment.normalize
616
838
 
617
- name = attr_name.gsub(/rb_intern\("([^"]+)"\)/, '\1')
839
+ name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
618
840
 
619
841
  attr = RDoc::Attr.new '', name, rw, comment
620
842
 
843
+ attr.record_location @top_level
621
844
  class_obj.add_attribute attr
622
845
  @stats.add_attribute attr
623
846
  end
@@ -630,23 +853,26 @@ class RDoc::Parser::C < RDoc::Parser
630
853
  parent_name = @known_classes[parent] || parent
631
854
 
632
855
  if in_module then
633
- enclosure = @classes[in_module] || @@enclosure_classes[in_module]
856
+ enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
634
857
 
635
858
  if enclosure.nil? and enclosure = @known_classes[in_module] then
636
- type = /^rb_m/ =~ in_module ? "module" : "class"
637
- handle_class_module in_module, type, enclosure, nil, nil
859
+ enc_type = /^rb_m/ =~ in_module ? :module : :class
860
+ handle_class_module in_module, enc_type, enclosure, nil, nil
638
861
  enclosure = @classes[in_module]
639
862
  end
640
863
 
641
864
  unless enclosure then
642
- warn "Enclosing class/module '#{in_module}' for #{type} #{class_name} not known"
865
+ @enclosure_dependencies[in_module] << var_name
866
+ @missing_dependencies[var_name] =
867
+ [var_name, type, class_name, parent, in_module]
868
+
643
869
  return
644
870
  end
645
871
  else
646
872
  enclosure = @top_level
647
873
  end
648
874
 
649
- if type == "class" then
875
+ if type == :class then
650
876
  full_name = if RDoc::ClassModule === enclosure then
651
877
  enclosure.full_name + "::#{class_name}"
652
878
  else
@@ -658,20 +884,24 @@ class RDoc::Parser::C < RDoc::Parser
658
884
  end
659
885
 
660
886
  cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name
661
-
662
- @stats.add_class cm
663
887
  else
664
888
  cm = enclosure.add_module RDoc::NormalModule, class_name
665
- @stats.add_module cm
666
889
  end
667
890
 
668
891
  cm.record_location enclosure.top_level
669
892
 
670
893
  find_class_comment cm.full_name, cm
671
894
 
895
+ case cm
896
+ when RDoc::NormalClass
897
+ @stats.add_class cm
898
+ when RDoc::NormalModule
899
+ @stats.add_module cm
900
+ end
901
+
672
902
  @classes[var_name] = cm
673
- @@enclosure_classes[var_name] = cm
674
903
  @known_classes[var_name] = cm.full_name
904
+ @store.add_c_enclosure var_name, cm
675
905
  end
676
906
 
677
907
  ##
@@ -679,7 +909,7 @@ class RDoc::Parser::C < RDoc::Parser
679
909
  # can override the C value of the comment to give a friendly definition.
680
910
  #
681
911
  # /* 300: The perfect score in bowling */
682
- # rb_define_const(cFoo, "PERFECT", INT2FIX(300);
912
+ # rb_define_const(cFoo, "PERFECT", INT2FIX(300));
683
913
  #
684
914
  # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
685
915
  # RDoc. Values may include quotes and escaped colons (\:).
@@ -692,46 +922,42 @@ class RDoc::Parser::C < RDoc::Parser
692
922
  class_obj = find_class var_name, class_name
693
923
 
694
924
  unless class_obj then
695
- warn "Enclosing class/module #{const_name.inspect} not known"
925
+ @options.warn 'Enclosing class or module %p is not known' % [const_name]
696
926
  return
697
927
  end
698
928
 
699
- comment = find_const_comment type, const_name
700
- comment = strip_stars comment
701
- comment = normalize_comment comment
929
+ comment = find_const_comment type, const_name, class_name
930
+ comment.normalize
702
931
 
703
932
  # In the case of rb_define_const, the definition and comment are in
704
933
  # "/* definition: comment */" form. The literal ':' and '\' characters
705
934
  # can be escaped with a backslash.
706
935
  if type.downcase == 'const' then
707
- elements = comment.split ':'
708
-
709
- if elements.nil? or elements.empty? then
710
- con = RDoc::Constant.new const_name, definition, comment
711
- else
712
- new_definition = elements[0..-2].join(':')
936
+ no_match, new_definition, new_comment = comment.text.split(/(\A.*):/)
713
937
 
938
+ if no_match and no_match.empty? then
714
939
  if new_definition.empty? then # Default to literal C definition
715
940
  new_definition = definition
716
941
  else
717
- new_definition.gsub!("\:", ":")
718
- new_definition.gsub!("\\", '\\')
942
+ new_definition = new_definition.gsub("\:", ":")
943
+ new_definition = new_definition.gsub("\\", '\\')
719
944
  end
720
945
 
721
946
  new_definition.sub!(/\A(\s+)/, '')
722
947
 
723
- new_comment = if $1.nil? then
724
- elements.last.lstrip
725
- else
726
- "#{$1}#{elements.last.lstrip}"
727
- end
948
+ new_comment = "#{$1}#{new_comment.lstrip}"
949
+
950
+ new_comment = RDoc::Comment.new new_comment, @top_level, :c
728
951
 
729
952
  con = RDoc::Constant.new const_name, new_definition, new_comment
953
+ else
954
+ con = RDoc::Constant.new const_name, definition, comment
730
955
  end
731
956
  else
732
957
  con = RDoc::Constant.new const_name, definition, comment
733
958
  end
734
959
 
960
+ con.record_location @top_level
735
961
  @stats.add_constant con
736
962
  class_obj.add_constant con
737
963
  end
@@ -748,20 +974,21 @@ class RDoc::Parser::C < RDoc::Parser
748
974
  # to +var_name+. +type+ is the type of method definition function used.
749
975
  # +singleton_method+ and +module_function+ create a singleton method.
750
976
 
751
- def handle_method(type, var_name, meth_name, meth_body, param_count,
977
+ def handle_method(type, var_name, meth_name, function, param_count,
752
978
  source_file = nil)
753
- singleton = false
754
979
  class_name = @known_classes[var_name]
980
+ singleton = @singleton_classes.key? var_name
755
981
 
756
- unless class_name then
757
- class_name = @singleton_classes[var_name]
758
- singleton = true if class_name
759
- end
982
+ @methods[var_name][function] << meth_name
760
983
 
761
984
  return unless class_name
762
985
 
763
986
  class_obj = find_class var_name, class_name
764
987
 
988
+ if existing_method = class_obj.method_list.find { |m| m.c_function == function }
989
+ add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
990
+ end
991
+
765
992
  if class_obj then
766
993
  if meth_name == 'initialize' then
767
994
  meth_name = 'new'
@@ -770,33 +997,37 @@ class RDoc::Parser::C < RDoc::Parser
770
997
  end
771
998
 
772
999
  meth_obj = RDoc::AnyMethod.new '', meth_name
1000
+ meth_obj.c_function = function
773
1001
  meth_obj.singleton =
774
1002
  singleton || %w[singleton_method module_function].include?(type)
775
1003
 
776
1004
  p_count = Integer(param_count) rescue -1
777
1005
 
778
- if p_count < 0 then
779
- meth_obj.params = "(...)"
780
- elsif p_count == 0
781
- meth_obj.params = "()"
782
- else
783
- meth_obj.params = "(" + (1..p_count).map{|i| "p#{i}"}.join(", ") + ")"
784
- end
785
-
786
1006
  if source_file then
787
1007
  file_name = File.join @file_dir, source_file
788
1008
 
789
1009
  if File.exist? file_name then
790
- body = (@@known_bodies[file_name] ||= File.read(file_name))
1010
+ file_content = File.read file_name
791
1011
  else
792
- warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
1012
+ @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
793
1013
  end
794
1014
  else
795
- body = @content
1015
+ file_content = @content
796
1016
  end
797
1017
 
798
- if find_body(class_name, meth_body, meth_obj, body) and
799
- meth_obj.document_self then
1018
+ body = find_body class_name, function, meth_obj, file_content
1019
+
1020
+ if body and meth_obj.document_self then
1021
+ meth_obj.params = if p_count < -1 then # -2 is Array
1022
+ '(*args)'
1023
+ elsif p_count == -1 then # argc, argv
1024
+ rb_scan_args body
1025
+ else
1026
+ "(#{(1..p_count).map { |i| "p#{i}" }.join ', '})"
1027
+ end
1028
+
1029
+
1030
+ meth_obj.record_location @top_level
800
1031
  class_obj.add_method meth_obj
801
1032
  @stats.add_method meth_obj
802
1033
  meth_obj.visibility = :private if 'private_method' == type
@@ -810,6 +1041,7 @@ class RDoc::Parser::C < RDoc::Parser
810
1041
  def handle_singleton sclass_var, class_var
811
1042
  class_name = @known_classes[class_var]
812
1043
 
1044
+ @known_classes[sclass_var] = class_name
813
1045
  @singleton_classes[sclass_var] = class_name
814
1046
  end
815
1047
 
@@ -830,6 +1062,30 @@ class RDoc::Parser::C < RDoc::Parser
830
1062
  end
831
1063
  end
832
1064
 
1065
+ ##
1066
+ # Loads the variable map with the given +name+ from the RDoc::Store, if
1067
+ # present.
1068
+
1069
+ def load_variable_map map_name
1070
+ return {} unless files = @store.cache[map_name]
1071
+ return {} unless name_map = files[@file_name]
1072
+
1073
+ class_map = {}
1074
+
1075
+ name_map.each do |variable, name|
1076
+ next unless mod = @store.find_class_or_module(name)
1077
+
1078
+ class_map[variable] = if map_name == :c_class_variables then
1079
+ mod
1080
+ else
1081
+ name
1082
+ end
1083
+ @known_classes[variable] = name
1084
+ end
1085
+
1086
+ class_map
1087
+ end
1088
+
833
1089
  ##
834
1090
  # Look for directives in a normal comment block:
835
1091
  #
@@ -837,12 +1093,10 @@ class RDoc::Parser::C < RDoc::Parser
837
1093
  # * :title: My Awesome Project
838
1094
  # */
839
1095
  #
840
- # This routine modifies its parameter
1096
+ # This method modifies the +comment+
841
1097
 
842
- def look_for_directives_in(context, comment)
843
- preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
844
-
845
- preprocess.handle comment, context do |directive, param|
1098
+ def look_for_directives_in context, comment
1099
+ @preprocess.handle comment, context do |directive, param|
846
1100
  case directive
847
1101
  when 'main' then
848
1102
  @options.main_page = param
@@ -857,19 +1111,94 @@ class RDoc::Parser::C < RDoc::Parser
857
1111
  end
858
1112
 
859
1113
  ##
860
- # Removes lines that are commented out that might otherwise get picked up
861
- # when scanning for classes and methods
1114
+ # Extracts parameters from the +method_body+ and returns a method
1115
+ # parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT
1116
+
1117
+ def rb_scan_args method_body
1118
+ method_body =~ /rb_scan_args\((.*?)\)/m
1119
+ return '(*args)' unless $1
1120
+
1121
+ $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
1122
+ format = $1.split(//)
1123
+
1124
+ lead = opt = trail = 0
1125
+
1126
+ if format.first =~ /\d/ then
1127
+ lead = $&.to_i
1128
+ format.shift
1129
+ if format.first =~ /\d/ then
1130
+ opt = $&.to_i
1131
+ format.shift
1132
+ if format.first =~ /\d/ then
1133
+ trail = $&.to_i
1134
+ format.shift
1135
+ block_arg = true
1136
+ end
1137
+ end
1138
+ end
862
1139
 
863
- def remove_commented_out_lines
864
- @content.gsub!(%r%//.*rb_define_%, '//')
1140
+ if format.first == '*' and not block_arg then
1141
+ var = true
1142
+ format.shift
1143
+ if format.first =~ /\d/ then
1144
+ trail = $&.to_i
1145
+ format.shift
1146
+ end
1147
+ end
1148
+
1149
+ if format.first == ':' then
1150
+ hash = true
1151
+ format.shift
1152
+ end
1153
+
1154
+ if format.first == '&' then
1155
+ block = true
1156
+ format.shift
1157
+ end
1158
+
1159
+ # if the format string is not empty there's a bug in the C code, ignore it
1160
+
1161
+ args = []
1162
+ position = 1
1163
+
1164
+ (1...(position + lead)).each do |index|
1165
+ args << "p#{index}"
1166
+ end
1167
+
1168
+ position += lead
1169
+
1170
+ (position...(position + opt)).each do |index|
1171
+ args << "p#{index} = v#{index}"
1172
+ end
1173
+
1174
+ position += opt
1175
+
1176
+ if var then
1177
+ args << '*args'
1178
+ position += 1
1179
+ end
1180
+
1181
+ (position...(position + trail)).each do |index|
1182
+ args << "p#{index}"
1183
+ end
1184
+
1185
+ position += trail
1186
+
1187
+ if hash then
1188
+ args << "p#{position} = {}"
1189
+ end
1190
+
1191
+ args << '&block' if block
1192
+
1193
+ "(#{args.join ', '})"
865
1194
  end
866
1195
 
867
1196
  ##
868
- # Removes private comments from +comment+
1197
+ # Removes lines that are commented out that might otherwise get picked up
1198
+ # when scanning for classes and methods
869
1199
 
870
- def remove_private_comments(comment)
871
- comment.gsub!(/\/?\*--\n(.*?)\/?\*\+\+/m, '')
872
- comment.sub!(/\/?\*--\n.*/m, '')
1200
+ def remove_commented_out_lines
1201
+ @content = @content.gsub(%r%//.*rb_define_%, '//')
873
1202
  end
874
1203
 
875
1204
  ##
@@ -878,14 +1207,19 @@ class RDoc::Parser::C < RDoc::Parser
878
1207
 
879
1208
  def scan
880
1209
  remove_commented_out_lines
881
- do_classes
1210
+
1211
+ do_classes_and_modules
1212
+ do_missing
1213
+
882
1214
  do_constants
883
1215
  do_methods
884
1216
  do_includes
885
1217
  do_aliases
886
1218
  do_attrs
1219
+
1220
+ @store.add_c_variables self
1221
+
887
1222
  @top_level
888
1223
  end
889
1224
 
890
1225
  end
891
-