yard 0.9.44 → 0.9.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87aef8f8a0b6c25d1a2c05214992313aa6278659214af6650d07876346b771ec
4
- data.tar.gz: 149cee78996a555a97d7223252df845be60ecaf9bf92d7c9bedeeb8fe14952bf
3
+ metadata.gz: 8e6dbc08e061218c5f0736d4b07923de3407ef37427f48307c01917e84c904e2
4
+ data.tar.gz: 7fc6e859d2f4a385eb7a956796782b3d6f45b0b480aadb566ed31aa862c5191b
5
5
  SHA512:
6
- metadata.gz: e7bd349e0d31fb2b79dd0c18a057ff9323206c4d6be3535f902f9fa45ee30a8649bd3036861fdf2ab90e017bfaf7622eb744461a2728a88b68792bc8acbd3fa9
7
- data.tar.gz: 2f4e486d27daf722a02c2efc2e7af568c12a76ebd30b23871a46c25c54e03f9e6f51397953dac330dba6b0581b7088882e581b04f43fe9ef64e3a0a93862df15
6
+ metadata.gz: 0ef54ea2c613b5b67200f0770ca5accb0c592511087efb5b66cb8c8847e89277247030befc947838eae3ef1f3f911acc66dfbaa0691e9119168e0d76d546ca76
7
+ data.tar.gz: 1d459a1eed141b9183ed4323e16cf0802b42c3043bd7fecc8aa6cc234e4c73a4b4fe90a39ad9bf063f6bc8b42ed911ab16ae56437ac7e4deaa595ef9829485aa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # main
2
2
 
