yard 0.9.25 → 0.9.28

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of yard might be problematic. Click here for more details.

Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +0 -0
  3. data/.gitattributes +4 -0
  4. data/.github/FUNDING.yml +3 -0
  5. data/.github/ISSUE_TEMPLATE.md +6 -6
  6. data/.github/PULL_REQUEST_TEMPLATE.md +5 -5
  7. data/.github/workflows/ci.yml +10 -10
  8. data/.github/workflows/gem.yml +19 -0
  9. data/.gitignore +0 -0
  10. data/.rspec +0 -0
  11. data/.rubocop.yml +0 -0
  12. data/.yardopts +0 -0
  13. data/.yardopts_guide +0 -0
  14. data/.yardopts_i18n +0 -0
  15. data/CHANGELOG.md +40 -8
  16. data/CONTRIBUTING.md +2 -2
  17. data/Gemfile +5 -3
  18. data/LICENSE +1 -1
  19. data/README.md +1 -1
  20. data/Rakefile +0 -3
  21. data/lib/yard/cli/stats.rb +4 -1
  22. data/lib/yard/cli/yardoc.rb +4 -2
  23. data/lib/yard/code_objects/method_object.rb +1 -1
  24. data/lib/yard/config.rb +5 -1
  25. data/lib/yard/handlers/c/base.rb +164 -164
  26. data/lib/yard/handlers/ruby/method_handler.rb +2 -2
  27. data/lib/yard/handlers/ruby/mixin_handler.rb +7 -2
  28. data/lib/yard/handlers/ruby/module_function_handler.rb +15 -3
  29. data/lib/yard/parser/ruby/ast_node.rb +9 -2
  30. data/lib/yard/parser/ruby/ruby_parser.rb +1 -1
  31. data/lib/yard/parser/source_parser.rb +1 -1
  32. data/lib/yard/server/commands/base.rb +2 -2
  33. data/lib/yard/server/commands/library_command.rb +1 -1
  34. data/lib/yard/tags/directives.rb +10 -1
  35. data/lib/yard/templates/helpers/html_helper.rb +5 -2
  36. data/lib/yard/templates/helpers/markup_helper.rb +2 -1
  37. data/lib/yard/templates/helpers/method_helper.rb +3 -1
  38. data/lib/yard/templates/section.rb +1 -3
  39. data/lib/yard/templates/template.rb +3 -1
  40. data/lib/yard/version.rb +1 -1
  41. data/lib/yard.rb +6 -0
  42. data/samus.json +15 -46
  43. data/tasks/prepare_tag.rake +45 -0
  44. data/templates/default/fulldoc/html/css/style.css +1 -0
  45. data/templates/default/layout/html/footer.erb +1 -1
  46. data/yard.gemspec +2 -1
  47. metadata +21 -4
  48. data/.travis.yml +0 -52
