rbs 3.9.4 → 4.2.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 (354) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +75 -0
  3. data/.clangd +2 -0
  4. data/.dockerignore +37 -0
  5. data/.gitattributes +1 -0
  6. data/.github/dependabot.yml +16 -14
  7. data/.github/workflows/bundle-update.yml +63 -0
  8. data/.github/workflows/c-check.yml +66 -0
  9. data/.github/workflows/changelog.yml +121 -0
  10. data/.github/workflows/comments.yml +6 -4
  11. data/.github/workflows/dependabot.yml +2 -2
  12. data/.github/workflows/jruby.yml +74 -0
  13. data/.github/workflows/release-gems.yml +234 -0
  14. data/.github/workflows/ruby.yml +86 -32
  15. data/.github/workflows/rust.yml +186 -0
  16. data/.github/workflows/truffleruby.yml +54 -0
  17. data/.github/workflows/typecheck.yml +6 -3
  18. data/.github/workflows/wasm.yml +55 -0
  19. data/.github/workflows/windows.yml +10 -4
  20. data/.gitignore +16 -0
  21. data/.rubocop.yml +1 -2
  22. data/CHANGELOG.md +502 -0
  23. data/Dockerfile.jruby +53 -0
  24. data/README.md +42 -5
  25. data/Rakefile +892 -111
  26. data/Steepfile +11 -0
  27. data/config.yml +665 -62
  28. data/core/array.rbs +541 -398
  29. data/core/basic_object.rbs +9 -8
  30. data/core/binding.rbs +0 -2
  31. data/core/builtin.rbs +9 -8
  32. data/core/class.rbs +11 -8
  33. data/core/comparable.rbs +55 -34
  34. data/core/complex.rbs +104 -78
  35. data/core/dir.rbs +61 -49
  36. data/core/encoding.rbs +12 -15
  37. data/core/enumerable.rbs +297 -196
  38. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  39. data/core/enumerator/product.rbs +5 -5
  40. data/core/enumerator.rbs +91 -28
  41. data/core/errno.rbs +11 -2
  42. data/core/errors.rbs +58 -29
  43. data/core/exception.rbs +13 -13
  44. data/core/fiber.rbs +74 -54
  45. data/core/file.rbs +260 -1151
  46. data/core/file_constants.rbs +463 -0
  47. data/core/file_stat.rbs +534 -0
  48. data/core/file_test.rbs +3 -3
  49. data/core/float.rbs +257 -116
  50. data/core/gc.rbs +425 -281
  51. data/core/hash.rbs +1151 -829
  52. data/core/integer.rbs +156 -195
  53. data/core/io/buffer.rbs +53 -42
  54. data/core/io/wait.rbs +13 -35
  55. data/core/io.rbs +222 -155
  56. data/core/kernel.rbs +239 -163
  57. data/core/marshal.rbs +4 -4
  58. data/core/match_data.rbs +16 -14
  59. data/core/math.rbs +107 -66
  60. data/core/method.rbs +69 -33
  61. data/core/module.rbs +302 -150
  62. data/core/nil_class.rbs +7 -6
  63. data/core/numeric.rbs +77 -63
  64. data/core/object.rbs +9 -11
  65. data/core/object_space/weak_key_map.rbs +7 -7
  66. data/core/object_space.rbs +30 -23
  67. data/core/pathname.rbs +1312 -0
  68. data/core/proc.rbs +95 -58
  69. data/core/process.rbs +222 -202
  70. data/core/ractor.rbs +364 -518
  71. data/core/random.rbs +21 -3
  72. data/core/range.rbs +181 -79
  73. data/core/rational.rbs +60 -89
  74. data/core/rbs/ops.rbs +154 -0
  75. data/core/rbs/unnamed/argf.rbs +63 -56
  76. data/core/rbs/unnamed/env_class.rbs +19 -14
  77. data/core/rbs/unnamed/main_class.rbs +123 -0
  78. data/core/rbs/unnamed/random.rbs +11 -118
  79. data/core/regexp.rbs +258 -214
  80. data/core/ruby.rbs +53 -0
  81. data/core/ruby_vm.rbs +78 -34
  82. data/core/rubygems/config_file.rbs +5 -5
  83. data/core/rubygems/errors.rbs +6 -70
  84. data/core/rubygems/requirement.rbs +5 -15
  85. data/core/rubygems/rubygems.rbs +18 -81
  86. data/core/rubygems/specification.rbs +8 -0
  87. data/core/rubygems/version.rbs +2 -163
  88. data/core/set.rbs +493 -363
  89. data/core/signal.rbs +26 -16
  90. data/core/string.rbs +3234 -1285
  91. data/core/struct.rbs +43 -42
  92. data/core/symbol.rbs +41 -34
  93. data/core/thread.rbs +139 -83
  94. data/core/time.rbs +81 -50
  95. data/core/trace_point.rbs +41 -35
  96. data/core/true_class.rbs +2 -2
  97. data/core/unbound_method.rbs +24 -16
  98. data/core/warning.rbs +7 -7
  99. data/docs/CONTRIBUTING.md +3 -2
  100. data/docs/aliases.md +79 -0
  101. data/docs/collection.md +3 -3
  102. data/docs/config.md +171 -0
  103. data/docs/encoding.md +56 -0
  104. data/docs/gem.md +0 -1
  105. data/docs/inline.md +634 -0
  106. data/docs/rbs_by_example.md +20 -20
  107. data/docs/release.md +303 -0
  108. data/docs/rust.md +96 -0
  109. data/docs/sigs.md +3 -3
  110. data/docs/stdlib.md +8 -0
  111. data/docs/syntax.md +60 -18
  112. data/docs/type_fingerprint.md +21 -0
  113. data/docs/wasm_serialization.md +80 -0
  114. data/exe/rbs +1 -1
  115. data/ext/rbs_extension/ast_translation.c +1870 -0
  116. data/ext/rbs_extension/ast_translation.h +41 -0
  117. data/ext/rbs_extension/class_constants.c +189 -0
  118. data/{include/rbs/constants.h → ext/rbs_extension/class_constants.h} +24 -1
  119. data/ext/rbs_extension/compat.h +10 -0
  120. data/ext/rbs_extension/extconf.rb +26 -1
  121. data/ext/rbs_extension/legacy_location.c +299 -0
  122. data/ext/rbs_extension/legacy_location.h +82 -0
  123. data/ext/rbs_extension/main.c +639 -23
  124. data/ext/rbs_extension/rbs_extension.h +6 -21
  125. data/ext/rbs_extension/rbs_string_bridging.c +9 -0
  126. data/ext/rbs_extension/rbs_string_bridging.h +24 -0
  127. data/include/rbs/ast.h +1055 -0
  128. data/include/rbs/defines.h +104 -0
  129. data/include/rbs/lexer.h +208 -0
  130. data/include/rbs/location.h +40 -0
  131. data/include/rbs/parser.h +187 -0
  132. data/include/rbs/serialize.h +39 -0
  133. data/include/rbs/string.h +47 -0
  134. data/include/rbs/util/rbs_allocator.h +59 -0
  135. data/include/rbs/util/rbs_assert.h +20 -0
  136. data/include/rbs/util/rbs_buffer.h +83 -0
  137. data/include/rbs/util/rbs_constant_pool.h +6 -70
  138. data/include/rbs/util/rbs_encoding.h +282 -0
  139. data/include/rbs/util/rbs_unescape.h +24 -0
  140. data/include/rbs.h +9 -2
  141. data/lib/rbs/annotate/formatter.rb +3 -13
  142. data/lib/rbs/annotate/rdoc_annotator.rb +30 -32
  143. data/lib/rbs/annotate/rdoc_source.rb +1 -1
  144. data/lib/rbs/ast/annotation.rb +1 -1
  145. data/lib/rbs/ast/comment.rb +1 -1
  146. data/lib/rbs/ast/declarations.rb +11 -11
  147. data/lib/rbs/ast/members.rb +14 -14
  148. data/lib/rbs/ast/ruby/annotations.rb +451 -0
  149. data/lib/rbs/ast/ruby/comment_block.rb +247 -0
  150. data/lib/rbs/ast/ruby/declarations.rb +291 -0
  151. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
  152. data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  153. data/lib/rbs/ast/ruby/members.rb +762 -0
  154. data/lib/rbs/ast/type_param.rb +25 -5
  155. data/lib/rbs/buffer.rb +142 -20
  156. data/lib/rbs/cli/diff.rb +16 -15
  157. data/lib/rbs/cli/validate.rb +63 -126
  158. data/lib/rbs/cli.rb +59 -29
  159. data/lib/rbs/collection/config/lockfile_generator.rb +28 -3
  160. data/lib/rbs/collection/sources/git.rb +7 -0
  161. data/lib/rbs/definition.rb +6 -1
  162. data/lib/rbs/definition_builder/ancestor_builder.rb +129 -70
  163. data/lib/rbs/definition_builder/method_builder.rb +74 -33
  164. data/lib/rbs/definition_builder.rb +181 -21
  165. data/lib/rbs/diff.rb +7 -1
  166. data/lib/rbs/environment/class_entry.rb +81 -0
  167. data/lib/rbs/environment/module_entry.rb +91 -0
  168. data/lib/rbs/environment.rb +410 -215
  169. data/lib/rbs/environment_loader.rb +2 -8
  170. data/lib/rbs/errors.rb +31 -21
  171. data/lib/rbs/inline_parser/comment_association.rb +117 -0
  172. data/lib/rbs/inline_parser.rb +568 -0
  173. data/lib/rbs/location_aux.rb +36 -4
  174. data/lib/rbs/locator.rb +5 -1
  175. data/lib/rbs/method_type.rb +5 -3
  176. data/lib/rbs/namespace.rb +47 -18
  177. data/lib/rbs/parser_aux.rb +37 -7
  178. data/lib/rbs/prototype/helpers.rb +24 -0
  179. data/lib/rbs/prototype/rb.rb +3 -28
  180. data/lib/rbs/prototype/rbi.rb +196 -45
  181. data/lib/rbs/prototype/runtime/value_object_generator.rb +0 -1
  182. data/lib/rbs/prototype/runtime.rb +13 -3
  183. data/lib/rbs/resolver/constant_resolver.rb +2 -2
  184. data/lib/rbs/resolver/type_name_resolver.rb +120 -44
  185. data/lib/rbs/rewriter.rb +70 -0
  186. data/lib/rbs/source.rb +99 -0
  187. data/lib/rbs/subtractor.rb +7 -4
  188. data/lib/rbs/test/type_check.rb +25 -3
  189. data/lib/rbs/type_name.rb +34 -21
  190. data/lib/rbs/types.rb +135 -81
  191. data/lib/rbs/unit_test/convertibles.rb +1 -0
  192. data/lib/rbs/unit_test/type_assertions.rb +47 -11
  193. data/lib/rbs/validator.rb +2 -2
  194. data/lib/rbs/version.rb +1 -1
  195. data/lib/rbs/wasm/deserializer.rb +213 -0
  196. data/lib/rbs/wasm/location.rb +61 -0
  197. data/lib/rbs/wasm/parser.rb +174 -0
  198. data/lib/rbs/wasm/runtime.rb +211 -0
  199. data/lib/rbs/wasm/serialization_schema.rb +111 -0
  200. data/lib/rbs.rb +25 -2
  201. data/lib/rbs_jars.rb +39 -0
  202. data/lib/rdoc/discover.rb +1 -1
  203. data/lib/rdoc_plugin/parser.rb +8 -3
  204. data/rbs.gemspec +34 -6
  205. data/schema/function.json +12 -1
  206. data/schema/typeParam.json +17 -1
  207. data/sig/ancestor_builder.rbs +1 -1
  208. data/sig/annotate/formatter.rbs +2 -2
  209. data/sig/annotate/rdoc_annotater.rbs +13 -10
  210. data/sig/ast/ruby/annotations.rbs +470 -0
  211. data/sig/ast/ruby/comment_block.rbs +127 -0
  212. data/sig/ast/ruby/declarations.rbs +158 -0
  213. data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  214. data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  215. data/sig/ast/ruby/members.rbs +198 -0
  216. data/sig/buffer.rbs +81 -5
  217. data/sig/cli/diff.rbs +5 -11
  218. data/sig/cli/validate.rbs +12 -8
  219. data/sig/cli.rbs +18 -18
  220. data/sig/collection/config/lockfile_generator.rbs +2 -0
  221. data/sig/definition.rbs +6 -0
  222. data/sig/definition_builder.rbs +3 -1
  223. data/sig/environment/class_entry.rbs +56 -0
  224. data/sig/environment/module_entry.rbs +65 -0
  225. data/sig/environment.rbs +94 -87
  226. data/sig/errors.rbs +26 -20
  227. data/sig/inline_parser/comment_association.rbs +71 -0
  228. data/sig/inline_parser.rbs +126 -0
  229. data/sig/location.rbs +32 -7
  230. data/sig/locator.rbs +0 -2
  231. data/sig/manifest.yaml +0 -2
  232. data/sig/method_builder.rbs +9 -4
  233. data/sig/namespace.rbs +20 -5
  234. data/sig/parser.rbs +79 -15
  235. data/sig/prototype/helpers.rbs +2 -0
  236. data/sig/prototype/rbi.rbs +33 -4
  237. data/sig/resolver/type_name_resolver.rbs +36 -10
  238. data/sig/rewriter.rbs +45 -0
  239. data/sig/source.rbs +48 -0
  240. data/sig/type_param.rbs +13 -8
  241. data/sig/typename.rbs +15 -5
  242. data/sig/types.rbs +21 -9
  243. data/sig/unit_test/spy.rbs +0 -8
  244. data/sig/unit_test/type_assertions.rbs +17 -2
  245. data/sig/wasm/deserializer.rbs +66 -0
  246. data/sig/wasm/serialization_schema.rbs +13 -0
  247. data/src/ast.c +1644 -0
  248. data/src/lexer.c +3223 -0
  249. data/src/lexer.re +187 -0
  250. data/src/lexstate.c +222 -0
  251. data/src/location.c +31 -0
  252. data/src/parser.c +4318 -0
  253. data/src/serialize.c +965 -0
  254. data/src/string.c +41 -0
  255. data/src/util/rbs_allocator.c +171 -0
  256. data/src/util/rbs_assert.c +19 -0
  257. data/src/util/rbs_buffer.c +54 -0
  258. data/src/util/rbs_constant_pool.c +18 -92
  259. data/src/util/rbs_encoding.c +21454 -0
  260. data/src/util/rbs_unescape.c +167 -0
  261. data/stdlib/abbrev/0/array.rbs +1 -1
  262. data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
  263. data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
  264. data/stdlib/cgi/0/core.rbs +9 -393
  265. data/stdlib/cgi/0/manifest.yaml +1 -0
  266. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  267. data/stdlib/coverage/0/coverage.rbs +7 -4
  268. data/stdlib/csv/0/csv.rbs +5 -5
  269. data/stdlib/date/0/date.rbs +92 -79
  270. data/stdlib/date/0/date_time.rbs +25 -24
  271. data/stdlib/delegate/0/delegator.rbs +11 -7
  272. data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
  273. data/stdlib/digest/0/digest.rbs +117 -1
  274. data/stdlib/erb/0/erb.rbs +754 -353
  275. data/stdlib/etc/0/etc.rbs +73 -54
  276. data/stdlib/fileutils/0/fileutils.rbs +179 -160
  277. data/stdlib/forwardable/0/forwardable.rbs +13 -10
  278. data/stdlib/io-console/0/io-console.rbs +2 -2
  279. data/stdlib/ipaddr/0/ipaddr.rbs +0 -5
  280. data/stdlib/json/0/json.rbs +232 -185
  281. data/stdlib/monitor/0/monitor.rbs +9 -9
  282. data/stdlib/net-http/0/net-http.rbs +162 -134
  283. data/stdlib/objspace/0/objspace.rbs +17 -34
  284. data/stdlib/open-uri/0/open-uri.rbs +48 -8
  285. data/stdlib/open3/0/open3.rbs +469 -10
  286. data/stdlib/openssl/0/openssl.rbs +521 -397
  287. data/stdlib/optparse/0/optparse.rbs +26 -17
  288. data/stdlib/pathname/0/pathname.rbs +11 -1381
  289. data/stdlib/pp/0/pp.rbs +9 -8
  290. data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
  291. data/stdlib/pstore/0/pstore.rbs +35 -30
  292. data/stdlib/psych/0/psych.rbs +65 -12
  293. data/stdlib/psych/0/store.rbs +2 -4
  294. data/stdlib/pty/0/pty.rbs +9 -6
  295. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  296. data/stdlib/rdoc/0/code_object.rbs +4 -3
  297. data/stdlib/rdoc/0/comment.rbs +2 -0
  298. data/stdlib/rdoc/0/options.rbs +76 -0
  299. data/stdlib/rdoc/0/parser.rbs +1 -1
  300. data/stdlib/rdoc/0/rdoc.rbs +7 -5
  301. data/stdlib/rdoc/0/store.rbs +2 -2
  302. data/stdlib/resolv/0/resolv.rbs +26 -69
  303. data/stdlib/ripper/0/ripper.rbs +25 -19
  304. data/stdlib/securerandom/0/manifest.yaml +2 -0
  305. data/stdlib/securerandom/0/securerandom.rbs +7 -20
  306. data/stdlib/shellwords/0/shellwords.rbs +3 -3
  307. data/stdlib/singleton/0/singleton.rbs +6 -0
  308. data/stdlib/socket/0/addrinfo.rbs +9 -9
  309. data/stdlib/socket/0/basic_socket.rbs +3 -3
  310. data/stdlib/socket/0/ip_socket.rbs +10 -8
  311. data/stdlib/socket/0/socket.rbs +23 -10
  312. data/stdlib/socket/0/tcp_server.rbs +1 -1
  313. data/stdlib/socket/0/tcp_socket.rbs +11 -3
  314. data/stdlib/socket/0/udp_socket.rbs +1 -1
  315. data/stdlib/socket/0/unix_server.rbs +1 -1
  316. data/stdlib/stringio/0/stringio.rbs +1211 -96
  317. data/stdlib/strscan/0/string_scanner.rbs +101 -80
  318. data/stdlib/tempfile/0/manifest.yaml +3 -0
  319. data/stdlib/tempfile/0/tempfile.rbs +25 -21
  320. data/stdlib/time/0/time.rbs +8 -6
  321. data/stdlib/timeout/0/timeout.rbs +58 -7
  322. data/stdlib/tsort/0/cyclic.rbs +4 -1
  323. data/stdlib/tsort/0/interfaces.rbs +8 -8
  324. data/stdlib/tsort/0/tsort.rbs +16 -15
  325. data/stdlib/uri/0/common.rbs +42 -20
  326. data/stdlib/uri/0/file.rbs +3 -3
  327. data/stdlib/uri/0/generic.rbs +21 -18
  328. data/stdlib/uri/0/http.rbs +2 -2
  329. data/stdlib/uri/0/ldap.rbs +2 -2
  330. data/stdlib/uri/0/mailto.rbs +3 -3
  331. data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
  332. data/stdlib/zlib/0/deflate.rbs +4 -3
  333. data/stdlib/zlib/0/gzip_file.rbs +1 -1
  334. data/stdlib/zlib/0/gzip_reader.rbs +8 -8
  335. data/stdlib/zlib/0/gzip_writer.rbs +16 -13
  336. data/stdlib/zlib/0/inflate.rbs +1 -1
  337. data/stdlib/zlib/0/need_dict.rbs +1 -1
  338. data/wasm/README.md +109 -0
  339. data/wasm/rbs_wasm.c +479 -0
  340. metadata +133 -19
  341. data/ext/rbs_extension/lexer.c +0 -2728
  342. data/ext/rbs_extension/lexer.h +0 -179
  343. data/ext/rbs_extension/lexer.re +0 -147
  344. data/ext/rbs_extension/lexstate.c +0 -175
  345. data/ext/rbs_extension/location.c +0 -325
  346. data/ext/rbs_extension/location.h +0 -85
  347. data/ext/rbs_extension/parser.c +0 -2982
  348. data/ext/rbs_extension/parser.h +0 -18
  349. data/ext/rbs_extension/parserstate.c +0 -411
  350. data/ext/rbs_extension/parserstate.h +0 -163
  351. data/ext/rbs_extension/unescape.c +0 -32
  352. data/include/rbs/ruby_objs.h +0 -72
  353. data/src/constants.c +0 -153
  354. data/src/ruby_objs.c +0 -799