3
+ # [0.9.45] - July 14th, 2026
4
+
5
+ [0.9.45]: https://github.com/lsegal/yard/compare/v0.9.44...v0.9.45
6
+
7
+ - Use `@param` types to document generated `Struct.new` and `Data.define` members (#1684)
8
+ - Add compatibility with RDoc 8
9
+ - Fix TypesExplainer parsing of types following Hash collections (#1688)
10
+ - Fix HTML generation for RBS constants without source values (#1686)
11
+ - Fix method redefinition warnings when loading YARD with Ruby warnings enabled (#1687)
12
+ - Improve sanitization of `yard server` request paths
13
+
3
14
  # [0.9.44] - May 25th, 2026
4
15
 
5
16
  [0.9.44]: https://github.com/lsegal/yard/compare/v0.9.43...v0.9.44
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # Helper methods to parse @attr_* tags on a class.
2
+ # Helper methods to document generated Struct and Data members.
3
3
  #
4
4
  # @deprecated The use of +@attr+ tags are deprecated since 0.8.0 in favour of
5
5
  # the +@!attribute+ directive. This module should not be relied on.
@@ -19,6 +19,26 @@ module YARD::Handlers::Ruby::StructHandlerMethods
19
19
  (klass.tags(specific_tag) + klass.tags(:attr)).find {|tag| tag.name == member }
20
20
  end
21
21
 
22
+ # Extracts the user's defined @param tag for a given generated member.
23
+ #
24
+ # @param [ClassObject] klass the class whose tags we're searching
25
+ # @param [String] member the name of the struct or data member we need
26
+ # @return [Tags::Tag, nil] the matching tag, or nil if not found
27
+ def parameter_tag_for_member(klass, member)
28
+ klass.tags(:param).find {|tag| tag.name == member }
29
+ end
30
+
31
+ # Returns the tag that supplies a generated member's type. Existing @attr*
32
+ # tags take precedence over the more concise @param form.
33
+ #
34
+ # @param [ClassObject] klass the class whose tags we're searching
35
+ # @param [String] member the name of the struct or data member we need
36
+ # @param [Symbol] type reader method, or writer method?
37
+ # @return [Tags::Tag, nil] the tag supplying the type, or nil if not found
38
+ def type_tag_for_member(klass, member, type = :read)
39
+ member_tag_for_member(klass, member, type) || parameter_tag_for_member(klass, member)
40
+ end
41
+
22
42
  # Retrieves all members defined in @attr* tags
23
43
  #
24
44
  # @param [ClassObject] klass the class with the attributes
@@ -61,7 +81,7 @@ module YARD::Handlers::Ruby::StructHandlerMethods
61
81
  # @return [String] a docstring to be attached to the getter method for this member
62
82
  def add_reader_tags(klass, new_method, member)
63
83
  member_tag = member_tag_for_member(klass, member, :read)
64
- return_type = return_type_from_tag(member_tag)
84
+ return_type = return_type_from_tag(type_tag_for_member(klass, member, :read))
65
85
  getter_doc_text = member_tag ? member_tag.text : "Returns the value of attribute #{member}"
66
86
  new_method.docstring.replace(getter_doc_text)
67
87
  new_method.add_tag YARD::Tags::Tag.new(:return, "the current value of #{member}", return_type)
@@ -76,7 +96,7 @@ module YARD::Handlers::Ruby::StructHandlerMethods
76
96
  # @return [String] a docstring to be attached to the setter method for this member
77
97
  def add_writer_tags(klass, new_method, member)
78
98
  member_tag = member_tag_for_member(klass, member, :write)
79
- return_type = return_type_from_tag(member_tag)
99
+ return_type = return_type_from_tag(type_tag_for_member(klass, member, :write))
80
100
  setter_doc_text = member_tag ? member_tag.text : "Sets the attribute #{member}"
81
101
  new_method.docstring.replace(setter_doc_text)
82
102
  new_method.add_tag YARD::Tags::Tag.new(:param, "the value to set the attribute #{member} to.", return_type, "value")
@@ -104,7 +124,7 @@ module YARD::Handlers::Ruby::StructHandlerMethods
104
124
  def create_writer(klass, member)
105
125
  # We want to convert these members into attributes just like
106
126
  # as if they were declared using attr_accessor.
107
- new_meth = register MethodObject.new(klass, "#{member}=", :instance) do |o|
127
+ new_meth = register_struct_member_method MethodObject.new(klass, "#{member}=", :instance) do |o|
108
128
  o.parameters = [['value', nil]]
109
129
  o.signature ||= "def #{member}=(value)"
110
130
  o.source ||= "#{o.signature}\n @#{member} = value\nend"
@@ -119,7 +139,7 @@ module YARD::Handlers::Ruby::StructHandlerMethods
119
139
  # @param [ClassObject] klass the class to attach the method to
120
140
  # @param [String] member the name of the member we're generating a method for
121
141
  def create_reader(klass, member)
122
- new_meth = register MethodObject.new(klass, member, :instance) do |o|
142
+ new_meth = register_struct_member_method MethodObject.new(klass, member, :instance) do |o|
123
143
  o.signature ||= "def #{member}"
124
144
  o.source ||= "#{o.signature}\n @#{member}\nend"
125
145
  end
@@ -140,4 +160,20 @@ module YARD::Handlers::Ruby::StructHandlerMethods
140
160
  create_reader klass, member if create_member_method?(klass, member, :read)
141
161
  end
142
162
  end
163
+
164
+ # Registers an auto-generated member method without reapplying the class's
165
+ # docstring to it. The generated reader or writer receives its own docstring
166
+ # and tags immediately after registration.
167
+ def register_struct_member_method(method, &block)
168
+ previous = @registering_struct_member_method
169
+ @registering_struct_member_method = true
170
+ register(method, &block)
171
+ ensure
172
+ @registering_struct_member_method = previous
173
+ end
174
+
175
+ def register_docstring(object, docstring = statement.comments, stmt = statement)
176
+ docstring = nil if @registering_struct_member_method
177
+ super(object, docstring, stmt)
178
+ end
143
179
  end
@@ -379,6 +379,7 @@ module YARD
379
379
  # entries from corrupting source ranges of later hash literals and brace blocks.
380
380
  # Bare hash patterns (key: val without braces) fire no brace scanner events, so
381
381
  # we only clean up when @map[:rbrace] confirms a closing brace was scanned.
382
+ begin; undef on_hshptn; rescue NameError; end
382
383
  def on_hshptn(*args)
383
384
  if (@map[:rbrace] ||= []).any?
384
385
  (@map[:lbrace] ||= []).pop
@@ -443,6 +444,7 @@ module YARD
443
444
  # on_rbracket scanner events. The corresponding parser events are on_aryptn/on_fndptn
444
445
  # (not on_aref), so we must clean up the bracket maps to prevent stale entries from
445
446
  # corrupting source ranges of later array indexing expressions.
447
+ begin; undef on_aryptn; rescue NameError; end
446
448
  def on_aryptn(*args)
447
449
  (@map[:lbracket] ||= []).pop
448
450
  (@map[:aref] ||= []).shift
@@ -451,6 +453,7 @@ module YARD
451
453
  AstNode.new(:aryptn, args)
452
454
  end
453
455
 
456
+ begin; undef on_fndptn; rescue NameError; end
454
457
  def on_fndptn(*args)
455
458
  (@map[:lbracket] ||= []).pop
456
459
  (@map[:aref] ||= []).shift
@@ -88,7 +88,7 @@ module YARD
88
88
  # of status, headers, and body wrapped in an array.
89
89
  def call(request)
90
90
  self.request = request
91
- self.path ||= File.cleanpath(request.path_info[1..-1])
91
+ self.path ||= Server.clean_path(request.path_info[1..-1])
92
92
  self.headers = {'Content-Type' => 'text/html'}
93
93
  self.body = ''
94
94
  self.status = 200
@@ -179,7 +179,7 @@ module YARD
179
179
  # @param (see #route_docs)
180
180
  # @return [Hash] finalized options
181
181
  def final_options(library, paths)
182
- path = File.cleanpath(paths.join('/')).gsub(%r{^(\.\./)+}, '')
182
+ path = Server.clean_path(paths.join('/'))
183
183
  adapter.options.merge(:library => library, :path => path)
184
184
  end
185
185
  end
data/lib/yard/server.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
  module YARD
3
3
  module Server
4
+ # Normalizes an HTTP request path into a relative command path.
5
+ # @api private
6
+ # @param [String] path the request path to normalize
7
+ # @return [String] a relative path using forward slashes
8
+ def self.clean_path(path)
9
+ path = File.cleanpath(path.tr('\\', '/'))
10
+ path.sub(/\A[A-Za-z]:(?!:)/, '').sub(%r{\A/+}, '')
11
+ end
12
+
4
13
  # Registers a static path to be used in static asset lookup.
5
14
  # @param [String] path the pathname to register
6
15
  # @return [void]
@@ -176,17 +176,25 @@ module YARD
176
176
 
177
177
  # @return [Array(Boolean, Array<Type>)] - finished, types
178
178
  def parse(until_tokens: [:parse_end])
179
+ parse_until(until_tokens).first
180
+ end
181
+
182
+ private
183
+
184
+ def parse_until(until_tokens)
179
185
  current_parsed_types = []
180
186
  type = nil
181
187
  name = nil
182
188
  finished = false
183
- parse_with_handlers do |token_type, token|
189
+ end_token = nil
190
+ types = parse_with_handlers do |token_type, token|
184
191
  case token_type
185
192
  when *until_tokens
186
193
  raise SyntaxError, "expecting name, got '#{token}'" if name.nil?
187
194
  type = create_type(name) unless type
188
195
  current_parsed_types << type
189
196
  finished = true
197
+ end_token = token_type
190
198
  when :type_name
191
199
  raise SyntaxError, "expecting END, got name '#{token}'" if name
192
200
  name = token
@@ -199,7 +207,8 @@ module YARD
199
207
  when :fixed_collection_start, :collection_start
200
208
  name ||= "Array"
201
209
  klass = token_type == :collection_start ? CollectionType : FixedCollectionType
202
- type = klass.new(name, parse(until_tokens: [:fixed_collection_end, :collection_end, :parse_end]))
210
+ nested_types, = parse_until([:fixed_collection_end, :collection_end, :parse_end])
211
+ type = klass.new(name, nested_types)
203
212
  when :hash_collection_start
204
213
  name ||= "Hash"
205
214
  type = parse_hash_collection(name)
@@ -207,10 +216,9 @@ module YARD
207
216
 
208
217
  [finished, current_parsed_types]
209
218
  end
219
+ [types, end_token]
210
220
  end
211
221
 
212
- private
213
-
214
222
  # @return [Array<Type>]
215
223
  def parse_with_handlers
216
224
  loop do
@@ -245,9 +253,10 @@ module YARD
245
253
  when :hash_collection_value
246
254
  # => - current keys map to the next value(s)
247
255
  raise SyntaxError, "no keys before =>" if current_keys.empty?
248
- values = parse(until_tokens: [:hash_collection_value_end, :parse_end])
256
+ values, end_token = parse_until([:hash_collection_value_end, :hash_collection_end, :parse_end])
249
257
  key_value_pairs << [current_keys, values]
250
258
  current_keys = []
259
+ finished = end_token != :hash_collection_value_end
251
260
  when :hash_collection_end, :parse_end
252
261
  # End of hash
253
262
  finished = true
@@ -11,7 +11,11 @@ module YARD
11
11
  require 'rdoc/markup/to_html'
12
12
  class RDocMarkup; MARKUP = RDoc::Markup end
13
13
  class RDocMarkupToHtml < RDoc::Markup::ToHtml
14
- if defined?(RDoc::VERSION) && RDoc::VERSION >= '4.0.0' &&
14
+ if defined?(RDoc::VERSION) && RDoc::VERSION.to_i >= 8
15
+ def initialize
16
+ super(pipe: true)
17
+ end
18
+ elsif defined?(RDoc::VERSION) && RDoc::VERSION >= '4.0.0' &&
15
19
  defined?(RDoc::Options)
16
20
  def initialize
17
21
  options = RDoc::Options.new
@@ -66,6 +66,8 @@ module YARD
66
66
 
67
67
  # @return [String] formats source code of a constant value
68
68
  def format_constant(value)
69
+ return "" unless value
70
+
69
71
  # last can return nil, so default to empty string
70
72
  sp = value.split("\n").last || ""
71
73
  sp = sp[/^(\s+)/, 1]
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.44'
5
+ VERSION = '0.9.45'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.44
4
+ version: 0.9.45
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loren Segal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-25 00:00:00.000000000 Z
11
+ date: 2026-07-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  YARD is a documentation generation tool for the Ruby programming language.
@@ -409,6 +409,7 @@ licenses:
409
409
  metadata:
410
410
  yard.run: yri
411
411
  changelog_uri: https://rubydoc.info/gems/yard/file/CHANGELOG.md
412
+ source_code_uri: https://github.com/lsegal/yard
412
413
  post_install_message:
413
414
  rdoc_options: []
414
415
  require_paths: