rbs 2.0.0 → 2.1.0

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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +5 -0
  3. data/CHANGELOG.md +23 -0
  4. data/README.md +6 -1
  5. data/core/array.rbs +2866 -1086
  6. data/core/basic_object.rbs +150 -30
  7. data/core/binding.rbs +33 -0
  8. data/core/builtin.rbs +4 -4
  9. data/core/class.rbs +43 -5
  10. data/core/comparable.rbs +57 -0
  11. data/core/complex.rbs +170 -4
  12. data/core/constants.rbs +51 -0
  13. data/core/deprecated.rbs +7 -0
  14. data/core/dir.rbs +305 -20
  15. data/core/encoding.rbs +472 -77
  16. data/core/enumerable.rbs +2173 -234
  17. data/core/enumerator.rbs +448 -182
  18. data/core/env.rbs +448 -1
  19. data/core/errno.rbs +1 -10
  20. data/core/errors.rbs +152 -2
  21. data/core/exception.rbs +201 -127
  22. data/core/false_class.rbs +27 -0
  23. data/core/fiber.rbs +118 -37
  24. data/core/fiber_error.rbs +8 -9
  25. data/core/file.rbs +1059 -139
  26. data/core/file_test.rbs +287 -32
  27. data/core/float.rbs +776 -300
  28. data/core/gc.rbs +185 -34
  29. data/core/global_variables.rbs +5 -1
  30. data/core/hash.rbs +1582 -649
  31. data/core/integer.rbs +974 -204
  32. data/core/io/buffer.rbs +710 -0
  33. data/core/io/wait.rbs +29 -8
  34. data/core/io.rbs +2438 -417
  35. data/core/kernel.rbs +2315 -316
  36. data/core/marshal.rbs +37 -2
  37. data/core/match_data.rbs +123 -6
  38. data/core/math.rbs +126 -6
  39. data/core/method.rbs +226 -102
  40. data/core/module.rbs +421 -45
  41. data/core/nil_class.rbs +64 -0
  42. data/core/numeric.rbs +620 -142
  43. data/core/object.rbs +453 -81
  44. data/core/object_space.rbs +92 -2
  45. data/core/proc.rbs +482 -285
  46. data/core/process.rbs +443 -34
  47. data/core/ractor.rbs +232 -9
  48. data/core/random.rbs +151 -52
  49. data/core/range.rbs +885 -160
  50. data/core/rational.rbs +122 -6
  51. data/core/rb_config.rbs +14 -4
  52. data/core/refinement.rbs +44 -0
  53. data/core/regexp.rbs +156 -14
  54. data/core/ruby_vm.rbs +42 -3
  55. data/core/signal.rbs +78 -39
  56. data/core/string.rbs +2123 -567
  57. data/core/string_io.rbs +204 -0
  58. data/core/struct.rbs +283 -28
  59. data/core/symbol.rbs +304 -30
  60. data/core/thread.rbs +1288 -688
  61. data/core/thread_group.rbs +66 -10
  62. data/core/time.rbs +643 -217
  63. data/core/trace_point.rbs +100 -12
  64. data/core/true_class.rbs +24 -0
  65. data/core/unbound_method.rbs +73 -7
  66. data/core/warning.rbs +37 -12
  67. data/docs/CONTRIBUTING.md +40 -34
  68. data/docs/stdlib.md +3 -102
  69. data/lib/rbs/annotate/annotations.rb +197 -0
  70. data/lib/rbs/annotate/formatter.rb +80 -0
  71. data/lib/rbs/annotate/rdoc_annotator.rb +398 -0
  72. data/lib/rbs/annotate/rdoc_source.rb +120 -0
  73. data/lib/rbs/annotate.rb +6 -0
  74. data/lib/rbs/cli.rb +45 -1
  75. data/lib/rbs/definition_builder.rb +5 -1
  76. data/lib/rbs/location_aux.rb +12 -0
  77. data/lib/rbs/prototype/rb.rb +12 -0
  78. data/lib/rbs/version.rb +1 -1
  79. data/sig/annotate/annotations.rbs +102 -0
  80. data/sig/annotate/formatter.rbs +24 -0
  81. data/sig/annotate/rdoc_annotater.rbs +82 -0
  82. data/sig/annotate/rdoc_source.rbs +30 -0
  83. data/sig/cli.rbs +2 -0
  84. data/sig/collection/{collections.rbs → sources.rbs} +0 -0
  85. data/sig/location.rbs +6 -0
  86. data/sig/method_types.rbs +5 -1
  87. data/sig/polyfill.rbs +78 -0
  88. data/stdlib/abbrev/0/abbrev.rbs +6 -0
  89. data/stdlib/abbrev/0/array.rbs +26 -0
  90. data/stdlib/base64/0/base64.rbs +31 -0
  91. data/stdlib/benchmark/0/benchmark.rbs +74 -3
  92. data/stdlib/bigdecimal/0/big_decimal.rbs +614 -165
  93. data/stdlib/bigdecimal-math/0/big_math.rbs +41 -64
  94. data/stdlib/cgi/0/core.rbs +59 -0
  95. data/stdlib/coverage/0/coverage.rbs +164 -2
  96. data/stdlib/csv/0/csv.rbs +2862 -398
  97. data/stdlib/date/0/date.rbs +483 -25
  98. data/stdlib/date/0/date_time.rbs +187 -12
  99. data/stdlib/dbm/0/dbm.rbs +152 -17
  100. data/stdlib/digest/0/digest.rbs +146 -0
  101. data/stdlib/erb/0/erb.rbs +65 -245
  102. data/stdlib/fiber/0/fiber.rbs +73 -91
  103. data/stdlib/fileutils/0/fileutils.rbs +301 -1
  104. data/stdlib/find/0/find.rbs +9 -0
  105. data/stdlib/forwardable/0/forwardable.rbs +65 -1
  106. data/stdlib/io-console/0/io-console.rbs +227 -15
  107. data/stdlib/ipaddr/0/ipaddr.rbs +161 -0
  108. data/stdlib/json/0/json.rbs +1146 -144
  109. data/stdlib/logger/0/formatter.rbs +24 -0
  110. data/stdlib/logger/0/log_device.rbs +64 -0
  111. data/stdlib/logger/0/logger.rbs +165 -13
  112. data/stdlib/logger/0/period.rbs +10 -0
  113. data/stdlib/logger/0/severity.rbs +26 -0
  114. data/stdlib/monitor/0/monitor.rbs +163 -0
  115. data/stdlib/mutex_m/0/mutex_m.rbs +35 -6
  116. data/stdlib/net-http/0/net-http.rbs +1492 -683
  117. data/stdlib/nkf/0/nkf.rbs +372 -0
  118. data/stdlib/objspace/0/objspace.rbs +149 -90
  119. data/stdlib/openssl/0/openssl.rbs +8108 -71
  120. data/stdlib/optparse/0/optparse.rbs +487 -19
  121. data/stdlib/pathname/0/pathname.rbs +425 -124
  122. data/stdlib/prettyprint/0/prettyprint.rbs +120 -99
  123. data/stdlib/prime/0/integer-extension.rbs +20 -2
  124. data/stdlib/prime/0/prime.rbs +88 -21
  125. data/stdlib/pstore/0/pstore.rbs +102 -0
  126. data/stdlib/pty/0/pty.rbs +64 -14
  127. data/stdlib/resolv/0/resolv.rbs +420 -31
  128. data/stdlib/rubygems/0/basic_specification.rbs +4 -1
  129. data/stdlib/rubygems/0/config_file.rbs +33 -1
  130. data/stdlib/rubygems/0/dependency_installer.rbs +4 -3
  131. data/stdlib/rubygems/0/installer.rbs +13 -1
  132. data/stdlib/rubygems/0/path_support.rbs +4 -1
  133. data/stdlib/rubygems/0/platform.rbs +5 -1
  134. data/stdlib/rubygems/0/request_set.rbs +44 -2
  135. data/stdlib/rubygems/0/requirement.rbs +65 -2
  136. data/stdlib/rubygems/0/rubygems.rbs +407 -0
  137. data/stdlib/rubygems/0/source_list.rbs +13 -0
  138. data/stdlib/rubygems/0/specification.rbs +21 -1
  139. data/stdlib/rubygems/0/stream_ui.rbs +3 -1
  140. data/stdlib/rubygems/0/uninstaller.rbs +8 -1
  141. data/stdlib/rubygems/0/version.rbs +60 -157
  142. data/stdlib/securerandom/0/securerandom.rbs +44 -0
  143. data/stdlib/set/0/set.rbs +420 -106
  144. data/stdlib/shellwords/0/shellwords.rbs +55 -77
  145. data/stdlib/singleton/0/singleton.rbs +20 -0
  146. data/stdlib/socket/0/addrinfo.rbs +210 -9
  147. data/stdlib/socket/0/basic_socket.rbs +103 -11
  148. data/stdlib/socket/0/ip_socket.rbs +31 -9
  149. data/stdlib/socket/0/socket.rbs +586 -38
  150. data/stdlib/socket/0/tcp_server.rbs +22 -2
  151. data/stdlib/socket/0/tcp_socket.rbs +12 -1
  152. data/stdlib/socket/0/udp_socket.rbs +25 -2
  153. data/stdlib/socket/0/unix_server.rbs +22 -2
  154. data/stdlib/socket/0/unix_socket.rbs +45 -5
  155. data/stdlib/strscan/0/string_scanner.rbs +210 -9
  156. data/stdlib/tempfile/0/tempfile.rbs +58 -10
  157. data/stdlib/time/0/time.rbs +208 -116
  158. data/stdlib/timeout/0/timeout.rbs +10 -0
  159. data/stdlib/tmpdir/0/tmpdir.rbs +13 -4
  160. data/stdlib/tsort/0/cyclic.rbs +1 -0
  161. data/stdlib/tsort/0/interfaces.rbs +1 -0
  162. data/stdlib/tsort/0/tsort.rbs +42 -0
  163. data/stdlib/uri/0/common.rbs +57 -8
  164. data/stdlib/uri/0/file.rbs +55 -109
  165. data/stdlib/uri/0/ftp.rbs +6 -3
  166. data/stdlib/uri/0/generic.rbs +556 -327
  167. data/stdlib/uri/0/http.rbs +26 -115
  168. data/stdlib/uri/0/https.rbs +8 -102
  169. data/stdlib/uri/0/ldap.rbs +143 -137
  170. data/stdlib/uri/0/ldaps.rbs +8 -102
  171. data/stdlib/uri/0/mailto.rbs +3 -0
  172. data/stdlib/uri/0/rfc2396_parser.rbs +66 -26
  173. data/stdlib/uri/0/ws.rbs +6 -3
  174. data/stdlib/uri/0/wss.rbs +5 -3
  175. data/stdlib/yaml/0/dbm.rbs +151 -87
  176. data/stdlib/yaml/0/store.rbs +6 -0
  177. data/stdlib/zlib/0/zlib.rbs +90 -31
  178. metadata +17 -5
  179. data/lib/rbs/location.rb +0 -221
