yard 0.9.26 → 0.9.37

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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -8
  3. data/LEGAL +29 -1
  4. data/LICENSE +1 -1
  5. data/README.md +9 -2
  6. data/docs/Tags.md +1 -1
  7. data/docs/WhatsNew.md +2 -2
  8. data/lib/yard/autoload.rb +3 -1
  9. data/lib/yard/cli/command.rb +1 -1
  10. data/lib/yard/cli/stats.rb +4 -1
  11. data/lib/yard/cli/yardoc.rb +5 -3
  12. data/lib/yard/code_objects/base.rb +5 -1
  13. data/lib/yard/code_objects/macro_object.rb +0 -1
  14. data/lib/yard/config.rb +5 -1
  15. data/lib/yard/docstring_parser.rb +1 -2
  16. data/lib/yard/handlers/processor.rb +0 -1
  17. data/lib/yard/handlers/ruby/attribute_handler.rb +1 -1
  18. data/lib/yard/handlers/ruby/legacy/attribute_handler.rb +1 -1
  19. data/lib/yard/handlers/ruby/method_handler.rb +2 -2
  20. data/lib/yard/handlers/ruby/mixin_handler.rb +15 -6
  21. data/lib/yard/handlers/ruby/module_function_handler.rb +15 -3
  22. data/lib/yard/handlers/ruby/visibility_handler.rb +13 -1
  23. data/lib/yard/i18n/locale.rb +1 -1
  24. data/lib/yard/i18n/message.rb +2 -2
  25. data/lib/yard/i18n/messages.rb +1 -1
  26. data/lib/yard/i18n/pot_generator.rb +1 -1
  27. data/lib/yard/logging.rb +116 -61
  28. data/lib/yard/open_struct.rb +67 -0
  29. data/lib/yard/options.rb +1 -1
  30. data/lib/yard/parser/ruby/ast_node.rb +9 -2
  31. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +19 -4
  32. data/lib/yard/parser/ruby/ruby_parser.rb +9 -3
  33. data/lib/yard/parser/source_parser.rb +4 -5
  34. data/lib/yard/registry_resolver.rb +2 -1
  35. data/lib/yard/server/commands/base.rb +1 -1
  36. data/lib/yard/server/commands/library_command.rb +9 -9
  37. data/lib/yard/server/commands/static_file_helpers.rb +1 -2
  38. data/lib/yard/server/http_utils.rb +512 -0
  39. data/lib/yard/server/rack_adapter.rb +13 -5
  40. data/lib/yard/tags/default_factory.rb +1 -0
  41. data/lib/yard/tags/directives.rb +10 -2
  42. data/lib/yard/tags/tag.rb +3 -2
  43. data/lib/yard/tags/types_explainer.rb +1 -1
  44. data/lib/yard/templates/engine.rb +0 -1
  45. data/lib/yard/templates/helpers/html_helper.rb +5 -2
  46. data/lib/yard/templates/helpers/markup_helper.rb +2 -1
  47. data/lib/yard/templates/helpers/method_helper.rb +3 -1
  48. data/lib/yard/templates/template.rb +3 -1
  49. data/lib/yard/templates/template_options.rb +0 -1
  50. data/lib/yard/version.rb +1 -1
  51. data/lib/yard.rb +6 -0
  52. data/po/ja.po +19 -19
  53. data/templates/default/fulldoc/html/css/full_list.css +3 -3
  54. data/templates/default/fulldoc/html/css/style.css +6 -0
  55. data/templates/default/fulldoc/html/frames.erb +9 -4
  56. data/templates/default/fulldoc/html/full_list.erb +5 -2
  57. data/templates/default/fulldoc/html/js/app.js +294 -264
  58. data/templates/default/fulldoc/html/js/full_list.js +30 -4
  59. data/templates/default/fulldoc/html/setup.rb +10 -2
  60. data/templates/default/layout/html/footer.erb +1 -1
  61. data/templates/default/onefile/html/headers.erb +2 -0
  62. data/templates/default/tags/html/example.erb +2 -2
  63. data/templates/default/tags/html/option.erb +1 -1
  64. metadata +5 -41
  65. data/.dockerignore +0 -2
  66. data/.gitattributes +0 -4
  67. data/.github/FUNDING.yml +0 -3
  68. data/.github/ISSUE_TEMPLATE.md +0 -33
  69. data/.github/PULL_REQUEST_TEMPLATE.md +0 -12
  70. data/.github/workflows/ci.yml +0 -42
  71. data/.github/workflows/gem.yml +0 -27
  72. data/.gitignore +0 -14
  73. data/.rspec +0 -2
  74. data/.rubocop.yml +0 -112
  75. data/.travis.yml +0 -49
  76. data/CODE_OF_CONDUCT.md +0 -15
  77. data/CONTRIBUTING.md +0 -140
  78. data/Dockerfile.samus +0 -28
  79. data/Gemfile +0 -33
  80. data/Rakefile +0 -39
  81. data/SECURITY.md +0 -26
  82. data/benchmarks/builtins_vs_eval.rb +0 -24
  83. data/benchmarks/concat_vs_join.rb +0 -13
  84. data/benchmarks/erb_vs_erubis.rb +0 -54
  85. data/benchmarks/format_args.rb +0 -47
  86. data/benchmarks/generation.rb +0 -38
  87. data/benchmarks/marshal_vs_dbm.rb +0 -64
  88. data/benchmarks/parsing.rb +0 -46
  89. data/benchmarks/pathname_vs_string.rb +0 -51
  90. data/benchmarks/rdoc_vs_yardoc.rb +0 -11
  91. data/benchmarks/registry_store_types.rb +0 -49
  92. data/benchmarks/ri_vs_yri.rb +0 -19
  93. data/benchmarks/ripper_parser.rb +0 -13
  94. data/benchmarks/splat_vs_flatten.rb +0 -13
  95. data/benchmarks/template_erb.rb +0 -23
  96. data/benchmarks/template_format.rb +0 -7
  97. data/benchmarks/template_profile.rb +0 -18
  98. data/benchmarks/yri_cache.rb +0 -20
  99. data/samus.json +0 -49
  100. data/tasks/update_error_map.rake +0 -53
  101. data/yard.gemspec +0 -23