@@ -1,164 +1,164 @@
1
- # frozen_string_literal: true
2
- module YARD
3
- module Handlers
4
- module C
5
- class Base < Handlers::Base
6
- include YARD::Parser::C
7
- include HandlerMethods
8
-
9
- # @return [Boolean] whether the handler handles this statement
10
- def self.handles?(statement, processor)
11
- processor.globals.cruby_processed_files ||= {}
12
- processor.globals.cruby_processed_files[processor.file] = true
13
-
14
- src = statement.respond_to?(:declaration) ?
15
- statement.declaration : statement.source
16
-
17
- handlers.any? do |a_handler|
18
- statement_class >= statement.class &&
19
- case a_handler
20
- when String
21
- src == a_handler
22
- when Regexp
23
- src =~ a_handler
24
- end
25
- end
26
- end
27
-
28
- def self.statement_class(type = nil)
29
- if type
30
- @statement_class = type
31
- else
32
- (defined?(@statement_class) && @statement_class) || Statement
33
- end
34
- end
35
-
36
- # @group Registering objects
37
-
38
- def register_docstring(object, docstring = nil, stmt = nil)
39
- super(object, docstring, stmt) if docstring
40
- end
41
-
42
- def register_file_info(object, file = nil, line = nil, comments = nil)
43
- super(object, file, line, comments) if file
44
- end
45
-
46
- def register_source(object, source = nil, type = nil)
47
- super(object, source, type) if source
48
- end
49
-
50
- def register_visibility(object, visibility = nil)
51
- super(object, visibility) if visibility
52
- end
53
-
54
- # @group Looking up Symbol and Var Values
55
-
56
- def symbols
57
- globals.cruby_symbols ||= {}
58
- end
59
-
60
- def override_comments
61
- globals.cruby_override_comments ||= []
62
- end
63
-
64
- def namespace_for_variable(var)
65
- return namespaces[var] if namespaces[var]
66
-
67
- # The global variables for Ruby's core error classes does not
68
- # represent their Ruby name. So we need to look up these names.
69
- name = ERROR_CLASS_NAMES[var]
70
- return P(name) if name
71
-
72
- # Otherwise the name is inferred from the C variable name.
73
- var = remove_var_prefix(var)
74
- var.empty? ? nil : P(var)
75
- end
76
-
77
- def ensure_variable_defined!(var, max_retries = 1)
78
- retries = 0
79
- object = nil
80
-
81
- loop do
82
- object = namespace_for_variable(var)
83
- break unless object.is_a?(Proxy)
84
-
85
- raise NamespaceMissingError, object if retries > max_retries
86
- log.debug "Missing namespace variable #{var} in file `#{parser.file}', moving it to the back of the line."
87
- parser.parse_remaining_files
88
- retries += 1
89
- end
90
-
91
- object
92
- end
93
-
94
- def namespaces
95
- globals.cruby_namespaces ||= {}
96
- end
97
-
98
- def processed_files
99
- globals.cruby_processed_files ||= {}
100
- end
101
-
102
- # @group Parsing an Inner Block
103
-
104
- def parse_block(opts = {})
105
- return if !statement.block || statement.block.empty?
106
- push_state(opts) do
107
- parser.process(statement.block)
108
- end
109
- end
110
-
111
- # @group Processing other files
112
-
113
- def process_file(file, object)
114
- file = File.cleanpath(file)
115
- return if processed_files[file]
116
- processed_files[file] = file
117
- begin
118
- log.debug "Processing embedded call to C source #{file}..."
119
- globals.ordered_parser.files.delete(file) if globals.ordered_parser
120
- parser.process(Parser::C::CParser.new(File.read(file), file).parse)
121
- rescue Errno::ENOENT
122
- log.warn "Missing source file `#{file}' when parsing #{object}"
123
- end
124
- end
125
-
126
- # @endgroup
127
-
128
- private
129
-
130
- # Generated by update_error_map.rb (Copy+past results)
131
- ERROR_CLASS_NAMES = {
132
- 'rb_eArgError' => 'ArgumentError',
133
- 'rb_eEncodingError' => 'EncodingError',
134
- 'rb_eException' => 'Exception',
135
- 'rb_eFatal' => 'fatal',
136
- 'rb_eFrozenError' => 'FrozenError',
137
- 'rb_eIndexError' => 'IndexError',
138
- 'rb_eInterrupt' => 'Interrupt',
139
- 'rb_eKeyError' => 'KeyError',
140
- 'rb_eLoadError' => 'LoadError',
141
- 'rb_eNameError' => 'NameError',
142
- 'rb_eNoMatchingPatternError' => 'NoMatchingPatternError',
143
- 'rb_eNoMemError' => 'NoMemoryError',
144
- 'rb_eNoMethodError' => 'NoMethodError',
145
- 'rb_eNotImpError' => 'NotImplementedError',
146
- 'rb_eRangeError' => 'RangeError',
147
- 'rb_eRuntimeError' => 'RuntimeError',
148
- 'rb_eScriptError' => 'ScriptError',
149
- 'rb_eSecurityError' => 'SecurityError',
150
- 'rb_eSignal' => 'SignalException',
151
- 'rb_eStandardError' => 'StandardError',
152
- 'rb_eSyntaxError' => 'SyntaxError',
153
- 'rb_eSystemCallError' => 'SystemCallError',
154
- 'rb_eSystemExit' => 'SystemExit',
155
- 'rb_eTypeError' => 'TypeError',
156
- }
157
-
158
- def remove_var_prefix(var)
159
- var.gsub(/^rb_[mc]|^[a-z_]+/, '')
160
- end
161
- end
162
- end
163
- end
164
- end
1
+ # frozen_string_literal: true
2
+ module YARD
3
+ module Handlers
4
+ module C
5
+ class Base < Handlers::Base
6
+ include YARD::Parser::C
7
+ include HandlerMethods
8
+
9
+ # @return [Boolean] whether the handler handles this statement
10
+ def self.handles?(statement, processor)
11
+ processor.globals.cruby_processed_files ||= {}
12
+ processor.globals.cruby_processed_files[processor.file] = true
13
+
14
+ src = statement.respond_to?(:declaration) ?
15
+ statement.declaration : statement.source
16
+
17
+ handlers.any? do |a_handler|
18
+ statement_class >= statement.class &&
19
+ case a_handler
20
+ when String
21
+ src == a_handler
22
+ when Regexp
23
+ src =~ a_handler
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.statement_class(type = nil)
29
+ if type
30
+ @statement_class = type
31
+ else
32
+ (defined?(@statement_class) && @statement_class) || Statement
33
+ end
34
+ end
35
+
36
+ # @group Registering objects
37
+
38
+ def register_docstring(object, docstring = nil, stmt = nil)
39
+ super(object, docstring, stmt) if docstring
40
+ end
41
+
42
+ def register_file_info(object, file = nil, line = nil, comments = nil)
43
+ super(object, file, line, comments) if file
44
+ end
45
+
46
+ def register_source(object, source = nil, type = nil)
47
+ super(object, source, type) if source
48
+ end
49
+
50
+ def register_visibility(object, visibility = nil)
51
+ super(object, visibility) if visibility
52
+ end
53
+
54
+ # @group Looking up Symbol and Var Values
55
+
56
+ def symbols
57
+ globals.cruby_symbols ||= {}
58
+ end
59
+
60
+ def override_comments
61
+ globals.cruby_override_comments ||= []
62
+ end
63
+
64
+ def namespace_for_variable(var)
65
+ return namespaces[var] if namespaces[var]
66
+
67
+ # The global variables for Ruby's core error classes does not
68
+ # represent their Ruby name. So we need to look up these names.
69
+ name = ERROR_CLASS_NAMES[var]
70
+ return P(name) if name
71
+
72
+ # Otherwise the name is inferred from the C variable name.
73
+ var = remove_var_prefix(var)
74
+ var.empty? ? nil : P(var)
75
+ end
76
+
77
+ def ensure_variable_defined!(var, max_retries = 1)
78
+ retries = 0
79
+ object = nil
80
+
81
+ loop do
82
+ object = namespace_for_variable(var)
83
+ break unless object.is_a?(Proxy)
84
+
85
+ raise NamespaceMissingError, object if retries > max_retries
86
+ log.debug "Missing namespace variable #{var} in file `#{parser.file}', moving it to the back of the line."
87
+ parser.parse_remaining_files
88
+ retries += 1
89
+ end
90
+
91
+ object
92
+ end
93
+
94
+ def namespaces
95
+ globals.cruby_namespaces ||= {}
96
+ end
97
+
98
+ def processed_files
99
+ globals.cruby_processed_files ||= {}
100
+ end
101
+
102
+ # @group Parsing an Inner Block
103
+
104
+ def parse_block(opts = {})
105
+ return if !statement.block || statement.block.empty?
106
+ push_state(opts) do
107
+ parser.process(statement.block)
108
+ end
109
+ end
110
+
111
+ # @group Processing other files
112
+
113
+ def process_file(file, object)
114
+ file = File.cleanpath(file)
115
+ return if processed_files[file]
116
+ processed_files[file] = file
117
+ begin
118
+ log.debug "Processing embedded call to C source #{file}..."
119
+ globals.ordered_parser.files.delete(file) if globals.ordered_parser
120
+ parser.process(Parser::C::CParser.new(File.read(file), file).parse)
121
+ rescue Errno::ENOENT
122
+ log.warn "Missing source file `#{file}' when parsing #{object}"
123
+ end
124
+ end
125
+
126
+ # @endgroup
127
+
128
+ private
129
+
130
+ # Generated by update_error_map.rb (Copy+past results)
131
+ ERROR_CLASS_NAMES = {
132
+ 'rb_eArgError' => 'ArgumentError',
133
+ 'rb_eEncodingError' => 'EncodingError',
134
+ 'rb_eException' => 'Exception',
135
+ 'rb_eFatal' => 'fatal',
136
+ 'rb_eFrozenError' => 'FrozenError',
137
+ 'rb_eIndexError' => 'IndexError',
138
+ 'rb_eInterrupt' => 'Interrupt',
139
+ 'rb_eKeyError' => 'KeyError',
140
+ 'rb_eLoadError' => 'LoadError',
141
+ 'rb_eNameError' => 'NameError',
142
+ 'rb_eNoMatchingPatternError' => 'NoMatchingPatternError',
143
+ 'rb_eNoMemError' => 'NoMemoryError',
144
+ 'rb_eNoMethodError' => 'NoMethodError',
145
+ 'rb_eNotImpError' => 'NotImplementedError',
146
+ 'rb_eRangeError' => 'RangeError',
147
+ 'rb_eRuntimeError' => 'RuntimeError',
148
+ 'rb_eScriptError' => 'ScriptError',
149
+ 'rb_eSecurityError' => 'SecurityError',
150
+ 'rb_eSignal' => 'SignalException',
151
+ 'rb_eStandardError' => 'StandardError',
152
+ 'rb_eSyntaxError' => 'SyntaxError',
153
+ 'rb_eSystemCallError' => 'SystemCallError',
154
+ 'rb_eSystemExit' => 'SystemExit',
155
+ 'rb_eTypeError' => 'TypeError',
156
+ }
157
+
158
+ def remove_var_prefix(var)
159
+ var.gsub(/^rb_[mc]|^[a-z_]+/, '')
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
@@ -67,7 +67,7 @@ class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base
67
67
  end
