yard 0.9.36 → 0.9.40
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 +59 -1
- data/README.md +29 -25
- 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 +18 -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/macro_object.rb +0 -1
- data/lib/yard/code_objects/proxy.rb +1 -1
- data/lib/yard/docstring_parser.rb +0 -1
- data/lib/yard/handlers/base.rb +23 -1
- data/lib/yard/handlers/processor.rb +1 -1
- 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 +14 -1
- data/lib/yard/i18n/locale.rb +1 -1
- data/lib/yard/i18n/pot_generator.rb +1 -1
- data/lib/yard/logging.rb +116 -61
- data/lib/yard/open_struct.rb +67 -0
- 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 +20 -5
- data/lib/yard/parser/ruby/ruby_parser.rb +109 -24
- data/lib/yard/parser/source_parser.rb +5 -4
- 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/default_factory.rb +1 -0
- data/lib/yard/tags/directives.rb +7 -1
- data/lib/yard/tags/library.rb +3 -3
- data/lib/yard/tags/overload_tag.rb +2 -1
- data/lib/yard/tags/tag.rb +2 -1
- data/lib/yard/tags/types_explainer.rb +5 -4
- data/lib/yard/templates/engine.rb +0 -1
- 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 +2125 -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/templates/template_options.rb +0 -1
- data/lib/yard/version.rb +1 -1
- data/po/ja.po +82 -82
- data/templates/default/fulldoc/html/css/full_list.css +3 -3
- data/templates/default/fulldoc/html/css/style.css +8 -15
- data/templates/default/fulldoc/html/full_list.erb +8 -5
- data/templates/default/fulldoc/html/js/app.js +546 -281
- data/templates/default/fulldoc/html/js/full_list.js +315 -189
- data/templates/default/fulldoc/html/setup.rb +10 -2
- data/templates/default/layout/html/headers.erb +1 -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/headers.erb +2 -0
- data/templates/default/onefile/html/layout.erb +3 -4
- data/templates/default/tags/html/example.erb +2 -2
- data/templates/guide/fulldoc/html/js/app.js +57 -26
- data/templates/guide/layout/html/layout.erb +9 -11
- metadata +19 -8
|
@@ -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
|
|
@@ -656,7 +656,7 @@ module YARD
|
|
|
656
656
|
if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
|
|
657
657
|
(@lex_state != EXPR_ARG || @space_seen)
|
|
658
658
|
c = peek(0)
|
|
659
|
-
tk = identify_here_document if /[
|
|
659
|
+
tk = identify_here_document if /[-~\w\"\'\`]/ =~ c
|
|
660
660
|
end
|
|
661
661
|
if !tk
|
|
662
662
|
@lex_state = EXPR_BEG
|
|
@@ -978,7 +978,7 @@ module YARD
|
|
|
978
978
|
end
|
|
979
979
|
|
|
980
980
|
def identify_identifier
|
|
981
|
-
token =
|
|
981
|
+
token = String.new
|
|
982
982
|
token.concat getc if peek(0) =~ /[$@]/
|
|
983
983
|
token.concat getc if peek(0) == "@"
|
|
984
984
|
|
|
@@ -1063,6 +1063,8 @@ module YARD
|
|
|
1063
1063
|
ch = getc
|
|
1064
1064
|
if ch == "-"
|
|
1065
1065
|
ch = getc
|
|
1066
|
+
elsif ch == "~"
|
|
1067
|
+
ch = getc
|
|
1066
1068
|
indent = true
|
|
1067
1069
|
end
|
|
1068
1070
|
if /['"`]/ =~ ch # '
|
|
@@ -1096,9 +1098,12 @@ module YARD
|
|
|
1096
1098
|
str = String.new
|
|
1097
1099
|
while (l = gets)
|
|
1098
1100
|
l.chomp!
|
|
1099
|
-
l
|
|
1100
|
-
|
|
1101
|
-
|
|
1101
|
+
if l == quoted
|
|
1102
|
+
str = dedent(str) if indent
|
|
1103
|
+
break
|
|
1104
|
+
else
|
|
1105
|
+
str << l.chomp << "\n"
|
|
1106
|
+
end
|
|
1102
1107
|
end
|
|
1103
1108
|
|
|
1104
1109
|
@reader.divert_read_from(reserve)
|
|
@@ -1108,6 +1113,16 @@ module YARD
|
|
|
1108
1113
|
Token(Ltype2Token[lt], str).set_text(str.dump)
|
|
1109
1114
|
end
|
|
1110
1115
|
|
|
1116
|
+
def dedent(str)
|
|
1117
|
+
lines = str.split("\n", -1)
|
|
1118
|
+
dedent_amt = lines.map do |line|
|
|
1119
|
+
line =~ /\S/ ? line.match(/^ */).offset(0)[1] : nil
|
|
1120
|
+
end.compact.min || 0
|
|
1121
|
+
return str if dedent_amt.zero?
|
|
1122
|
+
|
|
1123
|
+
lines.map { |line| line =~ /\S/ ? line.gsub(/^ {#{dedent_amt}}/, "") : line }.join("\n")
|
|
1124
|
+
end
|
|
1125
|
+
|
|
1111
1126
|
def identify_quotation(initial_char)
|
|
1112
1127
|
ch = getc
|
|
1113
1128
|
if lt = PERCENT_LTYPE[ch]
|
|
@@ -236,14 +236,26 @@ module YARD
|
|
|
236
236
|
|
|
237
237
|
def visit_event(node)
|
|
238
238
|
map = @map[MAPPINGS[node.type]]
|
|
239
|
-
|
|
239
|
+
|
|
240
|
+
# Pattern matching and `in` syntax creates :case nodes without 'case' tokens,
|
|
241
|
+
# fall back to the first child node.
|
|
242
|
+
if node.type == :case && (!map || map.empty?) && (child_node = node[0])
|
|
243
|
+
lstart = child_node.line_range.first
|
|
244
|
+
sstart = child_node.source_range.first
|
|
245
|
+
else
|
|
246
|
+
lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
|
|
247
|
+
(@map[:rbrace] ||= []).shift if map && MAPPINGS[node.type] == :lbrace
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
raise "Cannot determine start of node #{node} around #{file}:#{lineno}" if lstart.nil? || sstart.nil?
|
|
251
|
+
|
|
240
252
|
node.source_range = Range.new(sstart, @ns_charno - 1)
|
|
241
253
|
node.line_range = Range.new(lstart, lineno)
|
|
242
254
|
if node.respond_to?(:block)
|
|
243
255
|
sr = node.block.source_range
|
|
244
256
|
lr = node.block.line_range
|
|
245
|
-
node.block.source_range = Range.new(sr.
|
|
246
|
-
node.block.line_range = Range.new(lr.
|
|
257
|
+
node.block.source_range = Range.new(sr.begin, @tokens.last[2][1] - 1)
|
|
258
|
+
node.block.line_range = Range.new(lr.begin, @tokens.last[2][0])
|
|
247
259
|
end
|
|
248
260
|
node
|
|
249
261
|
end
|
|
@@ -259,7 +271,10 @@ module YARD
|
|
|
259
271
|
def visit_ns_token(token, data, ast_token = false)
|
|
260
272
|
add_token(token, data)
|
|
261
273
|
ch = charno
|
|
262
|
-
|
|
274
|
+
|
|
275
|
+
# For purposes of tracking parsing state, don't treat keywords as such
|
|
276
|
+
# where used as a symbol identifier.
|
|
277
|
+
@last_ns_token = [@last_ns_token && @last_ns_token.first == :symbeg ? :symbol : token, data]
|
|
263
278
|
@charno += data.length
|
|
264
279
|
@ns_charno = charno
|
|
265
280
|
@newline = [:semicolon, :comment, :kw, :op, :lparen, :lbrace].include?(token)
|
|
@@ -272,14 +287,14 @@ module YARD
|
|
|
272
287
|
if @percent_ary
|
|
273
288
|
if token == :words_sep && data !~ /\s\z/
|
|
274
289
|
rng = @percent_ary.source_range
|
|
275
|
-
rng = Range.new(rng.
|
|
290
|
+
rng = Range.new(rng.begin, rng.end.to_i + data.length)
|
|
276
291
|
@percent_ary.source_range = rng
|
|
277
292
|
@tokens << [token, data, [lineno, charno]]
|
|
278
293
|
@percent_ary = nil
|
|
279
294
|
return
|
|
280
295
|
elsif token == :tstring_end && data =~ /\A\s/
|
|
281
296
|
rng = @percent_ary.source_range
|
|
282
|
-
rng = Range.new(rng.
|
|
297
|
+
rng = Range.new(rng.begin, rng.end.to_i + data.length)
|
|
283
298
|
@percent_ary.source_range = rng
|
|
284
299
|
@tokens << [token, data, [lineno, charno]]
|
|
285
300
|
@percent_ary = nil
|
|
@@ -294,7 +309,7 @@ module YARD
|
|
|
294
309
|
@heredoc_tokens << [token, data, [lineno, charno]]
|
|
295
310
|
|
|
296
311
|
# fix ripper encoding of heredoc bug
|
|
297
|
-
# (see
|
|
312
|
+
# (see https://bugs.ruby-lang.org/issues/6200)
|
|
298
313
|
data.force_encoding(file_encoding) if file_encoding
|
|
299
314
|
|
|
300
315
|
@heredoc_state = :ended if token == :heredoc_end
|
|
@@ -322,6 +337,7 @@ module YARD
|
|
|
322
337
|
undef on_aref_field
|
|
323
338
|
undef on_lbracket
|
|
324
339
|
undef on_rbracket
|
|
340
|
+
undef on_rbrace
|
|
325
341
|
undef on_string_literal
|
|
326
342
|
undef on_lambda
|
|
327
343
|
undef on_unary
|
|
@@ -357,6 +373,20 @@ module YARD
|
|
|
357
373
|
visit_event AstNode.new(:hash, args.first || [])
|
|
358
374
|
end
|
|
359
375
|
|
|
376
|
+
# Ruby 3.0+ pattern matching: braced hash patterns ({key: val} syntax) fire
|
|
377
|
+
# on_lbrace and on_rbrace scanner events. The corresponding parser event is
|
|
378
|
+
# on_hshptn (not on_hash), so we must clean up the brace maps to prevent stale
|
|
379
|
+
# entries from corrupting source ranges of later hash literals and brace blocks.
|
|
380
|
+
# Bare hash patterns (key: val without braces) fire no brace scanner events, so
|
|
381
|
+
# we only clean up when @map[:rbrace] confirms a closing brace was scanned.
|
|
382
|
+
def on_hshptn(*args)
|
|
383
|
+
if (@map[:rbrace] ||= []).any?
|
|
384
|
+
(@map[:lbrace] ||= []).pop
|
|
385
|
+
@map[:rbrace].shift
|
|
386
|
+
end
|
|
387
|
+
AstNode.new(:hshptn, args)
|
|
388
|
+
end
|
|
389
|
+
|
|
360
390
|
def on_bare_assoc_hash(*args)
|
|
361
391
|
AstNode.new(:list, args.first)
|
|
362
392
|
end
|
|
@@ -377,20 +407,22 @@ module YARD
|
|
|
377
407
|
def on_aref(*args)
|
|
378
408
|
@map[:lbracket].pop
|
|
379
409
|
ll, lc = *@map[:aref].shift
|
|
380
|
-
sr = args.first.source_range.
|
|
381
|
-
lr = args.first.line_range.
|
|
410
|
+
sr = args.first.source_range.begin..lc
|
|
411
|
+
lr = args.first.line_range.begin..ll
|
|
382
412
|
AstNode.new(:aref, args, :char => sr, :line => lr)
|
|
383
413
|
end
|
|
384
414
|
|
|
385
415
|
def on_aref_field(*args)
|
|
386
416
|
@map[:lbracket].pop
|
|
387
|
-
|
|
388
|
-
|
|
417
|
+
ll, lc = *@map[:aref].shift
|
|
418
|
+
sr = args.first.source_range.begin..lc
|
|
419
|
+
lr = args.first.line_range.begin..ll
|
|
420
|
+
AstNode.new(:aref_field, args, :char => sr, :line => lr)
|
|
389
421
|
end
|
|
390
422
|
|
|
391
423
|
def on_array(other)
|
|
392
424
|
node = AstNode.node_class_for(:array).new(:array, [other])
|
|
393
|
-
map = @map[MAPPINGS[node.type]]
|
|
425
|
+
map = @map[MAPPINGS[node.type]] if other.nil? || other.type == :list
|
|
394
426
|
if map && !map.empty?
|
|
395
427
|
lstart, sstart = *map.pop
|
|
396
428
|
node.source_range = Range.new(sstart, @ns_charno - 1)
|
|
@@ -406,6 +438,27 @@ module YARD
|
|
|
406
438
|
node
|
|
407
439
|
end
|
|
408
440
|
|
|
441
|
+
# Ruby 3.0+ pattern matching: array patterns (SomeClass[a, b]) and find patterns
|
|
442
|
+
# (SomeClass[*pre, val, *post]) use [...] brackets, which fire on_lbracket and
|
|
443
|
+
# on_rbracket scanner events. The corresponding parser events are on_aryptn/on_fndptn
|
|
444
|
+
# (not on_aref), so we must clean up the bracket maps to prevent stale entries from
|
|
445
|
+
# corrupting source ranges of later array indexing expressions.
|
|
446
|
+
def on_aryptn(*args)
|
|
447
|
+
(@map[:lbracket] ||= []).pop
|
|
448
|
+
(@map[:aref] ||= []).shift
|
|
449
|
+
# Source range is intentionally not set; no handler is registered for
|
|
450
|
+
# pattern-match nodes, so they produce no documentation output.
|
|
451
|
+
AstNode.new(:aryptn, args)
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
def on_fndptn(*args)
|
|
455
|
+
(@map[:lbracket] ||= []).pop
|
|
456
|
+
(@map[:aref] ||= []).shift
|
|
457
|
+
# Source range is intentionally not set; no handler is registered for
|
|
458
|
+
# pattern-match nodes, so they produce no documentation output.
|
|
459
|
+
AstNode.new(:fndptn, args)
|
|
460
|
+
end
|
|
461
|
+
|
|
409
462
|
def on_lbracket(tok)
|
|
410
463
|
(@map[:lbracket] ||= []) << [lineno, charno]
|
|
411
464
|
visit_ns_token(:lbracket, tok, false)
|
|
@@ -416,6 +469,13 @@ module YARD
|
|
|
416
469
|
visit_ns_token(:rbracket, tok, false)
|
|
417
470
|
end
|
|
418
471
|
|
|
472
|
+
# Maintained explicitly (unlike on_lbracket/on_rbracket) so on_hshptn can
|
|
473
|
+
# distinguish braced from bare hash patterns in Ruby 3.0+ pattern matching.
|
|
474
|
+
def on_rbrace(tok)
|
|
475
|
+
(@map[:rbrace] ||= []) << [lineno, charno]
|
|
476
|
+
visit_ns_token(:rbrace, tok, false)
|
|
477
|
+
end
|
|
478
|
+
|
|
419
479
|
def on_dyna_symbol(sym)
|
|
420
480
|
rng = if sym.source_range.to_a.size == 0 # rubocop:disable Style/ZeroLengthPredicate
|
|
421
481
|
(sym.source_range.begin - 3)...sym.source_range.end
|
|
@@ -449,8 +509,8 @@ module YARD
|
|
|
449
509
|
def on_#{kw}(*args)
|
|
450
510
|
mapping = @map[#{kw.to_s.sub(/_mod$/, '').inspect}]
|
|
451
511
|
mapping.pop if mapping
|
|
452
|
-
sr = args.last.source_range.
|
|
453
|
-
lr = args.last.line_range.
|
|
512
|
+
sr = args.last.source_range.begin..args.first.source_range.end
|
|
513
|
+
lr = args.last.line_range.begin..args.first.line_range.end
|
|
454
514
|
#{node_class}.new(:#{kw}, args, :line => lr, :char => sr)
|
|
455
515
|
end
|
|
456
516
|
eof
|
|
@@ -473,8 +533,8 @@ module YARD
|
|
|
473
533
|
begin; undef on_#{kw}_add; rescue NameError; end
|
|
474
534
|
def on_#{kw}_add(list, item)
|
|
475
535
|
last = @source[@ns_charno,1] == "\n" ? @ns_charno - 1 : @ns_charno
|
|
476
|
-
list.source_range = (list.source_range.
|
|
477
|
-
list.line_range = (list.line_range.
|
|
536
|
+
list.source_range = (list.source_range.begin..last)
|
|
537
|
+
list.line_range = (list.line_range.begin..lineno)
|
|
478
538
|
list.push(item)
|
|
479
539
|
list
|
|
480
540
|
end
|
|
@@ -485,9 +545,9 @@ module YARD
|
|
|
485
545
|
node = visit_event_arr(LiteralNode.new(:string_literal, args))
|
|
486
546
|
if args.size == 1
|
|
487
547
|
r = args[0].source_range
|
|
488
|
-
if node.source_range != Range.new(r.
|
|
548
|
+
if node.source_range != Range.new(r.begin - 1, r.end + 1)
|
|
489
549
|
klass = AstNode.node_class_for(node[0].type)
|
|
490
|
-
r = Range.new(node.source_range.
|
|
550
|
+
r = Range.new(node.source_range.begin + 1, node.source_range.end - 1)
|
|
491
551
|
node[0] = klass.new(node[0].type, [@source[r]], :line => node.line_range, :char => r)
|
|
492
552
|
end
|
|
493
553
|
end
|
|
@@ -573,7 +633,7 @@ module YARD
|
|
|
573
633
|
@comments_flags[lineno] = @comments_flags[lineno - 1]
|
|
574
634
|
@comments_flags.delete(lineno - 1)
|
|
575
635
|
range = @comments_range.delete(lineno - 1)
|
|
576
|
-
source_range = range.
|
|
636
|
+
source_range = range.begin..source_range.end
|
|
577
637
|
comment = append_comment + "\n" + comment
|
|
578
638
|
end
|
|
579
639
|
|
|
@@ -609,6 +669,7 @@ module YARD
|
|
|
609
669
|
alias compile_error on_parse_error
|
|
610
670
|
|
|
611
671
|
def comment_starts_line?(charno)
|
|
672
|
+
return true if @source[charno] == "\n"
|
|
612
673
|
(charno - 1).downto(0) do |i|
|
|
613
674
|
ch = @source[i]
|
|
614
675
|
break if ch == "\n"
|
|
@@ -627,11 +688,13 @@ module YARD
|
|
|
627
688
|
end
|
|
628
689
|
|
|
629
690
|
# check upwards from line before node; check node's line at the end
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
691
|
+
if (n_l = node.line)
|
|
692
|
+
((n_l - 1).downto(n_l - 2).to_a + [n_l]).each do |line|
|
|
693
|
+
comment = @comments[line]
|
|
694
|
+
if comment && !comment.empty?
|
|
695
|
+
add_comment(line, node)
|
|
696
|
+
break
|
|
697
|
+
end
|
|
635
698
|
end
|
|
636
699
|
end
|
|
637
700
|
|
|
@@ -656,6 +719,23 @@ module YARD
|
|
|
656
719
|
end
|
|
657
720
|
end unless @comments.empty?
|
|
658
721
|
|
|
722
|
+
# Attach comments that fall within an otherwise empty
|
|
723
|
+
# class or module body. Without this step, a comment used
|
|
724
|
+
# solely for directives (like @!method) would be treated as
|
|
725
|
+
# a top-level comment and its directives would not be scoped
|
|
726
|
+
# to the namespace.
|
|
727
|
+
unless @comments.empty?
|
|
728
|
+
root.traverse do |node|
|
|
729
|
+
next unless [:class, :module, :sclass].include?(node.type)
|
|
730
|
+
body = node.children.last
|
|
731
|
+
next unless body && body.type == :list && body.empty?
|
|
732
|
+
@comments.keys.each do |line|
|
|
733
|
+
next unless node.line_range.include?(line)
|
|
734
|
+
add_comment(line, nil, body, true)
|
|
735
|
+
end
|
|
736
|
+
end
|
|
737
|
+
end
|
|
738
|
+
|
|
659
739
|
# insert all remaining comments
|
|
660
740
|
@comments.each do |line, _comment|
|
|
661
741
|
add_comment(line, nil, root, true)
|
|
@@ -667,6 +747,11 @@ module YARD
|
|
|
667
747
|
def add_comment(line, node = nil, before_node = nil, into = false)
|
|
668
748
|
comment = @comments[line]
|
|
669
749
|
source_range = @comments_range[line]
|
|
750
|
+
if comment && source_range
|
|
751
|
+
source = @source[source_range]
|
|
752
|
+
last_line = source.lines.to_a.last
|
|
753
|
+
return if last_line && last_line =~ /^\s*\#-\s*$/
|
|
754
|
+
end
|
|
670
755
|
line_range = ((line - comment.count("\n"))..line)
|
|
671
756
|
if node.nil?
|
|
672
757
|
node = CommentNode.new(:comment, [comment], :line => line_range, :char => source_range)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
require 'stringio'
|
|
3
|
-
require 'ostruct'
|
|
4
3
|
|
|
5
4
|
module YARD
|
|
6
5
|
module Parser
|
|
@@ -68,7 +67,7 @@ module YARD
|
|
|
68
67
|
|
|
69
68
|
# The default glob of files to be parsed.
|
|
70
69
|
# @since 0.9.0
|
|
71
|
-
DEFAULT_PATH_GLOB = ["{lib,app}/**/*.rb", "ext/**/*.{c,cc,cxx,cpp,rb}"]
|
|
70
|
+
DEFAULT_PATH_GLOB = ["{lib,app}/**/*.{rb,rbs}", "sig/**/*.rbs", "ext/**/*.{c,cc,cxx,cpp,rb}"]
|
|
72
71
|
|
|
73
72
|
# Byte order marks for various encodings
|
|
74
73
|
# @since 0.7.0
|
|
@@ -106,9 +105,10 @@ module YARD
|
|
|
106
105
|
end
|
|
107
106
|
end
|
|
108
107
|
files = [paths].flatten.
|
|
109
|
-
map {|p| File.directory?(p) ? "#{p}/**/*.{rb,c,cc,cxx,cpp}" : p }.
|
|
108
|
+
map {|p| File.directory?(p) ? "#{p}/**/*.{rb,rbs,c,cc,cxx,cpp}" : p }.
|
|
110
109
|
map {|p| p.include?("*") ? Dir[p].sort_by {|d| [d.length, d] } : p }.flatten.
|
|
111
|
-
reject {|p| !File.file?(p) || excluded.any? {|re| p =~ re } }
|
|
110
|
+
reject {|p| !File.file?(p) || excluded.any? {|re| p =~ re } }.
|
|
111
|
+
map {|p| p.encoding == Encoding.default_external ? p : p.dup.force_encoding(Encoding.default_external) }
|
|
112
112
|
|
|
113
113
|
log.enter_level(level) do
|
|
114
114
|
parse_in_order(*files.uniq)
|
|
@@ -379,6 +379,7 @@ module YARD
|
|
|
379
379
|
register_parser_type :ruby, Ruby::RubyParser
|
|
380
380
|
register_parser_type :ruby18, Ruby::Legacy::RubyParser
|
|
381
381
|
register_parser_type :c, C::CParser, ['c', 'cc', 'cxx', 'cpp']
|
|
382
|
+
register_parser_type :rbs, RBS::RbsParser, ['rbs']
|
|
382
383
|
|
|
383
384
|
self.parser_type = :ruby
|
|
384
385
|
|
|
@@ -75,6 +75,13 @@ module YARD
|
|
|
75
75
|
lexical_lookup = 0
|
|
76
76
|
while namespace && !resolved
|
|
77
77
|
resolved = lookup_path_direct(namespace, path, type)
|
|
78
|
+
# Prevent a bare name from resolving back to the namespace we started
|
|
79
|
+
# from when searching through a parent namespace. For example,
|
|
80
|
+
# `include Enumerable` inside `A::Enumerable` would walk up to namespace
|
|
81
|
+
# `A` and match `A::Enumerable`, creating a false self-referential mixin.
|
|
82
|
+
# Only skip when we have already moved to a parent (namespace != orignamespace).
|
|
83
|
+
# See https://github.com/lsegal/yard/issues/1116
|
|
84
|
+
resolved = nil if resolved.equal?(orignamespace) && !namespace.equal?(orignamespace)
|
|
78
85
|
resolved ||= lookup_path_inherited(namespace, path, type) if inheritance
|
|
79
86
|
break if resolved
|
|
80
87
|
namespace = namespace.parent
|
|
@@ -71,7 +71,7 @@ module YARD
|
|
|
71
71
|
# def load_yardoc_from_http
|
|
72
72
|
# Thread.new do
|
|
73
73
|
# # zip/unzip method implementations are not shown
|
|
74
|
-
# download_zip_file("
|
|
74
|
+
# download_zip_file("https://mysite.com/yardocs/#{self}.zip")
|
|
75
75
|
# unzip_file_to("/path/to/yardocs/#{self}")
|
|
76
76
|
# end
|
|
77
77
|
#
|