yard 0.9.36 → 0.9.38

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/README.md +17 -10
  4. data/docs/Templates.md +5 -4
  5. data/lib/yard/autoload.rb +1 -0
  6. data/lib/yard/code_objects/base.rb +1 -1
  7. data/lib/yard/code_objects/extra_file_object.rb +1 -0
  8. data/lib/yard/code_objects/macro_object.rb +0 -1
  9. data/lib/yard/docstring_parser.rb +0 -1
  10. data/lib/yard/handlers/base.rb +23 -1
  11. data/lib/yard/handlers/processor.rb +0 -1
  12. data/lib/yard/handlers/ruby/constant_handler.rb +23 -6
  13. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
  14. data/lib/yard/handlers/ruby/visibility_handler.rb +14 -1
  15. data/lib/yard/logging.rb +116 -61
  16. data/lib/yard/open_struct.rb +67 -0
  17. data/lib/yard/parser/ruby/ast_node.rb +5 -4
  18. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +20 -5
  19. data/lib/yard/parser/ruby/ruby_parser.rb +54 -21
  20. data/lib/yard/parser/source_parser.rb +2 -2
  21. data/lib/yard/tags/default_factory.rb +1 -0
  22. data/lib/yard/tags/directives.rb +0 -1
  23. data/lib/yard/tags/overload_tag.rb +2 -1
  24. data/lib/yard/tags/tag.rb +2 -1
  25. data/lib/yard/tags/types_explainer.rb +3 -3
  26. data/lib/yard/templates/engine.rb +0 -1
  27. data/lib/yard/templates/helpers/html_helper.rb +5 -1
  28. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +2 -0
  29. data/lib/yard/templates/template_options.rb +0 -1
  30. data/lib/yard/version.rb +1 -1
  31. data/templates/default/fulldoc/html/css/full_list.css +3 -3
  32. data/templates/default/fulldoc/html/css/style.css +8 -15
  33. data/templates/default/fulldoc/html/full_list.erb +5 -2
  34. data/templates/default/fulldoc/html/js/app.js +348 -267
  35. data/templates/default/fulldoc/html/js/full_list.js +52 -24
  36. data/templates/default/fulldoc/html/setup.rb +10 -2
  37. data/templates/default/onefile/html/headers.erb +2 -0
  38. data/templates/default/tags/html/example.erb +2 -2
  39. metadata +7 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1f492861606b6ce24d390317f2a97ccbd67bbf73b8b964ea6f9e61bb4096d9e
4
- data.tar.gz: 1a4ec96bd604c8ab68cf6c971fc22aff400f2d8ed853d3b0b5fc222f4c8e7767
3
+ metadata.gz: a3a536051e6077e89b4ef2bc4ac2f30e60b8e65d33cdca957fed25644bf901a7
4
+ data.tar.gz: 6f4a7736baaeec0a55e7595b12f5828927fc46115e20e4dd919e96543541cbbd
5
5
  SHA512:
6
- metadata.gz: 04b727cb198fd9559a9314989fae7bcf60202531f5ab634d211780b5bbf15b60341d8a8f5fa6fd890c743c7d1b953e7b49d3c8e73997f3397b7344a70442fd29
7
- data.tar.gz: c3df5e59c450adfc6d6088bd7c6a6c64f4477c1de65eae7cbd21e1c4ca410d606179bc88c84ed084b22d7b3f8bf66cc67426e9c103558b0a25c5ab01c1900ab9
6
+ metadata.gz: b9a5348496a1778b2f4a7793df24716329a665fdabbe237932cd126c8309be4543d35b35a279e4ddb3cb31978c1b6e88ae0b799004ee79f2316d6896b9057201
7
+ data.tar.gz: f5c993f3808b9f5baca0c8fc1f92abeb7a113b1be7164dfd71b0b4bff98c58416ea5a82baf473780995d132bbbd7ffbbbffceddb01fda40993fac04bdb790cf8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # main
2
2
 
