yard 0.9.37 → 0.9.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -1
- data/README.md +27 -30
- data/docs/GettingStarted.md +41 -15
- data/docs/Tags.md +5 -5
- data/docs/Templates.md +5 -4
- data/docs/WhatsNew.md +59 -7
- data/docs/templates/default/yard_tags/html/setup.rb +1 -1
- data/lib/yard/autoload.rb +17 -0
- data/lib/yard/cli/diff.rb +7 -2
- data/lib/yard/code_objects/base.rb +1 -1
- data/lib/yard/code_objects/extra_file_object.rb +1 -0
- data/lib/yard/code_objects/proxy.rb +1 -1
- data/lib/yard/handlers/base.rb +23 -1
- data/lib/yard/handlers/processor.rb +1 -0
- data/lib/yard/handlers/rbs/attribute_handler.rb +43 -0
- data/lib/yard/handlers/rbs/base.rb +38 -0
- data/lib/yard/handlers/rbs/constant_handler.rb +18 -0
- data/lib/yard/handlers/rbs/method_handler.rb +327 -0
- data/lib/yard/handlers/rbs/mixin_handler.rb +20 -0
- data/lib/yard/handlers/rbs/namespace_handler.rb +26 -0
- data/lib/yard/handlers/ruby/attribute_handler.rb +7 -4
- data/lib/yard/handlers/ruby/constant_handler.rb +24 -6
- data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
- data/lib/yard/handlers/ruby/visibility_handler.rb +1 -0
- data/lib/yard/i18n/locale.rb +1 -1
- data/lib/yard/i18n/pot_generator.rb +1 -1
- data/lib/yard/parser/rbs/rbs_parser.rb +325 -0
- data/lib/yard/parser/rbs/statement.rb +75 -0
- data/lib/yard/parser/ruby/ast_node.rb +5 -4
- data/lib/yard/parser/ruby/legacy/irb/slex.rb +19 -1
- data/lib/yard/parser/ruby/legacy/ruby_lex.rb +1 -1
- data/lib/yard/parser/ruby/ruby_parser.rb +109 -24
- data/lib/yard/parser/source_parser.rb +3 -2
- data/lib/yard/registry_resolver.rb +7 -0
- data/lib/yard/rubygems/specification.rb +1 -1
- data/lib/yard/server/library_version.rb +1 -1
- data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +208 -12
- data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +1 -17
- data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -2
- data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +3 -3
- data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +2 -3
- data/lib/yard/server/templates/doc_server/processing/html/processing.erb +22 -16
- data/lib/yard/tags/directives.rb +7 -0
- data/lib/yard/tags/library.rb +3 -3
- data/lib/yard/tags/overload_tag.rb +2 -1
- data/lib/yard/tags/tag.rb +1 -1
- data/lib/yard/tags/types_explainer.rb +5 -4
- data/lib/yard/templates/helpers/base_helper.rb +1 -1
- data/lib/yard/templates/helpers/html_helper.rb +21 -6
- data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +6 -1
- data/lib/yard/templates/helpers/markup/hybrid_markdown.rb +2147 -0
- data/lib/yard/templates/helpers/markup/rdoc_markup.rb +2 -0
- data/lib/yard/templates/helpers/markup_helper.rb +4 -2
- data/lib/yard/version.rb +1 -1
- data/po/ja.po +82 -82
- data/templates/default/fulldoc/html/css/style.css +33 -15
- data/templates/default/fulldoc/html/full_list.erb +4 -4
- data/templates/default/fulldoc/html/js/app.js +567 -271
- data/templates/default/fulldoc/html/js/full_list.js +341 -211
- data/templates/default/layout/html/headers.erb +1 -1
- data/templates/default/layout/html/layout.erb +2 -1
- data/templates/default/method/html/header.erb +3 -3
- data/templates/default/module/html/defines.erb +3 -3
- data/templates/default/module/html/inherited_methods.erb +1 -0
- data/templates/default/module/html/method_summary.erb +8 -0
- data/templates/default/module/setup.rb +20 -0
- data/templates/default/onefile/html/layout.erb +3 -4
- data/templates/guide/fulldoc/html/js/app.js +57 -26
- data/templates/guide/layout/html/layout.erb +9 -11
- metadata +18 -8
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module YARD
|
|
3
|
+
module Parser
|
|
4
|
+
module RBS
|
|
5
|
+
# Parses RBS (Ruby type signature) files and produces a list of
|
|
6
|
+
# {Statement} objects for post-processing by handlers.
|
|
7
|
+
#
|
|
8
|
+
# RBS is Ruby's official type signature format (introduced in Ruby 3.0).
|
|
9
|
+
# This parser handles: class/module/interface declarations, method
|
|
10
|
+
# signatures, attribute accessors, mixins, and constants.
|
|
11
|
+
#
|
|
12
|
+
# No external gem dependencies are used; the parser is hand-written.
|
|
13
|
+
class RbsParser < YARD::Parser::Base
|
|
14
|
+
# @param source [String] source code to parse
|
|
15
|
+
# @param filename [String] path to the source file
|
|
16
|
+
def initialize(source, filename)
|
|
17
|
+
@source = source
|
|
18
|
+
@filename = filename
|
|
19
|
+
@statements = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Parses the source and returns self.
|
|
23
|
+
# @return [RbsParser] self
|
|
24
|
+
def parse
|
|
25
|
+
lines = @source.lines.map { |l| l.chomp }
|
|
26
|
+
@statements, = parse_body(lines, 0, false)
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Tokenization is not implemented for RBS.
|
|
31
|
+
def tokenize
|
|
32
|
+
raise NotImplementedError, "RBS parser does not support tokenization"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @return [Array<Statement>] top-level statements for the post-processor
|
|
36
|
+
def enumerator
|
|
37
|
+
@statements
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# Parse a sequence of lines, returning statements and the index after the last consumed line.
|
|
43
|
+
#
|
|
44
|
+
# @param lines [Array<String>] source lines
|
|
45
|
+
# @param start [Integer] index to start from (0-based)
|
|
46
|
+
# @param stop_at_end [Boolean] when true, stop parsing when we see a bare `end`
|
|
47
|
+
# @return [Array(Array<Statement>, Integer)] [statements, new_index]
|
|
48
|
+
def parse_body(lines, start, stop_at_end)
|
|
49
|
+
statements = []
|
|
50
|
+
i = start
|
|
51
|
+
pending_comments = []
|
|
52
|
+
pending_start_1 = nil # 1-indexed line number of first pending comment
|
|
53
|
+
|
|
54
|
+
while i < lines.length
|
|
55
|
+
raw = lines[i]
|
|
56
|
+
stripped = raw.strip
|
|
57
|
+
|
|
58
|
+
if stripped =~ /\A#(.*)/
|
|
59
|
+
# Comment line – accumulate into pending docstring.
|
|
60
|
+
# Strip at most one leading space (conventional RBS doc style).
|
|
61
|
+
pending_comments << $1.sub(/\A /, '')
|
|
62
|
+
pending_start_1 ||= i + 1
|
|
63
|
+
i += 1
|
|
64
|
+
|
|
65
|
+
elsif stripped.empty?
|
|
66
|
+
# Blank line resets pending comments.
|
|
67
|
+
pending_comments = []
|
|
68
|
+
pending_start_1 = nil
|
|
69
|
+
i += 1
|
|
70
|
+
|
|
71
|
+
elsif stop_at_end && stripped == 'end'
|
|
72
|
+
# End of enclosing block.
|
|
73
|
+
return [statements, i + 1]
|
|
74
|
+
|
|
75
|
+
else
|
|
76
|
+
stmt, i = parse_statement(lines, i, pending_comments, pending_start_1)
|
|
77
|
+
statements << stmt if stmt
|
|
78
|
+
pending_comments = []
|
|
79
|
+
pending_start_1 = nil
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
[statements, i]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def strip_inline_comment(line)
|
|
87
|
+
in_single = false
|
|
88
|
+
in_double = false
|
|
89
|
+
escaped = false
|
|
90
|
+
|
|
91
|
+
line.each_char.with_index do |char, index|
|
|
92
|
+
if escaped
|
|
93
|
+
escaped = false
|
|
94
|
+
next
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
case char
|
|
98
|
+
when "\\"
|
|
99
|
+
escaped = true if in_single || in_double
|
|
100
|
+
when "'"
|
|
101
|
+
in_single = !in_single unless in_double
|
|
102
|
+
when '"'
|
|
103
|
+
in_double = !in_double unless in_single
|
|
104
|
+
when '#'
|
|
105
|
+
return line[0...index].rstrip unless in_single || in_double
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
line.rstrip
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def sanitized_statement_lines(lines, start_index)
|
|
113
|
+
overrides = { start_index => strip_inline_comment(lines[start_index]) }
|
|
114
|
+
|
|
115
|
+
j = start_index + 1
|
|
116
|
+
while j < lines.length && lines[j].lstrip.start_with?('|')
|
|
117
|
+
overrides[j] = strip_inline_comment(lines[j])
|
|
118
|
+
j += 1
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
overrides
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Dispatch a single declaration line.
|
|
125
|
+
def parse_statement(lines, i, comments, comment_start_1)
|
|
126
|
+
sanitized = sanitized_statement_lines(lines, i)
|
|
127
|
+
stripped = sanitized.fetch(i, lines[i]).strip
|
|
128
|
+
line_num = i + 1 # 1-indexed
|
|
129
|
+
|
|
130
|
+
docs = comments.empty? ? nil : comments.join("\n")
|
|
131
|
+
crange = comment_start_1 ? (comment_start_1)..(line_num - 1) : nil
|
|
132
|
+
|
|
133
|
+
case stripped
|
|
134
|
+
when /\Aclass\s/
|
|
135
|
+
parse_namespace(:class, lines, i, docs, crange)
|
|
136
|
+
when /\Amodule\s/
|
|
137
|
+
parse_namespace(:module, lines, i, docs, crange)
|
|
138
|
+
when /\Ainterface\s/
|
|
139
|
+
parse_namespace(:interface, lines, i, docs, crange)
|
|
140
|
+
when /\Adef\s/
|
|
141
|
+
parse_method_def(sanitized, lines, i, docs, crange)
|
|
142
|
+
when /\Aattr_reader\s/
|
|
143
|
+
parse_attr(:attr_reader, lines, i, docs, crange)
|
|
144
|
+
when /\Aattr_writer\s/
|
|
145
|
+
parse_attr(:attr_writer, lines, i, docs, crange)
|
|
146
|
+
when /\Aattr_accessor\s/
|
|
147
|
+
parse_attr(:attr_accessor, lines, i, docs, crange)
|
|
148
|
+
when /\A(include|extend|prepend)\s+(\S+)/
|
|
149
|
+
kind = $1.to_sym
|
|
150
|
+
name = $2.delete(';')
|
|
151
|
+
stmt = Statement.new(
|
|
152
|
+
:type => kind,
|
|
153
|
+
:name => name,
|
|
154
|
+
:mixin_name => name,
|
|
155
|
+
:line => line_num,
|
|
156
|
+
:source => stripped,
|
|
157
|
+
:comments => docs,
|
|
158
|
+
:comments_range => crange
|
|
159
|
+
)
|
|
160
|
+
[stmt, i + 1]
|
|
161
|
+
when /\Aalias\s+(\S+)\s+(\S+)/
|
|
162
|
+
stmt = Statement.new(
|
|
163
|
+
:type => :alias,
|
|
164
|
+
:name => $1,
|
|
165
|
+
:line => line_num,
|
|
166
|
+
:source => stripped,
|
|
167
|
+
:comments => docs,
|
|
168
|
+
:comments_range => crange
|
|
169
|
+
)
|
|
170
|
+
[stmt, i + 1]
|
|
171
|
+
when /\A(public|private|protected)\s*(\z|#)/
|
|
172
|
+
# Visibility modifier – skip silently.
|
|
173
|
+
[nil, i + 1]
|
|
174
|
+
when /\Aend\s*(\z|#)/
|
|
175
|
+
# Stray `end` – skip.
|
|
176
|
+
[nil, i + 1]
|
|
177
|
+
when /\Atype\s/
|
|
178
|
+
# Type alias declaration – nothing to document.
|
|
179
|
+
[nil, i + 1]
|
|
180
|
+
else
|
|
181
|
+
# Constant declaration: `NAME: Type`
|
|
182
|
+
if stripped =~ /\A([A-Z][a-zA-Z0-9_]*(?:::[A-Z][a-zA-Z0-9_]*)*)\s*:\s*(.+)\z/
|
|
183
|
+
stmt = Statement.new(
|
|
184
|
+
:type => :constant,
|
|
185
|
+
:name => $1,
|
|
186
|
+
:attr_rbs_type => $2.strip,
|
|
187
|
+
:line => line_num,
|
|
188
|
+
:source => stripped,
|
|
189
|
+
:comments => docs,
|
|
190
|
+
:comments_range => crange
|
|
191
|
+
)
|
|
192
|
+
[stmt, i + 1]
|
|
193
|
+
else
|
|
194
|
+
[nil, i + 1]
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def parse_namespace(type, lines, i, docs, crange)
|
|
200
|
+
# Strip trailing inline comment from the declaration line.
|
|
201
|
+
decl = lines[i].strip.sub(/\s*#.*\z/, '')
|
|
202
|
+
line_num = i + 1
|
|
203
|
+
|
|
204
|
+
name = nil
|
|
205
|
+
superclass = nil
|
|
206
|
+
|
|
207
|
+
case type
|
|
208
|
+
when :class
|
|
209
|
+
# class Foo[T] < Bar[String]
|
|
210
|
+
if decl =~ /\Aclass\s+([^\s<\[]+)(\[[^\]]*\])?(?:\s*<\s*(.+))?\z/
|
|
211
|
+
name = $1.strip
|
|
212
|
+
superclass = $3 ? $3.strip : nil
|
|
213
|
+
# Strip generic params from superclass, e.g. "Array[String]" -> "Array"
|
|
214
|
+
superclass.sub!(/\[.*\]\z/, '') if superclass
|
|
215
|
+
else
|
|
216
|
+
return [nil, i + 1]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
when :module
|
|
220
|
+
# module Foo[T] : SelfType
|
|
221
|
+
if decl =~ /\Amodule\s+([^\s\[(:]+)/
|
|
222
|
+
name = $1.strip
|
|
223
|
+
else
|
|
224
|
+
return [nil, i + 1]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
when :interface
|
|
228
|
+
# interface _Foo[T]
|
|
229
|
+
if decl =~ /\Ainterface\s+([^\s\[]+)/
|
|
230
|
+
name = $1.strip
|
|
231
|
+
else
|
|
232
|
+
return [nil, i + 1]
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
children, new_i = parse_body(lines, i + 1, true)
|
|
237
|
+
source = lines[i...new_i].join("\n")
|
|
238
|
+
|
|
239
|
+
stmt = Statement.new(
|
|
240
|
+
:type => type,
|
|
241
|
+
:name => name,
|
|
242
|
+
:superclass => superclass,
|
|
243
|
+
:line => line_num,
|
|
244
|
+
:source => source,
|
|
245
|
+
:comments => docs,
|
|
246
|
+
:comments_range => crange,
|
|
247
|
+
:block => children
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
[stmt, new_i]
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def parse_method_def(sanitized, lines, i, docs, crange)
|
|
254
|
+
stripped = sanitized.fetch(i, lines[i]).strip
|
|
255
|
+
line_num = i + 1
|
|
256
|
+
|
|
257
|
+
# def method_name: overload1
|
|
258
|
+
# | overload2
|
|
259
|
+
# Also handles: def self.method_name: ...
|
|
260
|
+
unless stripped =~ /\Adef\s+(self\.)?(\S+?)\s*:\s*(.*)\z/
|
|
261
|
+
return [nil, i + 1]
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
is_class_side = !$1.nil?
|
|
265
|
+
meth_name = $2
|
|
266
|
+
first_sig = $3.strip
|
|
267
|
+
|
|
268
|
+
sigs = [first_sig]
|
|
269
|
+
j = i + 1
|
|
270
|
+
|
|
271
|
+
# Collect `| overload` continuation lines.
|
|
272
|
+
while j < lines.length
|
|
273
|
+
cont = sanitized.fetch(j, lines[j]).strip
|
|
274
|
+
if cont =~ /\A\|\s*(.*)\z/
|
|
275
|
+
sigs << $1.strip
|
|
276
|
+
j += 1
|
|
277
|
+
else
|
|
278
|
+
break
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
stmt = Statement.new(
|
|
283
|
+
:type => :method_def,
|
|
284
|
+
:name => meth_name,
|
|
285
|
+
:line => line_num,
|
|
286
|
+
:source => lines[i...j].join("\n"),
|
|
287
|
+
:comments => docs,
|
|
288
|
+
:comments_range => crange,
|
|
289
|
+
:signatures => sigs,
|
|
290
|
+
:visibility => is_class_side ? :class : :instance
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
[stmt, j]
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def parse_attr(type, lines, i, docs, crange)
|
|
297
|
+
stripped = strip_inline_comment(lines[i]).strip
|
|
298
|
+
line_num = i + 1
|
|
299
|
+
keyword = type.to_s
|
|
300
|
+
|
|
301
|
+
# attr_reader [self.] name : Type
|
|
302
|
+
if stripped =~ /\A#{Regexp.escape(keyword)}\s+(self\.)?(\w+)\s*:\s*(.*)\z/
|
|
303
|
+
is_class = !$1.nil?
|
|
304
|
+
attr_name = $2
|
|
305
|
+
attr_type = $3.strip
|
|
306
|
+
|
|
307
|
+
stmt = Statement.new(
|
|
308
|
+
:type => type,
|
|
309
|
+
:name => attr_name,
|
|
310
|
+
:attr_rbs_type => attr_type,
|
|
311
|
+
:line => line_num,
|
|
312
|
+
:source => stripped,
|
|
313
|
+
:comments => docs,
|
|
314
|
+
:comments_range => crange,
|
|
315
|
+
:visibility => is_class ? :class : :instance
|
|
316
|
+
)
|
|
317
|
+
[stmt, i + 1]
|
|
318
|
+
else
|
|
319
|
+
[nil, i + 1]
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
module YARD
|
|
3
|
+
module Parser
|
|
4
|
+
module RBS
|
|
5
|
+
# Represents a single parsed declaration from an RBS file.
|
|
6
|
+
# Each Statement may have a block of child statements for
|
|
7
|
+
# namespace declarations (class, module, interface).
|
|
8
|
+
class Statement
|
|
9
|
+
# @return [Symbol] declaration type:
|
|
10
|
+
# :class, :module, :interface, :method_def,
|
|
11
|
+
# :attr_reader, :attr_writer, :attr_accessor,
|
|
12
|
+
# :include, :extend, :prepend, :constant, :alias
|
|
13
|
+
attr_reader :type
|
|
14
|
+
|
|
15
|
+
# @return [String] the declaration name
|
|
16
|
+
attr_reader :name
|
|
17
|
+
|
|
18
|
+
# @return [String, nil] the superclass name (for :class)
|
|
19
|
+
attr_reader :superclass
|
|
20
|
+
|
|
21
|
+
# @return [Integer] 1-indexed line number of this statement
|
|
22
|
+
attr_reader :line
|
|
23
|
+
|
|
24
|
+
# @return [String] raw source text of the statement
|
|
25
|
+
attr_reader :source
|
|
26
|
+
|
|
27
|
+
# @return [String, nil] adjacent comment text (the docstring)
|
|
28
|
+
attr_reader :comments
|
|
29
|
+
|
|
30
|
+
# @return [Range, nil] line range of the preceding comments
|
|
31
|
+
attr_reader :comments_range
|
|
32
|
+
|
|
33
|
+
# @return [false] RBS files don't use ## hash-flag comments
|
|
34
|
+
attr_reader :comments_hash_flag
|
|
35
|
+
|
|
36
|
+
# @return [Array<Statement>] child statements for namespace blocks
|
|
37
|
+
attr_reader :block
|
|
38
|
+
|
|
39
|
+
# @return [Array<String>] RBS type signature strings for :method_def
|
|
40
|
+
# Each element is one overload (e.g. "(String name) -> Integer")
|
|
41
|
+
attr_reader :signatures
|
|
42
|
+
|
|
43
|
+
# @return [String, nil] mixin name for :include/:extend/:prepend
|
|
44
|
+
attr_reader :mixin_name
|
|
45
|
+
|
|
46
|
+
# @return [String, nil] RBS type annotation for attrs and constants
|
|
47
|
+
attr_reader :attr_rbs_type
|
|
48
|
+
|
|
49
|
+
# @return [Symbol, nil] :class or :instance scope hint from parser
|
|
50
|
+
attr_reader :visibility
|
|
51
|
+
|
|
52
|
+
def initialize(attrs = {})
|
|
53
|
+
@type = attrs[:type]
|
|
54
|
+
@name = attrs[:name]
|
|
55
|
+
@superclass = attrs[:superclass]
|
|
56
|
+
@line = attrs[:line] || 1
|
|
57
|
+
@source = attrs[:source] || ''
|
|
58
|
+
@comments = attrs[:comments]
|
|
59
|
+
@comments_range = attrs[:comments_range]
|
|
60
|
+
@comments_hash_flag = false
|
|
61
|
+
@block = attrs[:block] || []
|
|
62
|
+
@signatures = attrs[:signatures] || []
|
|
63
|
+
@mixin_name = attrs[:mixin_name]
|
|
64
|
+
@attr_rbs_type = attrs[:attr_rbs_type]
|
|
65
|
+
@visibility = attrs[:visibility]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [String] a textual snippet used in error messages
|
|
69
|
+
def show
|
|
70
|
+
source
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -271,7 +271,7 @@ module YARD
|
|
|
271
271
|
|
|
272
272
|
# @return [Fixnum] the starting line number of the node
|
|
273
273
|
def line
|
|
274
|
-
line_range && line_range.
|
|
274
|
+
line_range && (line_range.begin || line_range.end)
|
|
275
275
|
end
|
|
276
276
|
|
|
277
277
|
# @return [String] the first line of source represented by the node.
|
|
@@ -345,8 +345,8 @@ module YARD
|
|
|
345
345
|
elsif !children.empty?
|
|
346
346
|
f = children.first
|
|
347
347
|
l = children.last
|
|
348
|
-
self.line_range = Range.new(f.line_range.
|
|
349
|
-
self.source_range = Range.new(f.source_range.
|
|
348
|
+
self.line_range = Range.new(f.line_range.begin, l.line_range.end)
|
|
349
|
+
self.source_range = Range.new(f.source_range.begin, l.source_range.end)
|
|
350
350
|
elsif @fallback_line || @fallback_source
|
|
351
351
|
self.line_range = @fallback_line
|
|
352
352
|
self.source_range = @fallback_source
|
|
@@ -431,7 +431,8 @@ module YARD
|
|
|
431
431
|
# shape is (required, optional, rest, more, keyword, keyword_rest, block)
|
|
432
432
|
# Ruby 3.1 moves :args_forward from rest to keyword_rest
|
|
433
433
|
args_index = YARD.ruby31? ? -2 : 2
|
|
434
|
-
|
|
434
|
+
node = self[args_index]
|
|
435
|
+
node.is_a?(AstNode) && node.type == :args_forward
|
|
435
436
|
end
|
|
436
437
|
end
|
|
437
438
|
|
|
@@ -10,7 +10,25 @@
|
|
|
10
10
|
#
|
|
11
11
|
#
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
begin
|
|
14
|
+
require "irb/notifier"
|
|
15
|
+
rescue LoadError
|
|
16
|
+
module IRB
|
|
17
|
+
module DebugLogger
|
|
18
|
+
def self.pp(*args) end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
module Notifier
|
|
22
|
+
D_NOMSG = 0x00
|
|
23
|
+
def self.def_notifier(*args) self end
|
|
24
|
+
def self.pp(*args) end
|
|
25
|
+
def self.exec_if(*args, &block) end
|
|
26
|
+
def self.printf(*args) end
|
|
27
|
+
def self.puts(*args) end
|
|
28
|
+
def self.level=(value) end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
14
32
|
|
|
15
33
|
# @private
|
|
16
34
|
module IRB
|