@@ -0,0 +1,398 @@
1
+ module RBS
2
+ module Annotate
3
+ class RDocAnnotator
4
+ attr_reader :source
5
+ attr_accessor :include_arg_lists, :include_filename
6
+
7
+ def initialize(source:)
8
+ @source = source
9
+
10
+ @include_arg_lists = true
11
+ @include_filename = true
12
+ end
13
+
14
+ def annotate_file(path)
15
+ content = path.read()
16
+
17
+ decls = Parser.parse_signature(content)
18
+
19
+ annotate_decls(decls)
20
+
21
+ path.open("w") do |io|
22
+ Writer.new(out: io).write(decls)
23
+ end
24
+ end
25
+
26
+ def annotate_decls(decls, outer: [])
27
+ decls.each do |decl|
28
+ case decl
29
+ when AST::Declarations::Class, AST::Declarations::Module
30
+ annotate_class(decl, outer: outer)
31
+ when AST::Declarations::Constant
32
+ annotate_constant(decl, outer: outer)
33
+ end
34
+ end
35
+ end
36
+
37
+ def each_part(subjects, tester:)
38
+ if block_given?
39
+ subjects.each do |subject, docs|
40
+ Formatter.each_part(subject.comment) do |doc|
41
+ if tester.test_path(doc.file || raise)
42
+ yield [doc, subject]
43
+ end
44
+ end
45
+ end
46
+ else
47
+ enum_for :each_part, tester: tester
48
+ end
49
+ end
50
+
51
+ def resolve_doc_source(copy, tester:)
52
+ case
53
+ when copy && (mn = copy.method_name) && copy.singleton?
54
+ doc_for_method(copy.type_name, singleton_method: mn, tester: tester)
55
+ when copy && (mn = copy.method_name) && !copy.singleton?
56
+ doc_for_method(copy.type_name, instance_method: mn, tester: tester)
57
+ when copy
58
+ doc_for_class(copy.type_name, tester: tester) || doc_for_constant(copy.type_name, tester: tester)
59
+ else
60
+ yield
61
+ end
62
+ end
63
+
64
+ def doc_for_class(name, tester:)
65
+ if clss = source.find_class(name)
66
+ formatter = Formatter.new()
67
+
68
+ each_part(clss, tester: tester) do |doc, _|
69
+ text = Formatter.translate(doc) or next
70
+
71
+ unless text.empty?
72
+ if include_filename
73
+ formatter << "<!-- rdoc-file=#{doc.file} -->"
74
+ end
75
+ formatter << text
76
+
77
+ formatter.margin
78
+ end
79
+ end
80
+
81
+ formatter.format(newline_at_end: true)
82
+ end
83
+ end
84
+
85
+ def doc_for_constant(name, tester:)
86
+ if constants = source.find_const(name)
87
+ formatter = Formatter.new
88
+
89
+ each_part(constants, tester: tester) do |doc, _|
90
+ text = Formatter.translate(doc) or next
91
+
92
+ unless text.empty?
93
+ if include_filename
94
+ formatter << "<!-- rdoc-file=#{doc.file} -->"
95
+ end
96
+
97
+ formatter << text
98
+
99
+ formatter.margin
100
+ end
101
+ end
102
+
103
+ formatter.format(newline_at_end: true)
104
+ end
105
+ end
106
+
107
+ def doc_for_method0(typename, instance_method: nil, singleton_method: nil, tester:)
108
+ ms = source.find_method(typename, instance_method: instance_method) if instance_method
109
+ ms = source.find_method(typename, singleton_method: singleton_method) if singleton_method
110
+
111
+ if ms
112
+ formatter = Formatter.new
113
+
114
+ each_part(ms, tester: tester) do |doc, method|
115
+ text = Formatter.translate(doc) or next
116
+ # @type var as: String?
117
+ as = (_ = method).arglists
118
+
119
+ if include_arg_lists && as
120
+ formatter << "<!--"
121
+ formatter << " rdoc-file=#{doc.file}" if include_filename
122
+ as.chomp.split("\n").each do |line|
123
+ formatter << " - #{line.strip}"
124
+ end
125
+ formatter << "-->"
126
+ else
127
+ if include_filename
128
+ formatter << "<!-- rdoc-file=#{doc.file} -->"
129
+ end
130
+ end
131
+
132
+ unless text.empty?
133
+ formatter << text
134
+ end
135
+
136
+ formatter.margin(separator: "----")
137
+ end
138
+
139
+ formatter.format(newline_at_end: false)
140
+ end
141
+ end
142
+
143
+ def doc_for_method(typename, instance_method: nil, singleton_method: nil, tester:)
144
+ formatter = Formatter.new()
145
+
146
+ case
147
+ when method = instance_method
148
+ doc = doc_for_alias(typename, name: method, singleton: false, tester: tester)
149
+ doc = doc_for_method0(typename, instance_method: method, tester: tester) if !doc || doc.empty?
150
+ if !doc || doc.empty?
151
+ if (s = method.to_s) =~ /\A[a-zA-Z_]/
152
+ # may be attribute
153
+ doc =
154
+ if s.end_with?("=")
155
+ doc_for_attribute(typename, s.delete_suffix("=").to_sym, require: "W", singleton: false, tester: tester)
156
+ else
157
+ doc_for_attribute(typename, s.to_sym, require: "R", singleton: false, tester: tester)
158
+ end
159
+ end
160
+ end
161
+ when method = singleton_method
162
+ doc = doc_for_alias(typename, name: method, singleton: true, tester: tester)
163
+ doc = doc_for_method0(typename, singleton_method: method, tester: tester) if !doc || doc.empty?
164
+ if !doc || doc.empty?
165
+ if (s = method.to_s) =~ /\A[a-zA-Z_]/
166
+ # may be attribute
167
+ doc =
168
+ if s.end_with?("=")
169
+ doc_for_attribute(typename, s.delete_suffix("=").to_sym, require: "W", singleton: true, tester: tester)
170
+ else
171
+ doc_for_attribute(typename, s.to_sym, require: "R", singleton: true, tester: tester)
172
+ end
173
+ end
174
+ end
175
+ else
176
+ raise
177
+ end
178
+
179
+ if doc
180
+ formatter << doc
181
+ formatter.format(newline_at_end: true)
182
+ end
183
+ end
184
+
185
+ def doc_for_alias(typename, name:, singleton:, tester:)
186
+ if as =
187
+ if singleton
188
+ source.find_method(typename, singleton_method: name)
189
+ else
190
+ source.find_method(typename, instance_method: name)
191
+ end
192
+
193
+ formatter = Formatter.new
194
+
195
+ each_part(as, tester: tester) do |doc, obj|
196
+ # @type var method: RDoc::AnyMethod
197
+ method = _ = obj
198
+
199
+ if method.is_alias_for
200
+ text = Formatter.translate(doc) or next
201
+
202
+ unless text.empty?
203
+ formatter << "<!-- rdoc-file=#{doc.file} -->" if include_filename
204
+ formatter << text
205
+ end
206
+ end
207
+ end
208
+
209
+ formatter.format(newline_at_end: true)
210
+ end
211
+ end
212
+
213
+ def doc_for_attribute(typename, attr_name, require: nil, singleton:, tester:)
214
+ if as = source.find_attribute(typename, attr_name, singleton: singleton)
215
+ as = as.select do |attr|
216
+ case require
217
+ when "R"
218
+ attr.rw == "R" || attr.rw == "RW"
219
+ when "W"
220
+ attr.rw == "W" || attr.rw == "RW"
221
+ else
222
+ true
223
+ end
224
+ end
225
+
226
+ return if as.empty?
227
+
228
+ formatter = Formatter.new()
229
+
230
+ each_part(as, tester: tester) do |doc, obj|
231
+ if text = Formatter.translate(doc)
232
+ unless text.empty?
233
+ formatter << "<!-- rdoc-file=#{doc.file} -->" if include_filename
234
+ formatter << text
235
+ end
236
+ end
237
+ end
238
+
239
+ formatter.format(newline_at_end: true)
240
+ end
241
+ end
242
+
243
+ def annotate_class(decl, outer:)
244
+ annots = annotations(decl)
245
+
246
+ full_name = resolve_name(decl.name, outer: outer)
247
+ unless annots.skip?
248
+ text = resolve_doc_source(annots.copy_annotation, tester: annots) { doc_for_class(full_name, tester: annots) }
249
+ end
250
+
251
+ replace_comment(decl, text)
252
+
253
+ unless annots.skip_all?
254
+ outer_ = outer + [decl.name.to_namespace]
255
+
256
+ decl.each_member do |member|
257
+ case member
258
+ when AST::Members::MethodDefinition
259
+ annotate_method(full_name, member)
260
+ when AST::Members::Alias
261
+ annotate_alias(full_name, member)
262
+ when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
263
+ annotate_attribute(full_name, member)
264
+ end
265
+ end
266
+
267
+ annotate_decls(decl.each_decl.to_a, outer: outer_)
268
+ end
269
+ end
270
+
271
+ def annotate_constant(const, outer:)
272
+ annots = Annotations.new([])
273
+
274
+ full_name = resolve_name(const.name, outer: outer)
275
+ text = doc_for_constant(full_name, tester: annots)
276
+
277
+ replace_comment(const, text)
278
+ end
279
+
280
+ def annotate_alias(typename, als)
281
+ annots = annotations(als)
282
+
283
+ unless annots.skip?
284
+ text = resolve_doc_source(annots.copy_annotation, tester: annots) do
285
+ case als.kind
286
+ when :instance
287
+ doc_for_method(typename, instance_method: als.new_name, tester: annots)
288
+ when :singleton
289
+ doc_for_method(typename, singleton_method: als.new_name, tester: annots)
290
+ end
291
+ end
292
+ end
293
+
294
+ replace_comment(als, text)
295
+ end
296
+
297
+ def join_docs(docs, separator: "----")
298
+ formatter = Formatter.new()
299
+
300
+ docs.each do |doc|
301
+ formatter << doc
302
+ formatter.margin(separator: separator)
303
+ end
304
+
305
+ unless formatter.empty?
306
+ formatter.format(newline_at_end: true)
307
+ end
308
+ end
309
+
310
+ def annotate_method(typename, method)
311
+ annots = annotations(method)
312
+
313
+ unless annots.skip?
314
+ text = resolve_doc_source(annots.copy_annotation, tester: annots) {
315
+ case method.kind
316
+ when :singleton
317
+ doc_for_method(typename, singleton_method: method.name, tester: annots)
318
+ when :instance
319
+ if method.name == :initialize
320
+ doc_for_method(typename, instance_method: :initialize, tester: annots) ||
321
+ doc_for_method(typename, singleton_method: :new, tester: annots)
322
+ else
323
+ doc_for_method(typename, instance_method: method.name, tester: annots)
324
+ end
325
+ when :singleton_instance
326
+ join_docs(
327
+ [
328
+ doc_for_method(typename, singleton_method: method.name, tester: annots),
329
+ doc_for_method(typename, instance_method: method.name, tester: annots)
330
+ ].uniq
331
+ )
332
+ end
333
+ }
334
+ end
335
+
336
+ replace_comment(method, text)
337
+ end
338
+
339
+ def annotate_attribute(typename, attr)
340
+ annots = annotations(attr)
341
+
342
+ unless annots.skip?
343
+ text = resolve_doc_source(annots.copy_annotation, tester: annots) do
344
+ # @type var docs: Array[String?]
345
+ docs = []
346
+
347
+ case attr.kind
348
+ when :instance
349
+ if attr.is_a?(AST::Members::AttrReader) || attr.is_a?(AST::Members::AttrAccessor)
350
+ docs << doc_for_method(typename, instance_method: attr.name, tester: annots)
351
+ end
352
+ if attr.is_a?(AST::Members::AttrWriter) || attr.is_a?(AST::Members::AttrAccessor)
353
+ docs << doc_for_method(typename, instance_method: :"#{attr.name}=", tester: annots)
354
+ end
355
+ when :singleton
356
+ if attr.is_a?(AST::Members::AttrReader) || attr.is_a?(AST::Members::AttrAccessor)
357
+ docs << doc_for_method(typename, singleton_method: attr.name, tester: annots)
358
+ end
359
+ if attr.is_a?(AST::Members::AttrWriter) || attr.is_a?(AST::Members::AttrAccessor)
360
+ docs << doc_for_method(typename, singleton_method: :"#{attr.name}=", tester: annots)
361
+ end
362
+ end
363
+ join_docs(docs.uniq)
364
+ end
365
+ end
366
+
367
+ replace_comment(attr, text)
368
+ end
369
+
370
+ def replace_comment(commented, string)
371
+ if string
372
+ if string.empty?
373
+ commented.instance_variable_set(:@comment, nil)
374
+ else
375
+ commented.instance_variable_set(
376
+ :@comment,
377
+ AST::Comment.new(location: nil, string: string)
378
+ )
379
+ end
380
+ end
381
+ end
382
+
383
+ def resolve_name(name, outer:)
384
+ namespace = outer.inject(RBS::Namespace.root) do |ns1, ns2|
385
+ ns1 + ns2
386
+ end
387
+
388
+ name.with_prefix(namespace).relative!
389
+ end
390
+
391
+ def annotations(annots)
392
+ # @type var as: Array[Annotations::t]
393
+ as = _ = annots.annotations.map {|annot| Annotations.parse(annot) }.compact
394
+ Annotations.new(as)
395
+ end
396
+ end
397
+ end
398
+ end
@@ -0,0 +1,120 @@
1
+ module RBS
2
+ module Annotate
3
+ class RDocSource
4
+ attr_accessor :with_system_dir, :with_gems_dir, :with_site_dir, :with_home_dir
5
+
6
+ attr_reader :extra_dirs
7
+
8
+ attr_reader :stores
9
+
10
+ def initialize
11
+ self.with_system_dir = true
12
+ self.with_gems_dir = false
13
+ self.with_site_dir = false
14
+ self.with_home_dir = false
15
+
16
+ @extra_dirs = []
17
+ @stores = []
18
+ end
19
+
20
+ def load
21
+ @stores.clear()
22
+
23
+ RDoc::RI::Paths.each(with_system_dir, with_site_dir, with_home_dir, with_gems_dir ? :latest : false, *extra_dirs.map(&:to_s)) do |path, type|
24
+ store = RDoc::Store.new(path, type)
25
+ store.load_all
26
+
27
+ @stores << store
28
+ end
29
+ end
30
+
31
+ def find_class(typename)
32
+ classes = []
33
+
34
+ @stores.each do |store|
35
+ if klass = store.find_class_or_module(typename.relative!.to_s)
36
+ classes << klass
37
+ end
38
+ end
39
+
40
+ unless classes.empty?
41
+ classes
42
+ end
43
+ end
44
+
45
+ def docs
46
+ if ds = yield
47
+ unless ds.empty?
48
+ ds.map(&:comment)
49
+ end
50
+ end
51
+ end
52
+
53
+ def class_docs(typename)
54
+ if classes = find_class(typename)
55
+ classes.map {|klass| klass.comment }
56
+ end
57
+ end
58
+
59
+ def find_const(const_name)
60
+ namespace =
61
+ if const_name.namespace.empty?
62
+ TypeName("::Object")
63
+ else
64
+ const_name.namespace.to_type_name
65
+ end
66
+
67
+ if classes = find_class(namespace)
68
+ # @type var consts: Array[RDoc::Constant]
69
+ consts = []
70
+
71
+ classes.each do |klass|
72
+ if const = klass.constants.find {|c| c.name == const_name.name.to_s }
73
+ consts << const
74
+ end
75
+ end
76
+
77
+ unless consts.empty?
78
+ consts
79
+ end
80
+ end
81
+ end
82
+
83
+ def find_method(typename, instance_method: nil, singleton_method: nil)
84
+ if classes = find_class(typename)
85
+ # @type var methods: Array[RDoc::AnyMethod]
86
+ methods = []
87
+
88
+ classes.each do |klass|
89
+ klass.method_list.each do |method|
90
+ if instance_method && !method.singleton && method.name == instance_method.to_s
91
+ methods << method
92
+ end
93
+
94
+ if singleton_method && method.singleton && method.name == singleton_method.to_s
95
+ methods << method
96
+ end
97
+ end
98
+ end
99
+
100
+ unless methods.empty?
101
+ methods
102
+ end
103
+ end
104
+ end
105
+
106
+ def find_attribute(typename, name, singleton:)
107
+ if klasss = find_class(typename)
108
+ # @type var attrs: Array[RDoc::Attr]
109
+ attrs = []
110
+
111
+ klasss.each do |kls|
112
+ attrs.concat(kls.attributes.select {|attr| attr.singleton == singleton && attr.name == name.to_s })
113
+ end
114
+
115
+ attrs unless attrs.empty?
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,6 @@
1
+ require "rdoc"
2
+
3
+ require "rbs/annotate/rdoc_annotator"
4
+ require "rbs/annotate/rdoc_source"
5
+ require "rbs/annotate/annotations"
6
+ require "rbs/annotate/formatter"
data/lib/rbs/cli.rb CHANGED
@@ -80,7 +80,7 @@ module RBS
80
80
  @stderr = stderr