68
68
 
69
69
  def format_args
70
- args = statement.parameters
70
+ return [] unless args = statement.parameters
71
71
 
72
72
  params = []
73
73
 
@@ -97,7 +97,7 @@ class YARD::Handlers::Ruby::MethodHandler < YARD::Handlers::Ruby::Base
97
97
  params << ['**' + args.double_splat_param.source, nil]
98
98
  end
99
99
 
100
- params << ['&' + args.block_param.source, nil] if args.block_param
100
+ params << ['&' + args.block_param.source, nil] if args.block_param && !args.args_forward
101
101
 
102
102
  params
103
103
  end
@@ -2,6 +2,7 @@
2
2
  # Handles the 'include' statement to mixin a module in the instance scope
3
3
  class YARD::Handlers::Ruby::MixinHandler < YARD::Handlers::Ruby::Base
4
4
  handles method_call(:include)
5
+ handles method_call(:prepend)
5
6
  namespace_only
6
7
 
7
8
  process do
@@ -34,11 +35,15 @@ class YARD::Handlers::Ruby::MixinHandler < YARD::Handlers::Ruby::Base
34
35
 
35
36
  rec = recipient(mixin)
36
37
  return if rec.nil? || rec.mixins(scope).include?(obj)
37
- rec.mixins(scope).unshift(obj)
38
+
39
+ shift = statement.method_name(true) == :include ? :unshift : :push
40
+ rec.mixins(scope).send(shift, obj)
38
41
  end