3
+ # [0.9.38] - December 5th, 2025
4
+
5
+ [0.9.38]: https://github.com/lsegal/yard/compare/v0.9.37...v0.9.38
6
+
7
+ - Add support for complex constant assignment (#1599)
8
+ - Add support for Data type structs (#1600)
9
+ - Support multi method duck type syntax in type explainer (#1631)
10
+ - Improve Ruby 3.5 compatibility (#1616)
11
+ - Update documentation for various type annotations (#1615)
12
+ - JavaScript frontend updates (resizer, JS bugs, reduce console verbosity) for default template
13
+ - Fix beginless/endless range errors (#1549, #1625)
14
+ - Fix path structure in Templates.md documentation (#1588)
15
+ - Fix signature handling in overload (#1590)
16
+ - Fix handling of **nil with named block (#1623)
17
+ - Fix directives in empty class bodies (#1624)
18
+ - Fix parsing of array within array syntax (#1604)
19
+ - Fix parsing of visibility keywords in front of class methods (#1632)
20
+
21
+ # [0.9.37] - September 4th, 2024
22
+
23
+ [0.9.37]: https://github.com/lsegal/yard/compare/v0.9.36...v0.9.37
24
+
25
+ - Fix JavaScript errors in `--one-file` template (#1426)
26
+ - Fix heredoc parsing and add support for squiggly heredocs (#1315, #1495)
27
+ - Accessibility improvements to the default template (#1501)
28
+ - Improved YARD documentation (#1410, #1512, #1516, #1544)
29
+ - Fix error when parsing `@option` tags (#1515)
30
+ - Fix issue parsing UTF-8 filenames (#1517)
31
+ - Replace OpenStruct with optimized YARD::OpenStruct to avoid ostruct performance warnings (#1545)
32
+ - Add support for `private attr_*` syntax (#1541)
33
+ - Remove logger dependency (#1546)
34
+
3
35
  # [0.9.36] - February 29th, 2024
4
36
 
5
37
  [0.9.36]: https://github.com/lsegal/yard/compare/v0.9.35...v0.9.36
data/README.md CHANGED
@@ -122,12 +122,19 @@ HTML. If running `which rdoc` turns up empty, install RDoc by issuing:
122
122
  $ sudo apt-get install rdoc
123
123
  ```
124
124
 
125
+ ### Markdown parser
126
+
127
+ When rendering markdown, yard will use one of several possible markdown providers,
128
+ [in order of priority](https://github.com/lsegal/yard/blob/e833aac7a01510245dd4ae1d1d18b046c8293c2d/lib/yard/templates/helpers/markup_helper.rb#L26-L33).
129
+ If you are experiencing rendering bugs (example [1](https://github.com/lsegal/yard/issues/1410) [2](https://github.com/lsegal/yard/issues/1543)), try adding one of the
130
+ gems further up in the list to your Gemfile.
131
+
125
132
  ## Usage
126
133
 
127
134
  There are a couple of ways to use YARD. The first is via command-line, and the
128
135
  second is the Rake task.
129
136
 
130
- **1. yard Command-line Tool**
137
+ ### 1. yard Command-line Tool
131
138
 
132
139
  YARD comes packaged with a executable named `yard` which can control the many
133
140
  functions of YARD, including generating documentation, graphs running the YARD
@@ -140,7 +147,7 @@ $ yard --help
140
147
  Plugins can also add commands to the `yard` executable to provide extra
141
148
  functionality.
142
149
 
143
- ### Generating Documentation
150
+ #### Generating Documentation
144
151
 
145
152
  <span class="note">The `yardoc` executable is a shortcut for `yard doc`.</span>
146
153
 
@@ -185,9 +192,9 @@ Note that the README file can be specified with its own `--readme` switch.
185
192
  You can also add a `.yardopts` file to your project directory which lists the
186
193
  switches separated by whitespace (newlines or space) to pass to yardoc whenever
187
194
  it is run. A full overview of the `.yardopts` file can be found in
188
- {YARD::CLI::Yardoc}.
195
+ [YARD::CLI::Yardoc](https://rubydoc.info/gems/yard/YARD/CLI/Yardoc#label-Options+File+-28.yardopts-29).
189
196
 
190
- ### Queries
197
+ #### Queries
191
198
 
192
199
  The `yardoc` tool also supports a `--query` argument to only include objects
193
200
  that match a certain data or meta-data query. The query syntax is Ruby, though a
@@ -214,7 +221,7 @@ following two lines both check for the existence of a return and param tag:
214
221
 
215
222
  For more information about the query syntax, see the {YARD::Verifier} class.
216
223
 
217
- **2. Rake Task**
224
+ ### 2. Rake Task
218
225
 
219
226
  The second most obvious is to generate docs via a Rake task. You can do this by
220
227
  adding the following to your `Rakefile`:
@@ -240,7 +247,7 @@ environment variable:
240
247
  $ rake yard OPTS='--any --extra --opts'
241
248
  ```
242
249
 
243
- **3. `yri` RI Implementation**
250
+ ### 3. `yri` RI Implementation
244
251
 
245
252
  The yri binary will use the cached .yardoc database to give you quick ri-style
246
253
  access to your documentation. It's way faster than ri but currently does not
@@ -264,7 +271,7 @@ $ yard gems
264
271
  If you don't have sudo access, it will write these files to your `~/.yard`
265
272
  directory. `yri` will also cache lookups there.
266
273
 
267
- **4. `yard server` Documentation Server**
274
+ ### 4. `yard server` Documentation Server
268
275
 
269
276
  The `yard server` command serves documentation for a local project or all
270
277
  installed RubyGems. To serve documentation for a project you are working on,
@@ -278,14 +285,14 @@ And the project inside the current directory will be parsed (if the source has
278
285
  not yet been scanned by YARD) and served at
279
286
  [http://localhost:8808](http://localhost:8808).
280
287
 
281
- ### Live Reloading
288
+ #### Live Reloading
282
289
 
283
290
  If you want to serve documentation on a project while you document it so that
284
291
  you can preview the results, simply pass `--reload` (`-r`) to the above command
285
292
  and YARD will reload any changed files on each request. This will allow you to
286
293
  change any documentation in the source and refresh to see the new contents.
287
294
 
288
- ### Serving Gems
295
+ #### Serving Gems
289
296
 
290
297
  To serve documentation for all installed gems, call:
291
298
 
@@ -297,7 +304,7 @@ This will also automatically build documentation for any gems that have not been
297
304
  previously scanned. Note that in this case there will be a slight delay between
298
305
  the first request of a newly parsed gem.
299
306
 
300
- **5. `yard graph` Graphviz Generator**
307
+ ### 5. `yard graph` Graphviz Generator
301
308
 
302
309
  You can use `yard graph` to generate dot graphs of your code. This, of course,
303
310
  requires [Graphviz](http://www.graphviz.org) and the `dot` binary. By default
data/docs/Templates.md CHANGED
@@ -280,10 +280,11 @@ seen above by creating such a path in our '/path/to/mytemplates' custom template
280
280
  path:
281
281
 
282
282
  /path/to/mytemplates/:
283
- |-- class
284
- | |-- html
285
- | | |-- customsection.erb
286
- | |-- setup.rb
283
+ |--default
284
+ | |-- class
285
+ | | |-- html
286
+ | | | |-- customsection.erb
287
+ | | |-- setup.rb
287
288
 
288
289
  The `setup.rb` file would look like:
289
290
 
data/lib/yard/autoload.rb CHANGED
@@ -298,6 +298,7 @@ module YARD
298
298
  autoload :DocstringParser, __p('docstring_parser')
299
299
  autoload :GemIndex, __p('gem_index')
300
300
  autoload :Logger, __p('logging')
301
+ autoload :OpenStruct, __p('open_struct')
301
302
  autoload :Options, __p('options')
302
303
  autoload :Registry, __p('registry')
303
304
  autoload :RegistryResolver, __p('registry_resolver')
@@ -228,7 +228,7 @@ module YARD
228
228
  # @example Create class Z inside namespace X::Y
229
229
  # CodeObjects::Base.new(P("X::Y"), :Z) # or
230
230
  # CodeObjects::Base.new(Registry.root, "X::Y")
231
- # @param [NamespaceObject] namespace the namespace the object belongs in,
231
+ # @param [NamespaceObject, :root, nil] namespace the namespace the object belongs in,
232
232
  # {Registry.root} or :root should be provided if it is associated with
233
233
  # the top level namespace.
234
234
  # @param [Symbol, String] name the name (or complex path) of the object.
@@ -127,6 +127,7 @@ module YARD::CodeObjects
127
127
  end
128
128
 
129
129
  def translate(data)
130
+ return data if locale.nil?
130
131
  text = YARD::I18n::Text.new(data, :have_header => true)
131
132
  text.translate(YARD::Registry.locale(locale))
132
133
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module CodeObjects
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  # Parses text and creates a {Docstring} object to represent documentation
@@ -462,6 +462,18 @@ module YARD
462
462
  end
463
463
  end
464
464
 
465
+ if docstring.is_a?(String)
466
+ if (m = docstring.match(/^\s*@!?visibility\s+(public|private|protected)\b/m))
467
+ vis_sym = m[1].to_sym
468
+
469
+ if object.nil?
470
+ globals.visibility_origin = :directive
471
+ elsif object.is_a?(CodeObjects::MethodObject)
472
+ object.visibility = vis_sym
473
+ end
474
+ end
475
+ end
476
+
465
477
  register_transitive_tags(object)
466
478
  end
467
479
 
@@ -511,7 +523,17 @@ module YARD
511
523
  def register_visibility(object, visibility = self.visibility)
512
524
  return unless object.respond_to?(:visibility=)
513
525
  return if object.is_a?(NamespaceObject)
514
- object.visibility = visibility
526
+
527
+ if object.is_a?(CodeObjects::MethodObject)
528
+ origin = globals.visibility_origin
529
+ if origin == :keyword
530
+ object.visibility = visibility if object.scope == scope
531
+ else
532
+ object.visibility = visibility
533
+ end
534
+ else
535
+ object.visibility = visibility
536
+ end
515
537
  end
516
538
 
517
539
  # Registers the same method information on the module function, if
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Handlers
@@ -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,34 @@ 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
+ klass.attributes[:instance][member] = SymbolHash[:read => nil, :write => nil]
53
+ create_reader(klass, member)
54
+ end
55
+ parse_block(statement[1].block[1], :namespace => klass) unless statement[1].block.nil?
56
+ else
57
+ raise YARD::Parser::UndocumentableError, "Data assignment to #{lhs.source}"
58
+ end
59
+ end
60
+
61
+ # Extract the parameters from the Struct.new or Data.define AST node, returning them as a list
45
62
  # of strings
46
63
  #
47
- # @param [MethodCallNode] superclass the AST node for the Struct.new call
64
+ # @param [MethodCallNode] superclass the AST node for the Struct.new or Data.define call
48
65
  # @return [Array<String>] the member names to generate methods for
49
66
  def extract_parameters(superclass)
50
67
  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
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