81
81
  end
82
82
 
83
- COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection]
83
+ COMMANDS = [:ast, :annotate, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse, :test, :collection]
84
84
 
85
85
  def parse_logging_options(opts)
86
86
  opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
@@ -791,6 +791,50 @@ Examples:
791
791
  exit 1 if syntax_error
792
792
  end
793
793
 
794
+ def run_annotate(args, options)
795
+ require "rbs/annotate"
796
+
797
+ source = RBS::Annotate::RDocSource.new()
798
+ annotator = RBS::Annotate::RDocAnnotator.new(source: source)
799
+
800
+ OptionParser.new do |opts|
801
+ opts.banner = <<-EOB
802
+ Usage: rbs annotate [options...] [files...]
803
+
804
+ Import documents from RDoc and update RBS files.
805
+
806
+ Examples:
807
+
808
+ $ rbs annotate stdlib/pathname/**/*.rbs
809
+
810
+ Options:
811
+ EOB
812
+
813
+ opts.on("--[no-]system", "Load RDoc from system (defaults to true)") {|b| source.with_system_dir = b }
814
+ opts.on("--[no-]gems", "Load RDoc from gems (defaults to false)") {|b| source.with_gems_dir = b }
815
+ opts.on("--[no-]site", "Load RDoc from site directory (defaults to false)") {|b| source.with_site_dir = b }
816
+ opts.on("--[no-]home", "Load RDoc from home directory (defaults to false)") {|b| source.with_home_dir = b }
817
+ opts.on("-d", "--dir DIRNAME", "Load RDoc from DIRNAME") {|d| source.extra_dirs << Pathname(d) }
818
+ opts.on("--[no-]arglists", "Generate arglists section (defaults to true)") {|b| annotator.include_arg_lists = b }
819
+ opts.on("--[no-]filename", "Include source file name in the documentation (defaults to true)") {|b| annotator.include_filename = b }
820
+ end.parse!(args)
821
+
822
+ source.load()
823
+
824
+ args.each do |file|
825
+ path = Pathname(file)
826
+ if path.directory?
827
+ Pathname.glob((path + "**/*.rbs").to_s).each do |path|
828
+ stdout.puts "Processing #{path}..."
829
+ annotator.annotate_file(path)
830
+ end
831
+ else
832
+ stdout.puts "Processing #{path}..."
833
+ annotator.annotate_file(path)
834
+ end
835
+ end
836
+ end
837
+
794
838
  def test_opt options