@@ -0,0 +1,512 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # httputils.rb -- HTTPUtils Module
4
+ #
5
+ # Author: IPR -- Internet Programming with Ruby -- writers
6
+ # Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
7
+ # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
8
+ # reserved.
9
+ #
10
+ # $IPR: httputils.rb,v 1.34 2003/06/05 21:34:08 gotoyuzo Exp $
11
+
12
+ require 'socket'
13
+ require 'tempfile'
14
+
15
+ module YARD::Server
16
+ CR = "\x0d" # :nodoc:
17
+ LF = "\x0a" # :nodoc:
18
+ CRLF = "\x0d\x0a" # :nodoc:
19
+
20
+ ##
21
+ # HTTPUtils provides utility methods for working with the HTTP protocol.
22
+ #
23
+ # This module is generally used internally by WEBrick
24
+
25
+ module HTTPUtils
26
+
27
+ ##
28
+ # Normalizes a request path. Raises an exception if the path cannot be
29
+ # normalized.
30
+
31
+ def normalize_path(path)
32
+ raise "abnormal path `#{path}'" if path[0] != ?/
33
+ ret = path.dup
34
+
35
+ ret.gsub!(%r{/+}o, '/') # // => /
36
+ while ret.sub!(%r'/\.(?:/|\Z)', '/'); end # /. => /
37
+ while ret.sub!(%r'/(?!\.\./)[^/]+/\.\.(?:/|\Z)', '/'); end # /foo/.. => /foo
38
+
39
+ raise "abnormal path `#{path}'" if %r{/\.\.(/|\Z)} =~ ret
40
+ ret
41
+ end
42
+ module_function :normalize_path
43
+
44
+ ##
45
+ # Default mime types
46
+
47
+ DefaultMimeTypes = {
48
+ "ai" => "application/postscript",
49
+ "asc" => "text/plain",
50
+ "avi" => "video/x-msvideo",
51
+ "bin" => "application/octet-stream",
52
+ "bmp" => "image/bmp",
53
+ "class" => "application/octet-stream",
54
+ "cer" => "application/pkix-cert",
55
+ "crl" => "application/pkix-crl",
56
+ "crt" => "application/x-x509-ca-cert",
57
+ #"crl" => "application/x-pkcs7-crl",
58
+ "css" => "text/css",
59
+ "dms" => "application/octet-stream",
60
+ "doc" => "application/msword",
61
+ "dvi" => "application/x-dvi",
62
+ "eps" => "application/postscript",
63
+ "etx" => "text/x-setext",
64
+ "exe" => "application/octet-stream",
65
+ "gif" => "image/gif",
66
+ "htm" => "text/html",
67
+ "html" => "text/html",
68
+ "jpe" => "image/jpeg",
69
+ "jpeg" => "image/jpeg",
70
+ "jpg" => "image/jpeg",
71
+ "js" => "application/javascript",
72
+ "json" => "application/json",
73
+ "lha" => "application/octet-stream",
74
+ "lzh" => "application/octet-stream",
75
+ "mjs" => "application/javascript",
76
+ "mov" => "video/quicktime",
77
+ "mpe" => "video/mpeg",
78
+ "mpeg" => "video/mpeg",
79
+ "mpg" => "video/mpeg",
80
+ "pbm" => "image/x-portable-bitmap",
81
+ "pdf" => "application/pdf",
82
+ "pgm" => "image/x-portable-graymap",
83
+ "png" => "image/png",
84
+ "pnm" => "image/x-portable-anymap",
85
+ "ppm" => "image/x-portable-pixmap",
86
+ "ppt" => "application/vnd.ms-powerpoint",
87
+ "ps" => "application/postscript",
88
+ "qt" => "video/quicktime",
89
+ "ras" => "image/x-cmu-raster",
90
+ "rb" => "text/plain",
91
+ "rd" => "text/plain",
92
+ "rtf" => "application/rtf",
93
+ "sgm" => "text/sgml",
94
+ "sgml" => "text/sgml",
95
+ "svg" => "image/svg+xml",
96
+ "tif" => "image/tiff",
97
+ "tiff" => "image/tiff",
98
+ "txt" => "text/plain",
99
+ "wasm" => "application/wasm",
100
+ "xbm" => "image/x-xbitmap",
101
+ "xhtml" => "text/html",
102
+ "xls" => "application/vnd.ms-excel",
103
+ "xml" => "text/xml",
104
+ "xpm" => "image/x-xpixmap",
105
+ "xwd" => "image/x-xwindowdump",
106
+ "zip" => "application/zip",
107
+ }
108
+
109
+ ##
110
+ # Loads Apache-compatible mime.types in +file+.
111
+
112
+ def load_mime_types(file)
113
+ # note: +file+ may be a "| command" for now; some people may
114
+ # rely on this, but currently we do not use this method by default.
115
+ open(file){ |io|
116
+ hash = Hash.new
117
+ io.each{ |line|
118
+ next if /^#/ =~ line
119
+ line.chomp!
120
+ mimetype, ext0 = line.split(/\s+/, 2)
121
+ next unless ext0
122
+ next if ext0.empty?
123
+ ext0.split(/\s+/).each{ |ext| hash[ext] = mimetype }
124
+ }
125
+ hash
126
+ }
127
+ end
128
+ module_function :load_mime_types
129
+
130
+ ##
131
+ # Returns the mime type of +filename+ from the list in +mime_tab+. If no
132
+ # mime type was found application/octet-stream is returned.
133
+
134
+ def mime_type(filename, mime_tab)
135
+ suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
136
+ suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
137
+ mime_tab[suffix1] || mime_tab[suffix2] || "application/octet-stream"
138
+ end
139
+ module_function :mime_type
140
+
141
+ ##
142
+ # Parses an HTTP header +raw+ into a hash of header fields with an Array
143
+ # of values.
144
+
145
+ def parse_header(raw)
146
+ header = Hash.new([].freeze)
147
+ field = nil
148
+ raw.each_line{|line|
149
+ case line
150
+ when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om
151
+ field, value = $1, $2
152
+ field.downcase!
153
+ header[field] = [] unless header.has_key?(field)
154
+ header[field] << value
155
+ when /^\s+(.*?)\s*\z/om
156
+ value = $1
157
+ unless field
158
+ raise HTTPStatus::BadRequest, "bad header '#{line}'."
159
+ end
160
+ header[field][-1] << " " << value
161
+ else
162
+ raise HTTPStatus::BadRequest, "bad header '#{line}'."
163
+ end
164
+ }
165
+ header.each{|key, values|
166
+ values.each(&:strip!)
167
+ }
168
+ header
169
+ end
170
+ module_function :parse_header
171
+
172
+ ##
173
+ # Splits a header value +str+ according to HTTP specification.
174
+
175
+ def split_header_value(str)
176
+ str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
177
+ (?:,\s*|\Z)'xn).flatten
178
+ end
179
+ module_function :split_header_value
180
+
181
+ ##
182
+ # Parses a Range header value +ranges_specifier+
183
+
184
+ def parse_range_header(ranges_specifier)
185
+ if /^bytes=(.*)/ =~ ranges_specifier
186
+ byte_range_set = split_header_value($1)
187
+ byte_range_set.collect{|range_spec|
188
+ case range_spec
189
+ when /^(\d+)-(\d+)/ then $1.to_i .. $2.to_i
190
+ when /^(\d+)-/ then $1.to_i .. -1
191
+ when /^-(\d+)/ then -($1.to_i) .. -1
192
+ else return nil
193
+ end
194
+ }
195
+ end
196
+ end
197
+ module_function :parse_range_header
198
+
199
+ ##
200
+ # Parses q values in +value+ as used in Accept headers.
201
+
202
+ def parse_qvalues(value)
203
+ tmp = []
204
+ if value
205
+ parts = value.split(/,\s*/)
206
+ parts.each {|part|
207
+ if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
208
+ val = m[1]
209
+ q = (m[2] or 1).to_f
210
+ tmp.push([val, q])
211
+ end
212
+ }
213
+ tmp = tmp.sort_by{|val, q| -q}
214
+ tmp.collect!{|val, q| val}
215
+ end
216
+ return tmp
217
+ end
218
+ module_function :parse_qvalues
219
+
220
+ ##
221
+ # Removes quotes and escapes from +str+
222
+
223
+ def dequote(str)
224
+ ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
225
+ ret.gsub!(/\\(.)/, "\\1")
226
+ ret
227
+ end
228
+ module_function :dequote
229
+
230
+ ##
231
+ # Quotes and escapes quotes in +str+
232
+
233
+ def quote(str)
234
+ '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
235
+ end
236
+ module_function :quote
237
+
238
+ ##
239
+ # Stores multipart form data. FormData objects are created when
240
+ # WEBrick::HTTPUtils.parse_form_data is called.
241
+
242
+ class FormData < String
243
+ EmptyRawHeader = [].freeze # :nodoc:
244
+ EmptyHeader = {}.freeze # :nodoc:
245
+
246
+ ##
247
+ # The name of the form data part
248
+
249
+ attr_accessor :name
250
+
251
+ ##
252
+ # The filename of the form data part
253
+
254
+ attr_accessor :filename
255
+
256
+ attr_accessor :next_data # :nodoc:
257
+ protected :next_data
258
+
259
+ ##
260
+ # Creates a new FormData object.
261
+ #
262
+ # +args+ is an Array of form data entries. One FormData will be created
263
+ # for each entry.
264
+ #
265
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you
266
+
267
+ def initialize(*args)
268
+ @name = @filename = @next_data = nil
269
+ if args.empty?
270
+ @raw_header = []
271
+ @header = nil
272
+ super("")
273
+ else
274
+ @raw_header = EmptyRawHeader
275
+ @header = EmptyHeader
276
+ super(args.shift)
277
+ unless args.empty?
278
+ @next_data = self.class.new(*args)
279
+ end
280
+ end
281
+ end
282
+
283
+ ##
284
+ # Retrieves the header at the first entry in +key+
285
+
286
+ def [](*key)
287
+ begin
288
+ @header[key[0].downcase].join(", ")
289
+ rescue StandardError, NameError
290
+ super
291
+ end
292
+ end
293
+
294
+ ##
295
+ # Adds +str+ to this FormData which may be the body, a header or a
296
+ # header entry.
297
+ #
298
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you
299
+
300
+ def <<(str)
301
+ if @header
302
+ super
303
+ elsif str == CRLF
304
+ @header = HTTPUtils::parse_header(@raw_header.join)
305
+ if cd = self['content-disposition']
306
+ if /\s+name="(.*?)"/ =~ cd then @name = $1 end
307
+ if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
308
+ end
309
+ else
310
+ @raw_header << str
311
+ end
312
+ self
313
+ end
314
+
315
+ ##
316
+ # Adds +data+ at the end of the chain of entries
317
+ #
318
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you.
319
+
320
+ def append_data(data)
321
+ tmp = self
322
+ while tmp
323
+ unless tmp.next_data
324
+ tmp.next_data = data
325
+ break
326
+ end
327
+ tmp = tmp.next_data
328
+ end
329
+ self
330
+ end
331
+
332
+ ##
333
+ # Yields each entry in this FormData
334
+
335
+ def each_data
336
+ tmp = self
337
+ while tmp
338
+ next_data = tmp.next_data
339
+ yield(tmp)
340
+ tmp = next_data
341
+ end
342
+ end
343
+
344
+ ##
345
+ # Returns all the FormData as an Array
346
+
347
+ def list
348
+ ret = []
349
+ each_data{|data|
350
+ ret << data.to_s
351
+ }
352
+ ret
353
+ end
354
+
355
+ ##
356
+ # A FormData will behave like an Array
357
+
358
+ alias :to_ary :list
359
+
360
+ ##
361
+ # This FormData's body
362
+
363
+ def to_s
364
+ String.new(self)
365
+ end
366
+ end
367
+
368
+ ##
369
+ # Parses the query component of a URI in +str+
370
+
371
+ def parse_query(str)
372
+ query = Hash.new
373
+ if str
374
+ str.split(/[&;]/).each{|x|
375
+ next if x.empty?
376
+ key, val = x.split(/=/,2)
377
+ key = unescape_form(key)
378
+ val = unescape_form(val.to_s)
379
+ val = FormData.new(val)
380
+ val.name = key
381
+ if query.has_key?(key)
382
+ query[key].append_data(val)
383
+ next
384
+ end
385
+ query[key] = val
386
+ }
387
+ end
388
+ query
389
+ end
390
+ module_function :parse_query
391
+
392
+ ##
393
+ # Parses form data in +io+ with the given +boundary+
394
+
395
+ def parse_form_data(io, boundary)
396
+ boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/
397
+ form_data = Hash.new
398
+ return form_data unless io
399
+ data = nil
400
+ io.each_line{|line|
401
+ if boundary_regexp =~ line
402
+ if data
403
+ data.chop!
404
+ key = data.name
405
+ if form_data.has_key?(key)
406
+ form_data[key].append_data(data)
407
+ else
408
+ form_data[key] = data
409
+ end
410
+ end
411
+ data = FormData.new
412
+ next
413
+ else
414
+ if data
415
+ data << line
416
+ end
417
+ end
418
+ }
419
+ return form_data
420
+ end
421
+ module_function :parse_form_data
422
+
423
+ #####
424
+
425
+ reserved = ';/?:@&=+$,'
426
+ num = '0123456789'
427
+ lowalpha = 'abcdefghijklmnopqrstuvwxyz'
428
+ upalpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
429
+ mark = '-_.!~*\'()'
430
+ unreserved = num + lowalpha + upalpha + mark
431
+ control = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f"
432
+ space = " "
433
+ delims = '<>#%"'
434
+ unwise = '{}|\\^[]`'
435
+ nonascii = (0x80..0xff).collect{|c| c.chr }.join
436
+
437
+ module_function
438
+
439
+ # :stopdoc:
440
+
441
+ def _make_regex(str) /([#{Regexp.escape(str)}])/n end
442
+ def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
443
+ def _escape(str, regex)
444
+ str = str.b
445
+ str.gsub!(regex) {"%%%02X" % $1.ord}
446
+ # %-escaped string should contain US-ASCII only
447
+ str.force_encoding(Encoding::US_ASCII)
448
+ end
449
+ def _unescape(str, regex)
450
+ str = str.b
451
+ str.gsub!(regex) {$1.hex.chr}
452
+ # encoding of %-unescaped string is unknown
453
+ str
454
+ end
455
+
456
+ UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
457
+ UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
458
+ NONASCII = _make_regex(nonascii)
459
+ ESCAPED = /%([0-9a-fA-F]{2})/
460
+ UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
461
+
462
+ # :startdoc:
463
+
464
+ ##
465
+ # Escapes HTTP reserved and unwise characters in +str+
466
+
467
+ def escape(str)
468
+ _escape(str, UNESCAPED)
469
+ end
470
+
471
+ ##
472
+ # Unescapes HTTP reserved and unwise characters in +str+
473
+
474
+ def unescape(str)
475
+ _unescape(str, ESCAPED)
476
+ end
477
+
478
+ ##
479
+ # Escapes form reserved characters in +str+
480
+
481
+ def escape_form(str)
482
+ ret = _escape(str, UNESCAPED_FORM)
483
+ ret.gsub!(/ /, "+")
484
+ ret
485
+ end
486
+
487
+ ##
488
+ # Unescapes form reserved characters in +str+
489
+
490
+ def unescape_form(str)
491
+ _unescape(str.gsub(/\+/, " "), ESCAPED)
492
+ end
493
+
494
+ ##
495
+ # Escapes path +str+
496
+
497
+ def escape_path(str)
498
+ result = ""
499
+ str.scan(%r{/([^/]*)}).each{|i|
500
+ result << "/" << _escape(i[0], UNESCAPED_PCHAR)
501
+ }
502
+ return result
503
+ end
504
+
505
+ ##
506
+ # Escapes 8 bit characters in +str+
507
+
508
+ def escape8bit(str)
509
+ _escape(str, NONASCII)
510
+ end
511
+ end
512
+ end
@@ -1,9 +1,17 @@
1
1
  # frozen_string_literal: true
2
- require 'rack'
3
- require 'webrick/httputils'
4
2
 
5
3
  module YARD
6
4
  module Server
5
+ begin
6
+ require 'rackup'
7
+ # @private
8
+ RackServer = Rackup::Server
9
+ rescue LoadError
10
+ require 'rack'
11
+ # @private
12
+ RackServer = Rack::Server
13
+ end
14
+
7
15
  # This class wraps the {RackAdapter} into a Rack-compatible middleware.
8
16
  # See {#initialize} for a list of options to pass via Rack's +#use+ method.
9
17
  #
@@ -42,7 +50,7 @@ module YARD
42
50
 
43
51
  # A server adapter to respond to requests using the Rack server infrastructure.
44
52
  class RackAdapter < Adapter
45
- include WEBrick::HTTPUtils
53
+ include YARD::Server::HTTPUtils
46
54
 
47
55
  # Responds to Rack requests and builds a response with the {Router}.
48
56
  # @return [Array(Numeric,Hash,Array)] the Rack-style response
@@ -56,11 +64,11 @@ module YARD
56
64
  [ex.message + "\n" + ex.backtrace.join("\n")]]
57
65
  end
58
66
 
59
- # Starts the +Rack::Server+. This method will pass control to the server and
67
+ # Starts the Rack server. This method will pass control to the server and
60
68
  # block.
61
69
  # @return [void]
62
70
  def start
63
- server = Rack::Server.new(server_options)
71
+ server = RackServer.new(server_options)
64
72
  server.instance_variable_set("@app", self)
65
73
  print_start_message(server)
66
74
  server.start
@@ -143,6 +143,7 @@ module YARD
143
143
  seen_space = false
144
144
  i = 0
145
145
  last_seen = ''
146
+ text ||= ''
146
147
  while i < text.length
147
148
  c = text[i, 1]
148
149
 
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Tags
@@ -74,6 +73,13 @@ module YARD
74
73
  def after_parse; end
75
74
 
76
75
  protected :parser
76
+
77
+ protected
78
+
79
+ def inside_directive?
80
+ return true if parser.state.inside_directive
81
+ parser.directives.any? { |d| d.is_a?(MethodDirective) && d.tag.text.empty? }
82
+ end
77
83
  end
78
84
 
79
85
  # Ends a group listing definition. Group definition automatically end
@@ -574,6 +580,8 @@ module YARD
574
580
  if %w(class instance module).include?(tag.text)
575
581
  if object.is_a?(CodeObjects::MethodObject)
576
582
  object.scope = tag.text.to_sym
583
+ elsif handler && !inside_directive?
584
+ handler.scope = tag.text.to_sym
577
585
  else
578
586
  parser.state.scope = tag.text.to_sym
579
587
  end
@@ -604,7 +612,7 @@ module YARD
604
612
  if %w(public protected private).include?(tag.text)
605
613
  if object.is_a?(CodeObjects::Base)
606
614
  object.visibility = tag.text.to_sym
607
- elsif handler && !parser.state.inside_directive
615
+ elsif handler && !inside_directive?
608
616
  handler.visibility = tag.text.to_sym
609
617
  else
610
618
  parser.state.visibility = tag.text.to_sym
data/lib/yard/tags/tag.rb CHANGED
@@ -23,6 +23,7 @@ module YARD
23
23
  attr_accessor :types
24
24
 
25
25
  # @return [String] a name associated with the tag
26
+ # @return [nil] if no tag name is supplied
26
27
  attr_accessor :name
27
28
 
28
29
  # @return [CodeObjects::Base] the associated object
@@ -58,10 +59,10 @@ module YARD
58
59
  end
59
60
 
60
61
  # Provides a plain English summary of the type specification, or nil
61
- # if no types are provided or parseable.
62
+ # if no types are provided or parsable.
62
63
  #
63
64
  # @return [String] a plain English description of the associated types
64
- # @return [nil] if no types are provided or not parseable
65
+ # @return [nil] if no types are provided or not parsable
65
66
  def explain_types
66
67
  return nil if !types || types.empty?
67
68
  TypesExplainer.explain(*types)
@@ -13,7 +13,7 @@ module YARD
13
13
  end
14
14
 
15
15
  # (see explain)
16
- # @raise [SyntaxError] if the types are not parseable
16
+ # @raise [SyntaxError] if the types are not parsable
17
17
  def self.explain!(*types)
18
18
  Parser.parse(types.join(", ")).join("; ")
19
19
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Templates
@@ -78,9 +78,10 @@ module YARD
78
78
  def html_markup_markdown(text)
79
79
  # TODO: other libraries might be more complex
80
80
  provider = markup_class(:markdown)
81
- if provider.to_s == 'RDiscount'
81
+ case provider.to_s
82
+ when 'RDiscount'
82
83
  provider.new(text, :autolink).to_html
83
- elsif provider.to_s == 'RedcarpetCompat'
84
+ when 'RedcarpetCompat'
84
85
  provider.new(text, :autolink,
85
86
  :fenced_code,
86
87
  :gh_blockcode,
@@ -88,6 +89,8 @@ module YARD
88
89
  :tables,
89
90
  :with_toc_data,
90
91
  :no_intraemphasis).to_html
92
+ when 'CommonMarker'
93
+ CommonMarker.render_html(text, %i[DEFAULT GITHUB_PRE_LANG], %i[autolink table])
91
94
  else
92
95
  provider.new(text).to_html
93
96
  end
@@ -29,7 +29,8 @@ module YARD
29
29
  {:lib => :bluecloth, :const => 'BlueCloth'},
30
30
  {:lib => :maruku, :const => 'Maruku'},
31
31
  {:lib => :'rpeg-markdown', :const => 'PEGMarkdown'},
32
- {:lib => :rdoc, :const => 'YARD::Templates::Helpers::Markup::RDocMarkdown'}
32
+ {:lib => :rdoc, :const => 'YARD::Templates::Helpers::Markup::RDocMarkdown'},
33
+ {:lib => :commonmarker, :const => 'CommonMarker'}
33
34
  ],
34
35
  :textile => [
35
36
  {:lib => :redcloth, :const => 'RedCloth'}
@@ -66,7 +66,9 @@ module YARD
66
66
 
67
67
  # @return [String] formats source code of a constant value
68
68
  def format_constant(value)
69
- sp = value.split("\n").last[/^(\s+)/, 1]
69
+ # last can return nil, so default to empty string
70
+ sp = value.split("\n").last || ""
71
+ sp = sp[/^(\s+)/, 1]
70
72
  num = sp ? sp.size : 0
71
73
  html_syntax_highlight value.gsub(/^\s{#{num}}/, '')
72
74
  end
@@ -176,7 +176,9 @@ module YARD
176
176
  def load_setup_rb
177
177
  setup_file = File.join(full_path, 'setup.rb')
178
178
  if File.file? setup_file
179
- module_eval(File.read(setup_file).taint, setup_file, 1)
179
+ setup_code = File.read(setup_file)
180
+ setup_code.taint if setup_code.respond_to?(:taint)
181
+ module_eval(setup_code, setup_file, 1)
180
182
  end
181
183
  end
182
184
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Templates