39
42
 
40
43
  def recipient(mixin)
41
- if statement[0].type == :var_ref && statement[0][0] != s(:kw, "self")
44
+ if statement[0].type == :const_path_ref
45
+ Proxy.new(namespace, statement[0].source)
46
+ elsif statement[0].type == :var_ref && statement[0][0] != s(:kw, "self")
42
47
  statement[0][0].type == :const ?
43
48
  Proxy.new(namespace, statement.namespace.source) :
44
49
  nil
@@ -2,6 +2,8 @@
2
2
  # Handles module_function calls to turn methods into public class methods.
3
3
  # Also creates a private instance copy of the method.
4
4
  class YARD::Handlers::Ruby::ModuleFunctionHandler < YARD::Handlers::Ruby::Base
5
+ include YARD::Handlers::Ruby::DecoratorHandlerMethods
6
+
5
7
  handles method_call(:module_function)
6
8
  namespace_only
7
9
 
@@ -13,15 +15,25 @@ class YARD::Handlers::Ruby::ModuleFunctionHandler < YARD::Handlers::Ruby::Base
13
15
  when :fcall, :command
14
16
  statement[1].traverse do |node|
15
17
  case node.type
18
+ when :def
19
+ process_decorator do |instance_method|
20
+ make_module_function(instance_method, namespace)
21
+ end
22
+ break
16
23
  when :symbol; name = node.first.source