795
839
  opts = []
796
840
 
@@ -539,8 +539,12 @@ module RBS
539
539
 
540
540
  if method_types
541
541
  method_types.each do |method_type|
542
+ merged_params = type_params
543
+ .reject {|param| method_type.type_param_names.include?(param.name) }
544
+ .concat(method_type.type_params)
545
+
542
546
  result = calculator.in_method_type(method_type: method_type, variables: param_names)
543
- validate_params_with(type_params, result: result) do |param|
547
+ validate_params_with(merged_params, result: result) do |param|
544
548
  raise InvalidVarianceAnnotationError.new(
545
549
  type_name: definition.type_name,
546
550
  param: param,
@@ -119,5 +119,17 @@ module RBS
119
119
  enum_for(:each_required_key)
120
120
  end
121
121
  end
122
+
123
+ def key?(name)
124
+ optional_key?(name) || required_key?(name)
125
+ end
126
+
127
+ def optional_key?(name)
128
+ _optional_keys.include?(name)
129
+ end
130
+
131
+ def required_key?(name)
132
+ _required_keys.include?(name)
133
+ end
122
134
  end
123
135
  end
@@ -197,6 +197,18 @@ module RBS
197
197
  )
198
198
  end
199
199
  end
200
+ when :prepend
201
+ args.each do |arg|
202
+ if (name = const_to_name(arg))
203
+ decls << AST::Members::Prepend.new(
204
+ name: name,
205
+ args: [],
206
+ annotations: [],
207
+ location: nil,
208
+ comment: comments[node.first_lineno - 1]
209
+ )
210
+ end
211
+ end
200
212
  when :extend
201
213
  args.each do |arg|
202
214
  if (name = const_to_name(arg, context: context))
data/lib/rbs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end