@@ -212,7 +212,6 @@ module RBS
212
212
 
213
213
  class DataGenerator < ValueObjectBase
214
214
  def self.generatable?(target)
215
- return false unless RUBY_VERSION >= '3.2'
216
215
  return false unless target < Data
217
216
  # Avoid direct inherited class like `class Option < Data`
218
217
  return false unless target.respond_to?(:members)
@@ -27,6 +27,10 @@ module RBS
27
27
  method_definition = @builder.build_singleton(module_name.absolute!).methods[method.name]
28
28
  return false unless method_definition
29
29
 
30
+ return false unless method_definition.defs.any? do |type_def|
31
+ type_def.implemented_in&.relative!.to_s == method.owner.to_s.delete_prefix("#<Class:").delete_suffix(">")
32
+ end
33
+
30
34
  method_definition.accessibility == accessibility
31
35
  end
32
36
 
@@ -36,6 +40,10 @@ module RBS
36
40
  method_definition = @builder.build_instance(module_name.absolute!).methods[method.name]
37
41
  return false unless method_definition
38
42
 
43
+ return false unless method_definition.defs.any? do |type_def|
44
+ type_def.implemented_in&.relative!.to_s == method.owner.to_s
45
+ end
46
+
39
47
  method_definition.accessibility == accessibility
