yard 0.9.36 → 0.9.43

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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -1
  3. data/README.md +29 -25
  4. data/docs/GettingStarted.md +41 -15
  5. data/docs/Parser.md +17 -42
  6. data/docs/Tags.md +5 -5
  7. data/docs/Templates.md +5 -4
  8. data/docs/WhatsNew.md +59 -7
  9. data/docs/templates/default/yard_tags/html/setup.rb +1 -1
  10. data/lib/yard/autoload.rb +18 -0
  11. data/lib/yard/cli/diff.rb +7 -2
  12. data/lib/yard/code_objects/base.rb +1 -1
  13. data/lib/yard/code_objects/extra_file_object.rb +1 -0
  14. data/lib/yard/code_objects/macro_object.rb +0 -1
  15. data/lib/yard/code_objects/proxy.rb +1 -1
  16. data/lib/yard/docstring_parser.rb +0 -1
  17. data/lib/yard/handlers/base.rb +23 -1
  18. data/lib/yard/handlers/processor.rb +1 -1
  19. data/lib/yard/handlers/rbs/attribute_handler.rb +79 -0
  20. data/lib/yard/handlers/rbs/base.rb +38 -0
  21. data/lib/yard/handlers/rbs/constant_handler.rb +18 -0
  22. data/lib/yard/handlers/rbs/method_handler.rb +327 -0
  23. data/lib/yard/handlers/rbs/mixin_handler.rb +20 -0
  24. data/lib/yard/handlers/rbs/namespace_handler.rb +26 -0
  25. data/lib/yard/handlers/ruby/attribute_handler.rb +7 -4
  26. data/lib/yard/handlers/ruby/constant_handler.rb +24 -6
  27. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
  28. data/lib/yard/handlers/ruby/visibility_handler.rb +14 -1
  29. data/lib/yard/i18n/locale.rb +1 -1
  30. data/lib/yard/i18n/pot_generator.rb +1 -1
  31. data/lib/yard/logging.rb +116 -61
  32. data/lib/yard/open_struct.rb +67 -0
  33. data/lib/yard/parser/rbs/rbs_parser.rb +325 -0
  34. data/lib/yard/parser/rbs/statement.rb +75 -0
  35. data/lib/yard/parser/ruby/ast_node.rb +5 -4
  36. data/lib/yard/parser/ruby/legacy/irb/slex.rb +19 -1
  37. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +20 -5
  38. data/lib/yard/parser/ruby/ruby_parser.rb +109 -24
  39. data/lib/yard/parser/source_parser.rb +5 -4
  40. data/lib/yard/registry_resolver.rb +7 -0
  41. data/lib/yard/rubygems/specification.rb +1 -1
  42. data/lib/yard/server/commands/base.rb +1 -1
  43. data/lib/yard/server/library_version.rb +1 -1
  44. data/lib/yard/server/templates/default/fulldoc/html/css/custom.css +168 -88
  45. data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +203 -12
  46. data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +1 -17
  47. data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -2
  48. data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +3 -3
  49. data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +2 -3
  50. data/lib/yard/server/templates/doc_server/processing/html/processing.erb +22 -16
  51. data/lib/yard/tags/default_factory.rb +1 -0
  52. data/lib/yard/tags/directives.rb +7 -1
  53. data/lib/yard/tags/library.rb +3 -3
  54. data/lib/yard/tags/overload_tag.rb +2 -1
  55. data/lib/yard/tags/tag.rb +2 -1
  56. data/lib/yard/tags/types_explainer.rb +5 -4
  57. data/lib/yard/templates/engine.rb +0 -1
  58. data/lib/yard/templates/helpers/base_helper.rb +1 -1
  59. data/lib/yard/templates/helpers/html_helper.rb +21 -6
  60. data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +6 -1
  61. data/lib/yard/templates/helpers/markup/hybrid_markdown.rb +2147 -0
  62. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +2 -0
  63. data/lib/yard/templates/helpers/markup_helper.rb +4 -2
  64. data/lib/yard/templates/template_options.rb +0 -1
  65. data/lib/yard/version.rb +1 -1
  66. data/po/ja.po +82 -82
  67. data/templates/default/fulldoc/html/css/common.css +1 -1
  68. data/templates/default/fulldoc/html/css/full_list.css +201 -53
  69. data/templates/default/fulldoc/html/css/style.css +991 -399
  70. data/templates/default/fulldoc/html/full_list.erb +8 -5
  71. data/templates/default/fulldoc/html/js/app.js +799 -312
  72. data/templates/default/fulldoc/html/js/full_list.js +332 -214
  73. data/templates/default/fulldoc/html/setup.rb +10 -2
  74. data/templates/default/layout/html/headers.erb +1 -1
  75. data/templates/default/layout/html/layout.erb +3 -1
  76. data/templates/default/method/html/header.erb +3 -3
  77. data/templates/default/module/html/defines.erb +3 -3
  78. data/templates/default/module/html/inherited_methods.erb +1 -0
  79. data/templates/default/module/html/method_summary.erb +8 -0
  80. data/templates/default/module/setup.rb +20 -0
  81. data/templates/default/onefile/html/headers.erb +2 -0
  82. data/templates/default/onefile/html/layout.erb +3 -4
  83. data/templates/default/tags/html/example.erb +2 -2
  84. data/templates/guide/fulldoc/html/css/style.css +347 -97
  85. data/templates/guide/fulldoc/html/js/app.js +61 -33
  86. data/templates/guide/layout/html/layout.erb +69 -72
  87. metadata +19 -8
