rdoc 8.0.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -3
- data/RI.md +75 -75
- data/exe/rdoc +2 -2
- data/lib/rdoc/code_object/alias.rb +71 -69
- data/lib/rdoc/code_object/any_method.rb +305 -303
- data/lib/rdoc/code_object/attr.rb +150 -148
- data/lib/rdoc/code_object/class_module.rb +798 -792
- data/lib/rdoc/code_object/constant.rb +175 -173
- data/lib/rdoc/code_object/context/section.rb +142 -138
- data/lib/rdoc/code_object/context.rb +926 -958
- data/lib/rdoc/code_object/extend.rb +7 -5
- data/lib/rdoc/code_object/include.rb +7 -5
- data/lib/rdoc/code_object/method_attr.rb +326 -319
- data/lib/rdoc/code_object/mixin.rb +97 -95
- data/lib/rdoc/code_object/normal_class.rb +77 -78
- data/lib/rdoc/code_object/normal_module.rb +61 -59
- data/lib/rdoc/code_object/require.rb +23 -39
- data/lib/rdoc/code_object/single_class.rb +21 -19
- data/lib/rdoc/code_object/top_level.rb +212 -219
- data/lib/rdoc/code_object.rb +305 -303
- data/lib/rdoc/comment.rb +275 -273
- data/lib/rdoc/cross_reference.rb +192 -190
- data/lib/rdoc/encoding.rb +105 -103
- data/lib/rdoc/erb_partial.rb +13 -11
- data/lib/rdoc/erbio.rb +29 -27
- data/lib/rdoc/generator/aliki.rb +161 -153
- data/lib/rdoc/generator/darkfish.rb +645 -635
- data/lib/rdoc/generator/json_index.rb +233 -229
- data/lib/rdoc/generator/markup.rb +164 -146
- data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
- data/lib/rdoc/generator/pot/po.rb +52 -51
- data/lib/rdoc/generator/pot/po_entry.rb +138 -132
- data/lib/rdoc/generator/pot.rb +85 -81
- data/lib/rdoc/generator/ri.rb +23 -19
- data/lib/rdoc/generator/template/aliki/DESIGN.md +6 -4
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +10 -10
- data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +207 -178
- data/lib/rdoc/generator/template/aliki/js/aliki.js +60 -84
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
- data/lib/rdoc/generator.rb +48 -46
- data/lib/rdoc/i18n/locale.rb +99 -95
- data/lib/rdoc/i18n/text.rb +109 -105
- data/lib/rdoc/i18n.rb +7 -5
- data/lib/rdoc/markdown/byte_runtime.rb +80 -0
- data/lib/rdoc/markdown.kpeg +15 -11
- data/lib/rdoc/markdown.rb +40 -47
- data/lib/rdoc/markup/block_quote.rb +12 -8
- data/lib/rdoc/markup/document.rb +127 -123
- data/lib/rdoc/markup/formatter.rb +219 -215
- data/lib/rdoc/markup/include.rb +33 -29
- data/lib/rdoc/markup/indented_paragraph.rb +37 -33
- data/lib/rdoc/markup/inline_parser.rb +281 -277
- data/lib/rdoc/markup/list.rb +80 -88
- data/lib/rdoc/markup/list_item.rb +73 -85
- data/lib/rdoc/markup/paragraph.rb +23 -19
- data/lib/rdoc/markup/parser.rb +501 -497
- data/lib/rdoc/markup/pre_process.rb +283 -279
- data/lib/rdoc/markup/raw.rb +2 -2
- data/lib/rdoc/markup/rule.rb +16 -12
- data/lib/rdoc/markup/to_ansi.rb +143 -139
- data/lib/rdoc/markup/to_bs.rb +72 -68
- data/lib/rdoc/markup/to_html.rb +594 -565
- data/lib/rdoc/markup/to_html_crossref.rb +234 -230
- data/lib/rdoc/markup/to_html_snippet.rb +232 -227
- data/lib/rdoc/markup/to_joined_paragraph.rb +36 -32
- data/lib/rdoc/markup/to_label.rb +63 -59
- data/lib/rdoc/markup/to_markdown.rb +212 -208
- data/lib/rdoc/markup/to_rdoc.rb +336 -332
- data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
- data/lib/rdoc/markup/to_test.rb +60 -56
- data/lib/rdoc/markup/to_tt_only.rb +84 -80
- data/lib/rdoc/markup/verbatim.rb +62 -58
- data/lib/rdoc/markup.rb +198 -196
- data/lib/rdoc/options.rb +1063 -1061
- data/lib/rdoc/parser/c.rb +1039 -1037
- data/lib/rdoc/parser/changelog.rb +319 -315
- data/lib/rdoc/parser/markdown.rb +17 -13
- data/lib/rdoc/parser/rbs.rb +239 -235
- data/lib/rdoc/parser/rd.rb +17 -13
- data/lib/rdoc/parser/ruby.rb +1245 -1124
- data/lib/rdoc/parser/ruby_colorizer.rb +263 -213
- data/lib/rdoc/parser/simple.rb +31 -27
- data/lib/rdoc/parser/text.rb +12 -8
- data/lib/rdoc/parser.rb +228 -220
- data/lib/rdoc/rbs_helper.rb +1 -1
- data/lib/rdoc/rd/inline.rb +57 -53
- data/lib/rdoc/rd.rb +90 -88
- data/lib/rdoc/rdoc.rb +500 -491
- data/lib/rdoc/ri/driver.rb +1140 -1135
- data/lib/rdoc/ri/formatter.rb +7 -3
- data/lib/rdoc/ri/paths.rb +140 -136
- data/lib/rdoc/ri/servlet.rb +354 -350
- data/lib/rdoc/ri/store.rb +4 -2
- data/lib/rdoc/ri/task.rb +55 -51
- data/lib/rdoc/ri.rb +14 -12
- data/lib/rdoc/rubygems_hook.rb +183 -181
- data/lib/rdoc/server.rb +349 -347
- data/lib/rdoc/stats/normal.rb +46 -42
- data/lib/rdoc/stats/quiet.rb +39 -35
- data/lib/rdoc/stats/verbose.rb +35 -31
- data/lib/rdoc/stats.rb +365 -363
- data/lib/rdoc/store.rb +888 -902
- data/lib/rdoc/task.rb +260 -256
- data/lib/rdoc/text.rb +135 -133
- data/lib/rdoc/token_stream.rb +101 -93
- data/lib/rdoc/tom_doc.rb +203 -201
- data/lib/rdoc/version.rb +1 -1
- metadata +4 -5
- data/lib/rdoc/markdown/literals.kpeg +0 -21
- data/lib/rdoc/markdown/literals.rb +0 -454
data/lib/rdoc/parser/c.rb
CHANGED
|
@@ -1,1227 +1,1229 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require 'tsort'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
# *
|
|
20
|
-
# *
|
|
21
|
-
# *
|
|
22
|
-
# *
|
|
23
|
-
# *
|
|
24
|
-
# *
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
# method
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
# *
|
|
104
|
-
# *
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
# *
|
|
111
|
-
# *
|
|
112
|
-
# *
|
|
113
|
-
# *
|
|
114
|
-
# *
|
|
115
|
-
# *
|
|
116
|
-
# *
|
|
117
|
-
#
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
+
@classes = load_variable_map :c_class_variables
|
|
181
|
+
@singleton_classes = load_variable_map :c_singleton_class_variables
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
@markup = @options.markup
|
|
182
184
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
+
# class_variable => { function => [method, ...] }
|
|
186
|
+
@methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }
|
|
185
187
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
+
# missing variable => [handle_class_module arguments]
|
|
189
|
+
@missing_dependencies = {}
|
|
188
190
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
196
|
+
@enclosure_dependencies.extend TSort
|
|
195
197
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
+
cycle = cycle_vars.sort.map do |var_name|
|
|
204
|
+
delete var_name
|
|
203
205
|
|
|
204
|
-
|
|
206
|
+
var_name, type, mod_name, = @missing_dependencies[var_name]
|
|
205
207
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
"#{type} #{mod_name} (#{var_name})"
|
|
209
|
+
end.join ', '
|
|
208
210
|
|
|
209
|
-
|
|
211
|
+
warn "Unable to create #{cycle} due to a cyclic class or module creation"
|
|
210
212
|
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
|
|
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
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
248
|
-
|
|
248
|
+
##
|
|
249
|
+
# Add alias, either from a direct alias definition, or from two
|
|
250
|
+
# method that reference the same function.
|
|
249
251
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
283
|
+
##
|
|
284
|
+
# Scans #content for boot_defclass
|
|
283
285
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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> #
|
|
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
|
-
|
|
333
|
-
\g<
|
|
334
|
-
|
|
335
|
-
|
|
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
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
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
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
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
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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
|
-
|
|
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
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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
|
-
|
|
504
|
-
# order being different than the declaration order.
|
|
508
|
+
def do_missing
|
|
509
|
+
return if @missing_dependencies.empty?
|
|
505
510
|
|
|
506
|
-
|
|
507
|
-
|
|
511
|
+
@enclosure_dependencies.tsort.each do |in_module|
|
|
512
|
+
arguments = @missing_dependencies.delete in_module
|
|
508
513
|
|
|
509
|
-
|
|
510
|
-
arguments = @missing_dependencies.delete in_module
|
|
514
|
+
next unless arguments # dependency on existing class
|
|
511
515
|
|
|
512
|
-
|
|
516
|
+
handle_class_module(*arguments)
|
|
517
|
+
end
|
|
518
|
+
end
|
|
513
519
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
520
|
+
##
|
|
521
|
+
# Finds the comment for an alias on +class_name+ from +new_name+ to
|
|
522
|
+
# +old_name+
|
|
517
523
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
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
|
-
|
|
523
|
-
|
|
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
|
-
|
|
529
|
-
|
|
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
|
-
|
|
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
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
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
|
-
|
|
596
|
+
##
|
|
597
|
+
# Find the C code corresponding to a Ruby method
|
|
596
598
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
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
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
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
|
-
|
|
611
|
-
|
|
612
|
+
# try to find the whole body
|
|
613
|
+
body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
|
|
612
614
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
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
|
-
|
|
620
|
-
|
|
621
|
+
override_comment = find_override_comment class_name, meth_obj
|
|
622
|
+
comment = override_comment if override_comment
|
|
621
623
|
|
|
622
|
-
|
|
624
|
+
find_modifiers comment, meth_obj if comment
|
|
623
625
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
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
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
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
|
-
|
|
639
|
+
find_body class_name, args[3], meth_obj, file_content, true
|
|
638
640
|
|
|
639
|
-
|
|
641
|
+
find_modifiers comment, meth_obj
|
|
640
642
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
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
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
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
|
-
|
|
654
|
+
body = find_body(class_name, args[0], meth_obj, file_content, true)
|
|
653
655
|
|
|
654
|
-
|
|
656
|
+
return body if body
|
|
655
657
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
662
|
-
|
|
663
|
-
|
|
663
|
+
if comment
|
|
664
|
+
find_modifiers comment, meth_obj
|
|
665
|
+
meth_obj.comment = comment
|
|
664
666
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
(
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
comment = $1
|
|
733
|
-
elsif @content =~ %r%((?>/\*.*?\*/\s+))
|
|
734
|
-
([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
|
|
735
|
-
comment = $1
|
|
736
|
-
else
|
|
737
|
-
comment = ''
|
|
738
|
-
end
|
|
739
|
-
|
|
740
|
-
comment = new_comment comment, @top_level, :c
|
|
694
|
+
##
|
|
695
|
+
# Look for class or module documentation above Init_+class_name+(void),
|
|
696
|
+
# in a Document-class +class_name+ (or module) comment or above an
|
|
697
|
+
# rb_define_class (or module). If a comment is supplied above a matching
|
|
698
|
+
# Init_ and a rb_define_class the Init_ comment is used.
|
|
699
|
+
#
|
|
700
|
+
# /*
|
|
701
|
+
# * This is a comment for Foo
|
|
702
|
+
# */
|
|
703
|
+
# Init_Foo(void) {
|
|
704
|
+
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|
705
|
+
# }
|
|
706
|
+
#
|
|
707
|
+
# /*
|
|
708
|
+
# * Document-class: Foo
|
|
709
|
+
# * This is a comment for Foo
|
|
710
|
+
# */
|
|
711
|
+
# Init_foo(void) {
|
|
712
|
+
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|
713
|
+
# }
|
|
714
|
+
#
|
|
715
|
+
# /*
|
|
716
|
+
# * This is a comment for Foo
|
|
717
|
+
# */
|
|
718
|
+
# VALUE cFoo = rb_define_class("Foo", rb_cObject);
|
|
719
|
+
|
|
720
|
+
def find_class_comment(class_name, class_mod)
|
|
721
|
+
comment = nil
|
|
722
|
+
|
|
723
|
+
if @content =~ %r%
|
|
724
|
+
((?>/\*.*?\*/\s+))
|
|
725
|
+
(static\s+)?
|
|
726
|
+
void\s+
|
|
727
|
+
Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm
|
|
728
|
+
comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
|
|
729
|
+
elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
|
|
730
|
+
(?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm
|
|
731
|
+
comment = "/*\n#{$1}"
|
|
732
|
+
elsif @content =~ %r%((?>/\*.*?\*/\s+))
|
|
733
|
+
([\w\.\s]+\s* = \s+)?rb_define_(class|module)[\t (]*?"(#{class_name})"%xm
|
|
734
|
+
comment = $1
|
|
735
|
+
elsif @content =~ %r%((?>/\*.*?\*/\s+))
|
|
736
|
+
([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm
|
|
737
|
+
comment = $1
|
|
738
|
+
else
|
|
739
|
+
comment = ''
|
|
740
|
+
end
|
|
741
741
|
|
|
742
|
-
|
|
742
|
+
comment = new_comment comment, @top_level, :c
|
|
743
743
|
|
|
744
|
-
|
|
745
|
-
end
|
|
744
|
+
look_for_directives_in class_mod, comment
|
|
746
745
|
|
|
747
|
-
|
|
748
|
-
# Generate a const table
|
|
749
|
-
|
|
750
|
-
def gen_const_table(file_content)
|
|
751
|
-
table = {}
|
|
752
|
-
@content.scan(%r{
|
|
753
|
-
(?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
754
|
-
rb_define_(?<type>\w+)\(\s*(?:\w+),\s*
|
|
755
|
-
"(?<name>\w+)"\s*,
|
|
756
|
-
.*?\)\s*;
|
|
757
|
-
| (?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
758
|
-
rb_define_global_(?<type>const)\(\s*
|
|
759
|
-
"(?<name>\w+)"\s*,
|
|
760
|
-
.*?\)\s*;
|
|
761
|
-
| (?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
762
|
-
rb_file_(?<type>const)\(\s*
|
|
763
|
-
"(?<name>\w+)"\s*,
|
|
764
|
-
.*?\)\s*;
|
|
765
|
-
| (?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
766
|
-
rb_curses_define_(?<type>const)\(\s*
|
|
767
|
-
(?<name>\w+)
|
|
768
|
-
\s*\)\s*;
|
|
769
|
-
| Document-(?:const|global|variable):\s
|
|
770
|
-
(?<name>(?:\w+::)*\w+)
|
|
771
|
-
\s*?\n(?<doc>(?>.*?\*/))
|
|
772
|
-
}mxi) do
|
|
773
|
-
name, doc, type = $~.values_at(:name, :doc, :type)
|
|
774
|
-
if type
|
|
775
|
-
table[[type, name]] = doc
|
|
776
|
-
else
|
|
777
|
-
table[name] = "/*\n" + doc
|
|
746
|
+
class_mod.add_comment comment, @top_level
|
|
778
747
|
end
|
|
779
|
-
end
|
|
780
|
-
table
|
|
781
|
-
end
|
|
782
|
-
|
|
783
|
-
##
|
|
784
|
-
# Finds a comment matching +type+ and +const_name+ either above the
|
|
785
|
-
# comment or in the matching Document- section.
|
|
786
|
-
|
|
787
|
-
def find_const_comment(type, const_name, class_name = nil)
|
|
788
|
-
@const_table ||= {}
|
|
789
|
-
@const_table[@content] ||= gen_const_table @content
|
|
790
|
-
table = @const_table[@content]
|
|
791
|
-
|
|
792
|
-
comment =
|
|
793
|
-
table[[type, const_name]] ||
|
|
794
|
-
(class_name && table[class_name + "::" + const_name]) ||
|
|
795
|
-
table[const_name] ||
|
|
796
|
-
''
|
|
797
|
-
|
|
798
|
-
new_comment comment, @top_level, :c
|
|
799
|
-
end
|
|
800
|
-
|
|
801
|
-
##
|
|
802
|
-
# Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
|
|
803
748
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
749
|
+
##
|
|
750
|
+
# Generate a const table
|
|
751
|
+
|
|
752
|
+
def gen_const_table(file_content)
|
|
753
|
+
table = {}
|
|
754
|
+
@content.scan(%r{
|
|
755
|
+
(?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
756
|
+
rb_define_(?<type>\w+)\(\s*(?:\w+),\s*
|
|
757
|
+
"(?<name>\w+)"\s*,
|
|
758
|
+
.*?\)\s*;
|
|
759
|
+
| (?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
760
|
+
rb_define_global_(?<type>const)\(\s*
|
|
761
|
+
"(?<name>\w+)"\s*,
|
|
762
|
+
.*?\)\s*;
|
|
763
|
+
| (?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
764
|
+
rb_file_(?<type>const)\(\s*
|
|
765
|
+
"(?<name>\w+)"\s*,
|
|
766
|
+
.*?\)\s*;
|
|
767
|
+
| (?<doc>(?>^\s*/\*.*?\*/\s+))
|
|
768
|
+
rb_curses_define_(?<type>const)\(\s*
|
|
769
|
+
(?<name>\w+)
|
|
770
|
+
\s*\)\s*;
|
|
771
|
+
| Document-(?:const|global|variable):\s
|
|
772
|
+
(?<name>(?:\w+::)*\w+)
|
|
773
|
+
\s*?\n(?<doc>(?>.*?\*/))
|
|
774
|
+
}mxi) do
|
|
775
|
+
name, doc, type = $~.values_at(:name, :doc, :type)
|
|
776
|
+
if type
|
|
777
|
+
table[[type, name]] = doc
|
|
778
|
+
else
|
|
779
|
+
table[name] = "/*\n" + doc
|
|
780
|
+
end
|
|
781
|
+
end
|
|
782
|
+
table
|
|
783
|
+
end
|
|
814
784
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
"/*\n#{$1}"
|
|
819
|
-
elsif @content =~ %r%Document-method:
|
|
820
|
-
\s#{name}\s*?\n((?>.*?\*/))%xm then
|
|
821
|
-
"/*\n#{$1}"
|
|
822
|
-
end
|
|
785
|
+
##
|
|
786
|
+
# Finds a comment matching +type+ and +const_name+ either above the
|
|
787
|
+
# comment or in the matching Document- section.
|
|
823
788
|
|
|
824
|
-
|
|
789
|
+
def find_const_comment(type, const_name, class_name = nil)
|
|
790
|
+
@const_table ||= {}
|
|
791
|
+
@const_table[@content] ||= gen_const_table @content
|
|
792
|
+
table = @const_table[@content]
|
|
825
793
|
|
|
826
|
-
|
|
827
|
-
|
|
794
|
+
comment =
|
|
795
|
+
table[[type, const_name]] ||
|
|
796
|
+
(class_name && table[class_name + "::" + const_name]) ||
|
|
797
|
+
table[const_name] ||
|
|
798
|
+
''
|
|
828
799
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
# +read+, +write+ or both
|
|
800
|
+
new_comment comment, @top_level, :c
|
|
801
|
+
end
|
|
832
802
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
rw += 'R' if TRUE_VALUES.include?(read)
|
|
836
|
-
rw += 'W' if TRUE_VALUES.include?(write)
|
|
803
|
+
##
|
|
804
|
+
# Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.
|
|
837
805
|
|
|
838
|
-
|
|
806
|
+
def find_modifiers(comment, meth_obj)
|
|
807
|
+
look_for_directives_in meth_obj, comment
|
|
808
|
+
end
|
|
839
809
|
|
|
840
|
-
|
|
810
|
+
##
|
|
811
|
+
# Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+
|
|
841
812
|
|
|
842
|
-
|
|
813
|
+
def find_override_comment(class_name, meth_obj)
|
|
814
|
+
name = Regexp.escape meth_obj.name
|
|
815
|
+
prefix = Regexp.escape meth_obj.name_prefix
|
|
843
816
|
|
|
844
|
-
|
|
817
|
+
comment = if @content =~ %r%Document-method:
|
|
818
|
+
\s+#{class_name}#{prefix}#{name}
|
|
819
|
+
\s*?\n((?>.*?\*/))%xm
|
|
820
|
+
"/*\n#{$1}"
|
|
821
|
+
elsif @content =~ %r%Document-method:
|
|
822
|
+
\s#{name}\s*?\n((?>.*?\*/))%xm
|
|
823
|
+
"/*\n#{$1}"
|
|
824
|
+
end
|
|
845
825
|
|
|
846
|
-
|
|
847
|
-
comment.normalize
|
|
826
|
+
return unless comment
|
|
848
827
|
|
|
849
|
-
|
|
828
|
+
new_comment comment, @top_level, :c
|
|
829
|
+
end
|
|
850
830
|
|
|
851
|
-
|
|
831
|
+
##
|
|
832
|
+
# Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
|
|
833
|
+
# +read+, +write+ or both
|
|
852
834
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
835
|
+
def handle_attr(var_name, attr_name, read, write)
|
|
836
|
+
rw = ''
|
|
837
|
+
rw += 'R' if TRUE_VALUES.include?(read)
|
|
838
|
+
rw += 'W' if TRUE_VALUES.include?(write)
|
|
857
839
|
|
|
858
|
-
|
|
859
|
-
# Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
|
|
860
|
-
# named +class_name+ in +parent+ which was assigned to the C +var_name+.
|
|
840
|
+
class_name = @known_classes[var_name]
|
|
861
841
|
|
|
862
|
-
|
|
863
|
-
parent_name = @known_classes[parent] || parent
|
|
842
|
+
return unless class_name
|
|
864
843
|
|
|
865
|
-
|
|
866
|
-
enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
|
|
844
|
+
class_obj = find_class var_name, class_name
|
|
867
845
|
|
|
868
|
-
|
|
869
|
-
enc_type = /^rb_m/ =~ in_module ? :module : :class
|
|
870
|
-
handle_class_module in_module, enc_type, enclosure, nil, nil
|
|
871
|
-
enclosure = @classes[in_module]
|
|
872
|
-
end
|
|
846
|
+
return unless class_obj
|
|
873
847
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
@missing_dependencies[var_name] =
|
|
877
|
-
[var_name, type, class_name, parent, in_module]
|
|
848
|
+
comment = find_attr_comment var_name, attr_name
|
|
849
|
+
comment.normalize
|
|
878
850
|
|
|
879
|
-
|
|
880
|
-
end
|
|
881
|
-
else
|
|
882
|
-
enclosure = @top_level
|
|
883
|
-
end
|
|
851
|
+
name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1')
|
|
884
852
|
|
|
885
|
-
|
|
886
|
-
full_name = if RDoc::ClassModule === enclosure then
|
|
887
|
-
enclosure.full_name + "::#{class_name}"
|
|
888
|
-
else
|
|
889
|
-
class_name
|
|
890
|
-
end
|
|
853
|
+
attr = Attr.new name, rw, comment
|
|
891
854
|
|
|
892
|
-
|
|
893
|
-
|
|
855
|
+
attr.record_location @top_level
|
|
856
|
+
class_obj.add_attribute attr
|
|
857
|
+
@stats.add_attribute attr
|
|
894
858
|
end
|
|
895
859
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
end
|
|
860
|
+
##
|
|
861
|
+
# Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
|
|
862
|
+
# named +class_name+ in +parent+ which was assigned to the C +var_name+.
|
|
900
863
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
find_class_comment cm.full_name, cm
|
|
905
|
-
|
|
906
|
-
case cm
|
|
907
|
-
when RDoc::NormalClass
|
|
908
|
-
@stats.add_class cm
|
|
909
|
-
when RDoc::NormalModule
|
|
910
|
-
@stats.add_module cm
|
|
911
|
-
end
|
|
912
|
-
|
|
913
|
-
@classes[var_name] = cm
|
|
914
|
-
@known_classes[var_name] = cm.full_name
|
|
915
|
-
@store.add_c_enclosure var_name, cm
|
|
916
|
-
end
|
|
864
|
+
def handle_class_module(var_name, type, class_name, parent, in_module)
|
|
865
|
+
parent_name = @known_classes[parent] || parent
|
|
917
866
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
# can override the C value of the comment to give a friendly definition.
|
|
921
|
-
#
|
|
922
|
-
# /* 300: The perfect score in bowling */
|
|
923
|
-
# rb_define_const(cFoo, "PERFECT", INT2FIX(300));
|
|
924
|
-
#
|
|
925
|
-
# Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
|
|
926
|
-
# RDoc. Values may include quotes and escaped colons (\:).
|
|
867
|
+
if in_module
|
|
868
|
+
enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)
|
|
927
869
|
|
|
928
|
-
|
|
929
|
-
|
|
870
|
+
if enclosure.nil? and enclosure = @known_classes[in_module]
|
|
871
|
+
enc_type = /^rb_m/ =~ in_module ? :module : :class
|
|
872
|
+
handle_class_module in_module, enc_type, enclosure, nil, nil
|
|
873
|
+
enclosure = @classes[in_module]
|
|
874
|
+
end
|
|
930
875
|
|
|
931
|
-
|
|
876
|
+
unless enclosure
|
|
877
|
+
@enclosure_dependencies[in_module] << var_name
|
|
878
|
+
@missing_dependencies[var_name] =
|
|
879
|
+
[var_name, type, class_name, parent, in_module]
|
|
932
880
|
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
end
|
|
881
|
+
return
|
|
882
|
+
end
|
|
883
|
+
else
|
|
884
|
+
enclosure = @top_level
|
|
885
|
+
end
|
|
939
886
|
|
|
940
|
-
|
|
941
|
-
|
|
887
|
+
if type == :class
|
|
888
|
+
full_name = if ClassModule === enclosure
|
|
889
|
+
enclosure.full_name + "::#{class_name}"
|
|
890
|
+
else
|
|
891
|
+
class_name
|
|
892
|
+
end
|
|
942
893
|
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
if type.downcase == 'const' then
|
|
947
|
-
if /\A(.+?)?:(?!\S)/ =~ comment.text
|
|
948
|
-
new_definition, new_comment = $1, $'
|
|
894
|
+
if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)%
|
|
895
|
+
parent_name = $1
|
|
896
|
+
end
|
|
949
897
|
|
|
950
|
-
|
|
951
|
-
new_definition = definition
|
|
898
|
+
cm = enclosure.add_class NormalClass, class_name, parent_name
|
|
952
899
|
else
|
|
953
|
-
|
|
900
|
+
cm = enclosure.add_module NormalModule, class_name
|
|
954
901
|
end
|
|
955
902
|
|
|
956
|
-
|
|
903
|
+
cm.record_location enclosure.top_level
|
|
904
|
+
enclosure.top_level.add_to_classes_or_modules cm
|
|
957
905
|
|
|
958
|
-
|
|
906
|
+
find_class_comment cm.full_name, cm
|
|
959
907
|
|
|
960
|
-
|
|
908
|
+
case cm
|
|
909
|
+
when NormalClass
|
|
910
|
+
@stats.add_class cm
|
|
911
|
+
when NormalModule
|
|
912
|
+
@stats.add_module cm
|
|
913
|
+
end
|
|
961
914
|
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
915
|
+
@classes[var_name] = cm
|
|
916
|
+
@known_classes[var_name] = cm.full_name
|
|
917
|
+
@store.add_c_enclosure var_name, cm
|
|
965
918
|
end
|
|
966
|
-
else
|
|
967
|
-
con = RDoc::Constant.new const_name, definition, comment
|
|
968
|
-
end
|
|
969
919
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
920
|
+
##
|
|
921
|
+
# Adds constants. By providing some_value: at the start of the comment you
|
|
922
|
+
# can override the C value of the comment to give a friendly definition.
|
|
923
|
+
#
|
|
924
|
+
# /* 300: The perfect score in bowling */
|
|
925
|
+
# rb_define_const(cFoo, "PERFECT", INT2FIX(300));
|
|
926
|
+
#
|
|
927
|
+
# Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
|
|
928
|
+
# RDoc. Values may include quotes and escaped colons (\:).
|
|
974
929
|
|
|
975
|
-
|
|
976
|
-
|
|
930
|
+
def handle_constants(type, var_name, const_name, definition)
|
|
931
|
+
class_name = @known_classes[var_name]
|
|
977
932
|
|
|
978
|
-
|
|
979
|
-
body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
|
|
980
|
-
end
|
|
933
|
+
return unless class_name
|
|
981
934
|
|
|
982
|
-
|
|
983
|
-
# Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
|
|
984
|
-
# to +var_name+. +type+ is the type of method definition function used.
|
|
985
|
-
# +singleton_method+ and +module_function+ create a singleton method.
|
|
935
|
+
class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/]
|
|
986
936
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
937
|
+
unless class_obj
|
|
938
|
+
@options.warn 'Enclosing class or module %p is not known' % [const_name]
|
|
939
|
+
return
|
|
940
|
+
end
|
|
991
941
|
|
|
992
|
-
|
|
942
|
+
comment = find_const_comment type, const_name, class_name
|
|
943
|
+
comment.normalize
|
|
993
944
|
|
|
994
|
-
|
|
945
|
+
# In the case of rb_define_const, the definition and comment are in
|
|
946
|
+
# "/* definition: comment */" form. The literal ':' and '\' characters
|
|
947
|
+
# can be escaped with a backslash.
|
|
948
|
+
if type.downcase == 'const'
|
|
949
|
+
if /\A(.+?)?:(?!\S)/ =~ comment.text
|
|
950
|
+
new_definition, new_comment = $1, $'
|
|
995
951
|
|
|
996
|
-
|
|
952
|
+
if !new_definition # Default to literal C definition
|
|
953
|
+
new_definition = definition
|
|
954
|
+
else
|
|
955
|
+
new_definition = new_definition.gsub(/\\([\\:])/, '\1')
|
|
956
|
+
end
|
|
997
957
|
|
|
998
|
-
|
|
999
|
-
add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
|
|
1000
|
-
end
|
|
958
|
+
new_definition.sub!(/\A(\s+)/, '')
|
|
1001
959
|
|
|
1002
|
-
|
|
1003
|
-
if meth_name == 'initialize' then
|
|
1004
|
-
meth_name = 'new'
|
|
1005
|
-
singleton = true
|
|
1006
|
-
type = 'method' # force public
|
|
1007
|
-
end
|
|
960
|
+
new_comment = "#{$1}#{new_comment.lstrip}"
|
|
1008
961
|
|
|
1009
|
-
|
|
1010
|
-
meth_obj = RDoc::AnyMethod.new meth_name, singleton: singleton
|
|
1011
|
-
meth_obj.c_function = function
|
|
962
|
+
new_comment = self.new_comment(new_comment, @top_level, :c)
|
|
1012
963
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
if File.exist? file_name then
|
|
1019
|
-
file_content = RDoc::Encoding.read_file file_name, @options.encoding
|
|
964
|
+
con = Constant.new const_name, new_definition, new_comment
|
|
965
|
+
else
|
|
966
|
+
con = Constant.new const_name, definition, comment
|
|
967
|
+
end
|
|
1020
968
|
else
|
|
1021
|
-
|
|
969
|
+
con = Constant.new const_name, definition, comment
|
|
1022
970
|
end
|
|
1023
|
-
|
|
1024
|
-
|
|
971
|
+
|
|
972
|
+
con.record_location @top_level
|
|
973
|
+
@stats.add_constant con
|
|
974
|
+
class_obj.add_constant con
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
##
|
|
978
|
+
# Removes #ifdefs that would otherwise confuse us
|
|
979
|
+
|
|
980
|
+
def handle_ifdefs_in(body)
|
|
981
|
+
body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
|
|
1025
982
|
end
|
|
1026
983
|
|
|
1027
|
-
|
|
984
|
+
##
|
|
985
|
+
# Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
|
|
986
|
+
# to +var_name+. +type+ is the type of method definition function used.
|
|
987
|
+
# +singleton_method+ and +module_function+ create a singleton method.
|
|
988
|
+
|
|
989
|
+
def handle_method(type, var_name, meth_name, function, param_count,
|
|
990
|
+
source_file = nil)
|
|
991
|
+
class_name = @known_classes[var_name]
|
|
992
|
+
singleton = @singleton_classes.key?(var_name) || %w[singleton_method module_function].include?(type)
|
|
1028
993
|
|
|
1029
|
-
|
|
1030
|
-
meth_obj.params = if p_count < -1 then # -2 is Array
|
|
1031
|
-
'(*args)'
|
|
1032
|
-
elsif p_count == -1 then # argc, argv
|
|
1033
|
-
rb_scan_args body
|
|
1034
|
-
else
|
|
1035
|
-
args = (1..p_count).map { |i| "p#{i}" }
|
|
1036
|
-
"(#{args.join ', '})"
|
|
1037
|
-
end
|
|
994
|
+
@methods[var_name][function] << meth_name
|
|
1038
995
|
|
|
996
|
+
return unless class_name
|
|
1039
997
|
|
|
1040
|
-
|
|
998
|
+
class_obj = find_class var_name, class_name
|
|
1041
999
|
|
|
1042
|
-
if
|
|
1043
|
-
class_obj.
|
|
1000
|
+
if existing_method = class_obj.method_list.find { |m| m.c_function == function && m.singleton == singleton }
|
|
1001
|
+
add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment, singleton: singleton)
|
|
1044
1002
|
end
|
|
1045
|
-
class_obj.add_method meth_obj
|
|
1046
1003
|
|
|
1047
|
-
|
|
1048
|
-
|
|
1004
|
+
if class_obj
|
|
1005
|
+
if meth_name == 'initialize'
|
|
1006
|
+
meth_name = 'new'
|
|
1007
|
+
singleton = true
|
|
1008
|
+
type = 'method' # force public
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
meth_obj = AnyMethod.new meth_name, singleton: singleton
|
|
1012
|
+
meth_obj.c_function = function
|
|
1013
|
+
|
|
1014
|
+
p_count = Integer(param_count) rescue -1
|
|
1015
|
+
|
|
1016
|
+
if source_file
|
|
1017
|
+
file_name = File.join @file_dir, source_file
|
|
1018
|
+
|
|
1019
|
+
if File.exist? file_name
|
|
1020
|
+
file_content = Encoding.read_file file_name, @options.encoding
|
|
1021
|
+
else
|
|
1022
|
+
@options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
|
|
1023
|
+
end
|
|
1024
|
+
else
|
|
1025
|
+
file_content = @content
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
body = find_body class_name, function, meth_obj, file_content
|
|
1029
|
+
|
|
1030
|
+
if body and meth_obj.document_self
|
|
1031
|
+
meth_obj.params = if p_count < -1 # -2 is Array
|
|
1032
|
+
'(*args)'
|
|
1033
|
+
elsif p_count == -1 # argc, argv
|
|
1034
|
+
rb_scan_args body
|
|
1035
|
+
else
|
|
1036
|
+
args = (1..p_count).map { |i| "p#{i}" }
|
|
1037
|
+
"(#{args.join ', '})"
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
meth_obj.record_location @top_level
|
|
1042
|
+
|
|
1043
|
+
if meth_obj.section_title
|
|
1044
|
+
class_obj.temporary_section = class_obj.add_section(meth_obj.section_title)
|
|
1045
|
+
end
|
|
1046
|
+
meth_obj.visibility = type == 'private_method' ? :private : :public
|
|
1047
|
+
class_obj.add_method meth_obj
|
|
1048
|
+
@stats.add_method meth_obj
|
|
1049
|
+
end
|
|
1050
|
+
end
|
|
1049
1051
|
end
|
|
1050
|
-
end
|
|
1051
|
-
end
|
|
1052
1052
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1053
|
+
##
|
|
1054
|
+
# Registers a singleton class +sclass_var+ as a singleton of +class_var+
|
|
1055
1055
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1056
|
+
def handle_singleton(sclass_var, class_var)
|
|
1057
|
+
if (klass = @classes[class_var])
|
|
1058
|
+
@classes[sclass_var] = klass
|
|
1059
|
+
end
|
|
1060
|
+
if (class_name = @known_classes[class_var])
|
|
1061
|
+
@known_classes[sclass_var] = class_name
|
|
1062
|
+
@singleton_classes[sclass_var] = class_name
|
|
1063
|
+
end
|
|
1064
|
+
end
|
|
1065
1065
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1066
|
+
##
|
|
1067
|
+
# Loads the variable map with the given +name+ from the RDoc::Store, if
|
|
1068
|
+
# present.
|
|
1069
1069
|
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1070
|
+
def load_variable_map(map_name)
|
|
1071
|
+
return {} unless files = @store.cache[map_name]
|
|
1072
|
+
return {} unless name_map = files[@file_name]
|
|
1073
1073
|
|
|
1074
|
-
|
|
1074
|
+
class_map = {}
|
|
1075
1075
|
|
|
1076
|
-
|
|
1077
|
-
|
|
1076
|
+
name_map.each do |variable, name|
|
|
1077
|
+
next unless mod = @store.find_class_or_module(name)
|
|
1078
1078
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1079
|
+
class_map[variable] = if map_name == :c_class_variables
|
|
1080
|
+
mod
|
|
1081
|
+
else
|
|
1082
|
+
name
|
|
1083
|
+
end
|
|
1084
|
+
@known_classes[variable] = name
|
|
1085
|
+
end
|
|
1086
1086
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1087
|
+
class_map
|
|
1088
|
+
end
|
|
1089
1089
|
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1090
|
+
##
|
|
1091
|
+
# Look for directives in a normal comment block:
|
|
1092
|
+
#
|
|
1093
|
+
# /*
|
|
1094
|
+
# * :nodoc:
|
|
1095
|
+
# */
|
|
1096
|
+
#
|
|
1097
|
+
# This method modifies the +comment+
|
|
1098
|
+
|
|
1099
|
+
def look_for_directives_in(context, comment)
|
|
1100
|
+
comment.text, format = @preprocess.run_pre_processes(comment.text, context, comment.line || 1, :c)
|
|
1101
|
+
comment.format = format if format
|
|
1102
|
+
@preprocess.run_post_processes(comment, context)
|
|
1103
|
+
comment.normalized = true
|
|
1104
|
+
comment
|
|
1105
|
+
end
|
|
1106
1106
|
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1107
|
+
##
|
|
1108
|
+
# Extracts parameters from the +method_body+ and returns a method
|
|
1109
|
+
# parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT
|
|
1110
1110
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1111
|
+
def rb_scan_args(method_body)
|
|
1112
|
+
method_body =~ /rb_scan_args\((.*?)\)/m
|
|
1113
|
+
return '(*args)' unless $1
|
|
1114
1114
|
|
|
1115
|
-
|
|
1116
|
-
|
|
1115
|
+
$1.split(/,/)[2] =~ /"(.*?)"/ # format argument
|
|
1116
|
+
format = $1.split(//)
|
|
1117
1117
|
|
|
1118
|
-
|
|
1118
|
+
lead = opt = trail = 0
|
|
1119
1119
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
format.shift
|
|
1123
|
-
if format.first =~ /\d/ then
|
|
1124
|
-
opt = $&.to_i
|
|
1125
|
-
format.shift
|
|
1126
|
-
if format.first =~ /\d/ then
|
|
1127
|
-
trail = $&.to_i
|
|
1120
|
+
if format.first =~ /\d/
|
|
1121
|
+
lead = $&.to_i
|
|
1128
1122
|
format.shift
|
|
1129
|
-
|
|
1123
|
+
if format.first =~ /\d/
|
|
1124
|
+
opt = $&.to_i
|
|
1125
|
+
format.shift
|
|
1126
|
+
if format.first =~ /\d/
|
|
1127
|
+
trail = $&.to_i
|
|
1128
|
+
format.shift
|
|
1129
|
+
block_arg = true
|
|
1130
|
+
end
|
|
1131
|
+
end
|
|
1130
1132
|
end
|
|
1131
|
-
end
|
|
1132
|
-
end
|
|
1133
1133
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1134
|
+
if format.first == '*' and not block_arg
|
|
1135
|
+
var = true
|
|
1136
|
+
format.shift
|
|
1137
|
+
if format.first =~ /\d/
|
|
1138
|
+
trail = $&.to_i
|
|
1139
|
+
format.shift
|
|
1140
|
+
end
|
|
1141
|
+
end
|
|
1142
1142
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1143
|
+
if format.first == ':'
|
|
1144
|
+
hash = true
|
|
1145
|
+
format.shift
|
|
1146
|
+
end
|
|
1147
1147
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1148
|
+
if format.first == '&'
|
|
1149
|
+
block = true
|
|
1150
|
+
format.shift
|
|
1151
|
+
end
|
|
1152
1152
|
|
|
1153
|
-
|
|
1153
|
+
# if the format string is not empty there's a bug in the C code, ignore it
|
|
1154
1154
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1155
|
+
args = []
|
|
1156
|
+
position = 1
|
|
1157
1157
|
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1158
|
+
(1...(position + lead)).each do |index|
|
|
1159
|
+
args << "p#{index}"
|
|
1160
|
+
end
|
|
1161
1161
|
|
|
1162
|
-
|
|
1162
|
+
position += lead
|
|
1163
1163
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1164
|
+
(position...(position + opt)).each do |index|
|
|
1165
|
+
args << "p#{index} = v#{index}"
|
|
1166
|
+
end
|
|
1167
1167
|
|
|
1168
|
-
|
|
1168
|
+
position += opt
|
|
1169
1169
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1170
|
+
if var
|
|
1171
|
+
args << '*args'
|
|
1172
|
+
position += 1
|
|
1173
|
+
end
|
|
1174
1174
|
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1175
|
+
(position...(position + trail)).each do |index|
|
|
1176
|
+
args << "p#{index}"
|
|
1177
|
+
end
|
|
1178
1178
|
|
|
1179
|
-
|
|
1179
|
+
position += trail
|
|
1180
1180
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1181
|
+
if hash
|
|
1182
|
+
args << "p#{position} = {}"
|
|
1183
|
+
end
|
|
1184
1184
|
|
|
1185
|
-
|
|
1185
|
+
args << '&block' if block
|
|
1186
1186
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1187
|
+
"(#{args.join ', '})"
|
|
1188
|
+
end
|
|
1189
1189
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1190
|
+
##
|
|
1191
|
+
# Removes lines that are commented out that might otherwise get picked up
|
|
1192
|
+
# when scanning for classes and methods
|
|
1193
1193
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1194
|
+
def remove_commented_out_lines
|
|
1195
|
+
@content = @content.gsub(%r%//.*rb_define_%, '//')
|
|
1196
|
+
end
|
|
1197
1197
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1198
|
+
##
|
|
1199
|
+
# Extracts the classes, modules, methods, attributes, constants and aliases
|
|
1200
|
+
# from a C file and returns an RDoc::TopLevel for this file
|
|
1201
1201
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1202
|
+
def scan
|
|
1203
|
+
remove_commented_out_lines
|
|
1204
1204
|
|
|
1205
|
-
|
|
1206
|
-
|
|
1205
|
+
do_classes_and_modules
|
|
1206
|
+
do_missing
|
|
1207
1207
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1208
|
+
do_constants
|
|
1209
|
+
do_methods
|
|
1210
|
+
do_includes
|
|
1211
|
+
do_aliases
|
|
1212
|
+
do_attrs
|
|
1213
1213
|
|
|
1214
|
-
|
|
1214
|
+
@store.add_c_variables self
|
|
1215
1215
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1216
|
+
@top_level
|
|
1217
|
+
end
|
|
1218
1218
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1219
|
+
##
|
|
1220
|
+
# Creates a RDoc::Comment instance.
|
|
1221
1221
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1222
|
+
def new_comment(text = nil, location = nil, language = nil)
|
|
1223
|
+
Comment.new(text, location, language).tap do |comment|
|
|
1224
|
+
comment.format = @markup
|
|
1225
|
+
end
|
|
1226
|
+
end
|
|
1225
1227
|
end
|
|
1226
1228
|
end
|
|
1227
1229
|
end
|