40
48
  end
41
49
 
@@ -50,8 +58,8 @@ module RBS
50
58
  type_name_absolute = type_name.absolute!
51
59
  @mixin_decls_cache ||= {} #: Hash[TypeName, Array[AST::Members::Mixin]]
52
60
  @mixin_decls_cache.fetch(type_name_absolute) do
53
- @mixin_decls_cache[type_name_absolute] = @builder.env.class_decls[type_name_absolute].decls.flat_map do |d|
54
- d.decl.members.select { |m| m.kind_of?(AST::Members::Mixin) }
61
+ @mixin_decls_cache[type_name_absolute] = @builder.env.class_decls[type_name_absolute].each_decl.flat_map do |decl|
62
+ decl.members.select { |m| m.kind_of?(AST::Members::Mixin) }
55
63
  end
56
64
  end
57
65
  end
@@ -69,6 +77,8 @@ module RBS
69
77
  attr_accessor :outline
70
78
 
71
79
  def initialize(patterns:, env:, merge:, todo: false, owners_included: [])
80
+ Kernel.warn("RBS::Prototype::Runtime is deprecated. See https://github.com/ruby/rbs/issues/2841")
81
+
72
82
  @patterns = patterns
73
83
  @decls = nil
74
84
  @modules = {}
@@ -517,7 +527,7 @@ module RBS
517
527
 