17
24
  when :string_content; name = node.source
18
25
  else next
19
26
  end
27
+
20
28
  instance_method = MethodObject.new(namespace, name)
21
- class_method = MethodObject.new(namespace, name, :module)
22
- instance_method.copy_to(class_method)
23
- class_method.visibility = :public
29
+ make_module_function(instance_method, namespace)
24
30
  end
25
31
  end
26
32
  end
33
+
34
+ def make_module_function(instance_method, namespace)
35
+ class_method = MethodObject.new(namespace, instance_method.name, :module)
36
+ instance_method.copy_to(class_method)
37
+ class_method.visibility = :public
38
+ end
27
39
  end
@@ -426,6 +426,13 @@ module YARD
426
426
  def block_param
427
427
  self[-1] ? self[-1][0] : nil
428
428
  end
429
+
430
+ def args_forward
431
+ # shape is (required, optional, rest, more, keyword, keyword_rest, block)
432
+ # Ruby 3.1 moves :args_forward from rest to keyword_rest
433
+ args_index = YARD.ruby31? ? -2 : 2
434
+ self[args_index].type == :args_forward if self[args_index]
435
+ end
429
436
  end
430
437
 
431
438
  class MethodCallNode < AstNode
@@ -480,7 +487,7 @@ module YARD
480
487
  end
481
488
 
482
489
  def parameters(include_block_param = true)
483
- params = self[1 + index_adjust]
490
+ return unless params = self[1 + index_adjust]
484
491
  params = params[0] if params.type == :paren
485
492
  include_block_param ? params : params[0...-1]
486
493
  end
@@ -488,7 +495,7 @@ module YARD
488
495
  def signature
489
496
  params_src = ''
490
497
  params = self[1 + index_adjust]
491
- if params.first
498
+ if params and params.first
492
499
  params_src = params.type == :paren ? '' : ' '
493
500
  params_src += params.source.gsub(/\s+(\s|\))/m, '\1')
494
501
  end
@@ -370,7 +370,7 @@ module YARD
370
370
 
371
371
  def on_aref(*args)
372
372
  @map[:lbracket].pop
373
- ll, lc = *@map[:aref].pop
373
+ ll, lc = *@map[:aref].shift
374
374
  sr = args.first.source_range.first..lc
375
375
  lr = args.first.line_range.first..ll
376
376
  AstNode.new(:aref, args, :char => sr, :line => lr)
@@ -64,7 +64,7 @@ module YARD
64
64
  class SourceParser
65
65
  SHEBANG_LINE = /\A\s*#!\S+/
