yard 0.9.39 → 0.9.40
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 +4 -4
- data/CHANGELOG.md +16 -1
- data/README.md +18 -21
- data/docs/GettingStarted.md +41 -15
- data/docs/Tags.md +5 -5
- data/docs/WhatsNew.md +59 -7
- data/docs/templates/default/yard_tags/html/setup.rb +1 -1
- data/lib/yard/autoload.rb +17 -0
- data/lib/yard/cli/diff.rb +7 -2
- data/lib/yard/code_objects/proxy.rb +1 -1
- data/lib/yard/handlers/processor.rb +1 -0
- data/lib/yard/handlers/rbs/attribute_handler.rb +43 -0
- data/lib/yard/handlers/rbs/base.rb +38 -0
- data/lib/yard/handlers/rbs/constant_handler.rb +18 -0
- data/lib/yard/handlers/rbs/method_handler.rb +327 -0
- data/lib/yard/handlers/rbs/mixin_handler.rb +20 -0
- data/lib/yard/handlers/rbs/namespace_handler.rb +26 -0
- data/lib/yard/handlers/ruby/attribute_handler.rb +7 -4
- data/lib/yard/handlers/ruby/constant_handler.rb +1 -0
- data/lib/yard/i18n/locale.rb +1 -1
- data/lib/yard/i18n/pot_generator.rb +1 -1
- data/lib/yard/parser/rbs/rbs_parser.rb +325 -0
- data/lib/yard/parser/rbs/statement.rb +75 -0
- data/lib/yard/parser/ruby/ruby_parser.rb +51 -1
- data/lib/yard/parser/source_parser.rb +3 -2
- data/lib/yard/registry_resolver.rb +7 -0
- data/lib/yard/server/library_version.rb +1 -1
- data/lib/yard/server/templates/default/fulldoc/html/js/autocomplete.js +208 -12
- data/lib/yard/server/templates/default/layout/html/breadcrumb.erb +1 -17
- data/lib/yard/server/templates/default/method_details/html/permalink.erb +4 -2
- data/lib/yard/server/templates/doc_server/library_list/html/headers.erb +3 -3
- data/lib/yard/server/templates/doc_server/library_list/html/library_list.erb +2 -3
- data/lib/yard/server/templates/doc_server/processing/html/processing.erb +22 -16
- data/lib/yard/tags/directives.rb +7 -0
- data/lib/yard/tags/library.rb +3 -3
- data/lib/yard/tags/types_explainer.rb +2 -1
- data/lib/yard/templates/helpers/base_helper.rb +1 -1
- data/lib/yard/templates/helpers/html_helper.rb +15 -4
- data/lib/yard/templates/helpers/html_syntax_highlight_helper.rb +6 -1
- data/lib/yard/templates/helpers/markup/hybrid_markdown.rb +2125 -0
- data/lib/yard/templates/helpers/markup_helper.rb +4 -2
- data/lib/yard/version.rb +1 -1
- data/po/ja.po +82 -82
- data/templates/default/fulldoc/html/full_list.erb +4 -4
- data/templates/default/fulldoc/html/js/app.js +503 -319
- data/templates/default/fulldoc/html/js/full_list.js +310 -213
- data/templates/default/layout/html/headers.erb +1 -1
- data/templates/default/method/html/header.erb +3 -3
- data/templates/default/module/html/defines.erb +3 -3
- data/templates/default/module/html/inherited_methods.erb +1 -0
- data/templates/default/module/html/method_summary.erb +8 -0
- data/templates/default/module/setup.rb +20 -0
- data/templates/default/onefile/html/layout.erb +3 -4
- data/templates/guide/fulldoc/html/js/app.js +57 -26
- data/templates/guide/layout/html/layout.erb +9 -11
- metadata +13 -4
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Handles RBS method definitions (def name: signature).
|
|
3
|
+
#
|
|
4
|
+
# Creates a {YARD::CodeObjects::MethodObject} for each declaration
|
|
5
|
+
# and infers @param, @return, @yield, and @yieldparam tags from the
|
|
6
|
+
# RBS type signature when those tags are absent from the docstring.
|
|
7
|
+
class YARD::Handlers::RBS::MethodHandler < YARD::Handlers::RBS::Base
|
|
8
|
+
handles :method_def
|
|
9
|
+
|
|
10
|
+
process do
|
|
11
|
+
meth_scope = statement.visibility == :class ? :class : :instance
|
|
12
|
+
obj = register MethodObject.new(namespace, statement.name, meth_scope)
|
|
13
|
+
apply_signature_tags(obj, statement.signatures)
|
|
14
|
+
|
|
15
|
+
# For initialize, ensure the return type is the class, not void.
|
|
16
|
+
if statement.name == 'initialize'
|
|
17
|
+
ret_tags = obj.tags(:return)
|
|
18
|
+
if ret_tags.none? || (ret_tags.length == 1 && ret_tags.first.types == ['void'])
|
|
19
|
+
obj.docstring.delete_tags(:return)
|
|
20
|
+
obj.add_tag YARD::Tags::Tag.new(:return, "a new instance of #{namespace.name}",
|
|
21
|
+
[namespace.name.to_s])
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Convert an RBS type string to an array of YARD type strings.
|
|
27
|
+
#
|
|
28
|
+
# @param rbs [String] e.g. "String | Integer", "Array[String]", "bool"
|
|
29
|
+
# @return [Array<String>]
|
|
30
|
+
def self.rbs_type_to_yard_types(rbs)
|
|
31
|
+
rbs = rbs.strip
|
|
32
|
+
return ['void'] if rbs == 'void'
|
|
33
|
+
return ['Boolean'] if rbs == 'bool'
|
|
34
|
+
return ['Object'] if rbs == 'untyped'
|
|
35
|
+
return ['nil'] if rbs == 'nil'
|
|
36
|
+
|
|
37
|
+
# Strip outer parentheses: `(String | Integer)` → recurse on inner.
|
|
38
|
+
if rbs.start_with?('(') && rbs.end_with?(')') && bracket_depth(rbs[1..-2]) == 0
|
|
39
|
+
return rbs_type_to_yard_types(rbs[1..-2])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# `Type?` is shorthand for `Type | nil` when the ? is outermost.
|
|
43
|
+
if rbs =~ /\A(.+)\?\z/ && bracket_depth($1) == 0
|
|
44
|
+
return rbs_type_to_yard_types($1) + ['nil']
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
split_on_pipe(rbs).map { |t| t.strip }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
# Apply tags from all overload signatures to the method object.
|
|
53
|
+
def apply_signature_tags(obj, sigs)
|
|
54
|
+
return if sigs.nil? || sigs.empty?
|
|
55
|
+
|
|
56
|
+
if sigs.length == 1
|
|
57
|
+
# Single signature: add @param and @return directly.
|
|
58
|
+
add_param_return_tags(obj, sigs.first)
|
|
59
|
+
else
|
|
60
|
+
# Multiple signatures: add @overload tags.
|
|
61
|
+
sigs.each { |sig| add_overload_tag(obj, statement.name, sig) }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Add @param / @return / @yield / @yieldparam from a single overload sig.
|
|
66
|
+
def add_param_return_tags(obj, sig)
|
|
67
|
+
parsed = parse_function_type(sig)
|
|
68
|
+
|
|
69
|
+
parsed[:params].each do |p|
|
|
70
|
+
next if p[:block] # block param handled via @yield below
|
|
71
|
+
tag_name = p[:name] ? p[:name].to_s : nil
|
|
72
|
+
next if tag_name && obj.tags(:param).any? { |t| t.name == tag_name }
|
|
73
|
+
obj.add_tag YARD::Tags::Tag.new(:param, '', p[:types], tag_name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if (blk = parsed[:block_param])
|
|
77
|
+
add_yield_tags(obj, blk)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
unless obj.has_tag?(:return)
|
|
81
|
+
obj.add_tag YARD::Tags::Tag.new(:return, '', parsed[:return_types])
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Add an @overload tag for one signature overload.
|
|
86
|
+
def add_overload_tag(obj, meth_name, sig)
|
|
87
|
+
parsed = parse_function_type(sig)
|
|
88
|
+
param_sigs = parsed[:params].reject { |p| p[:block] }.map.with_index do |p, idx|
|
|
89
|
+
p[:name] || "arg#{idx}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Build the overload tag text: signature line + nested @param/@return lines.
|
|
93
|
+
lines = ["#{meth_name}(#{param_sigs.join(', ')})"]
|
|
94
|
+
parsed[:params].reject { |p| p[:block] }.each_with_index do |p, idx|
|
|
95
|
+
pname = p[:name] || "arg#{idx}"
|
|
96
|
+
lines << " @param #{pname} [#{p[:types].join(', ')}]"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if (blk = parsed[:block_param])
|
|
100
|
+
add_yield_tags(obj, blk)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
lines << " @return [#{parsed[:return_types].join(', ')}]"
|
|
104
|
+
obj.add_tag YARD::Tags::OverloadTag.new(:overload, lines.join("\n"))
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Add @yield and @yieldparam tags from a parsed block type.
|
|
108
|
+
def add_yield_tags(obj, blk)
|
|
109
|
+
return if obj.has_tag?(:yield) && obj.has_tag?(:yieldparam)
|
|
110
|
+
obj.add_tag YARD::Tags::Tag.new(:yield, '') unless obj.has_tag?(:yield)
|
|
111
|
+
blk[:params].each_with_index do |p, idx|
|
|
112
|
+
pname = p[:name] || "arg#{idx}"
|
|
113
|
+
next if obj.tags(:yieldparam).any? { |t| t.name == pname }
|
|
114
|
+
obj.add_tag YARD::Tags::Tag.new(:yieldparam, '', p[:types], pname)
|
|
115
|
+
end
|
|
116
|
+
unless obj.has_tag?(:yieldreturn)
|
|
117
|
+
obj.add_tag YARD::Tags::Tag.new(:yieldreturn, '', self.class.rbs_type_to_yard_types(blk[:return_type] || 'void'))
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Parse a single RBS function type string (one overload) into its components.
|
|
122
|
+
#
|
|
123
|
+
# @param sig [String] e.g. "(String name, Integer age) -> String"
|
|
124
|
+
# @return [Hash] { :params => [...], :block_param => Hash|nil, :return_types => [...] }
|
|
125
|
+
def parse_function_type(sig)
|
|
126
|
+
sig = sig.strip
|
|
127
|
+
return { :params => [], :block_param => nil, :return_types => ['void'] } if sig.empty?
|
|
128
|
+
|
|
129
|
+
remaining = sig
|
|
130
|
+
params = []
|
|
131
|
+
block_param = nil
|
|
132
|
+
|
|
133
|
+
# 1. Extract positional/keyword params: leading `(...)`.
|
|
134
|
+
if remaining.start_with?('(')
|
|
135
|
+
close = find_matching(remaining, 0, '(', ')')
|
|
136
|
+
raise YARD::Parser::UndocumentableError, "malformed signature (unclosed '('): #{sig}" if close.nil?
|
|
137
|
+
params_str = remaining[1...close]
|
|
138
|
+
remaining = remaining[close + 1..-1].lstrip
|
|
139
|
+
params = parse_params_list(params_str)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# 2. Extract block type: `{ ... }`.
|
|
143
|
+
if remaining.start_with?('{')
|
|
144
|
+
close = find_matching(remaining, 0, '{', '}')
|
|
145
|
+
raise YARD::Parser::UndocumentableError, "malformed signature (unclosed '{'): #{sig}" if close.nil?
|
|
146
|
+
block_inner = remaining[1...close]
|
|
147
|
+
remaining = remaining[close + 1..-1].lstrip
|
|
148
|
+
block_param = parse_block_type(block_inner)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# 3. Return type after `->`.
|
|
152
|
+
return_types = if remaining =~ /\A->\s*(.*)\z/
|
|
153
|
+
self.class.rbs_type_to_yard_types($1.strip)
|
|
154
|
+
else
|
|
155
|
+
['void']
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
{ :params => params, :block_param => block_param, :return_types => return_types }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Parse a comma-separated parameter list (content inside outer parens).
|
|
162
|
+
def parse_params_list(str)
|
|
163
|
+
str = str.strip
|
|
164
|
+
return [] if str.empty?
|
|
165
|
+
|
|
166
|
+
split_by_comma(str).map { |p| parse_single_param(p.strip) }.compact
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Parse one parameter from an RBS param list.
|
|
170
|
+
def parse_single_param(param)
|
|
171
|
+
return nil if param.empty?
|
|
172
|
+
|
|
173
|
+
optional = false
|
|
174
|
+
rest = false
|
|
175
|
+
|
|
176
|
+
# Optional marker `?`.
|
|
177
|
+
if param.start_with?('?') && !param.start_with?('?(')
|
|
178
|
+
optional = true
|
|
179
|
+
param = param[1..-1].lstrip
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Double-splat `**` (rest keyword).
|
|
183
|
+
if param.start_with?('**')
|
|
184
|
+
rest = true
|
|
185
|
+
param = param[2..-1].lstrip
|
|
186
|
+
# Single-splat `*` (rest positional).
|
|
187
|
+
elsif param.start_with?('*') && !param.start_with?('*)')
|
|
188
|
+
rest = true
|
|
189
|
+
param = param[1..-1].lstrip
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Block-type proc: `^(...)`.
|
|
193
|
+
if param.start_with?('^')
|
|
194
|
+
return { :name => nil, :types => [param], :optional => false, :rest => false, :block => true }
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Keyword parameter: `name: Type` or `?name: Type`.
|
|
198
|
+
if param =~ /\A([a-z_]\w*)\s*:\s*(.*)\z/ && !rest
|
|
199
|
+
kw_name = $1
|
|
200
|
+
kw_type = $2.strip
|
|
201
|
+
return { :name => "#{kw_name}:", :types => self.class.rbs_type_to_yard_types(kw_type),
|
|
202
|
+
:optional => optional, :rest => false }
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Positional: `Type [param_name]`.
|
|
206
|
+
type_str, param_name = extract_type_and_name(param)
|
|
207
|
+
{ :name => param_name, :types => self.class.rbs_type_to_yard_types(type_str),
|
|
208
|
+
:optional => optional, :rest => rest }
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Split a type+name string like "Array[String] names" into ["Array[String]", "names"].
|
|
212
|
+
# The name is the trailing lowercase identifier (if any).
|
|
213
|
+
def extract_type_and_name(str)
|
|
214
|
+
str = str.strip
|
|
215
|
+
if str =~ /\A(.*\S)\s+([a-z_]\w*)\z/m
|
|
216
|
+
type_part = $1.strip
|
|
217
|
+
name_part = $2
|
|
218
|
+
# Exclude RBS type keywords from being mistaken for names.
|
|
219
|
+
unless %w[void untyped nil bool top bottom self instance class].include?(name_part)
|
|
220
|
+
return [type_part, name_part] unless type_part.empty?
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
[str, nil]
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Parse the inside of a `{ ... }` block type, e.g. "(Integer) -> String".
|
|
227
|
+
def parse_block_type(inner)
|
|
228
|
+
inner = inner.strip
|
|
229
|
+
params = []
|
|
230
|
+
ret = nil
|
|
231
|
+
|
|
232
|
+
if inner.start_with?('(')
|
|
233
|
+
close = find_matching(inner, 0, '(', ')')
|
|
234
|
+
raise YARD::Parser::UndocumentableError, "malformed block type (unclosed '('): #{inner}" if close.nil?
|
|
235
|
+
params = parse_params_list(inner[1...close])
|
|
236
|
+
rest = inner[close + 1..-1].lstrip
|
|
237
|
+
else
|
|
238
|
+
rest = inner
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
ret = $1.strip if rest =~ /\A->\s*(.*)\z/
|
|
242
|
+
{ :params => params, :return_type => ret }
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Find the index of the matching close bracket starting from +start+.
|
|
246
|
+
# @return [nil] if no matching bracket is found (malformed input).
|
|
247
|
+
def find_matching(str, start, open, close)
|
|
248
|
+
depth = 0
|
|
249
|
+
(start...str.length).each do |i|
|
|
250
|
+
case str[i]
|
|
251
|
+
when open then depth += 1
|
|
252
|
+
when close
|
|
253
|
+
depth -= 1
|
|
254
|
+
return i if depth == 0
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
nil
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
# Split +str+ on commas that are not inside brackets.
|
|
261
|
+
def split_by_comma(str)
|
|
262
|
+
depth = 0
|
|
263
|
+
parts = []
|
|
264
|
+
cur = String.new('')
|
|
265
|
+
str.each_char do |c|
|
|
266
|
+
case c
|
|
267
|
+
when '(', '[', '{'
|
|
268
|
+
depth += 1
|
|
269
|
+
cur << c
|
|
270
|
+
when ')', ']', '}'
|
|
271
|
+
depth -= 1
|
|
272
|
+
cur << c
|
|
273
|
+
when ','
|
|
274
|
+
if depth == 0
|
|
275
|
+
parts << cur.strip
|
|
276
|
+
cur = String.new('')
|
|
277
|
+
else
|
|
278
|
+
cur << c
|
|
279
|
+
end
|
|
280
|
+
else
|
|
281
|
+
cur << c
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
parts << cur.strip unless cur.strip.empty?
|
|
285
|
+
parts
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Split +str+ on `|` that are not inside brackets.
|
|
289
|
+
def self.split_on_pipe(str)
|
|
290
|
+
depth = 0
|
|
291
|
+
parts = []
|
|
292
|
+
cur = String.new('')
|
|
293
|
+
str.each_char do |c|
|
|
294
|
+
case c
|
|
295
|
+
when '(', '[', '{'
|
|
296
|
+
depth += 1
|
|
297
|
+
cur << c
|
|
298
|
+
when ')', ']', '}'
|
|
299
|
+
depth -= 1
|
|
300
|
+
cur << c
|
|
301
|
+
when '|'
|
|
302
|
+
if depth == 0
|
|
303
|
+
parts << cur.strip
|
|
304
|
+
cur = String.new('')
|
|
305
|
+
else
|
|
306
|
+
cur << c
|
|
307
|
+
end
|
|
308
|
+
else
|
|
309
|
+
cur << c
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
parts << cur.strip unless cur.strip.empty?
|
|
313
|
+
parts
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Return the bracket depth of the full string (should be 0 for well-formed types).
|
|
317
|
+
def self.bracket_depth(str)
|
|
318
|
+
depth = 0
|
|
319
|
+
str.each_char do |c|
|
|
320
|
+
case c
|
|
321
|
+
when '(', '[', '{' then depth += 1
|
|
322
|
+
when ')', ']', '}' then depth -= 1
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
depth
|
|
326
|
+
end
|
|
327
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Handles RBS include, extend, and prepend declarations.
|
|
3
|
+
class YARD::Handlers::RBS::MixinHandler < YARD::Handlers::RBS::Base
|
|
4
|
+
handles :include, :extend, :prepend
|
|
5
|
+
|
|
6
|
+
process do
|
|
7
|
+
mixin = P(namespace, statement.mixin_name)
|
|
8
|
+
case statement.type
|
|
9
|
+
when :include
|
|
10
|
+
mixins = namespace.mixins(:instance)
|
|
11
|
+
mixins << mixin unless mixins.include?(mixin)
|
|
12
|
+
when :extend
|
|
13
|
+
mixins = namespace.mixins(:class)
|
|
14
|
+
mixins << mixin unless mixins.include?(mixin)
|
|
15
|
+
when :prepend
|
|
16
|
+
mixins = namespace.mixins(:instance)
|
|
17
|
+
mixins.unshift(mixin) unless mixins.include?(mixin)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Handles RBS class, module, and interface declarations by registering
|
|
3
|
+
# the corresponding namespace code objects and recursing into their bodies.
|
|
4
|
+
class YARD::Handlers::RBS::NamespaceHandler < YARD::Handlers::RBS::Base
|
|
5
|
+
handles :class, :module, :interface
|
|
6
|
+
namespace_only
|
|
7
|
+
|
|
8
|
+
process do
|
|
9
|
+
name = statement.name
|
|
10
|
+
type = statement.type
|
|
11
|
+
|
|
12
|
+
obj = case type
|
|
13
|
+
when :class
|
|
14
|
+
klass = register ClassObject.new(namespace, name)
|
|
15
|
+
if (sc = statement.superclass) && !sc.strip.empty?
|
|
16
|
+
klass.superclass = P(namespace, sc)
|
|
17
|
+
klass.superclass.type = :class if klass.superclass.is_a?(Proxy)
|
|
18
|
+
end
|
|
19
|
+
klass
|
|
20
|
+
when :module, :interface
|
|
21
|
+
register ModuleObject.new(namespace, name)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
parse_block(:namespace => obj)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -31,8 +31,6 @@ class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base
|
|
|
31
31
|
|
|
32
32
|
# Add all attributes
|
|
33
33
|
validated_attribute_names(params).each do |name|
|
|
34
|
-
namespace.attributes[scope][name] ||= SymbolHash[:read => nil, :write => nil]
|
|
35
|
-
|
|
36
34
|
# Show their methods as well
|
|
37
35
|
{:read => name, :write => "#{name}="}.each do |type, meth|
|
|
38
36
|
if type == :read ? read : write
|
|
@@ -52,12 +50,17 @@ class YARD::Handlers::Ruby::AttributeHandler < YARD::Handlers::Ruby::Base
|
|
|
52
50
|
register(o)
|
|
53
51
|
o.docstring = doc if o.docstring.blank?(false)
|
|
54
52
|
|
|
55
|
-
# Register the object explicitly
|
|
56
|
-
|
|
53
|
+
# Register the object explicitly.
|
|
54
|
+
# Use o.scope rather than scope: register() may have changed o.scope
|
|
55
|
+
# via a @!scope directive, so the attribute must be stored under the
|
|
56
|
+
# method's final scope to keep attr_info's lookup consistent.
|
|
57
|
+
namespace.attributes[o.scope][name] ||= SymbolHash[:read => nil, :write => nil]
|
|
58
|
+
namespace.attributes[o.scope][name][type] = o
|
|
57
59
|
else
|
|
58
60
|
obj = namespace.children.find {|other| other.name == meth.to_sym && other.scope == scope }
|
|
59
61
|
|
|
60
62
|
# register an existing method as attribute
|
|
63
|
+
namespace.attributes[scope][name] ||= SymbolHash[:read => nil, :write => nil]
|
|
61
64
|
namespace.attributes[scope][name][type] = obj if obj
|
|
62
65
|
end
|
|
63
66
|
end
|
|
@@ -49,6 +49,7 @@ class YARD::Handlers::Ruby::ConstantHandler < YARD::Handlers::Ruby::Base
|
|
|
49
49
|
if (lhs.type == :var_field && lhs[0].type == :const) || lhs.type == :const_path_field
|
|
50
50
|
klass = create_class(lhs.source, P(:Data))
|
|
51
51
|
extract_parameters(statement[1]).each do |member|
|
|
52
|
+
next if klass.attributes[:instance][member]
|
|
52
53
|
klass.attributes[:instance][member] = SymbolHash[:read => nil, :write => nil]
|
|
53
54
|
create_reader(klass, member)
|
|
54
55
|
end
|
data/lib/yard/i18n/locale.rb
CHANGED
|
@@ -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
|
|
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
|
|
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.
|