518
528
  generate_mixin(mod, decl, type_name, type_name_absolute)
519
529
 
520
- unless mod < Struct || (RUBY_VERSION >= '3.2' && mod < Data)
530
+ unless mod < Struct || mod < Data
521
531
  generate_methods(mod, type_name, decl.members) unless outline
522
532
  end
523
533
 
@@ -32,7 +32,7 @@ module RBS
32
32
  end
33
33
 
34
34
  environment.class_alias_decls.each do |name, entry|
35
- normalized_entry = environment.normalized_module_class_entry(name) or next
35
+ normalized_entry = environment.module_class_entry(name, normalized: true) or next
36
36
  constant = constant_of_module(name, normalized_entry)
37
37
 
38
38
  # Insert class/module aliases into `children_table` and `toplevel` table
@@ -176,7 +176,7 @@ module RBS
176
176
  end
177
177
 
178
178
  def constants_from_ancestors(module_name, constants:)
179
- entry = builder.env.normalized_module_class_entry(module_name) or raise
179
+ entry = builder.env.module_class_entry(module_name, normalized: true) or raise
180
180
 
181
181
  if entry.is_a?(Environment::ClassEntry) || entry.is_a?(Environment::ModuleEntry)
182
182
  constants.merge!(table.children(BuiltinNames::Object.name) || raise)