@@ -9,6 +9,9 @@ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
9
9
  if statement[1].call? && statement[1][0][0] == s(:const, "Struct") &&
10
10
  statement[1][2] == s(:ident, "new")
11
11
  process_structclass(statement)
12
+ elsif statement[1].call? && statement[1][0][0] == s(:const, "Data") &&
13
+ statement[1][2] == s(:ident, "define")
14
+ process_dataclass(statement)
12
15
  elsif statement[0].type == :var_field && statement[0][0].type == :const
13
16
  process_constant(statement)
14
17
  elsif statement[0].type == :const_path_field
@@ -31,20 +34,35 @@ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
31
34
  end
32
35
 
33
36
  def process_structclass(statement)
34
- lhs = statement[0][0]
35
- if lhs.type == :const
36
- klass = create_class(lhs[0], P(:Struct))
37
+ lhs = statement[0]
38
+ if (lhs.type == :var_field && lhs[0].type == :const) || lhs.type == :const_path_field
39
+ klass = create_class(lhs.source, P(:Struct))
37
40
  create_attributes(klass, extract_parameters(statement[1]))
38
41
  parse_block(statement[1].block[1], :namespace => klass) unless statement[1].block.nil?
39
42
  else
40
- raise YARD::Parser::UndocumentableError, "Struct assignment to #{statement[0].source}"
43
+ raise YARD::Parser::UndocumentableError, "Struct assignment to #{lhs.source}"
41
44
  end
42
45
  end
43
46
 
44
- # Extract the parameters from the Struct.new AST node, returning them as a list
47
+ def process_dataclass(statement)
48
+ lhs = statement[0]
49
+ if (lhs.type == :var_field && lhs[0].type == :const) || lhs.type == :const_path_field
50
+ klass = create_class(lhs.source, P(:Data))
51
+ extract_parameters(statement[1]).each do |member|
52
+ next if klass.attributes[:instance][member]
53
+ klass.attributes[:instance][member] = SymbolHash[:read => nil, :write => nil]
54
+ create_reader(klass, member)
55
+ end
56
+ parse_block(statement[1].block[1], :namespace => klass) unless statement[1].block.nil?
57
+ else
58
+ raise YARD::Parser::UndocumentableError, "Data assignment to #{lhs.source}"
59
+ end
60
+ end
61
+
62
+ # Extract the parameters from the Struct.new or Data.define AST node, returning them as a list
45
63
  # of strings
46
64
  #
47
- # @param [MethodCallNode] superclass the AST node for the Struct.new call
65
+ # @param [MethodCallNode] superclass the AST node for the Struct.new or Data.define call
48
66
  # @return [Array<String>] the member names to generate methods for
49
67
  def extract_parameters(superclass)
50
68
  return [] unless superclass.parameters
@@ -8,9 +8,10 @@ class YARD::Handlers::Ruby::Legacy::VisibilityHandler < YARD::Handlers::Ruby::Le
8
8
  vis = statement.tokens.first.text
9
9
  if statement.tokens.size == 1
10
10
  self.visibility = vis
11
+ globals.visibility_origin = :keyword
11
12
  else
12
13
  tokval_list(statement.tokens[2..-1], :attr).each do |name|
13
- MethodObject.new(namespace, name, scope) {|o| o.visibility = vis }
14
+ MethodObject.new(namespace, name, scope) { |o| o.visibility = vis }
14
15
  end
15
16
  end
16
17
  end
@@ -13,10 +13,23 @@ class YARD::Handlers::Ruby::VisibilityHandler < YARD::Handlers::Ruby::Base
13
13
  case statement.type
14
14
  when :var_ref, :vcall
15
15
  self.visibility = ident.first.to_sym
16
- when :fcall, :command
16
+ globals.visibility_origin = :keyword
17
+ when :command
18
+ if RUBY_VERSION >= '3.' && is_attribute_method?(statement.parameters.first)
19
+ parse_block(statement.parameters.first, visibility: ident.first.to_sym)
20
+ return
21
+ end
22
+ process_decorator do |method|
23
+ method.visibility = ident.first if method.respond_to? :visibility=
24
+ end
25
+ when :fcall
17
26
  process_decorator do |method|
18
27
  method.visibility = ident.first if method.respond_to? :visibility=
19
28
  end
20
29
  end
21
30
  end
31
+
32
+ def is_attribute_method?(node)
33
+ node.type == :command && node.jump(:ident).first.to_s =~ /^attr_(accessor|writer|reader)$/
34
+ end
22
35
  end
@@ -24,7 +24,7 @@ module YARD
24
24
 
25
25
  # @return [String] the name of the locale. It used IETF language
26
26
  # tag format +[language[_territory][.codeset][@modifier]]+.
27
- # @see http://tools.ietf.org/rfc/bcp/bcp47.txt
27
+ # @see https://tools.ietf.org/rfc/bcp/bcp47.txt
28
28
  # BCP 47 - Tags for Identifying Languages
29
29
  attr_reader :name
30
30
 
@@ -60,7 +60,7 @@ module YARD
60
60
  # File.open(po_file_path, "w") do |pot_file|
61
61
  # pot_file.print(pot)
62
62
  # end
63
- # @see http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
63
+ # @see https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
64
64
  # GNU gettext manual about details of PO file
65
65
  class PotGenerator
66
66
  # Extracted messages.
data/lib/yard/logging.rb CHANGED
@@ -1,12 +1,44 @@
1
1
  # encoding: utf-8
2
2
  # frozen_string_literal: true
3
- require 'logger'
4
3
  require 'thread'
5
4
 
6
5
  module YARD
7
6
  # Handles console logging for info, warnings and errors.
8
7
  # Uses the stdlib Logger class in Ruby for all the backend logic.
9
- class Logger < ::Logger
8
+ class Logger
9
+ # Log severity levels
10
+ module Severity
11
+ # Debugging log level
12
+ DEBUG = 0
13
+
14
+ # Information log level
15
+ INFO = 1
16
+
17
+ # Warning log level
18
+ WARN = 2
19
+
20
+ # Error log level
21
+ ERROR = 3
22
+
23
+ # Fatal log level
24
+ FATAL = 4
25
+
26
+ # Unknown log level
27
+ UNKNOWN = 5
28
+
29
+ # @private
30
+ SEVERITIES = {
31
+ DEBUG => :debug,
32
+ INFO => :info,
33
+ WARN => :warn,
34
+ ERROR => :error,
35
+ FATAL => :fatal,
36
+ UNKNOWN => :unknown
37
+ }
38
+ end
39
+
40
+ include Severity
41
+
10
42
  # The list of characters displayed beside the progress bar to indicate
11
43
  # "movement".
12
44
  # @since 0.8.2
@@ -14,25 +46,31 @@ module YARD
14
46
 
15
47
  # @return [IO] the IO object being logged to
16
48
  # @since 0.8.2
17
- def io; @logdev end
18
- def io=(pipe) @logdev = pipe end
49
+ attr_accessor :io
19
50
 
20
51
  # @return [Boolean] whether backtraces should be shown (by default
21
52
  # this is on).
22
53
  def show_backtraces; @show_backtraces || level == DEBUG end
23
54
  attr_writer :show_backtraces
24
55
 
56
+ # @return [DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN] the logging level
57
+ attr_accessor :level
58
+
59
+ # @return [Boolean] whether a warn message has been emitted. Used for status tracking.
60
+ attr_accessor :warned
61
+
25
62
  # @return [Boolean] whether progress indicators should be shown when
26
63
  # logging CLIs (by default this is off).
27
64
  def show_progress
28
65
  return false if YARD.ruby18? # threading is too ineffective for progress support
29
- return false if YARD.windows? # windows has poor ANSI support
30
66
  return false unless io.tty? # no TTY support on IO
31
67
  return false unless level > INFO # no progress in verbose/debug modes
32
68
  @show_progress
33
69
  end
34
70
  attr_writer :show_progress
35
71
 
72
+ # @!group Constructor Methods
73
+
36
74
  # The logger instance
37
75
  # @return [Logger] the logger instance
38
76
  def self.instance(pipe = STDOUT)
@@ -40,13 +78,12 @@ module YARD
40
78
  end
41
79
 
42
80
  # Creates a new logger
81
+ # @private
43
82
  def initialize(pipe, *args)
44
- super(pipe, *args)
45
83
  self.io = pipe
46
84
  self.show_backtraces = true
47
85
  self.show_progress = false
48
86
  self.level = WARN
49
- self.formatter = method(:format_log)
50
87
  self.warned = false
51
88
  @progress_indicator = 0
52
89
  @mutex = Mutex.new
@@ -54,36 +91,64 @@ module YARD
54
91
  @progress_last_update = Time.now
55
92
  end
56
93
 
57
- # Changes the debug level to DEBUG if $DEBUG is set
58
- # and writes a debugging message.
59
- def debug(*args)
60
- self.level = DEBUG if $DEBUG
61
- super
94
+ # @!macro [attach] logger.create_log_method
95
+ # @method $1(message)
96
+ # Logs a message with the $1 severity level.
97
+ # @param message [String] the message to log
98
+ # @see #log
99
+ # @return [void]
100
+ # @private
101
+ def self.create_log_method(name)
102
+ severity = Severity.const_get(name.to_s.upcase)
103
+ define_method(name) { |message| log(severity, message) }
62
104
  end
63
105
 
106
+ # @!group Logging Methods
107
+
108
+ create_log_method :info
109
+ create_log_method :error
110
+ create_log_method :fatal
111
+ create_log_method :unknown
112
+
113
+ # Changes the debug level to DEBUG if $DEBUG is set and writes a debugging message.
114
+ create_log_method :debug
115
+
64
116
  # Remembers when a warning occurs and writes a warning message.
65
- def warn(*args)
66
- self.warned = true
67
- super
117
+ create_log_method :warn
118
+
119
+ # Logs a message with a given severity
120
+ # @param severity [DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN] the severity level
121
+ # @param message [String] the message to log
122
+ def log(severity, message)
123
+ self.level = DEBUG if $DEBUG
124
+ return unless severity >= level
125
+
126
+ self.warned = true if severity == WARN
127
+ clear_line
128
+ puts "[#{SEVERITIES[severity].to_s.downcase}]: #{message}"
68
129
  end
69
- attr_accessor :warned
70
130
 
71
- # Captures the duration of a block of code for benchmark analysis. Also
72
- # calls {#progress} on the message to display it to the user.
131
+ # @!group Level Control Methods
132
+
133
+ # Sets the logger level for the duration of the block
73
134
  #
74
- # @todo Implement capture storage for reporting of benchmarks
75
- # @param [String] msg the message to display
76
- # @param [Symbol, nil] nontty_log the level to log as if the output
77
- # stream is not a TTY. Use +nil+ for no alternate logging.
78
- # @yield a block of arbitrary code to benchmark
79
- # @return [void]
80
- def capture(msg, nontty_log = :debug)
81
- progress(msg, nontty_log)
135
+ # @example
136
+ # log.enter_level(Logger::ERROR) do
137
+ # YARD.parse_string "def x; end"
138
+ # end
139
+ # @param [Fixnum] new_level the logger level for the duration of the block.
140
+ # values can be found in Ruby's Logger class.
141
+ # @yield the block with the logger temporarily set to +new_level+
142
+ def enter_level(new_level = level)
143
+ old_level = level
144
+ self.level = new_level
82
145
  yield
83
146
  ensure
84
- clear_progress
147
+ self.level = old_level
85
148
  end
86
149
 
150
+ # @!group Utility Printing Methods
151
+
87
152
  # Displays a progress indicator for a given message. This progress report
88
153
  # is only displayed on TTY displays, otherwise the message is passed to
89
154
  # the +nontty_log+ level.
@@ -120,7 +185,7 @@ module YARD
120
185
  # @since 0.8.2
121
186
  def clear_progress
122
187
  return unless show_progress
123
- print_no_newline("\e[?25h\e[2K")
188
+ io.write("\e[?25h\e[2K")
124
189
  @progress_msg = nil
125
190
  end
126
191
 
@@ -133,16 +198,13 @@ module YARD
133
198
  print("#{msg}\n")
134
199
  end
135
200
 
136
- alias print_no_newline <<
137
- private :print_no_newline
138
-
139
201
  # Displays an unformatted line to the logger output stream.
140
202
  # @param [String] msg the message to display
141
203
  # @return [void]
142
204
  # @since 0.8.2
143
205
  def print(msg = '')
144
206
  clear_line
145
- print_no_newline(msg)
207
+ io.write(msg)
146
208
  end