66
66
  ENCODING_LINE = %r{\A(?:\s*#*!.*\r?\n)?\s*(?:#+|/\*+|//+).*coding\s*[:=]{1,2}\s*([a-z\d_\-]+)}i
67
- FROZEN_STRING_LINE = /frozen(-|_)string(-|_)literal: true/i
67
+ FROZEN_STRING_LINE = /frozen(-|_)string(-|_)literal:\s+(true|false)/i
68
68
 
69
69
  # The default glob of files to be parsed.
70
70
  # @since 0.9.0
@@ -183,7 +183,7 @@ module YARD
183
183
  self.body = "Not found: #{request.path}"
184
184
  headers['Content-Type'] = 'text/plain'
185
185
  headers['X-Cascade'] = 'pass'
186
- headers.delete('Cache-Control')
186
+ headers['Cache-Control'] = 'nocache'
187
187
  end
188
188
 
189
189
  # Sets the headers and status code for a redirection to a given URL
@@ -201,7 +201,7 @@ module YARD
201
201
  # requests served with "?1234567890" style timestamp query strings.
202
202
  def add_cache_control
203
203
  return if request.query_string.to_i == 0
204
- headers['Cache-Control'] = 'private, max-age=300'
204
+ headers['Cache-Control'] ||= 'public, max-age=300'
205
205
  end
206
206
  end
207
207
  end
@@ -31,7 +31,7 @@ module YARD
31
31
  # @abstract
32
32
  class LibraryCommand < Base
33
33
  begin
34
- Process.fork { exit 0 }
34
+ Process.fork { }
35
35
  CAN_FORK = true
36
36
  rescue Exception # rubocop:disable Lint/RescueException
37
37
  CAN_FORK = false
@@ -74,6 +74,13 @@ module YARD
74
74
  def after_parse; end
75
75
 
76
76
  protected :parser
77
+
78
+ protected
79
+
80
+ def inside_directive?
81
+ return true if parser.state.inside_directive
82
+ parser.directives.any? { |d| d.is_a?(MethodDirective) && d.tag.text.empty? }
83
+ end
77
84
  end
78
85
 
79
86
  # Ends a group listing definition. Group definition automatically end
@@ -574,6 +581,8 @@ module YARD
574
581
  if %w(class instance module).include?(tag.text)
575
582
  if object.is_a?(CodeObjects::MethodObject)
576
583
  object.scope = tag.text.to_sym
584
+ elsif handler && !inside_directive?
585
+ handler.scope = tag.text.to_sym
577
586
  else
578
587
  parser.state.scope = tag.text.to_sym
579
588
  end
@@ -604,7 +613,7 @@ module YARD
604
613
  if %w(public protected private).include?(tag.text)
605
614
  if object.is_a?(CodeObjects::Base)
606
615
  object.visibility = tag.text.to_sym
607
- elsif handler && !parser.state.inside_directive
616
+ elsif handler && !inside_directive?
608
617
  handler.visibility = tag.text.to_sym
609
618
  else
610
619
  parser.state.visibility = tag.text.to_sym
@@ -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])
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
@@ -20,9 +20,7 @@ module YARD
20
20
 
21
21
  def [](*args)
22
22
  if args.first.is_a?(Range) || args.size > 1
23
- obj = super(*args)
24
- obj.name = name
25
- return obj
23
+ return self.class.new(name, *super(*args))
26
24
  elsif args.first.is_a?(Integer)
27
25
  return super(*args)
28
26
  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
data/lib/yard/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module YARD
5
- VERSION = '0.9.25'
5
+ VERSION = '0.9.28'
6
6
  end
data/lib/yard.rb CHANGED
@@ -48,6 +48,12 @@ module YARD
48
48
 
49
49
  # @return [Boolean] whether YARD is being run in Ruby 2.0
50
50
  def self.ruby2?; @ruby2 ||= (RUBY_VERSION >= '2.0.0') end
51
+
52
+ # @return [Boolean] whether YARD is being run in Ruby 3.0
53
+ def self.ruby3?; @ruby3 ||= (RUBY_VERSION >= '3.0.0') end
54
+
55
+ # @return [Boolean] whether YARD is being run in Ruby 3.1
56
+ def self.ruby31?; @ruby31 ||= (RUBY_VERSION >= '3.1.0') end
51
57
  end
52
58
 
53
59
  # Keep track of Ruby version for compatibility code