@@ -5,85 +5,161 @@ module RBS
5
5
  class TypeNameResolver
6
6
  attr_reader :all_names
7
7
  attr_reader :cache
8
- attr_reader :env
8
+ attr_reader :aliases
9
9
 
10
- def initialize(env)
11
- @all_names = Set[]
10
+ def initialize(all_names, aliases)
11
+ @all_names = all_names
12
+ @aliases = aliases
12
13
  @cache = {}
13
- @env = env
14
+ end
15
+
16
+ def self.build(env)
17
+ all_names = Set.new #: Set[TypeName]
14
18
 
15
19
  all_names.merge(env.class_decls.keys)
16
20
  all_names.merge(env.interface_decls.keys)
17
21
  all_names.merge(env.type_alias_decls.keys)
18
- all_names.merge(env.class_alias_decls.keys)
19
- end
20
22
 
21
- def try_cache(query)
22
- cache.fetch(query) do
23
- result = yield
24
- cache[query] = result
23
+ aliases = {} #: Hash[TypeName, [TypeName, context]]
24
+
25
+ env.class_alias_decls.each do |name, entry|
26
+ aliases[name] = [entry.decl.old_name, entry.context]
25
27
  end
28
+
29
+ new(all_names, aliases)
30
+ end
31
+
32
+ def try_cache(type_name, context)
33
+ inner = cache[context] ||= {}
34
+ inner.fetch(type_name) { inner[type_name] = yield }
26
35
  end
27
36
 
28
37
  def resolve(type_name, context:)
29
- if type_name.absolute?
38
+ if type_name.absolute? && has_type_name?(type_name)
30
39
  return type_name
31
40
  end
32
41
 
33
- try_cache([type_name, context]) do
34
- head, tail = partition(type_name)
35
-
36
- head = resolve_in(head, context)
42
+ try_cache(type_name, context) do
43
+ if type_name.class?
44
+ resolve_namespace0(type_name, context, Set.new) || nil
45
+ else
46
+ namespace = type_name.namespace
37
47
 
38
- if head
39
- if tail
40
- absolute_name = tail.with_prefix(head.to_namespace)
41
- if env.normalize_type_name?(absolute_name)
42
- absolute_name
43
- end
48
+ if namespace.empty?
49
+ resolve_type_name(type_name.name, context)
44
50
  else
45
- head
51
+ if namespace = resolve_namespace0(namespace.to_type_name, context, Set.new)
52
+ type_name = TypeName[namespace.to_namespace, type_name.name]
53
+ has_type_name?(type_name)
54
+ end
46
55
  end
47
56
  end
48
57
  end
49
58
  end
50
59
 
51
- def partition(type_name)
52
- if type_name.namespace.empty?
53
- head = type_name.name
54
- tail = nil
55
- else
56
- head, *tail = type_name.namespace.path
60
+ def resolve_namespace(type_name, context:)
61
+ if type_name.absolute? && has_type_name?(type_name)
62
+ return type_name
63
+ end
57
64
 