147
209
  alias << print
148
210
 
@@ -158,48 +220,41 @@ module YARD
158
220
  exc.backtrace[0..5].map {|x| "\n\t#{x}" }.join + "\n")
159
221
  end
160
222
 
223
+ # @!group Benchmarking Methods
224
+
225
+ # Captures the duration of a block of code for benchmark analysis. Also
226
+ # calls {#progress} on the message to display it to the user.
227
+ #
228
+ # @todo Implement capture storage for reporting of benchmarks
229
+ # @param [String] msg the message to display
230
+ # @param [Symbol, nil] nontty_log the level to log as if the output
231
+ # stream is not a TTY. Use +nil+ for no alternate logging.
232
+ # @yield a block of arbitrary code to benchmark
233
+ # @return [void]
234
+ def capture(msg, nontty_log = :debug)
235
+ progress(msg, nontty_log)
236
+ yield
237
+ ensure
238
+ clear_progress
239
+ end
240
+
241
+ # @!endgroup
242
+
161
243
  # Warns that the Ruby environment does not support continuations. Applies
162
244
  # to JRuby, Rubinius and MacRuby. This warning will only display once
163
245
  # per Ruby process.
164
246
  #
165
247
  # @deprecated Continuations are no longer needed by YARD 0.8.0+.
166
248
  # @return [void]
249
+ # @private
167
250
  def warn_no_continuations
168
251
  end
169
252
 
170
- # Sets the logger level for the duration of the block
171
- #
172
- # @example
173
- # log.enter_level(Logger::ERROR) do
174
- # YARD.parse_string "def x; end"
175
- # end
176
- # @param [Fixnum] new_level the logger level for the duration of the block.
177
- # values can be found in Ruby's Logger class.
178
- # @yield the block with the logger temporarily set to +new_level+
179
- def enter_level(new_level = level)
180
- old_level = level
181
- self.level = new_level
182
- yield
183
- ensure
184
- self.level = old_level
185
- end
186
-
187
253
  private
188
254
 
189
- # Override this internal Logger method to clear line
190
- def add(*args)
191
- clear_line
192
- super(*args)
193
- end
194
-
195
255
  def clear_line
196
256
  return unless @progress_msg
197
- print_no_newline("\e[2K\r")
198
- end
199
-
200
- # Log format (from Logger implementation). Used by Logger internally
201
- def format_log(sev, _time, _prog, msg)
202
- "[#{sev.downcase}]: #{msg}\n"
257
+ io.write("\e[2K\r")
203
258
  end
204
259
  end
205
260
  end
@@ -0,0 +1,67 @@
1
+ module YARD
2
+ # An OpenStruct compatible struct class that allows for basic access of attributes
3
+ # via +struct.attr_name+ and +struct.attr_name = value+.
4
+ class OpenStruct
5
+ def initialize(hash = {})
6
+ @table = hash.each_pair { |k, v| [k.to_sym, v] }
7
+ end
8
+
9
+ # @private
10
+ def method_missing(name, *args)
11
+ if name.to_s.end_with?('=')
12
+ varname = name.to_s[0..-2].to_sym
13
+ __cache_lookup__(varname)
14
+ send(name, args.first)
15
+ else
16
+ __cache_lookup__(name)
17
+ send(name)
18
+ end
19
+ end
20
+
21
+ def to_h
22
+ @table.dup
23
+ end
24
+
25
+ def ==(other)
26
+ other.is_a?(self.class) && to_h == other.to_h
27
+ end
28
+
29
+ def hash
30
+ @table.hash
31
+ end
32
+
33
+ def dig(*keys)
34
+ @table.dig(*keys)
35
+ end
36
+
37
+ def []=(key, value)
38
+ @table[key.to_sym] = value
39
+ end
40
+
41
+ def [](key)
42
+ @table[key.to_sym]
43
+ end
44
+
45
+ def each_pair(&block)
46
+ @table.each_pair(&block)
47
+ end
48
+
49
+ def marshal_dump
50
+ @table
51
+ end
52
+
53
+ def marshal_load(data)
54
+ @table = data
55
+ end
56
+
57
+ private
58
+
59
+ def __cache_lookup__(name)
60
+ key = name.to_sym.inspect
61
+ instance_eval <<-RUBY, __FILE__, __LINE__ + 1
62
+ def #{name}; @table[#{key}]; end
63
+ def #{name.to_s.sub('?','_')}=(v); @table[#{key}] = v; end unless #{key}.to_s.include?('?')
64
+ RUBY
65
+ end
66
+ end
67
+ end