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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.rdoc +220 -0
- data/CVE-2013-0256.rdoc +49 -0
- data/ExampleMarkdown.md +37 -0
- data/ExampleRDoc.rdoc +208 -0
- data/Gemfile +12 -0
- data/History.rdoc +1666 -0
- data/LEGAL.rdoc +50 -0
- data/LICENSE.rdoc +57 -0
- data/README.rdoc +129 -0
- data/RI.rdoc +57 -0
- data/Rakefile +84 -81
- data/TODO.rdoc +59 -0
- data/bin/console +7 -0
- data/bin/setup +6 -0
- data/{bin → exe}/rdoc +11 -2
- data/exe/ri +12 -0
- data/lib/rdoc/alias.rb +1 -2
- data/lib/rdoc/anon_class.rb +3 -2
- data/lib/rdoc/any_method.rb +234 -40
- data/lib/rdoc/attr.rb +79 -11
- data/lib/rdoc/class_module.rb +443 -71
- data/lib/rdoc/code_object.rb +216 -20
- data/lib/rdoc/code_objects.rb +4 -21
- data/lib/rdoc/comment.rb +250 -0
- data/lib/rdoc/constant.rb +110 -9
- data/lib/rdoc/context/section.rb +232 -0
- data/lib/rdoc/context.rb +392 -172
- data/lib/rdoc/cross_reference.rb +202 -0
- data/lib/rdoc/encoding.rb +83 -28
- data/lib/rdoc/erb_partial.rb +19 -0
- data/lib/rdoc/erbio.rb +8 -3
- data/lib/rdoc/extend.rb +10 -0
- data/lib/rdoc/generator/darkfish.rb +507 -84
- data/lib/rdoc/generator/json_index.rb +300 -0
- data/lib/rdoc/generator/markup.rb +27 -74
- data/lib/rdoc/generator/pot/message_extractor.rb +68 -0
- data/lib/rdoc/generator/pot/po.rb +84 -0
- data/lib/rdoc/generator/pot/po_entry.rb +141 -0
- data/lib/rdoc/generator/pot.rb +98 -0
- data/lib/rdoc/generator/ri.rb +8 -62
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +5 -0
- data/lib/rdoc/generator/template/darkfish/_head.rhtml +22 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_VCS_info.rhtml +19 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml +9 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +15 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_in_files.rhtml +9 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +15 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +15 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml +12 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml +11 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +12 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml +11 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml +14 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +11 -0
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +18 -0
- data/lib/rdoc/generator/template/darkfish/class.rhtml +172 -0
- data/lib/rdoc/generator/template/darkfish/css/fonts.css +167 -0
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +639 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf +0 -0
- data/lib/rdoc/generator/template/darkfish/images/add.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/arrow_up.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/delete.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/tag_blue.png +0 -0
- data/lib/rdoc/generator/template/darkfish/images/transparent.png +0 -0
- data/lib/rdoc/generator/template/darkfish/index.rhtml +18 -60
- data/lib/rdoc/generator/template/darkfish/js/darkfish.js +51 -83
- data/lib/rdoc/generator/template/darkfish/js/search.js +110 -0
- data/lib/rdoc/generator/template/darkfish/page.rhtml +18 -0
- data/lib/rdoc/generator/template/darkfish/servlet_not_found.rhtml +18 -0
- data/lib/rdoc/generator/template/darkfish/servlet_root.rhtml +62 -0
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +58 -0
- data/lib/rdoc/generator/template/json_index/.document +1 -0
- data/lib/rdoc/generator/template/json_index/js/navigation.js +105 -0
- data/lib/rdoc/generator/template/json_index/js/searcher.js +229 -0
- data/lib/rdoc/generator.rb +24 -13
- data/lib/rdoc/ghost_method.rb +1 -2
- data/lib/rdoc/i18n/locale.rb +102 -0
- data/lib/rdoc/i18n/text.rb +126 -0
- data/lib/rdoc/i18n.rb +10 -0
- data/lib/rdoc/include.rb +5 -95
- data/lib/rdoc/known_classes.rb +5 -2
- data/lib/rdoc/markdown/entities.rb +2132 -0
- data/lib/rdoc/markdown/literals.kpeg +23 -0
- data/lib/rdoc/markdown/literals.rb +416 -0
- data/lib/rdoc/markdown.kpeg +1237 -0
- data/lib/rdoc/markdown.rb +16684 -0
- data/lib/rdoc/markup/attr_changer.rb +23 -0
- data/lib/rdoc/markup/attr_span.rb +36 -0
- data/lib/rdoc/markup/attribute_manager.rb +135 -62
- data/lib/rdoc/markup/attributes.rb +71 -0
- data/lib/rdoc/markup/blank_line.rb +1 -0
- data/lib/rdoc/markup/block_quote.rb +15 -0
- data/lib/rdoc/markup/document.rb +96 -9
- data/lib/rdoc/markup/formatter.rb +138 -25
- data/lib/rdoc/markup/hard_break.rb +32 -0
- data/lib/rdoc/markup/heading.rb +61 -2
- data/lib/rdoc/markup/include.rb +43 -0
- data/lib/rdoc/markup/indented_paragraph.rb +48 -0
- data/lib/rdoc/markup/list.rb +25 -4
- data/lib/rdoc/markup/list_item.rb +18 -4
- data/lib/rdoc/markup/paragraph.rb +15 -0
- data/lib/rdoc/markup/parser.rb +180 -88
- data/lib/rdoc/markup/pre_process.rb +183 -38
- data/lib/rdoc/markup/raw.rb +6 -5
- data/lib/rdoc/markup/regexp_handling.rb +41 -0
- data/lib/rdoc/markup/rule.rb +1 -0
- data/lib/rdoc/markup/table.rb +47 -0
- data/lib/rdoc/markup/to_ansi.rb +17 -7
- data/lib/rdoc/markup/to_bs.rb +5 -8
- data/lib/rdoc/markup/to_html.rb +238 -137
- data/lib/rdoc/markup/to_html_crossref.rb +125 -152
- data/lib/rdoc/markup/to_html_snippet.rb +285 -0
- data/lib/rdoc/markup/to_joined_paragraph.rb +47 -0
- data/lib/rdoc/markup/to_label.rb +75 -0
- data/lib/rdoc/markup/to_markdown.rb +192 -0
- data/lib/rdoc/markup/to_rdoc.rb +85 -15
- data/lib/rdoc/markup/to_table_of_contents.rb +89 -0
- data/lib/rdoc/markup/to_test.rb +2 -4
- data/lib/rdoc/markup/to_tt_only.rb +121 -0
- data/lib/rdoc/markup/verbatim.rb +39 -0
- data/lib/rdoc/markup.rb +388 -110
- data/lib/rdoc/meta_method.rb +1 -2
- data/lib/rdoc/method_attr.rb +87 -21
- data/lib/rdoc/mixin.rb +121 -0
- data/lib/rdoc/normal_class.rb +39 -10
- data/lib/rdoc/normal_module.rb +22 -7
- data/lib/rdoc/options.rb +613 -73
- data/lib/rdoc/parser/c.rb +621 -287
- data/lib/rdoc/parser/changelog.rb +335 -0
- data/lib/rdoc/parser/markdown.rb +24 -0
- data/lib/rdoc/parser/rd.rb +23 -0
- data/lib/rdoc/parser/ripper_state_lex.rb +590 -0
- data/lib/rdoc/parser/ruby.rb +1368 -762
- data/lib/rdoc/parser/ruby_tools.rb +42 -35
- data/lib/rdoc/parser/simple.rb +23 -11
- data/lib/rdoc/parser/text.rb +12 -0
- data/lib/rdoc/parser.rb +162 -89
- data/lib/rdoc/rd/block_parser.rb +1056 -0
- data/lib/rdoc/rd/block_parser.ry +639 -0
- data/lib/rdoc/rd/inline.rb +72 -0
- data/lib/rdoc/rd/inline_parser.rb +1208 -0
- data/lib/rdoc/rd/inline_parser.ry +593 -0
- data/lib/rdoc/rd.rb +100 -0
- data/lib/rdoc/rdoc.rb +208 -115
- data/lib/rdoc/require.rb +1 -2
- data/lib/rdoc/ri/driver.rb +734 -239
- data/lib/rdoc/ri/formatter.rb +1 -0
- data/lib/rdoc/ri/paths.rb +91 -48
- data/lib/rdoc/ri/store.rb +3 -261
- data/lib/rdoc/ri/task.rb +71 -0
- data/lib/rdoc/ri.rb +5 -2
- data/lib/rdoc/rubygems_hook.rb +246 -0
- data/lib/rdoc/servlet.rb +451 -0
- data/lib/rdoc/single_class.rb +14 -2
- data/lib/rdoc/stats/normal.rb +19 -12
- data/lib/rdoc/stats/quiet.rb +1 -0
- data/lib/rdoc/stats/verbose.rb +1 -0
- data/lib/rdoc/stats.rb +262 -104
- data/lib/rdoc/store.rb +979 -0
- data/lib/rdoc/task.rb +84 -44
- data/lib/rdoc/text.rb +117 -72
- data/lib/rdoc/token_stream.rb +73 -4
- data/lib/rdoc/tom_doc.rb +263 -0
- data/lib/rdoc/top_level.rb +111 -261
- data/lib/rdoc/version.rb +8 -0
- data/lib/rdoc.rb +127 -64
- data/man/ri.1 +247 -0
- data/rdoc.gemspec +249 -0
- metadata +171 -291
- data/.autotest +0 -16
- data/.document +0 -5
- data/History.txt +0 -594
- data/LICENSE.txt +0 -57
- data/Manifest.txt +0 -158
- data/README.txt +0 -45
- data/RI.txt +0 -58
- data/bin/ri +0 -5
- data/lib/rdoc/gauntlet.rb +0 -52
- data/lib/rdoc/generator/template/darkfish/classpage.rhtml +0 -296
- data/lib/rdoc/generator/template/darkfish/filepage.rhtml +0 -124
- data/lib/rdoc/generator/template/darkfish/js/jquery.js +0 -32
- data/lib/rdoc/generator/template/darkfish/js/quicksearch.js +0 -114
- data/lib/rdoc/generator/template/darkfish/js/thickbox-compressed.js +0 -10
- data/lib/rdoc/generator/template/darkfish/rdoc.css +0 -706
- data/lib/rdoc/markup/formatter_test_case.rb +0 -689
- data/lib/rdoc/markup/inline.rb +0 -137
- data/lib/rdoc/markup/text_formatter_test_case.rb +0 -116
- data/lib/rdoc/ruby_lex.rb +0 -1291
- data/lib/rdoc/ruby_token.rb +0 -416
- data/test/README +0 -1
- data/test/binary.dat +0 -0
- data/test/hidden.zip.txt +0 -1
- data/test/test.ja.rdoc +0 -10
- data/test/test.ja.txt +0 -8
- data/test/test.txt +0 -1
- data/test/test_attribute_manager.rb +0 -120
- data/test/test_rdoc_alias.rb +0 -13
- data/test/test_rdoc_any_method.rb +0 -126
- data/test/test_rdoc_attr.rb +0 -61
- data/test/test_rdoc_class_module.rb +0 -233
- data/test/test_rdoc_code_object.rb +0 -165
- data/test/test_rdoc_constant.rb +0 -15
- data/test/test_rdoc_context.rb +0 -370
- data/test/test_rdoc_encoding.rb +0 -166
- data/test/test_rdoc_generator_darkfish.rb +0 -119
- data/test/test_rdoc_generator_ri.rb +0 -76
- data/test/test_rdoc_include.rb +0 -96
- data/test/test_rdoc_markup.rb +0 -37
- data/test/test_rdoc_markup_attribute_manager.rb +0 -240
- data/test/test_rdoc_markup_document.rb +0 -51
- data/test/test_rdoc_markup_paragraph.rb +0 -9
- data/test/test_rdoc_markup_parser.rb +0 -1395
- data/test/test_rdoc_markup_pre_process.rb +0 -185
- data/test/test_rdoc_markup_raw.rb +0 -27
- data/test/test_rdoc_markup_to_ansi.rb +0 -328
- data/test/test_rdoc_markup_to_bs.rb +0 -341
- data/test/test_rdoc_markup_to_html.rb +0 -335
- data/test/test_rdoc_markup_to_html_crossref.rb +0 -169
- data/test/test_rdoc_markup_to_rdoc.rb +0 -327
- data/test/test_rdoc_method_attr.rb +0 -122
- data/test/test_rdoc_normal_class.rb +0 -17
- data/test/test_rdoc_normal_module.rb +0 -31
- data/test/test_rdoc_options.rb +0 -342
- data/test/test_rdoc_parser.rb +0 -83
- data/test/test_rdoc_parser_c.rb +0 -912
- data/test/test_rdoc_parser_ruby.rb +0 -1754
- data/test/test_rdoc_parser_simple.rb +0 -99
- data/test/test_rdoc_rdoc.rb +0 -164
- data/test/test_rdoc_require.rb +0 -25
- data/test/test_rdoc_ri_driver.rb +0 -846
- data/test/test_rdoc_ri_paths.rb +0 -43
- data/test/test_rdoc_ri_store.rb +0 -352
- data/test/test_rdoc_ruby_lex.rb +0 -23
- data/test/test_rdoc_stats.rb +0 -38
- data/test/test_rdoc_task.rb +0 -92
- data/test/test_rdoc_text.rb +0 -251
- data/test/test_rdoc_top_level.rb +0 -120
- data/test/xref_data.rb +0 -62
- data/test/xref_test_case.rb +0 -61
- data.tar.gz.sig +0 -3
- metadata.gz.sig +0 -0
data/lib/rdoc/parser/ruby.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
##
|
2
3
|
# This file contains stuff stolen outright from:
|
3
4
|
#
|
@@ -7,17 +8,6 @@
|
|
7
8
|
# by Keiju ISHITSUKA (Nippon Rational Inc.)
|
8
9
|
#
|
9
10
|
|
10
|
-
require 'rdoc/ruby_token'
|
11
|
-
require 'rdoc/ruby_lex'
|
12
|
-
|
13
|
-
require 'rdoc/code_objects'
|
14
|
-
require 'rdoc/token_stream'
|
15
|
-
require 'rdoc/markup/pre_process'
|
16
|
-
require 'rdoc/parser'
|
17
|
-
require 'rdoc/parser/ruby_tools'
|
18
|
-
|
19
|
-
$TOKEN_DEBUG ||= nil
|
20
|
-
|
21
11
|
##
|
22
12
|
# Extracts code elements from a source file returning a TopLevel object
|
23
13
|
# containing the constituent file elements.
|
@@ -32,6 +22,7 @@ $TOKEN_DEBUG ||= nil
|
|
32
22
|
# * aliases
|
33
23
|
# * private, public, protected
|
34
24
|
# * private_class_function, public_class_function
|
25
|
+
# * private_constant, public_constant
|
35
26
|
# * module_function
|
36
27
|
# * attr, attr_reader, attr_writer, attr_accessor
|
37
28
|
# * extra accessors given on the command line
|
@@ -103,7 +94,7 @@ $TOKEN_DEBUG ||= nil
|
|
103
94
|
# You can force the name of a method using the :method: directive:
|
104
95
|
#
|
105
96
|
# ##
|
106
|
-
# # :method:
|
97
|
+
# # :method: some_method!
|
107
98
|
#
|
108
99
|
# By default, meta-methods are instance methods. To indicate that a method is
|
109
100
|
# a singleton method instead use the :singleton-method: directive:
|
@@ -114,7 +105,10 @@ $TOKEN_DEBUG ||= nil
|
|
114
105
|
# You can also use the :singleton-method: directive with a name:
|
115
106
|
#
|
116
107
|
# ##
|
117
|
-
# # :singleton-method:
|
108
|
+
# # :singleton-method: some_method!
|
109
|
+
#
|
110
|
+
# You can define arguments for metaprogrammed methods via either the
|
111
|
+
# :call-seq:, :arg: or :args: directives.
|
118
112
|
#
|
119
113
|
# Additionally you can mark a method as an attribute by
|
120
114
|
# using :attr:, :attr_reader:, :attr_writer: or :attr_accessor:. Just like
|
@@ -144,11 +138,13 @@ $TOKEN_DEBUG ||= nil
|
|
144
138
|
# Note that by default, the :method: directive will be ignored if there is a
|
145
139
|
# standard rdocable item following it.
|
146
140
|
|
141
|
+
require 'ripper'
|
142
|
+
require_relative 'ripper_state_lex'
|
143
|
+
|
147
144
|
class RDoc::Parser::Ruby < RDoc::Parser
|
148
145
|
|
149
146
|
parse_files_matching(/\.rbw?$/)
|
150
147
|
|
151
|
-
include RDoc::RubyToken
|
152
148
|
include RDoc::TokenStream
|
153
149
|
include RDoc::Parser::RubyTools
|
154
150
|
|
@@ -168,40 +164,110 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
168
164
|
def initialize(top_level, file_name, content, options, stats)
|
169
165
|
super
|
170
166
|
|
167
|
+
if /\t/ =~ content then
|
168
|
+
tab_width = @options.tab_width
|
169
|
+
content = content.split(/\n/).map do |line|
|
170
|
+
1 while line.gsub!(/\t+/) {
|
171
|
+
' ' * (tab_width*$&.length - $`.length % tab_width)
|
172
|
+
} && $~
|
173
|
+
line
|
174
|
+
end.join("\n")
|
175
|
+
end
|
176
|
+
|
171
177
|
@size = 0
|
172
178
|
@token_listeners = nil
|
173
|
-
|
174
|
-
@scanner
|
179
|
+
content = RDoc::Encoding.remove_magic_comment content
|
180
|
+
@scanner = RDoc::Parser::RipperStateLex.parse(content)
|
181
|
+
@content = content
|
182
|
+
@scanner_point = 0
|
175
183
|
@prev_seek = nil
|
184
|
+
@markup = @options.markup
|
185
|
+
@track_visibility = :nodoc != @options.visibility
|
186
|
+
@encoding = @options.encoding
|
176
187
|
|
177
188
|
reset
|
178
189
|
end
|
179
190
|
|
191
|
+
def tk_nl?(tk)
|
192
|
+
:on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# Retrieves the read token stream and replaces +pattern+ with +replacement+
|
197
|
+
# using gsub. If the result is only a ";" returns an empty string.
|
198
|
+
|
199
|
+
def get_tkread_clean pattern, replacement # :nodoc:
|
200
|
+
read = get_tkread.gsub(pattern, replacement).strip
|
201
|
+
return '' if read == ';'
|
202
|
+
read
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# Extracts the visibility information for the visibility token +tk+
|
207
|
+
# and +single+ class type identifier.
|
208
|
+
#
|
209
|
+
# Returns the visibility type (a string), the visibility (a symbol) and
|
210
|
+
# +singleton+ if the methods following should be converted to singleton
|
211
|
+
# methods.
|
212
|
+
|
213
|
+
def get_visibility_information tk, single # :nodoc:
|
214
|
+
vis_type = tk[:text]
|
215
|
+
singleton = single == SINGLE
|
216
|
+
|
217
|
+
vis =
|
218
|
+
case vis_type
|
219
|
+
when 'private' then :private
|
220
|
+
when 'protected' then :protected
|
221
|
+
when 'public' then :public
|
222
|
+
when 'private_class_method' then
|
223
|
+
singleton = true
|
224
|
+
:private
|
225
|
+
when 'public_class_method' then
|
226
|
+
singleton = true
|
227
|
+
:public
|
228
|
+
when 'module_function' then
|
229
|
+
singleton = true
|
230
|
+
:public
|
231
|
+
else
|
232
|
+
raise RDoc::Error, "Invalid visibility: #{tk.name}"
|
233
|
+
end
|
234
|
+
|
235
|
+
return vis_type, vis, singleton
|
236
|
+
end
|
237
|
+
|
180
238
|
##
|
181
239
|
# Look for the first comment in a file that isn't a shebang line.
|
182
240
|
|
183
241
|
def collect_first_comment
|
184
242
|
skip_tkspace
|
185
|
-
comment = ''
|
243
|
+
comment = ''.dup
|
244
|
+
comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
|
186
245
|
first_line = true
|
246
|
+
first_comment_tk_kind = nil
|
247
|
+
line_no = nil
|
187
248
|
|
188
249
|
tk = get_tk
|
189
250
|
|
190
|
-
while
|
191
|
-
|
251
|
+
while tk && (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
|
252
|
+
comment_body = retrieve_comment_body(tk)
|
253
|
+
if first_line and comment_body =~ /\A#!/ then
|
192
254
|
skip_tkspace
|
193
255
|
tk = get_tk
|
194
|
-
elsif first_line and
|
256
|
+
elsif first_line and comment_body =~ /\A#\s*-\*-/ then
|
195
257
|
first_line = false
|
196
258
|
skip_tkspace
|
197
259
|
tk = get_tk
|
198
260
|
else
|
261
|
+
break if first_comment_tk_kind and not first_comment_tk_kind === tk[:kind]
|
262
|
+
first_comment_tk_kind = tk[:kind]
|
263
|
+
|
264
|
+
line_no = tk[:line_no] if first_line
|
199
265
|
first_line = false
|
200
|
-
comment <<
|
266
|
+
comment << comment_body
|
201
267
|
tk = get_tk
|
202
268
|
|
203
|
-
if
|
204
|
-
|
269
|
+
if :on_nl === tk then
|
270
|
+
skip_tkspace_without_nl
|
205
271
|
tk = get_tk
|
206
272
|
end
|
207
273
|
end
|
@@ -209,45 +275,61 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
209
275
|
|
210
276
|
unget_tk tk
|
211
277
|
|
212
|
-
comment
|
278
|
+
new_comment comment, line_no
|
213
279
|
end
|
214
280
|
|
215
281
|
##
|
216
|
-
#
|
282
|
+
# Consumes trailing whitespace from the token stream
|
217
283
|
|
218
|
-
def
|
219
|
-
|
284
|
+
def consume_trailing_spaces # :nodoc:
|
285
|
+
skip_tkspace_without_nl
|
286
|
+
end
|
220
287
|
|
221
|
-
|
288
|
+
##
|
289
|
+
# Creates a new attribute in +container+ with +name+.
|
290
|
+
|
291
|
+
def create_attr container, single, name, rw, comment # :nodoc:
|
292
|
+
att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE
|
293
|
+
record_location att
|
294
|
+
|
295
|
+
container.add_attribute att
|
296
|
+
@stats.add_attribute att
|
297
|
+
|
298
|
+
att
|
222
299
|
end
|
223
300
|
|
224
301
|
##
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#--
|
228
|
-
# TODO handle undent
|
302
|
+
# Creates a module alias in +container+ at +rhs_name+ (or at the top-level
|
303
|
+
# for "::") with the name from +constant+.
|
229
304
|
|
230
|
-
def
|
231
|
-
if
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
305
|
+
def create_module_alias container, constant, rhs_name # :nodoc:
|
306
|
+
mod = if rhs_name =~ /^::/ then
|
307
|
+
@store.find_class_or_module rhs_name
|
308
|
+
else
|
309
|
+
container.find_module_named rhs_name
|
310
|
+
end
|
236
311
|
|
237
|
-
|
312
|
+
container.add_module_alias mod, rhs_name, constant, @top_level
|
313
|
+
end
|
314
|
+
|
315
|
+
##
|
316
|
+
# Aborts with +msg+
|
317
|
+
|
318
|
+
def error(msg)
|
319
|
+
msg = make_message msg
|
320
|
+
|
321
|
+
abort msg
|
238
322
|
end
|
239
323
|
|
240
324
|
##
|
241
|
-
# Looks for a true or false token.
|
242
|
-
# found.
|
325
|
+
# Looks for a true or false token.
|
243
326
|
|
244
327
|
def get_bool
|
245
328
|
skip_tkspace
|
246
329
|
tk = get_tk
|
247
|
-
|
248
|
-
when TkTRUE
|
330
|
+
if :on_kw == tk[:kind] && 'true' == tk[:text]
|
249
331
|
true
|
250
|
-
|
332
|
+
elsif :on_kw == tk[:kind] && ('false' == tk[:text] || 'nil' == tk[:text])
|
251
333
|
false
|
252
334
|
else
|
253
335
|
unget_tk tk
|
@@ -260,58 +342,87 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
260
342
|
# with :: separated named) and return the ultimate name, the associated
|
261
343
|
# container, and the given name (with the ::).
|
262
344
|
|
263
|
-
def get_class_or_module
|
345
|
+
def get_class_or_module container, ignore_constants = false
|
264
346
|
skip_tkspace
|
265
347
|
name_t = get_tk
|
266
|
-
given_name = ''
|
348
|
+
given_name = ''.dup
|
267
349
|
|
268
350
|
# class ::A -> A is in the top level
|
269
|
-
|
270
|
-
when TkCOLON2, TkCOLON3 then # bug
|
351
|
+
if :on_op == name_t[:kind] and '::' == name_t[:text] then # bug
|
271
352
|
name_t = get_tk
|
272
353
|
container = @top_level
|
273
354
|
given_name << '::'
|
274
355
|
end
|
275
356
|
|
276
|
-
|
277
|
-
given_name << name_t
|
357
|
+
skip_tkspace_without_nl
|
358
|
+
given_name << name_t[:text]
|
278
359
|
|
279
|
-
|
360
|
+
is_self = name_t[:kind] == :on_op && name_t[:text] == '<<'
|
361
|
+
new_modules = []
|
362
|
+
while !is_self && (tk = peek_tk) and :on_op == tk[:kind] and '::' == tk[:text] do
|
280
363
|
prev_container = container
|
281
|
-
container = container.find_module_named name_t
|
282
|
-
|
283
|
-
|
284
|
-
|
364
|
+
container = container.find_module_named name_t[:text]
|
365
|
+
container ||=
|
366
|
+
if ignore_constants then
|
367
|
+
c = RDoc::NormalModule.new name_t[:text]
|
368
|
+
c.store = @store
|
369
|
+
new_modules << [prev_container, c]
|
370
|
+
c
|
371
|
+
else
|
372
|
+
c = prev_container.add_module RDoc::NormalModule, name_t[:text]
|
373
|
+
c.ignore unless prev_container.document_children
|
374
|
+
@top_level.add_to_classes_or_modules c
|
375
|
+
c
|
376
|
+
end
|
377
|
+
|
378
|
+
record_location container
|
379
|
+
|
285
380
|
get_tk
|
381
|
+
skip_tkspace
|
382
|
+
if :on_lparen == peek_tk[:kind] # ProcObjectInConstant::()
|
383
|
+
parse_method_or_yield_parameters
|
384
|
+
break
|
385
|
+
end
|
286
386
|
name_t = get_tk
|
287
|
-
|
387
|
+
unless :on_const == name_t[:kind] || :on_ident == name_t[:kind]
|
388
|
+
raise RDoc::Error, "Invalid class or module definition: #{given_name}"
|
389
|
+
end
|
390
|
+
if prev_container == container and !ignore_constants
|
391
|
+
given_name = name_t[:text]
|
392
|
+
else
|
393
|
+
given_name << '::' + name_t[:text]
|
394
|
+
end
|
288
395
|
end
|
289
|
-
|
290
|
-
|
396
|
+
|
397
|
+
skip_tkspace_without_nl
|
398
|
+
|
399
|
+
return [container, name_t, given_name, new_modules]
|
291
400
|
end
|
292
401
|
|
293
402
|
##
|
294
403
|
# Return a superclass, which can be either a constant of an expression
|
295
404
|
|
296
405
|
def get_class_specification
|
297
|
-
tk =
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
406
|
+
tk = peek_tk
|
407
|
+
if tk.nil?
|
408
|
+
return ''
|
409
|
+
elsif :on_kw == tk[:kind] && 'self' == tk[:text]
|
410
|
+
return 'self'
|
411
|
+
elsif :on_gvar == tk[:kind]
|
412
|
+
return ''
|
304
413
|
end
|
305
414
|
|
306
|
-
|
307
|
-
|
415
|
+
res = get_constant
|
416
|
+
|
417
|
+
skip_tkspace_without_nl
|
308
418
|
|
309
419
|
get_tkread # empty out read buffer
|
310
420
|
|
311
421
|
tk = get_tk
|
422
|
+
return res unless tk
|
312
423
|
|
313
|
-
case tk
|
314
|
-
when
|
424
|
+
case tk[:kind]
|
425
|
+
when :on_nl, :on_comment, :on_embdoc, :on_semicolon then
|
315
426
|
unget_tk(tk)
|
316
427
|
return res
|
317
428
|
end
|
@@ -326,42 +437,164 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
326
437
|
|
327
438
|
def get_constant
|
328
439
|
res = ""
|
329
|
-
|
440
|
+
skip_tkspace_without_nl
|
330
441
|
tk = get_tk
|
331
442
|
|
332
|
-
while
|
333
|
-
res += tk
|
443
|
+
while tk && ((:on_op == tk[:kind] && '::' == tk[:text]) || :on_const == tk[:kind]) do
|
444
|
+
res += tk[:text]
|
334
445
|
tk = get_tk
|
335
446
|
end
|
336
447
|
|
337
|
-
# if res.empty?
|
338
|
-
# warn("Unexpected token #{tk} in constant")
|
339
|
-
# end
|
340
448
|
unget_tk(tk)
|
341
449
|
res
|
342
450
|
end
|
343
451
|
|
344
452
|
##
|
345
|
-
# Get
|
453
|
+
# Get an included module that may be surrounded by parens
|
454
|
+
|
455
|
+
def get_included_module_with_optional_parens
|
456
|
+
skip_tkspace_without_nl
|
457
|
+
get_tkread
|
458
|
+
tk = get_tk
|
459
|
+
end_token = get_end_token tk
|
460
|
+
return '' unless end_token
|
346
461
|
|
347
|
-
def get_constant_with_optional_parens
|
348
|
-
skip_tkspace false
|
349
462
|
nest = 0
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
463
|
+
continue = false
|
464
|
+
only_constant = true
|
465
|
+
|
466
|
+
while tk != nil do
|
467
|
+
is_element_of_constant = false
|
468
|
+
case tk[:kind]
|
469
|
+
when :on_semicolon then
|
470
|
+
break if nest == 0
|
471
|
+
when :on_lbracket then
|
472
|
+
nest += 1
|
473
|
+
when :on_rbracket then
|
474
|
+
nest -= 1
|
475
|
+
when :on_lbrace then
|
476
|
+
nest += 1
|
477
|
+
when :on_rbrace then
|
478
|
+
nest -= 1
|
479
|
+
if nest <= 0
|
480
|
+
# we might have a.each { |i| yield i }
|
481
|
+
unget_tk(tk) if nest < 0
|
482
|
+
break
|
483
|
+
end
|
484
|
+
when :on_lparen then
|
485
|
+
nest += 1
|
486
|
+
when end_token[:kind] then
|
487
|
+
if end_token[:kind] == :on_rparen
|
488
|
+
nest -= 1
|
489
|
+
break if nest <= 0
|
490
|
+
else
|
491
|
+
break if nest <= 0
|
492
|
+
end
|
493
|
+
when :on_rparen then
|
494
|
+
nest -= 1
|
495
|
+
when :on_comment, :on_embdoc then
|
496
|
+
@read.pop
|
497
|
+
if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
|
498
|
+
(!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then
|
499
|
+
break if !continue and nest <= 0
|
500
|
+
end
|
501
|
+
when :on_comma then
|
502
|
+
continue = true
|
503
|
+
when :on_ident then
|
504
|
+
continue = false if continue
|
505
|
+
when :on_kw then
|
506
|
+
case tk[:text]
|
507
|
+
when 'def', 'do', 'case', 'for', 'begin', 'class', 'module'
|
508
|
+
nest += 1
|
509
|
+
when 'if', 'unless', 'while', 'until', 'rescue'
|
510
|
+
# postfix if/unless/while/until/rescue must be EXPR_LABEL
|
511
|
+
nest += 1 unless (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0
|
512
|
+
when 'end'
|
513
|
+
nest -= 1
|
514
|
+
break if nest == 0
|
515
|
+
end
|
516
|
+
when :on_const then
|
517
|
+
is_element_of_constant = true
|
518
|
+
when :on_op then
|
519
|
+
is_element_of_constant = true if '::' == tk[:text]
|
520
|
+
end
|
521
|
+
only_constant = false unless is_element_of_constant
|
522
|
+
tk = get_tk
|
354
523
|
end
|
355
524
|
|
356
|
-
|
525
|
+
if only_constant
|
526
|
+
get_tkread_clean(/\s+/, ' ')
|
527
|
+
else
|
528
|
+
''
|
529
|
+
end
|
530
|
+
end
|
357
531
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
532
|
+
##
|
533
|
+
# Little hack going on here. In the statement:
|
534
|
+
#
|
535
|
+
# f = 2*(1+yield)
|
536
|
+
#
|
537
|
+
# We see the RPAREN as the next token, so we need to exit early. This still
|
538
|
+
# won't catch all cases (such as "a = yield + 1"
|
539
|
+
|
540
|
+
def get_end_token tk # :nodoc:
|
541
|
+
case tk[:kind]
|
542
|
+
when :on_lparen
|
543
|
+
token = RDoc::Parser::RipperStateLex::Token.new
|
544
|
+
token[:kind] = :on_rparen
|
545
|
+
token[:text] = ')'
|
546
|
+
token
|
547
|
+
when :on_rparen
|
548
|
+
nil
|
549
|
+
else
|
550
|
+
token = RDoc::Parser::RipperStateLex::Token.new
|
551
|
+
token[:kind] = :on_nl
|
552
|
+
token[:text] = "\n"
|
553
|
+
token
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
##
|
558
|
+
# Retrieves the method container for a singleton method.
|
559
|
+
|
560
|
+
def get_method_container container, name_t # :nodoc:
|
561
|
+
prev_container = container
|
562
|
+
container = container.find_module_named(name_t[:text])
|
563
|
+
|
564
|
+
unless container then
|
565
|
+
constant = prev_container.constants.find do |const|
|
566
|
+
const.name == name_t[:text]
|
567
|
+
end
|
568
|
+
|
569
|
+
if constant then
|
570
|
+
parse_method_dummy prev_container
|
571
|
+
return
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
unless container then
|
576
|
+
# TODO seems broken, should starting at Object in @store
|
577
|
+
obj = name_t[:text].split("::").inject(Object) do |state, item|
|
578
|
+
state.const_get(item)
|
579
|
+
end rescue nil
|
580
|
+
|
581
|
+
type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule
|
582
|
+
|
583
|
+
unless [Class, Module].include?(obj.class) then
|
584
|
+
warn("Couldn't find #{name_t[:text]}. Assuming it's a module")
|
585
|
+
end
|
586
|
+
|
587
|
+
if type == RDoc::NormalClass then
|
588
|
+
sclass = obj.superclass ? obj.superclass.name : nil
|
589
|
+
container = prev_container.add_class type, name_t[:text], sclass
|
590
|
+
else
|
591
|
+
container = prev_container.add_module type, name_t[:text]
|
592
|
+
end
|
593
|
+
|
594
|
+
record_location container
|
362
595
|
end
|
363
596
|
|
364
|
-
|
597
|
+
container
|
365
598
|
end
|
366
599
|
|
367
600
|
##
|
@@ -369,28 +602,36 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
369
602
|
|
370
603
|
def get_symbol_or_name
|
371
604
|
tk = get_tk
|
372
|
-
case tk
|
373
|
-
when
|
374
|
-
text = tk
|
605
|
+
case tk[:kind]
|
606
|
+
when :on_symbol then
|
607
|
+
text = tk[:text].sub(/^:/, '')
|
375
608
|
|
376
|
-
|
609
|
+
next_tk = peek_tk
|
610
|
+
if next_tk && :on_op == next_tk[:kind] && '=' == next_tk[:text] then
|
377
611
|
get_tk
|
378
612
|
text << '='
|
379
613
|
end
|
380
614
|
|
381
615
|
text
|
382
|
-
when
|
383
|
-
tk
|
384
|
-
when
|
385
|
-
|
386
|
-
TkSTAR,
|
387
|
-
TkSTRING then
|
388
|
-
tk.text
|
616
|
+
when :on_ident, :on_const, :on_gvar, :on_cvar, :on_ivar, :on_op, :on_kw then
|
617
|
+
tk[:text]
|
618
|
+
when :on_tstring, :on_dstring then
|
619
|
+
tk[:text][1..-2]
|
389
620
|
else
|
390
621
|
raise RDoc::Error, "Name or symbol expected (got #{tk})"
|
391
622
|
end
|
392
623
|
end
|
393
624
|
|
625
|
+
##
|
626
|
+
# Marks containers between +container+ and +ancestor+ as ignored
|
627
|
+
|
628
|
+
def suppress_parents container, ancestor # :nodoc:
|
629
|
+
while container and container != ancestor do
|
630
|
+
container.suppress unless container.documented?
|
631
|
+
container = container.parent
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
394
635
|
##
|
395
636
|
# Look for directives in a normal comment block:
|
396
637
|
#
|
@@ -399,77 +640,69 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
399
640
|
#
|
400
641
|
# This routine modifies its +comment+ parameter.
|
401
642
|
|
402
|
-
def look_for_directives_in
|
403
|
-
preprocess
|
404
|
-
|
405
|
-
preprocess.handle comment, context do |directive, param|
|
643
|
+
def look_for_directives_in container, comment
|
644
|
+
@preprocess.handle comment, container do |directive, param|
|
406
645
|
case directive
|
407
|
-
when 'enddoc' then
|
408
|
-
context.done_documenting = true
|
409
|
-
''
|
410
|
-
when 'main' then
|
411
|
-
@options.main_page = param if @options.respond_to? :main_page
|
412
|
-
''
|
413
646
|
when 'method', 'singleton-method',
|
414
647
|
'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then
|
415
648
|
false # handled elsewhere
|
416
649
|
when 'section' then
|
417
|
-
|
418
|
-
comment.
|
650
|
+
break unless container.kind_of?(RDoc::Context)
|
651
|
+
container.set_current_section param, comment.dup
|
652
|
+
comment.text = ''
|
419
653
|
break
|
420
|
-
when 'startdoc' then
|
421
|
-
context.start_doc
|
422
|
-
context.force_documentation = true
|
423
|
-
''
|
424
|
-
when 'stopdoc' then
|
425
|
-
context.stop_doc
|
426
|
-
''
|
427
|
-
when 'title' then
|
428
|
-
@options.default_title = param if @options.respond_to? :default_title=
|
429
|
-
''
|
430
654
|
end
|
431
655
|
end
|
432
656
|
|
433
|
-
|
657
|
+
comment.remove_private
|
434
658
|
end
|
435
659
|
|
436
660
|
##
|
437
661
|
# Adds useful info about the parser to +message+
|
438
662
|
|
439
663
|
def make_message message
|
440
|
-
prefix = "#{@file_name}:"
|
664
|
+
prefix = "#{@file_name}:".dup
|
441
665
|
|
442
|
-
|
666
|
+
tk = peek_tk
|
667
|
+
prefix << "#{tk[:line_no]}:#{tk[:char_no]}:" if tk
|
443
668
|
|
444
669
|
"#{prefix} #{message}"
|
445
670
|
end
|
446
671
|
|
672
|
+
##
|
673
|
+
# Creates a comment with the correct format
|
674
|
+
|
675
|
+
def new_comment comment, line_no = nil
|
676
|
+
c = RDoc::Comment.new comment, @top_level, :ruby
|
677
|
+
c.line = line_no
|
678
|
+
c.format = @markup
|
679
|
+
c
|
680
|
+
end
|
681
|
+
|
447
682
|
##
|
448
683
|
# Creates an RDoc::Attr for the name following +tk+, setting the comment to
|
449
684
|
# +comment+.
|
450
685
|
|
451
686
|
def parse_attr(context, single, tk, comment)
|
687
|
+
line_no = tk[:line_no]
|
688
|
+
|
452
689
|
args = parse_symbol_arg 1
|
453
690
|
if args.size > 0 then
|
454
691
|
name = args[0]
|
455
692
|
rw = "R"
|
456
|
-
|
693
|
+
skip_tkspace_without_nl
|
457
694
|
tk = get_tk
|
458
695
|
|
459
|
-
if
|
696
|
+
if :on_comma == tk[:kind] then
|
460
697
|
rw = "RW" if get_bool
|
461
698
|
else
|
462
699
|
unget_tk tk
|
463
700
|
end
|
464
701
|
|
465
|
-
att =
|
466
|
-
att.
|
702
|
+
att = create_attr context, single, name, rw, comment
|
703
|
+
att.line = line_no
|
467
704
|
|
468
705
|
read_documentation_modifiers att, RDoc::ATTR_MODIFIERS
|
469
|
-
|
470
|
-
context.add_attribute att if att.document_self
|
471
|
-
|
472
|
-
@stats.add_attribute att
|
473
706
|
else
|
474
707
|
warn "'attr' ignored - looks like a variable"
|
475
708
|
end
|
@@ -480,14 +713,18 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
480
713
|
# comment for each to +comment+.
|
481
714
|
|
482
715
|
def parse_attr_accessor(context, single, tk, comment)
|
716
|
+
line_no = tk[:line_no]
|
717
|
+
|
483
718
|
args = parse_symbol_arg
|
484
719
|
rw = "?"
|
485
720
|
|
486
721
|
tmp = RDoc::CodeObject.new
|
487
722
|
read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS
|
488
|
-
|
723
|
+
# TODO In most other places we let the context keep track of document_self
|
724
|
+
# and add found items appropriately but here we do not. I'm not sure why.
|
725
|
+
return if @track_visibility and not tmp.document_self
|
489
726
|
|
490
|
-
case tk
|
727
|
+
case tk[:text]
|
491
728
|
when "attr_reader" then rw = "R"
|
492
729
|
when "attr_writer" then rw = "W"
|
493
730
|
when "attr_accessor" then rw = "RW"
|
@@ -496,11 +733,8 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
496
733
|
end
|
497
734
|
|
498
735
|
for name in args
|
499
|
-
att =
|
500
|
-
att.
|
501
|
-
|
502
|
-
context.add_attribute att
|
503
|
-
@stats.add_attribute att
|
736
|
+
att = create_attr context, single, name, rw, comment
|
737
|
+
att.line = line_no
|
504
738
|
end
|
505
739
|
end
|
506
740
|
|
@@ -508,19 +742,19 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
508
742
|
# Parses an +alias+ in +context+ with +comment+
|
509
743
|
|
510
744
|
def parse_alias(context, single, tk, comment)
|
745
|
+
line_no = tk[:line_no]
|
746
|
+
|
511
747
|
skip_tkspace
|
512
748
|
|
513
|
-
if
|
749
|
+
if :on_lparen === peek_tk[:kind] then
|
514
750
|
get_tk
|
515
751
|
skip_tkspace
|
516
752
|
end
|
517
753
|
|
518
754
|
new_name = get_symbol_or_name
|
519
755
|
|
520
|
-
@scanner.instance_eval { @lex_state = EXPR_FNAME }
|
521
|
-
|
522
756
|
skip_tkspace
|
523
|
-
if
|
757
|
+
if :on_comma === peek_tk[:kind] then
|
524
758
|
get_tk
|
525
759
|
skip_tkspace
|
526
760
|
end
|
@@ -533,10 +767,11 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
533
767
|
|
534
768
|
al = RDoc::Alias.new(get_tkread, old_name, new_name, comment,
|
535
769
|
single == SINGLE)
|
536
|
-
|
770
|
+
record_location al
|
771
|
+
al.line = line_no
|
537
772
|
|
538
773
|
read_documentation_modifiers al, RDoc::ATTR_MODIFIERS
|
539
|
-
context.add_alias al
|
774
|
+
context.add_alias al
|
540
775
|
@stats.add_alias al
|
541
776
|
|
542
777
|
al
|
@@ -546,260 +781,458 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
546
781
|
# Extracts call parameters from the token stream.
|
547
782
|
|
548
783
|
def parse_call_parameters(tk)
|
549
|
-
end_token = case tk
|
550
|
-
when
|
551
|
-
|
552
|
-
when
|
784
|
+
end_token = case tk[:kind]
|
785
|
+
when :on_lparen
|
786
|
+
:on_rparen
|
787
|
+
when :on_rparen
|
553
788
|
return ""
|
554
789
|
else
|
555
|
-
|
790
|
+
:on_nl
|
556
791
|
end
|
557
792
|
nest = 0
|
558
793
|
|
559
794
|
loop do
|
560
|
-
|
561
|
-
|
795
|
+
break if tk.nil?
|
796
|
+
case tk[:kind]
|
797
|
+
when :on_semicolon
|
562
798
|
break
|
563
|
-
when
|
799
|
+
when :on_lparen
|
564
800
|
nest += 1
|
565
801
|
when end_token
|
566
|
-
if end_token ==
|
802
|
+
if end_token == :on_rparen
|
567
803
|
nest -= 1
|
568
|
-
break if
|
804
|
+
break if RDoc::Parser::RipperStateLex.end?(tk) and nest <= 0
|
569
805
|
else
|
570
|
-
break
|
806
|
+
break if RDoc::Parser::RipperStateLex.end?(tk)
|
571
807
|
end
|
572
|
-
when
|
808
|
+
when :on_comment, :on_embdoc
|
573
809
|
unget_tk(tk)
|
574
810
|
break
|
575
|
-
when
|
576
|
-
|
811
|
+
when :on_op
|
812
|
+
if tk[:text] =~ /^(.{1,2})?=$/
|
813
|
+
unget_tk(tk)
|
814
|
+
break
|
815
|
+
end
|
577
816
|
end
|
578
817
|
tk = get_tk
|
579
818
|
end
|
580
|
-
|
581
|
-
|
582
|
-
res
|
819
|
+
|
820
|
+
get_tkread_clean "\n", " "
|
583
821
|
end
|
584
822
|
|
585
823
|
##
|
586
824
|
# Parses a class in +context+ with +comment+
|
587
825
|
|
588
|
-
def parse_class
|
589
|
-
|
590
|
-
container, name_t, given_name = get_class_or_module container
|
826
|
+
def parse_class container, single, tk, comment
|
827
|
+
line_no = tk[:line_no]
|
591
828
|
|
592
|
-
|
593
|
-
|
594
|
-
name = name_t.name
|
595
|
-
superclass = '::Object'
|
829
|
+
declaration_context = container
|
830
|
+
container, name_t, given_name, = get_class_or_module container
|
596
831
|
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
832
|
+
if name_t[:kind] == :on_const
|
833
|
+
cls = parse_class_regular container, declaration_context, single,
|
834
|
+
name_t, given_name, comment
|
835
|
+
elsif name_t[:kind] == :on_op && name_t[:text] == '<<'
|
836
|
+
case name = get_class_specification
|
837
|
+
when 'self', container.name
|
838
|
+
read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
|
839
|
+
parse_statements container, SINGLE
|
840
|
+
return # don't update line
|
841
|
+
else
|
842
|
+
cls = parse_class_singleton container, name, comment
|
602
843
|
end
|
844
|
+
else
|
845
|
+
warn "Expected class name or '<<'. Got #{name_t[:kind]}: #{name_t[:text].inspect}"
|
846
|
+
return
|
847
|
+
end
|
603
848
|
|
604
|
-
|
605
|
-
cls = declaration_context.add_class cls_type, given_name, superclass
|
849
|
+
cls.line = line_no
|
606
850
|
|
607
|
-
|
608
|
-
|
609
|
-
cls.comment = comment if cls.document_self
|
851
|
+
# after end modifiers
|
852
|
+
read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
|
610
853
|
|
611
|
-
|
612
|
-
|
854
|
+
cls
|
855
|
+
end
|
613
856
|
|
614
|
-
|
615
|
-
|
616
|
-
case name = get_class_specification
|
617
|
-
when "self", container.name
|
618
|
-
parse_statements container, SINGLE
|
619
|
-
else
|
620
|
-
other = RDoc::TopLevel.find_class_named name
|
857
|
+
##
|
858
|
+
# Parses and creates a regular class
|
621
859
|
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
other.comment = comment
|
626
|
-
end
|
860
|
+
def parse_class_regular container, declaration_context, single, # :nodoc:
|
861
|
+
name_t, given_name, comment
|
862
|
+
superclass = '::Object'
|
627
863
|
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
864
|
+
if given_name =~ /^::/ then
|
865
|
+
declaration_context = @top_level
|
866
|
+
given_name = $'
|
867
|
+
end
|
868
|
+
|
869
|
+
tk = peek_tk
|
870
|
+
if tk[:kind] == :on_op && tk[:text] == '<' then
|
871
|
+
get_tk
|
872
|
+
skip_tkspace
|
873
|
+
superclass = get_class_specification
|
874
|
+
superclass = '(unknown)' if superclass.empty?
|
875
|
+
end
|
876
|
+
|
877
|
+
cls_type = single == SINGLE ? RDoc::SingleClass : RDoc::NormalClass
|
878
|
+
cls = declaration_context.add_class cls_type, given_name, superclass
|
879
|
+
cls.ignore unless container.document_children
|
880
|
+
|
881
|
+
read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS
|
882
|
+
record_location cls
|
883
|
+
|
884
|
+
cls.add_comment comment, @top_level
|
885
|
+
|
886
|
+
@top_level.add_to_classes_or_modules cls
|
887
|
+
@stats.add_class cls
|
888
|
+
|
889
|
+
suppress_parents container, declaration_context unless cls.document_self
|
890
|
+
|
891
|
+
parse_statements cls
|
892
|
+
|
893
|
+
cls
|
894
|
+
end
|
635
895
|
|
636
|
-
|
637
|
-
|
896
|
+
##
|
897
|
+
# Parses a singleton class in +container+ with the given +name+ and
|
898
|
+
# +comment+.
|
638
899
|
|
639
|
-
|
640
|
-
|
900
|
+
def parse_class_singleton container, name, comment # :nodoc:
|
901
|
+
other = @store.find_class_named name
|
902
|
+
|
903
|
+
unless other then
|
904
|
+
if name =~ /^::/ then
|
905
|
+
name = $'
|
906
|
+
container = @top_level
|
641
907
|
end
|
642
908
|
|
643
|
-
|
644
|
-
|
909
|
+
other = container.add_module RDoc::NormalModule, name
|
910
|
+
record_location other
|
911
|
+
|
912
|
+
# class << $gvar
|
913
|
+
other.ignore if name.empty?
|
914
|
+
|
915
|
+
other.add_comment comment, @top_level
|
916
|
+
end
|
917
|
+
|
918
|
+
# notify :nodoc: all if not a constant-named class/module
|
919
|
+
# (and remove any comment)
|
920
|
+
unless name =~ /\A(::)?[A-Z]/ then
|
921
|
+
other.document_self = nil
|
922
|
+
other.document_children = false
|
923
|
+
other.clear_comment
|
645
924
|
end
|
925
|
+
|
926
|
+
@top_level.add_to_classes_or_modules other
|
927
|
+
@stats.add_class other
|
928
|
+
|
929
|
+
read_documentation_modifiers other, RDoc::CLASS_MODIFIERS
|
930
|
+
parse_statements(other, SINGLE)
|
931
|
+
|
932
|
+
other
|
646
933
|
end
|
647
934
|
|
648
935
|
##
|
649
|
-
# Parses a constant in +context+ with +comment+
|
936
|
+
# Parses a constant in +context+ with +comment+. If +ignore_constants+ is
|
937
|
+
# true, no found constants will be added to RDoc.
|
938
|
+
|
939
|
+
def parse_constant container, tk, comment, ignore_constants = false
|
940
|
+
line_no = tk[:line_no]
|
650
941
|
|
651
|
-
|
652
|
-
|
653
|
-
skip_tkspace false
|
942
|
+
name = tk[:text]
|
943
|
+
skip_tkspace_without_nl
|
654
944
|
|
655
945
|
return unless name =~ /^\w+$/
|
656
946
|
|
657
|
-
|
947
|
+
new_modules = []
|
948
|
+
if :on_op == peek_tk[:kind] && '::' == peek_tk[:text] then
|
949
|
+
unget_tk tk
|
658
950
|
|
659
|
-
|
660
|
-
|
661
|
-
|
951
|
+
container, name_t, _, new_modules = get_class_or_module container, true
|
952
|
+
|
953
|
+
name = name_t[:text]
|
662
954
|
end
|
663
955
|
|
664
|
-
|
665
|
-
|
956
|
+
is_array_or_hash = false
|
957
|
+
if peek_tk && :on_lbracket == peek_tk[:kind]
|
958
|
+
get_tk
|
959
|
+
nest = 1
|
960
|
+
while bracket_tk = get_tk
|
961
|
+
case bracket_tk[:kind]
|
962
|
+
when :on_lbracket
|
963
|
+
nest += 1
|
964
|
+
when :on_rbracket
|
965
|
+
nest -= 1
|
966
|
+
break if nest == 0
|
967
|
+
end
|
968
|
+
end
|
969
|
+
skip_tkspace_without_nl
|
970
|
+
is_array_or_hash = true
|
971
|
+
end
|
666
972
|
|
667
|
-
|
973
|
+
unless peek_tk && :on_op == peek_tk[:kind] && '=' == peek_tk[:text] then
|
974
|
+
return false
|
975
|
+
end
|
976
|
+
get_tk
|
668
977
|
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
978
|
+
unless ignore_constants
|
979
|
+
new_modules.each do |prev_c, new_module|
|
980
|
+
prev_c.add_module_by_normal_module new_module
|
981
|
+
new_module.ignore unless prev_c.document_children
|
982
|
+
@top_level.add_to_classes_or_modules new_module
|
983
|
+
end
|
673
984
|
end
|
674
985
|
|
675
|
-
|
986
|
+
value = ''
|
987
|
+
con = RDoc::Constant.new name, value, comment
|
988
|
+
|
989
|
+
body = parse_constant_body container, con, is_array_or_hash
|
990
|
+
|
991
|
+
return unless body
|
992
|
+
|
993
|
+
con.value = body
|
994
|
+
record_location con
|
995
|
+
con.line = line_no
|
996
|
+
read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
|
997
|
+
|
998
|
+
return if is_array_or_hash
|
999
|
+
|
1000
|
+
@stats.add_constant con
|
1001
|
+
container.add_constant con
|
1002
|
+
|
1003
|
+
true
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
def parse_constant_body container, constant, is_array_or_hash # :nodoc:
|
1007
|
+
nest = 0
|
1008
|
+
rhs_name = ''.dup
|
1009
|
+
|
1010
|
+
get_tkread
|
1011
|
+
|
1012
|
+
tk = get_tk
|
676
1013
|
|
1014
|
+
body = nil
|
677
1015
|
loop do
|
678
|
-
|
679
|
-
|
1016
|
+
break if tk.nil?
|
1017
|
+
if :on_semicolon == tk[:kind] then
|
680
1018
|
break if nest <= 0
|
681
|
-
|
682
|
-
|
1019
|
+
elsif [:on_tlambeg, :on_lparen, :on_lbrace, :on_lbracket].include?(tk[:kind]) then
|
1020
|
+
nest += 1
|
1021
|
+
elsif (:on_kw == tk[:kind] && 'def' == tk[:text]) then
|
683
1022
|
nest += 1
|
684
|
-
|
1023
|
+
elsif (:on_kw == tk[:kind] && %w{do if unless case begin}.include?(tk[:text])) then
|
1024
|
+
if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
|
1025
|
+
nest += 1
|
1026
|
+
end
|
1027
|
+
elsif [:on_rparen, :on_rbrace, :on_rbracket].include?(tk[:kind]) ||
|
1028
|
+
(:on_kw == tk[:kind] && 'end' == tk[:text]) then
|
685
1029
|
nest -= 1
|
686
|
-
|
687
|
-
|
688
|
-
|
1030
|
+
elsif (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
|
1031
|
+
unget_tk tk
|
1032
|
+
if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then
|
1033
|
+
body = get_tkread_clean(/^[ \t]+/, '')
|
1034
|
+
read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
|
689
1035
|
break
|
1036
|
+
else
|
1037
|
+
read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS
|
690
1038
|
end
|
691
|
-
|
692
|
-
rhs_name << tk
|
693
|
-
|
694
|
-
if nest <= 0 and TkNL === peek_tk then
|
695
|
-
mod = if rhs_name =~ /^::/ then
|
696
|
-
RDoc::TopLevel.find_class_or_module rhs_name
|
697
|
-
else
|
698
|
-
container.find_module_named rhs_name
|
699
|
-
end
|
1039
|
+
elsif :on_const == tk[:kind] then
|
1040
|
+
rhs_name << tk[:text]
|
700
1041
|
|
701
|
-
|
702
|
-
|
1042
|
+
next_tk = peek_tk
|
1043
|
+
if nest <= 0 and (next_tk.nil? || :on_nl == next_tk[:kind]) then
|
1044
|
+
create_module_alias container, constant, rhs_name unless is_array_or_hash
|
703
1045
|
break
|
704
1046
|
end
|
705
|
-
|
706
|
-
if nest <= 0
|
707
|
-
(@scanner.lex_state == EXPR_END || !@scanner.continue) then
|
1047
|
+
elsif :on_nl == tk[:kind] then
|
1048
|
+
if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then
|
708
1049
|
unget_tk tk
|
709
1050
|
break
|
710
1051
|
end
|
711
|
-
|
1052
|
+
elsif :on_op == tk[:kind] && '::' == tk[:text]
|
712
1053
|
rhs_name << '::'
|
713
|
-
when nil then
|
714
|
-
break
|
715
1054
|
end
|
716
1055
|
tk = get_tk
|
717
1056
|
end
|
718
1057
|
|
719
|
-
|
720
|
-
res = "" if res == ";"
|
721
|
-
|
722
|
-
con = RDoc::Constant.new name, res, comment
|
723
|
-
con.record_location @top_level
|
724
|
-
read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS
|
725
|
-
|
726
|
-
@stats.add_constant con
|
727
|
-
container.add_constant con if con.document_self
|
1058
|
+
body ? body : get_tkread_clean(/^[ \t]+/, '')
|
728
1059
|
end
|
729
1060
|
|
730
1061
|
##
|
731
1062
|
# Generates an RDoc::Method or RDoc::Attr from +comment+ by looking for
|
732
1063
|
# :method: or :attr: directives in +comment+.
|
733
1064
|
|
734
|
-
def parse_comment
|
735
|
-
|
736
|
-
column = tk
|
1065
|
+
def parse_comment container, tk, comment
|
1066
|
+
return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc'
|
1067
|
+
column = tk[:char_no]
|
1068
|
+
line_no = comment.line.nil? ? tk[:line_no] : comment.line
|
1069
|
+
|
1070
|
+
comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3')
|
1071
|
+
singleton = !!$~
|
737
1072
|
|
738
|
-
|
1073
|
+
co =
|
1074
|
+
if (comment.text = comment.text.sub(/^# +:?method: *(\S*).*?\n/i, '')) && !!$~ then
|
1075
|
+
line_no += $`.count("\n")
|
1076
|
+
parse_comment_ghost container, comment.text, $1, column, line_no, comment
|
1077
|
+
elsif (comment.text = comment.text.sub(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '')) && !!$~ then
|
1078
|
+
parse_comment_attr container, $1, $3, comment
|
1079
|
+
end
|
739
1080
|
|
740
|
-
|
741
|
-
|
742
|
-
|
1081
|
+
if co then
|
1082
|
+
co.singleton = singleton
|
1083
|
+
co.line = line_no
|
1084
|
+
end
|
743
1085
|
|
744
|
-
|
745
|
-
|
746
|
-
meth.singleton = singleton
|
1086
|
+
true
|
1087
|
+
end
|
747
1088
|
|
748
|
-
|
749
|
-
|
750
|
-
|
1089
|
+
##
|
1090
|
+
# Parse a comment that is describing an attribute in +container+ with the
|
1091
|
+
# given +name+ and +comment+.
|
751
1092
|
|
752
|
-
|
753
|
-
|
754
|
-
meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
|
1093
|
+
def parse_comment_attr container, type, name, comment # :nodoc:
|
1094
|
+
return if name.empty?
|
755
1095
|
|
756
|
-
|
1096
|
+
rw = case type
|
1097
|
+
when 'attr_reader' then 'R'
|
1098
|
+
when 'attr_writer' then 'W'
|
1099
|
+
else 'RW'
|
1100
|
+
end
|
757
1101
|
|
758
|
-
|
1102
|
+
create_attr container, NORMAL, name, rw, comment
|
1103
|
+
end
|
759
1104
|
|
760
|
-
|
1105
|
+
def parse_comment_ghost container, text, name, column, line_no, # :nodoc:
|
1106
|
+
comment
|
1107
|
+
name = nil if name.empty?
|
761
1108
|
|
762
|
-
|
1109
|
+
meth = RDoc::GhostMethod.new get_tkread, name
|
1110
|
+
record_location meth
|
763
1111
|
|
764
|
-
|
1112
|
+
meth.start_collecting_tokens
|
1113
|
+
indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
|
1114
|
+
position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
|
1115
|
+
position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
|
1116
|
+
newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
|
1117
|
+
meth.add_tokens [position_comment, newline, indent]
|
1118
|
+
|
1119
|
+
meth.params =
|
1120
|
+
if text.sub!(/^#\s+:?args?:\s*(.*?)\s*$/i, '') then
|
1121
|
+
$1
|
1122
|
+
else
|
1123
|
+
''
|
1124
|
+
end
|
765
1125
|
|
766
|
-
|
767
|
-
|
768
|
-
rw = case $1
|
769
|
-
when 'attr_reader' then 'R'
|
770
|
-
when 'attr_writer' then 'W'
|
771
|
-
else 'RW'
|
772
|
-
end
|
1126
|
+
comment.normalize
|
1127
|
+
comment.extract_call_seq meth
|
773
1128
|
|
774
|
-
|
1129
|
+
return unless meth.name
|
775
1130
|
|
776
|
-
|
777
|
-
att = RDoc::Attr.new get_tkread, name, rw, comment
|
778
|
-
att.record_location @top_level
|
1131
|
+
container.add_method meth
|
779
1132
|
|
780
|
-
|
1133
|
+
meth.comment = comment
|
781
1134
|
|
782
|
-
|
783
|
-
end
|
1135
|
+
@stats.add_method meth
|
784
1136
|
|
785
|
-
|
1137
|
+
meth
|
786
1138
|
end
|
787
1139
|
|
788
1140
|
##
|
789
|
-
#
|
1141
|
+
# Creates an RDoc::Method on +container+ from +comment+ if there is a
|
1142
|
+
# Signature section in the comment
|
790
1143
|
|
791
|
-
def
|
1144
|
+
def parse_comment_tomdoc container, tk, comment
|
1145
|
+
return unless signature = RDoc::TomDoc.signature(comment)
|
1146
|
+
column = tk[:char_no]
|
1147
|
+
line_no = tk[:line_no]
|
1148
|
+
|
1149
|
+
name, = signature.split %r%[ \(]%, 2
|
1150
|
+
|
1151
|
+
meth = RDoc::GhostMethod.new get_tkread, name
|
1152
|
+
record_location meth
|
1153
|
+
meth.line = line_no
|
1154
|
+
|
1155
|
+
meth.start_collecting_tokens
|
1156
|
+
indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
|
1157
|
+
position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
|
1158
|
+
position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
|
1159
|
+
newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
|
1160
|
+
meth.add_tokens [position_comment, newline, indent]
|
1161
|
+
|
1162
|
+
meth.call_seq = signature
|
1163
|
+
|
1164
|
+
comment.normalize
|
1165
|
+
|
1166
|
+
return unless meth.name
|
1167
|
+
|
1168
|
+
container.add_method meth
|
1169
|
+
|
1170
|
+
meth.comment = comment
|
1171
|
+
|
1172
|
+
@stats.add_method meth
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
##
|
1176
|
+
# Parses an +include+ or +extend+, indicated by the +klass+ and adds it to
|
1177
|
+
# +container+ # with +comment+
|
1178
|
+
|
1179
|
+
def parse_extend_or_include klass, container, comment # :nodoc:
|
792
1180
|
loop do
|
793
1181
|
skip_tkspace_comment
|
794
1182
|
|
795
|
-
name =
|
796
|
-
|
1183
|
+
name = get_included_module_with_optional_parens
|
1184
|
+
|
1185
|
+
unless name.empty? then
|
1186
|
+
obj = container.add klass, name, comment
|
1187
|
+
record_location obj
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
return if peek_tk.nil? || :on_comma != peek_tk[:kind]
|
797
1191
|
|
798
|
-
return unless TkCOMMA === peek_tk
|
799
1192
|
get_tk
|
800
1193
|
end
|
801
1194
|
end
|
802
1195
|
|
1196
|
+
##
|
1197
|
+
# Parses identifiers that can create new methods or change visibility.
|
1198
|
+
#
|
1199
|
+
# Returns true if the comment was not consumed.
|
1200
|
+
|
1201
|
+
def parse_identifier container, single, tk, comment # :nodoc:
|
1202
|
+
case tk[:text]
|
1203
|
+
when 'private', 'protected', 'public', 'private_class_method',
|
1204
|
+
'public_class_method', 'module_function' then
|
1205
|
+
parse_visibility container, single, tk
|
1206
|
+
return true
|
1207
|
+
when 'private_constant', 'public_constant'
|
1208
|
+
parse_constant_visibility container, single, tk
|
1209
|
+
return true
|
1210
|
+
when 'attr' then
|
1211
|
+
parse_attr container, single, tk, comment
|
1212
|
+
when /^attr_(reader|writer|accessor)$/ then
|
1213
|
+
parse_attr_accessor container, single, tk, comment
|
1214
|
+
when 'alias_method' then
|
1215
|
+
parse_alias container, single, tk, comment
|
1216
|
+
when 'require', 'include' then
|
1217
|
+
# ignore
|
1218
|
+
else
|
1219
|
+
if comment.text =~ /\A#\#$/ then
|
1220
|
+
case comment.text
|
1221
|
+
when /^# +:?attr(_reader|_writer|_accessor)?:/ then
|
1222
|
+
parse_meta_attr container, single, tk, comment
|
1223
|
+
else
|
1224
|
+
method = parse_meta_method container, single, tk, comment
|
1225
|
+
method.params = container.params if
|
1226
|
+
container.params
|
1227
|
+
method.block_params = container.block_params if
|
1228
|
+
container.block_params
|
1229
|
+
end
|
1230
|
+
end
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
false
|
1234
|
+
end
|
1235
|
+
|
803
1236
|
##
|
804
1237
|
# Parses a meta-programmed attribute and creates an RDoc::Attr.
|
805
1238
|
#
|
@@ -837,9 +1270,10 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
837
1270
|
|
838
1271
|
tmp = RDoc::CodeObject.new
|
839
1272
|
read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS
|
840
|
-
return unless tmp.document_self
|
841
1273
|
|
842
|
-
|
1274
|
+
regexp = /^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i
|
1275
|
+
if regexp =~ comment.text then
|
1276
|
+
comment.text = comment.text.sub(regexp, '')
|
843
1277
|
rw = case $1
|
844
1278
|
when 'attr_reader' then 'R'
|
845
1279
|
when 'attr_writer' then 'W'
|
@@ -849,216 +1283,175 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
849
1283
|
end
|
850
1284
|
|
851
1285
|
if name then
|
852
|
-
att =
|
853
|
-
att.record_location @top_level
|
854
|
-
|
855
|
-
context.add_attribute att
|
856
|
-
@stats.add_attribute att
|
1286
|
+
att = create_attr context, single, name, rw, comment
|
857
1287
|
else
|
858
1288
|
args.each do |attr_name|
|
859
|
-
att =
|
860
|
-
single == SINGLE)
|
861
|
-
att.record_location @top_level
|
862
|
-
|
863
|
-
context.add_attribute att
|
864
|
-
@stats.add_attribute att
|
1289
|
+
att = create_attr context, single, attr_name, rw, comment
|
865
1290
|
end
|
866
1291
|
end
|
1292
|
+
|
1293
|
+
att
|
867
1294
|
end
|
868
1295
|
|
869
1296
|
##
|
870
1297
|
# Parses a meta-programmed method
|
871
1298
|
|
872
1299
|
def parse_meta_method(container, single, tk, comment)
|
873
|
-
|
874
|
-
|
1300
|
+
column = tk[:char_no]
|
1301
|
+
line_no = tk[:line_no]
|
875
1302
|
|
876
1303
|
start_collecting_tokens
|
877
1304
|
add_token tk
|
878
1305
|
add_token_listener self
|
879
1306
|
|
880
|
-
|
1307
|
+
skip_tkspace_without_nl
|
881
1308
|
|
882
|
-
|
1309
|
+
comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3')
|
1310
|
+
singleton = !!$~
|
883
1311
|
|
884
|
-
|
885
|
-
name = $1 unless $1.empty?
|
886
|
-
end
|
1312
|
+
name = parse_meta_method_name comment, tk
|
887
1313
|
|
888
|
-
|
889
|
-
name_t = get_tk
|
890
|
-
case name_t
|
891
|
-
when TkSYMBOL then
|
892
|
-
name = name_t.text[1..-1]
|
893
|
-
when TkSTRING then
|
894
|
-
name = name_t.value[1..-2]
|
895
|
-
when TkASSIGN then # ignore
|
896
|
-
remove_token_listener self
|
897
|
-
return
|
898
|
-
else
|
899
|
-
warn "unknown name token #{name_t.inspect} for meta-method '#{tk.name}'"
|
900
|
-
name = 'unknown'
|
901
|
-
end
|
902
|
-
end
|
1314
|
+
return unless name
|
903
1315
|
|
904
1316
|
meth = RDoc::MetaMethod.new get_tkread, name
|
905
|
-
|
1317
|
+
record_location meth
|
1318
|
+
meth.line = line_no
|
906
1319
|
meth.singleton = singleton
|
907
1320
|
|
908
1321
|
remove_token_listener self
|
909
1322
|
|
910
1323
|
meth.start_collecting_tokens
|
911
|
-
indent =
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
meth.add_tokens [position_comment, NEWLINE_TOKEN, indent]
|
1324
|
+
indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
|
1325
|
+
position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
|
1326
|
+
position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
|
1327
|
+
newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
|
1328
|
+
meth.add_tokens [position_comment, newline, indent]
|
917
1329
|
meth.add_tokens @token_stream
|
918
1330
|
|
1331
|
+
parse_meta_method_params container, single, meth, tk, comment
|
1332
|
+
|
1333
|
+
meth.comment = comment
|
1334
|
+
|
1335
|
+
@stats.add_method meth
|
1336
|
+
|
1337
|
+
meth
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
##
|
1341
|
+
# Parses the name of a metaprogrammed method. +comment+ is used to
|
1342
|
+
# determine the name while +tk+ is used in an error message if the name
|
1343
|
+
# cannot be determined.
|
1344
|
+
|
1345
|
+
def parse_meta_method_name comment, tk # :nodoc:
|
1346
|
+
if comment.text.sub!(/^# +:?method: *(\S*).*?\n/i, '') then
|
1347
|
+
return $1 unless $1.empty?
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
name_t = get_tk
|
1351
|
+
|
1352
|
+
if :on_symbol == name_t[:kind] then
|
1353
|
+
name_t[:text][1..-1]
|
1354
|
+
elsif :on_tstring == name_t[:kind] then
|
1355
|
+
name_t[:text][1..-2]
|
1356
|
+
elsif :on_op == name_t[:kind] && '=' == name_t[:text] then # ignore
|
1357
|
+
remove_token_listener self
|
1358
|
+
|
1359
|
+
nil
|
1360
|
+
else
|
1361
|
+
warn "unknown name token #{name_t.inspect} for meta-method '#{tk[:text]}'"
|
1362
|
+
'unknown'
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
##
|
1367
|
+
# Parses the parameters and block for a meta-programmed method.
|
1368
|
+
|
1369
|
+
def parse_meta_method_params container, single, meth, tk, comment # :nodoc:
|
919
1370
|
token_listener meth do
|
920
1371
|
meth.params = ''
|
921
1372
|
|
922
|
-
|
1373
|
+
look_for_directives_in meth, comment
|
1374
|
+
comment.normalize
|
1375
|
+
comment.extract_call_seq meth
|
923
1376
|
|
924
|
-
container.add_method meth
|
1377
|
+
container.add_method meth
|
925
1378
|
|
926
1379
|
last_tk = tk
|
927
1380
|
|
928
1381
|
while tk = get_tk do
|
929
|
-
|
930
|
-
when TkSEMICOLON then
|
1382
|
+
if :on_semicolon == tk[:kind] then
|
931
1383
|
break
|
932
|
-
|
933
|
-
break unless last_tk and
|
934
|
-
|
1384
|
+
elsif :on_nl == tk[:kind] then
|
1385
|
+
break unless last_tk and :on_comma == last_tk[:kind]
|
1386
|
+
elsif :on_sp == tk[:kind] then
|
935
1387
|
# expression continues
|
1388
|
+
elsif :on_kw == tk[:kind] && 'do' == tk[:text] then
|
1389
|
+
parse_statements container, single, meth
|
1390
|
+
break
|
936
1391
|
else
|
937
1392
|
last_tk = tk
|
938
1393
|
end
|
939
1394
|
end
|
940
1395
|
end
|
941
|
-
|
942
|
-
meth.comment = comment
|
943
|
-
|
944
|
-
@stats.add_method meth
|
945
1396
|
end
|
946
1397
|
|
947
1398
|
##
|
948
1399
|
# Parses a normal method defined by +def+
|
949
1400
|
|
950
1401
|
def parse_method(container, single, tk, comment)
|
951
|
-
|
952
|
-
|
1402
|
+
singleton = nil
|
1403
|
+
added_container = false
|
953
1404
|
name = nil
|
954
|
-
|
955
|
-
|
1405
|
+
column = tk[:char_no]
|
1406
|
+
line_no = tk[:line_no]
|
956
1407
|
|
957
1408
|
start_collecting_tokens
|
958
1409
|
add_token tk
|
959
1410
|
|
960
1411
|
token_listener self do
|
961
|
-
|
1412
|
+
prev_container = container
|
1413
|
+
name, container, singleton = parse_method_name container
|
1414
|
+
added_container = container != prev_container
|
1415
|
+
end
|
962
1416
|
|
963
|
-
|
964
|
-
name_t = get_tk
|
965
|
-
back_tk = skip_tkspace
|
966
|
-
meth = nil
|
967
|
-
added_container = false
|
1417
|
+
return unless name
|
968
1418
|
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
skip_tkspace
|
973
|
-
name_t2 = get_tk
|
974
|
-
|
975
|
-
case name_t
|
976
|
-
when TkSELF, TkMOD then
|
977
|
-
name = name_t2.name
|
978
|
-
when TkCONSTANT then
|
979
|
-
name = name_t2.name
|
980
|
-
prev_container = container
|
981
|
-
container = container.find_module_named(name_t.name)
|
982
|
-
unless container then
|
983
|
-
added_container = true
|
984
|
-
obj = name_t.name.split("::").inject(Object) do |state, item|
|
985
|
-
state.const_get(item)
|
986
|
-
end rescue nil
|
987
|
-
|
988
|
-
type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule
|
989
|
-
|
990
|
-
unless [Class, Module].include?(obj.class) then
|
991
|
-
warn("Couldn't find #{name_t.name}. Assuming it's a module")
|
992
|
-
end
|
1419
|
+
meth = RDoc::AnyMethod.new get_tkread, name
|
1420
|
+
look_for_directives_in meth, comment
|
1421
|
+
meth.singleton = single == SINGLE ? true : singleton
|
993
1422
|
|
994
|
-
|
995
|
-
|
996
|
-
container = prev_container.add_class type, name_t.name, sclass
|
997
|
-
else
|
998
|
-
container = prev_container.add_module type, name_t.name
|
999
|
-
end
|
1423
|
+
record_location meth
|
1424
|
+
meth.line = line_no
|
1000
1425
|
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
when TkTRUE, TkFALSE, TkNIL then
|
1009
|
-
klass_name = "#{name_t.name.capitalize}Class"
|
1010
|
-
container = RDoc::TopLevel.find_class_named klass_name
|
1011
|
-
container ||= @top_level.add_class RDoc::NormalClass, klass_name
|
1426
|
+
meth.start_collecting_tokens
|
1427
|
+
indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column)
|
1428
|
+
token = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment)
|
1429
|
+
token[:text] = "# File #{@top_level.relative_name}, line #{line_no}"
|
1430
|
+
newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n")
|
1431
|
+
meth.add_tokens [token, newline, indent]
|
1432
|
+
meth.add_tokens @token_stream
|
1012
1433
|
|
1013
|
-
|
1014
|
-
else
|
1015
|
-
warn "unexpected method name token #{name_t.inspect}"
|
1016
|
-
# break
|
1017
|
-
skip_method container
|
1018
|
-
return
|
1019
|
-
end
|
1434
|
+
parse_method_params_and_body container, single, meth, added_container
|
1020
1435
|
|
1021
|
-
|
1022
|
-
|
1023
|
-
else
|
1024
|
-
unget_tk dot
|
1025
|
-
back_tk.reverse_each do |token|
|
1026
|
-
unget_tk token
|
1027
|
-
end
|
1436
|
+
comment.normalize
|
1437
|
+
comment.extract_call_seq meth
|
1028
1438
|
|
1029
|
-
|
1030
|
-
when TkSTAR, TkAMPER then
|
1031
|
-
name_t.text
|
1032
|
-
else
|
1033
|
-
unless name_t.respond_to? :name then
|
1034
|
-
warn "expected method name token, . or ::, got #{name_t.inspect}"
|
1035
|
-
skip_method container
|
1036
|
-
return
|
1037
|
-
end
|
1038
|
-
name_t.name
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
meth = RDoc::AnyMethod.new get_tkread, name
|
1042
|
-
meth.singleton = (single == SINGLE)
|
1043
|
-
end
|
1044
|
-
end
|
1439
|
+
meth.comment = comment
|
1045
1440
|
|
1046
|
-
|
1441
|
+
# after end modifiers
|
1442
|
+
read_documentation_modifiers meth, RDoc::METHOD_MODIFIERS
|
1047
1443
|
|
1048
|
-
meth
|
1049
|
-
|
1050
|
-
indent.set_text " " * column
|
1444
|
+
@stats.add_method meth
|
1445
|
+
end
|
1051
1446
|
|
1052
|
-
|
1053
|
-
|
1054
|
-
meth.add_tokens [token, NEWLINE_TOKEN, indent]
|
1055
|
-
meth.add_tokens @token_stream
|
1447
|
+
##
|
1448
|
+
# Parses the parameters and body of +meth+
|
1056
1449
|
|
1450
|
+
def parse_method_params_and_body container, single, meth, added_container
|
1057
1451
|
token_listener meth do
|
1058
|
-
@scanner.instance_eval do @continue = false end
|
1059
1452
|
parse_method_parameters meth
|
1060
1453
|
|
1061
|
-
if meth.document_self then
|
1454
|
+
if meth.document_self or not @track_visibility then
|
1062
1455
|
container.add_method meth
|
1063
1456
|
elsif added_container then
|
1064
1457
|
container.document_self = false
|
@@ -1067,7 +1460,7 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1067
1460
|
# Having now read the method parameters and documentation modifiers, we
|
1068
1461
|
# now know whether we have to rename #initialize to ::new
|
1069
1462
|
|
1070
|
-
if name == "initialize" && !meth.singleton then
|
1463
|
+
if meth.name == "initialize" && !meth.singleton then
|
1071
1464
|
if meth.dont_rename_initialize then
|
1072
1465
|
meth.visibility = :protected
|
1073
1466
|
else
|
@@ -1079,12 +1472,108 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1079
1472
|
|
1080
1473
|
parse_statements container, single, meth
|
1081
1474
|
end
|
1475
|
+
end
|
1082
1476
|
|
1083
|
-
|
1477
|
+
##
|
1478
|
+
# Parses a method that needs to be ignored.
|
1084
1479
|
|
1085
|
-
|
1480
|
+
def parse_method_dummy container
|
1481
|
+
dummy = RDoc::Context.new
|
1482
|
+
dummy.parent = container
|
1483
|
+
dummy.store = container.store
|
1484
|
+
skip_method dummy
|
1485
|
+
end
|
1086
1486
|
|
1087
|
-
|
1487
|
+
##
|
1488
|
+
# Parses the name of a method in +container+.
|
1489
|
+
#
|
1490
|
+
# Returns the method name, the container it is in (for def Foo.name) and if
|
1491
|
+
# it is a singleton or regular method.
|
1492
|
+
|
1493
|
+
def parse_method_name container # :nodoc:
|
1494
|
+
skip_tkspace
|
1495
|
+
name_t = get_tk
|
1496
|
+
back_tk = skip_tkspace_without_nl
|
1497
|
+
singleton = false
|
1498
|
+
|
1499
|
+
dot = get_tk
|
1500
|
+
if dot[:kind] == :on_period || (dot[:kind] == :on_op && dot[:text] == '::') then
|
1501
|
+
singleton = true
|
1502
|
+
|
1503
|
+
name, container = parse_method_name_singleton container, name_t
|
1504
|
+
else
|
1505
|
+
unget_tk dot
|
1506
|
+
back_tk.reverse_each do |token|
|
1507
|
+
unget_tk token
|
1508
|
+
end
|
1509
|
+
|
1510
|
+
name = parse_method_name_regular container, name_t
|
1511
|
+
end
|
1512
|
+
|
1513
|
+
return name, container, singleton
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
##
|
1517
|
+
# For the given +container+ and initial name token +name_t+ the method name
|
1518
|
+
# is parsed from the token stream for a regular method.
|
1519
|
+
|
1520
|
+
def parse_method_name_regular container, name_t # :nodoc:
|
1521
|
+
if :on_op == name_t[:kind] && (%w{* & [] []= <<}.include?(name_t[:text])) then
|
1522
|
+
name_t[:text]
|
1523
|
+
else
|
1524
|
+
unless [:on_kw, :on_const, :on_ident].include?(name_t[:kind]) then
|
1525
|
+
warn "expected method name token, . or ::, got #{name_t.inspect}"
|
1526
|
+
skip_method container
|
1527
|
+
return
|
1528
|
+
end
|
1529
|
+
name_t[:text]
|
1530
|
+
end
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
##
|
1534
|
+
# For the given +container+ and initial name token +name_t+ the method name
|
1535
|
+
# and the new +container+ (if necessary) are parsed from the token stream
|
1536
|
+
# for a singleton method.
|
1537
|
+
|
1538
|
+
def parse_method_name_singleton container, name_t # :nodoc:
|
1539
|
+
skip_tkspace
|
1540
|
+
name_t2 = get_tk
|
1541
|
+
|
1542
|
+
if (:on_kw == name_t[:kind] && 'self' == name_t[:text]) || (:on_op == name_t[:kind] && '%' == name_t[:text]) then
|
1543
|
+
# NOTE: work around '[' being consumed early
|
1544
|
+
if :on_lbracket == name_t2[:kind]
|
1545
|
+
get_tk
|
1546
|
+
name = '[]'
|
1547
|
+
else
|
1548
|
+
name = name_t2[:text]
|
1549
|
+
end
|
1550
|
+
elsif :on_const == name_t[:kind] then
|
1551
|
+
name = name_t2[:text]
|
1552
|
+
|
1553
|
+
container = get_method_container container, name_t
|
1554
|
+
|
1555
|
+
return unless container
|
1556
|
+
|
1557
|
+
name
|
1558
|
+
elsif :on_ident == name_t[:kind] || :on_ivar == name_t[:kind] || :on_gvar == name_t[:kind] then
|
1559
|
+
parse_method_dummy container
|
1560
|
+
|
1561
|
+
name = nil
|
1562
|
+
elsif (:on_kw == name_t[:kind]) && ('true' == name_t[:text] || 'false' == name_t[:text] || 'nil' == name_t[:text]) then
|
1563
|
+
klass_name = "#{name_t[:text].capitalize}Class"
|
1564
|
+
container = @store.find_class_named klass_name
|
1565
|
+
container ||= @top_level.add_class RDoc::NormalClass, klass_name
|
1566
|
+
|
1567
|
+
name = name_t2[:text]
|
1568
|
+
else
|
1569
|
+
warn "unexpected method name token #{name_t.inspect}"
|
1570
|
+
# break
|
1571
|
+
skip_method container
|
1572
|
+
|
1573
|
+
name = nil
|
1574
|
+
end
|
1575
|
+
|
1576
|
+
return name, container
|
1088
1577
|
end
|
1089
1578
|
|
1090
1579
|
##
|
@@ -1092,63 +1581,61 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1092
1581
|
|
1093
1582
|
def parse_method_or_yield_parameters(method = nil,
|
1094
1583
|
modifiers = RDoc::METHOD_MODIFIERS)
|
1095
|
-
|
1584
|
+
skip_tkspace_without_nl
|
1096
1585
|
tk = get_tk
|
1586
|
+
end_token = get_end_token tk
|
1587
|
+
return '' unless end_token
|
1097
1588
|
|
1098
|
-
# Little hack going on here. In the statement
|
1099
|
-
# f = 2*(1+yield)
|
1100
|
-
# We see the RPAREN as the next token, so we need
|
1101
|
-
# to exit early. This still won't catch all cases
|
1102
|
-
# (such as "a = yield + 1"
|
1103
|
-
end_token = case tk
|
1104
|
-
when TkLPAREN, TkfLPAREN
|
1105
|
-
TkRPAREN
|
1106
|
-
when TkRPAREN
|
1107
|
-
return ""
|
1108
|
-
else
|
1109
|
-
TkNL
|
1110
|
-
end
|
1111
1589
|
nest = 0
|
1590
|
+
continue = false
|
1112
1591
|
|
1113
|
-
|
1114
|
-
case tk
|
1115
|
-
when
|
1592
|
+
while tk != nil do
|
1593
|
+
case tk[:kind]
|
1594
|
+
when :on_semicolon then
|
1116
1595
|
break if nest == 0
|
1117
|
-
when
|
1596
|
+
when :on_lbracket then
|
1597
|
+
nest += 1
|
1598
|
+
when :on_rbracket then
|
1599
|
+
nest -= 1
|
1600
|
+
when :on_lbrace then
|
1118
1601
|
nest += 1
|
1119
|
-
when
|
1602
|
+
when :on_rbrace then
|
1120
1603
|
nest -= 1
|
1121
1604
|
if nest <= 0
|
1122
1605
|
# we might have a.each { |i| yield i }
|
1123
1606
|
unget_tk(tk) if nest < 0
|
1124
1607
|
break
|
1125
1608
|
end
|
1126
|
-
when
|
1609
|
+
when :on_lparen then
|
1127
1610
|
nest += 1
|
1128
|
-
when end_token then
|
1129
|
-
if end_token ==
|
1611
|
+
when end_token[:kind] then
|
1612
|
+
if end_token[:kind] == :on_rparen
|
1130
1613
|
nest -= 1
|
1131
|
-
break if
|
1614
|
+
break if nest <= 0
|
1132
1615
|
else
|
1133
|
-
break
|
1616
|
+
break
|
1134
1617
|
end
|
1135
|
-
when
|
1618
|
+
when :on_rparen then
|
1136
1619
|
nest -= 1
|
1137
|
-
when
|
1138
|
-
unget_tk tk
|
1139
|
-
read_documentation_modifiers method, modifiers
|
1620
|
+
when :on_comment, :on_embdoc then
|
1140
1621
|
@read.pop
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1622
|
+
if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and
|
1623
|
+
(!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then
|
1624
|
+
if method && method.block_params.nil? then
|
1625
|
+
unget_tk tk
|
1626
|
+
read_documentation_modifiers method, modifiers
|
1627
|
+
end
|
1628
|
+
break if !continue and nest <= 0
|
1629
|
+
end
|
1630
|
+
when :on_comma then
|
1631
|
+
continue = true
|
1632
|
+
when :on_ident then
|
1633
|
+
continue = false if continue
|
1145
1634
|
end
|
1146
1635
|
tk = get_tk
|
1147
1636
|
end
|
1148
1637
|
|
1149
|
-
|
1150
|
-
res = '' if res == ';'
|
1151
|
-
res
|
1638
|
+
get_tkread_clean(/\s+/, ' ')
|
1152
1639
|
end
|
1153
1640
|
|
1154
1641
|
##
|
@@ -1159,34 +1646,37 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1159
1646
|
#
|
1160
1647
|
# and add this as the block_params for the method
|
1161
1648
|
|
1162
|
-
def parse_method_parameters
|
1649
|
+
def parse_method_parameters method
|
1163
1650
|
res = parse_method_or_yield_parameters method
|
1164
1651
|
|
1165
1652
|
res = "(#{res})" unless res =~ /\A\(/
|
1166
1653
|
method.params = res unless method.params
|
1167
1654
|
|
1168
|
-
if
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1655
|
+
return if method.block_params
|
1656
|
+
|
1657
|
+
skip_tkspace_without_nl
|
1658
|
+
read_documentation_modifiers method, RDoc::METHOD_MODIFIERS
|
1172
1659
|
end
|
1173
1660
|
|
1174
1661
|
##
|
1175
1662
|
# Parses an RDoc::NormalModule in +container+ with +comment+
|
1176
1663
|
|
1177
|
-
def parse_module
|
1664
|
+
def parse_module container, single, tk, comment
|
1178
1665
|
container, name_t, = get_class_or_module container
|
1179
1666
|
|
1180
|
-
name = name_t
|
1667
|
+
name = name_t[:text]
|
1181
1668
|
|
1182
1669
|
mod = container.add_module RDoc::NormalModule, name
|
1183
|
-
mod.
|
1670
|
+
mod.ignore unless container.document_children
|
1671
|
+
record_location mod
|
1184
1672
|
|
1185
1673
|
read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS
|
1186
|
-
mod.
|
1187
|
-
parse_statements
|
1674
|
+
mod.add_comment comment, @top_level
|
1675
|
+
parse_statements mod
|
1676
|
+
|
1677
|
+
# after end modifiers
|
1678
|
+
read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS
|
1188
1679
|
|
1189
|
-
@top_level.add_to_classes_or_modules mod
|
1190
1680
|
@stats.add_module mod
|
1191
1681
|
end
|
1192
1682
|
|
@@ -1197,12 +1687,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1197
1687
|
skip_tkspace_comment
|
1198
1688
|
tk = get_tk
|
1199
1689
|
|
1200
|
-
if
|
1690
|
+
if :on_lparen == tk[:kind] then
|
1201
1691
|
skip_tkspace_comment
|
1202
1692
|
tk = get_tk
|
1203
1693
|
end
|
1204
1694
|
|
1205
|
-
name = tk
|
1695
|
+
name = tk[:text][1..-2] if :on_tstring == tk[:kind]
|
1206
1696
|
|
1207
1697
|
if name then
|
1208
1698
|
@top_level.add_require RDoc::Require.new(name, comment)
|
@@ -1212,10 +1702,44 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1212
1702
|
end
|
1213
1703
|
|
1214
1704
|
##
|
1215
|
-
#
|
1705
|
+
# Parses a rescue
|
1706
|
+
|
1707
|
+
def parse_rescue
|
1708
|
+
skip_tkspace_without_nl
|
1709
|
+
|
1710
|
+
while tk = get_tk
|
1711
|
+
case tk[:kind]
|
1712
|
+
when :on_nl, :on_semicolon, :on_comment then
|
1713
|
+
break
|
1714
|
+
when :on_comma then
|
1715
|
+
skip_tkspace_without_nl
|
1716
|
+
|
1717
|
+
get_tk if :on_nl == peek_tk[:kind]
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
skip_tkspace_without_nl
|
1721
|
+
end
|
1722
|
+
end
|
1723
|
+
|
1724
|
+
##
|
1725
|
+
# Retrieve comment body without =begin/=end
|
1726
|
+
|
1727
|
+
def retrieve_comment_body(tk)
|
1728
|
+
if :on_embdoc == tk[:kind]
|
1729
|
+
tk[:text].gsub(/\A=begin.*\n/, '').gsub(/=end\n?\z/, '')
|
1730
|
+
else
|
1731
|
+
tk[:text]
|
1732
|
+
end
|
1733
|
+
end
|
1734
|
+
|
1735
|
+
##
|
1736
|
+
# The core of the Ruby parser.
|
1216
1737
|
|
1217
1738
|
def parse_statements(container, single = NORMAL, current_method = nil,
|
1218
|
-
comment = '')
|
1739
|
+
comment = new_comment(''))
|
1740
|
+
raise 'no' unless RDoc::Comment === comment
|
1741
|
+
comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
|
1742
|
+
|
1219
1743
|
nest = 1
|
1220
1744
|
save_visibility = container.visibility
|
1221
1745
|
|
@@ -1223,35 +1747,63 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1223
1747
|
|
1224
1748
|
while tk = get_tk do
|
1225
1749
|
keep_comment = false
|
1750
|
+
try_parse_comment = false
|
1226
1751
|
|
1227
|
-
non_comment_seen = true unless
|
1752
|
+
non_comment_seen = true unless (:on_comment == tk[:kind] or :on_embdoc == tk[:kind])
|
1228
1753
|
|
1229
|
-
case tk
|
1230
|
-
when
|
1231
|
-
|
1232
|
-
|
1754
|
+
case tk[:kind]
|
1755
|
+
when :on_nl, :on_ignored_nl, :on_comment, :on_embdoc then
|
1756
|
+
if :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]
|
1757
|
+
skip_tkspace
|
1758
|
+
tk = get_tk
|
1759
|
+
else
|
1760
|
+
past_tokens = @read.size > 1 ? @read[0..-2] : []
|
1761
|
+
nl_position = 0
|
1762
|
+
past_tokens.reverse.each_with_index do |read_tk, i|
|
1763
|
+
if read_tk =~ /^\n$/ then
|
1764
|
+
nl_position = (past_tokens.size - 1) - i
|
1765
|
+
break
|
1766
|
+
elsif read_tk =~ /^#.*\n$/ then
|
1767
|
+
nl_position = ((past_tokens.size - 1) - i) + 1
|
1768
|
+
break
|
1769
|
+
end
|
1770
|
+
end
|
1771
|
+
comment_only_line = past_tokens[nl_position..-1].all?{ |c| c =~ /^\s+$/ }
|
1772
|
+
unless comment_only_line then
|
1773
|
+
tk = get_tk
|
1774
|
+
end
|
1775
|
+
end
|
1233
1776
|
|
1234
|
-
if
|
1777
|
+
if tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then
|
1235
1778
|
if non_comment_seen then
|
1236
1779
|
# Look for RDoc in a comment about to be thrown away
|
1237
1780
|
non_comment_seen = parse_comment container, tk, comment unless
|
1238
1781
|
comment.empty?
|
1239
1782
|
|
1240
1783
|
comment = ''
|
1784
|
+
comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
|
1241
1785
|
end
|
1242
1786
|
|
1243
|
-
|
1244
|
-
|
1787
|
+
line_no = nil
|
1788
|
+
while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do
|
1789
|
+
comment_body = retrieve_comment_body(tk)
|
1790
|
+
line_no = tk[:line_no] if comment.empty?
|
1791
|
+
comment += comment_body
|
1792
|
+
comment << "\n" unless comment_body =~ /\n\z/
|
1245
1793
|
|
1246
|
-
|
1247
|
-
|
1794
|
+
if comment_body.size > 1 && comment_body =~ /\n\z/ then
|
1795
|
+
skip_tkspace_without_nl # leading spaces
|
1796
|
+
end
|
1248
1797
|
tk = get_tk
|
1249
1798
|
end
|
1250
1799
|
|
1800
|
+
comment = new_comment comment, line_no
|
1801
|
+
|
1251
1802
|
unless comment.empty? then
|
1252
1803
|
look_for_directives_in container, comment
|
1253
1804
|
|
1254
1805
|
if container.done_documenting then
|
1806
|
+
throw :eof if RDoc::TopLevel === container
|
1255
1807
|
container.ongoing_visibility = save_visibility
|
1256
1808
|
end
|
1257
1809
|
end
|
@@ -1263,171 +1815,179 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1263
1815
|
|
1264
1816
|
unget_tk tk
|
1265
1817
|
keep_comment = true
|
1818
|
+
container.current_line_visibility = nil
|
1266
1819
|
|
1267
|
-
when
|
1268
|
-
|
1820
|
+
when :on_kw then
|
1821
|
+
case tk[:text]
|
1822
|
+
when 'class' then
|
1269
1823
|
parse_class container, single, tk, comment
|
1270
|
-
else
|
1271
|
-
nest += 1
|
1272
|
-
end
|
1273
1824
|
|
1274
|
-
|
1275
|
-
if container.document_children then
|
1825
|
+
when 'module' then
|
1276
1826
|
parse_module container, single, tk, comment
|
1277
|
-
else
|
1278
|
-
nest += 1
|
1279
|
-
end
|
1280
1827
|
|
1281
|
-
|
1282
|
-
if container.document_self then
|
1828
|
+
when 'def' then
|
1283
1829
|
parse_method container, single, tk, comment
|
1284
|
-
|
1830
|
+
|
1831
|
+
when 'alias' then
|
1832
|
+
parse_alias container, single, tk, comment unless current_method
|
1833
|
+
|
1834
|
+
when 'yield' then
|
1835
|
+
if current_method.nil? then
|
1836
|
+
warn "Warning: yield outside of method" if container.document_self
|
1837
|
+
else
|
1838
|
+
parse_yield container, single, tk, current_method
|
1839
|
+
end
|
1840
|
+
|
1841
|
+
when 'until', 'while' then
|
1842
|
+
if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
|
1843
|
+
nest += 1
|
1844
|
+
skip_optional_do_after_expression
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
# Until and While can have a 'do', which shouldn't increase the nesting.
|
1848
|
+
# We can't solve the general case, but we can handle most occurrences by
|
1849
|
+
# ignoring a do at the end of a line.
|
1850
|
+
|
1851
|
+
# 'for' is trickier
|
1852
|
+
when 'for' then
|
1285
1853
|
nest += 1
|
1286
|
-
|
1854
|
+
skip_for_variable
|
1855
|
+
skip_optional_do_after_expression
|
1287
1856
|
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1857
|
+
when 'case', 'do', 'if', 'unless', 'begin' then
|
1858
|
+
if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0
|
1859
|
+
nest += 1
|
1860
|
+
end
|
1292
1861
|
|
1293
|
-
|
1294
|
-
|
1295
|
-
parse_alias container, single, tk, comment
|
1296
|
-
end
|
1862
|
+
when 'super' then
|
1863
|
+
current_method.calls_super = true if current_method
|
1297
1864
|
|
1298
|
-
|
1299
|
-
|
1300
|
-
warn "Warning: yield outside of method" if container.document_self
|
1301
|
-
else
|
1302
|
-
parse_yield container, single, tk, current_method
|
1303
|
-
end
|
1865
|
+
when 'rescue' then
|
1866
|
+
parse_rescue
|
1304
1867
|
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1868
|
+
when 'end' then
|
1869
|
+
nest -= 1
|
1870
|
+
if nest == 0 then
|
1871
|
+
container.ongoing_visibility = save_visibility
|
1308
1872
|
|
1309
|
-
|
1310
|
-
nest += 1
|
1311
|
-
skip_optional_do_after_expression
|
1873
|
+
parse_comment container, tk, comment unless comment.empty?
|
1312
1874
|
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
skip_for_variable
|
1317
|
-
skip_optional_do_after_expression
|
1875
|
+
return
|
1876
|
+
end
|
1877
|
+
end
|
1318
1878
|
|
1319
|
-
when
|
1320
|
-
|
1879
|
+
when :on_const then
|
1880
|
+
unless parse_constant container, tk, comment, current_method then
|
1881
|
+
try_parse_comment = true
|
1882
|
+
end
|
1321
1883
|
|
1322
|
-
when
|
1884
|
+
when :on_ident then
|
1323
1885
|
if nest == 1 and current_method.nil? then
|
1324
|
-
|
1325
|
-
when 'private', 'protected', 'public', 'private_class_method',
|
1326
|
-
'public_class_method', 'module_function' then
|
1327
|
-
parse_visibility container, single, tk
|
1328
|
-
keep_comment = true
|
1329
|
-
when 'attr' then
|
1330
|
-
parse_attr container, single, tk, comment
|
1331
|
-
when /^attr_(reader|writer|accessor)$/ then
|
1332
|
-
parse_attr_accessor container, single, tk, comment
|
1333
|
-
when 'alias_method' then
|
1334
|
-
parse_alias container, single, tk, comment if
|
1335
|
-
container.document_self
|
1336
|
-
when 'require', 'include' then
|
1337
|
-
# ignore
|
1338
|
-
else
|
1339
|
-
if container.document_self and comment =~ /\A#\#$/ then
|
1340
|
-
case comment
|
1341
|
-
when /^# +:?attr(_reader|_writer|_accessor)?:/ then
|
1342
|
-
parse_meta_attr container, single, tk, comment
|
1343
|
-
else
|
1344
|
-
parse_meta_method container, single, tk, comment
|
1345
|
-
end
|
1346
|
-
end
|
1347
|
-
end
|
1886
|
+
keep_comment = parse_identifier container, single, tk, comment
|
1348
1887
|
end
|
1349
1888
|
|
1350
|
-
case tk
|
1889
|
+
case tk[:text]
|
1351
1890
|
when "require" then
|
1352
1891
|
parse_require container, comment
|
1353
1892
|
when "include" then
|
1354
|
-
|
1893
|
+
parse_extend_or_include RDoc::Include, container, comment
|
1894
|
+
when "extend" then
|
1895
|
+
parse_extend_or_include RDoc::Extend, container, comment
|
1355
1896
|
end
|
1356
1897
|
|
1357
|
-
when TkEND then
|
1358
|
-
nest -= 1
|
1359
|
-
if nest == 0 then
|
1360
|
-
read_documentation_modifiers container, RDoc::CLASS_MODIFIERS
|
1361
|
-
container.ongoing_visibility = save_visibility
|
1362
|
-
|
1363
|
-
parse_comment container, tk, comment unless comment.empty?
|
1364
|
-
|
1365
|
-
return
|
1366
|
-
end
|
1367
1898
|
else
|
1899
|
+
try_parse_comment = nest == 1
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
if try_parse_comment then
|
1368
1903
|
non_comment_seen = parse_comment container, tk, comment unless
|
1369
1904
|
comment.empty?
|
1370
1905
|
|
1371
|
-
|
1906
|
+
keep_comment = false
|
1372
1907
|
end
|
1373
1908
|
|
1374
|
-
|
1909
|
+
unless keep_comment then
|
1910
|
+
comment = new_comment ''
|
1911
|
+
comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding
|
1912
|
+
container.params = nil
|
1913
|
+
container.block_params = nil
|
1914
|
+
end
|
1375
1915
|
|
1376
|
-
|
1377
|
-
get_tkread
|
1378
|
-
skip_tkspace false
|
1379
|
-
end while peek_tk == TkNL
|
1916
|
+
consume_trailing_spaces
|
1380
1917
|
end
|
1918
|
+
|
1919
|
+
container.params = nil
|
1920
|
+
container.block_params = nil
|
1381
1921
|
end
|
1382
1922
|
|
1383
1923
|
##
|
1384
1924
|
# Parse up to +no+ symbol arguments
|
1385
1925
|
|
1386
1926
|
def parse_symbol_arg(no = nil)
|
1387
|
-
args = []
|
1388
|
-
|
1389
1927
|
skip_tkspace_comment
|
1390
1928
|
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
end
|
1929
|
+
tk = get_tk
|
1930
|
+
if tk[:kind] == :on_lparen
|
1931
|
+
parse_symbol_arg_paren no
|
1932
|
+
else
|
1933
|
+
parse_symbol_arg_space no, tk
|
1934
|
+
end
|
1935
|
+
end
|
1399
1936
|
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1937
|
+
##
|
1938
|
+
# Parses up to +no+ symbol arguments surrounded by () and places them in
|
1939
|
+
# +args+.
|
1940
|
+
|
1941
|
+
def parse_symbol_arg_paren no # :nodoc:
|
1942
|
+
args = []
|
1943
|
+
|
1944
|
+
loop do
|
1945
|
+
skip_tkspace_comment
|
1946
|
+
if tk1 = parse_symbol_in_arg
|
1947
|
+
args.push tk1
|
1948
|
+
break if no and args.size >= no
|
1409
1949
|
end
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1950
|
+
|
1951
|
+
skip_tkspace_comment
|
1952
|
+
case (tk2 = get_tk)[:kind]
|
1953
|
+
when :on_rparen
|
1954
|
+
break
|
1955
|
+
when :on_comma
|
1956
|
+
else
|
1957
|
+
warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC
|
1958
|
+
break
|
1415
1959
|
end
|
1960
|
+
end
|
1416
1961
|
|
1417
|
-
|
1418
|
-
|
1962
|
+
args
|
1963
|
+
end
|
1419
1964
|
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
break
|
1424
|
-
end
|
1965
|
+
##
|
1966
|
+
# Parses up to +no+ symbol arguments separated by spaces and places them in
|
1967
|
+
# +args+.
|
1425
1968
|
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1969
|
+
def parse_symbol_arg_space no, tk # :nodoc:
|
1970
|
+
args = []
|
1971
|
+
|
1972
|
+
unget_tk tk
|
1973
|
+
if tk = parse_symbol_in_arg
|
1974
|
+
args.push tk
|
1975
|
+
return args if no and args.size >= no
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
loop do
|
1979
|
+
skip_tkspace_without_nl
|
1980
|
+
|
1981
|
+
tk1 = get_tk
|
1982
|
+
if tk1.nil? || :on_comma != tk1[:kind] then
|
1983
|
+
unget_tk tk1
|
1984
|
+
break
|
1985
|
+
end
|
1986
|
+
|
1987
|
+
skip_tkspace_comment
|
1988
|
+
if tk = parse_symbol_in_arg
|
1989
|
+
args.push tk
|
1990
|
+
break if no and args.size >= no
|
1431
1991
|
end
|
1432
1992
|
end
|
1433
1993
|
|
@@ -1438,12 +1998,12 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1438
1998
|
# Returns symbol text from the next token
|
1439
1999
|
|
1440
2000
|
def parse_symbol_in_arg
|
1441
|
-
|
1442
|
-
|
1443
|
-
tk
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
2001
|
+
tk = get_tk
|
2002
|
+
if :on_symbol == tk[:kind] then
|
2003
|
+
tk[:text].sub(/^:/, '')
|
2004
|
+
elsif :on_tstring == tk[:kind] then
|
2005
|
+
tk[:text][1..-2]
|
2006
|
+
elsif :on_dstring == tk[:kind] or :on_ident == tk[:kind] then
|
1447
2007
|
nil # ignore
|
1448
2008
|
else
|
1449
2009
|
warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC
|
@@ -1452,12 +2012,20 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1452
2012
|
end
|
1453
2013
|
|
1454
2014
|
##
|
1455
|
-
# Parses statements
|
2015
|
+
# Parses statements in the top-level +container+
|
1456
2016
|
|
1457
|
-
def parse_top_level_statements
|
2017
|
+
def parse_top_level_statements container
|
1458
2018
|
comment = collect_first_comment
|
1459
|
-
|
2019
|
+
|
2020
|
+
look_for_directives_in container, comment
|
2021
|
+
|
2022
|
+
throw :eof if container.done_documenting
|
2023
|
+
|
2024
|
+
@markup = comment.format
|
2025
|
+
|
2026
|
+
# HACK move if to RDoc::Context#comment=
|
1460
2027
|
container.comment = comment if container.document_self unless comment.empty?
|
2028
|
+
|
1461
2029
|
parse_statements container, NORMAL, nil, comment
|
1462
2030
|
end
|
1463
2031
|
|
@@ -1465,65 +2033,39 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1465
2033
|
# Determines the visibility in +container+ from +tk+
|
1466
2034
|
|
1467
2035
|
def parse_visibility(container, single, tk)
|
1468
|
-
singleton =
|
1469
|
-
|
1470
|
-
vis_type = tk.name
|
1471
|
-
|
1472
|
-
vis = case vis_type
|
1473
|
-
when 'private' then :private
|
1474
|
-
when 'protected' then :protected
|
1475
|
-
when 'public' then :public
|
1476
|
-
when 'private_class_method' then
|
1477
|
-
singleton = true
|
1478
|
-
:private
|
1479
|
-
when 'public_class_method' then
|
1480
|
-
singleton = true
|
1481
|
-
:public
|
1482
|
-
when 'module_function' then
|
1483
|
-
singleton = true
|
1484
|
-
:public
|
1485
|
-
else
|
1486
|
-
raise RDoc::Error, "Invalid visibility: #{tk.name}"
|
1487
|
-
end
|
2036
|
+
vis_type, vis, singleton = get_visibility_information tk, single
|
1488
2037
|
|
1489
2038
|
skip_tkspace_comment false
|
1490
2039
|
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
2040
|
+
ptk = peek_tk
|
2041
|
+
# Ryan Davis suggested the extension to ignore modifiers, because he
|
2042
|
+
# often writes
|
2043
|
+
#
|
2044
|
+
# protected unless $TESTING
|
2045
|
+
#
|
2046
|
+
if [:on_nl, :on_semicolon].include?(ptk[:kind]) || (:on_kw == ptk[:kind] && (['if', 'unless'].include?(ptk[:text]))) then
|
1498
2047
|
container.ongoing_visibility = vis
|
2048
|
+
elsif :on_kw == ptk[:kind] && 'def' == ptk[:text]
|
2049
|
+
container.current_line_visibility = vis
|
1499
2050
|
else
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
module_functions = []
|
1505
|
-
|
1506
|
-
container.methods_matching args do |m|
|
1507
|
-
s_m = m.dup
|
1508
|
-
s_m.record_location @top_level
|
1509
|
-
s_m.singleton = true
|
1510
|
-
s_m.visibility = :public
|
1511
|
-
module_functions << s_m
|
1512
|
-
end
|
2051
|
+
update_visibility container, vis_type, vis, singleton
|
2052
|
+
end
|
2053
|
+
end
|
1513
2054
|
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
2055
|
+
##
|
2056
|
+
# Parses a Module#private_constant or Module#public_constant call from +tk+.
|
2057
|
+
|
2058
|
+
def parse_constant_visibility(container, single, tk)
|
2059
|
+
args = parse_symbol_arg
|
2060
|
+
case tk[:text]
|
2061
|
+
when 'private_constant'
|
2062
|
+
vis = :private
|
2063
|
+
when 'public_constant'
|
2064
|
+
vis = :public
|
2065
|
+
else
|
2066
|
+
raise RDoc::Error, 'Unreachable'
|
1526
2067
|
end
|
2068
|
+
container.set_constant_visibility_for args, vis
|
1527
2069
|
end
|
1528
2070
|
|
1529
2071
|
##
|
@@ -1533,7 +2075,6 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1533
2075
|
return if method.block_params
|
1534
2076
|
|
1535
2077
|
get_tkread
|
1536
|
-
@scanner.instance_eval { @continue = false }
|
1537
2078
|
method.block_params = parse_method_or_yield_parameters
|
1538
2079
|
end
|
1539
2080
|
|
@@ -1547,49 +2088,72 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1547
2088
|
#
|
1548
2089
|
# class MyClass # :nodoc:
|
1549
2090
|
#
|
1550
|
-
# We return the directive name and any parameters as a two element array
|
2091
|
+
# We return the directive name and any parameters as a two element array if
|
2092
|
+
# the name is in +allowed+. A directive can be found anywhere up to the end
|
2093
|
+
# of the current line.
|
1551
2094
|
|
1552
2095
|
def read_directive allowed
|
1553
|
-
|
2096
|
+
tokens = []
|
2097
|
+
|
2098
|
+
while tk = get_tk do
|
2099
|
+
tokens << tk
|
1554
2100
|
|
1555
|
-
|
1556
|
-
|
2101
|
+
if :on_nl == tk[:kind] or (:on_kw == tk[:kind] && 'def' == tk[:text]) then
|
2102
|
+
return
|
2103
|
+
elsif :on_comment == tk[:kind] or :on_embdoc == tk[:kind] then
|
2104
|
+
return unless tk[:text] =~ /\s*:?([\w-]+):\s*(.*)/
|
1557
2105
|
|
1558
|
-
|
2106
|
+
directive = $1.downcase
|
1559
2107
|
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
2108
|
+
return [directive, $2] if allowed.include? directive
|
2109
|
+
|
2110
|
+
return
|
2111
|
+
end
|
2112
|
+
end
|
2113
|
+
ensure
|
2114
|
+
unless tokens.length == 1 and (:on_comment == tokens.first[:kind] or :on_embdoc == tokens.first[:kind]) then
|
2115
|
+
tokens.reverse_each do |token|
|
2116
|
+
unget_tk token
|
2117
|
+
end
|
1563
2118
|
end
|
1564
2119
|
end
|
1565
2120
|
|
1566
2121
|
##
|
1567
|
-
# Handles the
|
1568
|
-
#
|
2122
|
+
# Handles directives following the definition for +context+ (any
|
2123
|
+
# RDoc::CodeObject) if the directives are +allowed+ at this point.
|
2124
|
+
#
|
2125
|
+
# See also RDoc::Markup::PreProcess#handle_directive
|
1569
2126
|
|
1570
|
-
def read_documentation_modifiers
|
1571
|
-
|
2127
|
+
def read_documentation_modifiers context, allowed
|
2128
|
+
skip_tkspace_without_nl
|
2129
|
+
directive, value = read_directive allowed
|
1572
2130
|
|
1573
2131
|
return unless directive
|
1574
2132
|
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
2133
|
+
@preprocess.handle_directive '', directive, value, context do |dir, param|
|
2134
|
+
if %w[notnew not_new not-new].include? dir then
|
2135
|
+
context.dont_rename_initialize = true
|
2136
|
+
|
2137
|
+
true
|
2138
|
+
end
|
1580
2139
|
end
|
1581
2140
|
end
|
1582
2141
|
|
1583
2142
|
##
|
1584
|
-
#
|
2143
|
+
# Records the location of this +container+ in the file for this parser and
|
2144
|
+
# adds it to the list of classes and modules in the file.
|
1585
2145
|
|
1586
|
-
def
|
1587
|
-
|
1588
|
-
|
2146
|
+
def record_location container # :nodoc:
|
2147
|
+
case container
|
2148
|
+
when RDoc::ClassModule then
|
2149
|
+
@top_level.add_to_classes_or_modules container
|
2150
|
+
end
|
2151
|
+
|
2152
|
+
container.record_location @top_level
|
1589
2153
|
end
|
1590
2154
|
|
1591
2155
|
##
|
1592
|
-
# Scans this
|
2156
|
+
# Scans this Ruby file for Ruby constructs
|
1593
2157
|
|
1594
2158
|
def scan
|
1595
2159
|
reset
|
@@ -1597,30 +2161,35 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1597
2161
|
catch :eof do
|
1598
2162
|
begin
|
1599
2163
|
parse_top_level_statements @top_level
|
2164
|
+
|
1600
2165
|
rescue StandardError => e
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
count = i
|
1607
|
-
byte = @scanner.getc
|
1608
|
-
break unless byte
|
1609
|
-
bytes << byte
|
2166
|
+
if @content.include?('<%') and @content.include?('%>') then
|
2167
|
+
# Maybe, this is ERB.
|
2168
|
+
$stderr.puts "\033[2KRDoc detects ERB file. Skips it for compatibility:"
|
2169
|
+
$stderr.puts @file_name
|
2170
|
+
return
|
1610
2171
|
end
|
1611
|
-
|
1612
|
-
|
2172
|
+
|
2173
|
+
if @scanner_point >= @scanner.size
|
2174
|
+
now_line_no = @scanner[@scanner.size - 1][:line_no]
|
2175
|
+
else
|
2176
|
+
now_line_no = peek_tk[:line_no]
|
2177
|
+
end
|
2178
|
+
first_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no }
|
2179
|
+
last_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no + 1 }
|
2180
|
+
last_tk_index = last_tk_index ? last_tk_index - 1 : @scanner.size - 1
|
2181
|
+
code = @scanner[first_tk_index..last_tk_index].map{ |t| t[:text] }.join
|
1613
2182
|
|
1614
2183
|
$stderr.puts <<-EOF
|
1615
2184
|
|
1616
|
-
#{self.class} failure around line #{
|
2185
|
+
#{self.class} failure around line #{now_line_no} of
|
1617
2186
|
#{@file_name}
|
1618
2187
|
|
1619
2188
|
EOF
|
1620
2189
|
|
1621
|
-
unless
|
2190
|
+
unless code.empty? then
|
2191
|
+
$stderr.puts code
|
1622
2192
|
$stderr.puts
|
1623
|
-
$stderr.puts bytes.inspect
|
1624
2193
|
end
|
1625
2194
|
|
1626
2195
|
raise e
|
@@ -1634,58 +2203,52 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1634
2203
|
# while, until, and for have an optional do
|
1635
2204
|
|
1636
2205
|
def skip_optional_do_after_expression
|
1637
|
-
|
2206
|
+
skip_tkspace_without_nl
|
1638
2207
|
tk = get_tk
|
1639
|
-
case tk
|
1640
|
-
when TkLPAREN, TkfLPAREN then
|
1641
|
-
end_token = TkRPAREN
|
1642
|
-
else
|
1643
|
-
end_token = TkNL
|
1644
|
-
end
|
1645
2208
|
|
1646
2209
|
b_nest = 0
|
1647
2210
|
nest = 0
|
1648
|
-
@scanner.instance_eval { @continue = false }
|
1649
2211
|
|
1650
2212
|
loop do
|
1651
|
-
|
1652
|
-
|
2213
|
+
break unless tk
|
2214
|
+
case tk[:kind]
|
2215
|
+
when :on_semicolon, :on_nl, :on_ignored_nl then
|
1653
2216
|
break if b_nest.zero?
|
1654
|
-
when
|
2217
|
+
when :on_lparen then
|
1655
2218
|
nest += 1
|
1656
|
-
when
|
1657
|
-
|
1658
|
-
when
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
break if
|
1666
|
-
|
1667
|
-
|
2219
|
+
when :on_rparen then
|
2220
|
+
nest -= 1
|
2221
|
+
when :on_kw then
|
2222
|
+
case tk[:text]
|
2223
|
+
when 'begin'
|
2224
|
+
b_nest += 1
|
2225
|
+
when 'end'
|
2226
|
+
b_nest -= 1
|
2227
|
+
when 'do'
|
2228
|
+
break if nest.zero?
|
2229
|
+
end
|
2230
|
+
when :on_comment, :on_embdoc then
|
2231
|
+
if b_nest.zero? and "\n" == tk[:text][-1] then
|
2232
|
+
break
|
1668
2233
|
end
|
1669
|
-
when nil then
|
1670
|
-
break
|
1671
2234
|
end
|
1672
2235
|
tk = get_tk
|
1673
2236
|
end
|
1674
2237
|
|
1675
|
-
|
2238
|
+
skip_tkspace_without_nl
|
1676
2239
|
|
1677
|
-
get_tk if
|
2240
|
+
get_tk if peek_tk && :on_kw == peek_tk[:kind] && 'do' == peek_tk[:text]
|
1678
2241
|
end
|
1679
2242
|
|
1680
2243
|
##
|
1681
2244
|
# skip the var [in] part of a 'for' statement
|
1682
2245
|
|
1683
2246
|
def skip_for_variable
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
2247
|
+
skip_tkspace_without_nl
|
2248
|
+
get_tk
|
2249
|
+
skip_tkspace_without_nl
|
1687
2250
|
tk = get_tk
|
1688
|
-
unget_tk(tk) unless
|
2251
|
+
unget_tk(tk) unless :on_kw == tk[:kind] and 'in' == tk[:text]
|
1689
2252
|
end
|
1690
2253
|
|
1691
2254
|
##
|
@@ -1702,20 +2265,63 @@ class RDoc::Parser::Ruby < RDoc::Parser
|
|
1702
2265
|
|
1703
2266
|
def skip_tkspace_comment(skip_nl = true)
|
1704
2267
|
loop do
|
1705
|
-
skip_tkspace
|
1706
|
-
|
2268
|
+
skip_nl ? skip_tkspace : skip_tkspace_without_nl
|
2269
|
+
next_tk = peek_tk
|
2270
|
+
return if next_tk.nil? || (:on_comment != next_tk[:kind] and :on_embdoc != next_tk[:kind])
|
1707
2271
|
get_tk
|
1708
2272
|
end
|
1709
2273
|
end
|
1710
2274
|
|
1711
2275
|
##
|
1712
|
-
#
|
2276
|
+
# Updates visibility in +container+ from +vis_type+ and +vis+.
|
1713
2277
|
|
1714
|
-
def
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
2278
|
+
def update_visibility container, vis_type, vis, singleton # :nodoc:
|
2279
|
+
new_methods = []
|
2280
|
+
|
2281
|
+
case vis_type
|
2282
|
+
when 'module_function' then
|
2283
|
+
args = parse_symbol_arg
|
2284
|
+
container.set_visibility_for args, :private, false
|
2285
|
+
|
2286
|
+
container.methods_matching args do |m|
|
2287
|
+
s_m = m.dup
|
2288
|
+
record_location s_m
|
2289
|
+
s_m.singleton = true
|
2290
|
+
new_methods << s_m
|
2291
|
+
end
|
2292
|
+
when 'public_class_method', 'private_class_method' then
|
2293
|
+
args = parse_symbol_arg
|
2294
|
+
|
2295
|
+
container.methods_matching args, true do |m|
|
2296
|
+
if m.parent != container then
|
2297
|
+
m = m.dup
|
2298
|
+
record_location m
|
2299
|
+
new_methods << m
|
2300
|
+
end
|
2301
|
+
|
2302
|
+
m.visibility = vis
|
2303
|
+
end
|
2304
|
+
else
|
2305
|
+
args = parse_symbol_arg
|
2306
|
+
container.set_visibility_for args, vis, singleton
|
2307
|
+
end
|
2308
|
+
|
2309
|
+
new_methods.each do |method|
|
2310
|
+
case method
|
2311
|
+
when RDoc::AnyMethod then
|
2312
|
+
container.add_method method
|
2313
|
+
when RDoc::Attr then
|
2314
|
+
container.add_attribute method
|
2315
|
+
end
|
2316
|
+
method.visibility = vis
|
2317
|
+
end
|
1718
2318
|
end
|
1719
2319
|
|
1720
|
-
|
2320
|
+
##
|
2321
|
+
# Prints +message+ to +$stderr+ unless we're being quiet
|
1721
2322
|
|
2323
|
+
def warn message
|
2324
|
+
@options.warn make_message message
|
2325
|
+
end
|
2326
|
+
|
2327
|
+
end
|