58
- head or raise
65
+ unless type_name.class?
66
+ raise "Type name must be a class name: #{type_name}"
67
+ end
59
68
 
60
- tail = TypeName.new(
61
- name: type_name.name,
62
- namespace: Namespace.new(absolute: false, path: tail)
63
- )
69
+ try_cache(type_name, context) do
70
+ ns = resolve_namespace0(type_name, context, Set.new) or return ns
64
71
  end
72
+ end
65
73
 
66
- [head, tail]
74
+ def has_type_name?(full_name)
75
+ if all_names.include?(full_name)
76
+ full_name
77
+ end
67
78
  end
68
79
 
69
- def resolve_in(head, context)
80
+ def aliased_name?(type_name)
81
+ if aliases.key?(type_name)
82
+ type_name
83
+ end
84
+ end
85
+
86
+ def resolve_type_name(type_name, context)
70
87
  if context
71
- parent, child = context
72
- case child
88
+ outer, inner = context
89
+ case inner
73
90
  when false
74
- resolve_in(head, parent)
91
+ resolve_type_name(type_name, outer)
92
+ else
93
+ has_type_name?(inner) or raise "Context must be normalized: #{inner.inspect}"
94
+ has_type_name?(TypeName[inner.to_namespace, type_name]) || resolve_type_name(type_name, outer)
95
+ end
96
+ else
97
+ type_name = TypeName[Namespace.root, type_name]
98
+ has_type_name?(type_name)
99
+ end
100
+ end
101
+
102
+ def resolve_head_namespace(head, context)
103
+ if context
104
+ outer, inner = context
105
+ case inner
106
+ when false
107
+ resolve_head_namespace(head, outer)
75
108
  when TypeName
76
- name = TypeName.new(name: head, namespace: child.to_namespace)
77
- has_name?(name) || resolve_in(head, parent)
109
+ has_type_name?(inner) or raise "Context must be normalized: #{inner.inspect}"
110
+ type_name = TypeName[inner.to_namespace, head]
111
+ has_type_name?(type_name) || aliased_name?(type_name) || resolve_head_namespace(head, outer)
78
112
  end
79
113
  else
80
- has_name?(TypeName.new(name: head, namespace: Namespace.root))
114
+ type_name = TypeName[Namespace.root, head]
115
+ has_type_name?(type_name) || aliased_name?(type_name)
81
116
  end
82
117
  end
83
118
 
84
- def has_name?(full_name)
85
- if all_names.include?(full_name)
86
- full_name
119
+ def normalize_namespace(type_name, rhs, context, visited)
120
+ if visited.include?(type_name)
121
+ # Cycle detected
122
+ return false
123
+ end
124
+
125
+ visited << type_name
126
+
127
+ begin
128
+ resolve_namespace0(rhs, context, visited)
129
+ ensure
130
+ visited.delete(type_name)
131
+ end
132
+ end
133
+
134
+ def resolve_namespace0(type_name, context, visited)
135
+ head, *tail = [*type_name.namespace.path, type_name.name]
136
+
137
+ head = head #: Symbol
138
+
139
+ head =
140
+ if type_name.absolute?
141
+ root_name = TypeName[Namespace.root, head]
142
+ has_type_name?(root_name) || aliased_name?(root_name)
143
+ else
144
+ resolve_head_namespace(head, context)
145
+ end
146
+
147
+ if head
148
+ if (rhs, context = aliases.fetch(head, nil))
149
+ head = normalize_namespace(head, rhs, context, visited) or return head
150
+ end
151
+
152
+ tail.inject(head) do |namespace, name|
153
+ type_name = TypeName[namespace.to_namespace, name]
154
+ case
155
+ when has_type_name?(type_name)
156
+ type_name
157
+ when (rhs, context = aliases.fetch(type_name, nil))
158
+ m = normalize_namespace(type_name, rhs, context, visited) or return m
159
+ else
160
+ return nil
161
+ end
162
+ end
87
163
  end
88
164
  end
89
165
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class Rewriter
5
+ attr_reader :buffer
6
+
7
+ def initialize(buffer)
8
+ raise "Rewriter only supports toplevel buffers" if buffer.parent
9
+
10
+ @buffer = buffer
11
+ @rewrites = []
12
+ end
13
+
14
+ def rewrite(location, string)
15
+ @rewrites.each do |existing_location, _|
16
+ if location.start_pos < existing_location.end_pos && existing_location.start_pos < location.end_pos
17
+ raise "Overlapping rewrites: #{existing_location} and #{location}"
18
+ end
19
+ end
20
+
21
+ @rewrites << [location, string]
22
+ self
23
+ end
24
+
25
+ def add_comment(*locations, content:)
26
+ earliest = locations.min_by(&:start_pos) or raise "At least one location is required"
27
+ insert_pos = earliest.start_pos
28
+ indent = " " * earliest.start_column
29
+
30
+ formatted = format_comment(content, indent)
31
+
32
+ loc = Location.new(buffer, insert_pos, insert_pos)
33
+ rewrite(loc, "#{formatted}\n#{indent}")
34
+ end
35
+
36
+ def replace_comment(comment, content:)
37
+ location = comment.location or raise "Comment must have a location"
38
+ indent = " " * location.start_column
39
+
40
+ rewrite(location, format_comment(content, indent))
41
+ end
42
+
43
+ def delete_comment(comment)
44
+ location = comment.location or raise "Comment must have a location"
45
+ line_start = location.start_pos - location.start_column
46
+ line_end = location.end_pos + 1
47
+ loc = Location.new(buffer, line_start, line_end)
48
+ rewrite(loc, "")
49
+ end
50
+
51
+ def string
52
+ result = buffer.content.dup
53
+
54
+ @rewrites.sort_by { |location, _| location.start_pos }.reverse_each do |location, replacement|
55
+ result[location.start_pos...location.end_pos] = replacement
56
+ end
57
+
58
+ result
59
+ end
60
+
61
+ private
62
+
63
+ def format_comment(content, indent)
64
+ content.lines.map do |line|
65
+ line = line.chomp
66
+ line.empty? ? "#" : "# #{line}"
67
+ end.join("\n#{indent}")
68
+ end
69
+ end
70
+ end
data/lib/rbs/source.rb ADDED
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module Source
5
+ class RBS
6
+ attr_reader :buffer, :directives, :declarations
7
+
8
+ def initialize(buffer, directives, decls)
9
+ @buffer = buffer
10
+ @directives = directives
11
+ @declarations = decls
12
+ end
13
+
14
+ def each_type_name(&block)
15
+ if block
16
+ set = Set[] #: Set[TypeName]
17
+ declarations.each do |decl|
18
+ each_declaration_type_name(set, decl, &block)
19
+ end
20
+ else
21
+ enum_for :each_type_name
22
+ end
23
+ end
24
+
25
+ def each_declaration_type_name(names, decl, &block)
26
+ case decl
27
+ when AST::Declarations::Class
28
+ decl.each_decl { each_declaration_type_name(names, _1, &block) }
29
+ type_name = decl.name
30
+ when AST::Declarations::Module
31
+ decl.each_decl { each_declaration_type_name(names, _1, &block) }
32
+ type_name = decl.name
33
+ when AST::Declarations::Interface
34
+ type_name = decl.name
35
+ when AST::Declarations::TypeAlias
36
+ type_name = decl.name
37
+ when AST::Declarations::ModuleAlias
38
+ type_name = decl.new_name
39
+ when AST::Declarations::ClassAlias
40
+ type_name = decl.new_name
41
+ end
42
+
43
+ if type_name
44
+ unless names.include?(type_name)
45
+ yield type_name
46
+ names << type_name
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ class Ruby
53
+ attr_reader :buffer
54
+ attr_reader :prism_result
55
+ attr_reader :declarations
56
+ attr_reader :diagnostics
57
+
58
+ def initialize(buffer, prism, declarations, diagnostics)
59
+ @buffer = buffer
60
+ @prism_result = prism
61
+ @declarations = declarations
62
+ @diagnostics = diagnostics
63
+ end
64
+
65
+ def each_type_name(&block)
66
+ if block
67
+ names = Set[] #: Set[TypeName]
68
+ declarations.each do |decl|
69
+ each_declaration_type_name(names, decl, &block)
70
+ end
71
+ else
72
+ enum_for :each_type_name
73
+ end
74
+ end
75
+
76
+ def each_declaration_type_name(names, decl, &block)
77
+ case decl
78
+ when AST::Ruby::Declarations::ClassDecl
79
+ decl.each_decl do |d|
80
+ each_declaration_type_name(names, d, &block)
81
+ end
82
+ type_name = decl.class_name
83
+ when AST::Ruby::Declarations::ModuleDecl
84
+ decl.each_decl do |d|
85
+ each_declaration_type_name(names, d, &block)
86
+ end
87
+ type_name = decl.module_name
88
+ end
89
+
90
+ if type_name
91
+ unless names.include?(type_name)
92
+ yield type_name
93
+ names << type_name
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -107,7 +107,9 @@ module RBS
107
107
  each_member(owner).any? do |m|
108
108
  case m
109
109
  when AST::Members::InstanceVariable
110
- m.name == name
110
+ m.name == name && kind == :instance
111
+ when AST::Members::ClassInstanceVariable
112
+ m.name == name && kind == :singleton
111
113
  when AST::Members::Attribute
112
114
  ivar_name = m.ivar_name == false ? nil : m.ivar_name || :"@#{m.name}"
113
115
  ivar_name == name && m.kind == kind
@@ -129,9 +131,10 @@ module RBS
129
131
 
130
132
  entry = @subtrahend.class_decls[owner]
131
133
  return unless entry
132
- decls = entry.decls.map { |d| d.decl }
133
-
134
- decls.each { |d| d.members.each { |m| block.call(m) } }
134
+ entry.each_decl do |d|
135
+ next unless d.is_a?(AST::Declarations::Base)
136
+ d.members.each { |m| block.call(m) }
137
+ end
135
138
  end
136
139
 
137
140
  private def mixin_exist?(owner, mixin, context:)
@@ -245,7 +245,7 @@ module RBS
245
245
  when Types::Bases::Any
246
246
  true
247
247
  when Types::Bases::Bool
248
- val.is_a?(TrueClass) || val.is_a?(FalseClass)
248
+ Test.call(val, IS_AP, TrueClass) || Test.call(val, IS_AP, FalseClass)
249
249
  when Types::Bases::Top
250
250
  true
251
251
  when Types::Bases::Bottom
@@ -264,6 +264,9 @@ module RBS
264
264
  klass = get_class(type.name) or return false
265
265
  if params = builder.env.normalized_module_class_entry(type.name.absolute!)&.type_params
266
266
  args = AST::TypeParam.normalize_args(params, type.args)
267
+ if args.size != params.size
268
+ return false
269
+ end
267
270
  unless args == type.args
268
271
  type = Types::ClassInstance.new(name: type.name, args: args, location: type.location)
269
272
  end
@@ -288,6 +291,19 @@ module RBS
288
291
  values << args
289
292
  nil
290
293
  end
294
+ when nil
295
+ values = []
296
+ count = 10_000
297
+
298
+ ret = val.each do |*args|
299
+ count -= 1
300
+ values << args
301
+ break if count <= 0
302
+ end
303
+
304
+ if count == 0
305
+ ret = self
306
+ end
291
307
  else
292
308
  values = []
293
309
  ret = val.each do |*args|
@@ -323,7 +339,7 @@ module RBS
323
339
  rescue TypeError
324
340
  return false
325
341
  end
326
- val.is_a?(singleton_class)
342
+ Test.call(val, IS_AP, singleton_class)
327
343
  when Types::Interface
328
344
  if (definition = builder.build_interface(type.name.absolute!))
329
345
  definition.methods.each.all? do |method_name, method|
@@ -340,7 +356,12 @@ module RBS
340
356
  when Types::Variable
341
357
  true
342
358
  when Types::Literal
343
- type.literal == val
359
+ begin
360
+ type.literal == val
361
+ rescue NoMethodError
362
+ raise if defined?(val.==)
363
+ false
364
+ end
344
365
  when Types::Union
345
366
  type.types.any? {|type| value(val, type) }
346
367
  when Types::Intersection
@@ -351,6 +372,7 @@ module RBS
351
372
  value(val, builder.expand_alias2(type.name.absolute!, type.args))
352
373
  when Types::Tuple
353
374
  Test.call(val, IS_AP, ::Array) &&
375
+ type.types.length == val.length &&
354
376
  type.types.map.with_index {|ty, index| value(val[index], ty) }.all?
355
377
  when Types::Record
356
378
  Test::call(val, IS_AP, ::Hash) &&
data/lib/rbs/type_name.rb CHANGED
@@ -22,21 +22,47 @@ module RBS
22
22
  end
23
23
  end
24
24
 
25
+ # Process-wide flyweight cache. Two-level Hash keyed by canonical
26
+ # Namespace identity (outer uses `compare_by_identity`) and name
27
+ # Symbol.
28
+ @intern_mutex = Mutex.new
29
+ @intern_cache = {} #: Hash[Namespace, Hash[Symbol, TypeName]]
30
+ @intern_cache.compare_by_identity
31
+
32
+ # Returns a canonical `TypeName` instance for the given `namespace` /
33
+ # `name` pair. The namespace is canonicalized through `Namespace.[]`
34
+ # so identity-based lookup works regardless of the caller passing a
35
+ # fresh `Namespace.new` or an already-interned instance.
36
+ def self.[](namespace, name)
37
+ ns = Namespace[namespace.path, namespace.absolute?]
38
+
39
+ inner = @intern_cache[ns]
40
+ if inner && (cached = inner[name])
41
+ return cached
42
+ end
43
+
44
+ @intern_mutex.synchronize do
45
+ inner = (@intern_cache[ns] ||= {})
46
+ inner[name] ||= new(namespace: ns, name: name)
47
+ end
48
+ end
49
+
25
50
  def ==(other)
51
+ return true if equal?(other)
26
52
  other.is_a?(self.class) && other.namespace == namespace && other.name == name
27
53
  end
28
54
 
29
55
  alias eql? ==
30
56
 
31
57
  def hash
32
- namespace.hash ^ name.hash
58
+ @hash ||= namespace.hash ^ name.hash
33
59
  end
34
60
 
35
61
  def to_s
36
62
  "#{namespace.to_s}#{name}"
37
63
  end
38
64
 
39
- def to_json(state = _ = nil)
65
+ def to_json(state = nil)
40
66
  to_s.to_json(state)
41
67
  end
42
68
 
@@ -53,7 +79,7 @@ module RBS
53
79
  end
54
80
 
55
81
  def absolute!
56
- self.class.new(namespace: namespace.absolute!, name: name)
82
+ TypeName[namespace.absolute!, name]
57
83
  end
58
84
 
59
85
  def absolute?
@@ -61,7 +87,7 @@ module RBS
61
87
  end
62
88
 
63
89
  def relative!
64
- self.class.new(namespace: namespace.relative!, name: name)
90
+ TypeName[namespace.relative!, name]
65
91
  end
66
92
 
67
93
  def interface?
@@ -69,7 +95,7 @@ module RBS
69
95
  end
70
96
 
71
97
  def with_prefix(namespace)
72
- self.class.new(namespace: namespace + self.namespace, name: name)
98
+ TypeName[namespace + self.namespace, name]
73
99
  end
74
100
 
75
101
  def split
@@ -80,30 +106,17 @@ module RBS
80
106
  if other.absolute?
81
107
  other
82
108
  else
83
- TypeName.new(
84
- namespace: self.to_namespace + other.namespace,
85
- name: other.name
86
- )
109
+ TypeName[self.to_namespace + other.namespace, other.name]
87
110
  end
88
111
  end
89
-
112
+
90
113
  def self.parse(string)
91
114
  absolute = string.start_with?("::")
92
115
 
93
116
  *path, name = string.delete_prefix("::").split("::").map(&:to_sym)
94
117
  raise unless name
95
118
 
96
- TypeName.new(
97
- name: name,
98
- namespace: RBS::Namespace.new(path: path, absolute: absolute)
99
- )
119
+ TypeName[Namespace[path, absolute], name]
100
120
  end
101
121
  end
102
122
  end
103
-
104
- module Kernel
105
- def TypeName(string)
106
- warn "Kernel#TypeName() is deprecated. Use RBS::TypeName.parse instead.", category: :deprecated
107
- RBS::TypeName.parse(string)
108
- end
109
- end