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
data/lib/rbs/namespace.rb CHANGED
@@ -9,30 +9,65 @@ module RBS
9
9
  @absolute = absolute ? true : false
10
10
  end
11
11
 
12
+ # Process-wide flyweight cache. Two tries (one per `absolute` flag)
13
+ # keyed on path Symbols, with the cached Namespace stored under the
14
+ # `INTERN_LEAF` sentinel at each path's terminal node.
15
+ @intern_mutex = Mutex.new
16
+ @intern_trie_absolute = {}
17
+ @intern_trie_relative = {}
18
+ INTERN_LEAF = Module.new
19
+
20
+ # Returns a canonical `Namespace` instance for the given `path` /
21
+ # `absolute` pair. Repeated calls with structurally equal arguments
22
+ # return the same object, so callers can rely on `equal?` for fast
23
+ # equality. The path Array is duplicated and frozen on insert.
24
+ def self.[](path, absolute)
25
+ absolute = absolute ? true : false
26
+
27
+ # Lock-free fast path.
28
+ node = absolute ? @intern_trie_absolute : @intern_trie_relative
29
+ path.each do |sym|
30
+ node = node[sym]
31
+ break unless node
32
+ end
33
+ if node && (cached = node[INTERN_LEAF])
34
+ return cached
35
+ end
36
+
37
+ @intern_mutex.synchronize do
38
+ node = absolute ? @intern_trie_absolute : @intern_trie_relative
39
+ path.each { |sym| node = (node[sym] ||= {}) }
40
+ node[INTERN_LEAF] ||= begin
41
+ frozen_path = path.frozen? ? path : path.dup.freeze
42
+ new(path: frozen_path, absolute: absolute)
43
+ end
44
+ end
45
+ end
46
+
12
47
  def self.empty
13
- @empty ||= new(path: [], absolute: false)
48
+ @empty ||= self[[], false]
14
49
  end
15
50
 
16
51
  def self.root
17
- @root ||= new(path: [], absolute: true)
52
+ @root ||= self[[], true]
18
53
  end
19
54
 
20
55
  def +(other)
21
56
  if other.absolute?
22
57
  other
23
58
  else
24
- self.class.new(path: path + other.path, absolute: absolute?)
59
+ Namespace[path + other.path, absolute?]
25
60
  end
26
61
  end
27
62
 
28
63
  def append(component)
29
- self.class.new(path: path + [component], absolute: absolute?)
64
+ Namespace[path + [component], absolute?]
30
65
  end
31
66
 
32
67
  def parent
33
68
  @parent ||= begin
34
69
  raise "Parent with empty namespace" if empty?
35
- self.class.new(path: path.take(path.size - 1), absolute: absolute?)
70
+ Namespace[path.take(path.size - 1), absolute?]
36
71
  end
37
72
  end
38
73
 
@@ -45,11 +80,11 @@ module RBS
45
80
  end
46
81
 
47
82
  def absolute!
48
- self.class.new(path: path, absolute: true)
83
+ Namespace[path, true]
49
84
  end
50
85
 
51
86
  def relative!
52
- self.class.new(path: path, absolute: false)
87
+ Namespace[path, false]
53
88
  end
54
89
 
55
90
  def empty?
@@ -57,13 +92,14 @@ module RBS
57
92
  end
58
93
 
59
94
  def ==(other)
95
+ return true if equal?(other)
60
96
  other.is_a?(Namespace) && other.path == path && other.absolute? == absolute?
61
97
  end
62
98
 
63
99
  alias eql? ==
64
100
 
65
101
  def hash
66
- path.hash ^ absolute?.hash
102
+ @hash ||= path.hash ^ absolute?.hash
67
103
  end
68
104
 
69
105
  def split
@@ -87,14 +123,14 @@ module RBS
87
123
  raise unless name
88
124
  raise unless parent
89
125
 
90
- TypeName.new(name: name, namespace: parent)
126
+ TypeName[parent, name]
91
127
  end
92
128
 
93
129
  def self.parse(string)
94
130
  if string.start_with?("::")
95
- new(path: string.split("::").drop(1).map(&:to_sym), absolute: true)
131
+ self[string.split("::").drop(1).map(&:to_sym), true]
96
132
  else
97
- new(path: string.split("::").map(&:to_sym), absolute: false)
133
+ self[string.split("::").map(&:to_sym), false]
98
134
  end
99
135
  end
100
136
 
@@ -116,10 +152,3 @@ module RBS
116
152
  end
117
153
  end
118
154
  end
119
-
120
- module Kernel
121
- def Namespace(name)
122
- warn "Kernel#Namespace() is deprecated. Use RBS::Namespace.parse instead.", category: :deprecated
123
- RBS::Namespace.parse(name)
124
- end
125
- end
@@ -5,14 +5,16 @@ require_relative "parser/token"
5
5
 
6
6
  module RBS
7
7
  class Parser
8
- def self.parse_type(source, range: 0..., variables: [], require_eof: false)
8
+ def self.parse_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false, void_allowed: true, self_allowed: true, classish_allowed: true)
9
9
  buf = buffer(source)
10
- _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
10
+ byte_range = byte_range(range, buf.content) if range
11
+ _parse_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof, void_allowed, self_allowed, classish_allowed)
11
12
  end
12
13
 
13
- def self.parse_method_type(source, range: 0..., variables: [], require_eof: false)
14
+ def self.parse_method_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false)
14
15
  buf = buffer(source)
15
- _parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
16
+ byte_range = byte_range(range, buf.content) if range
17
+ _parse_method_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof, false)
16
18
  end
17
19
 
18
20
  def self.parse_signature(source)
@@ -25,7 +27,8 @@ module RBS
25
27
  else
26
28
  0
27
29
  end
28
- dirs, decls = _parse_signature(buf, start_pos, buf.last_position)
30
+ content = buf.content
31
+ dirs, decls = _parse_signature(buf, start_pos, content.bytesize, false)
29
32
 
30
33
  if resolved
31
34
  dirs = dirs.dup if dirs.frozen?
@@ -35,6 +38,11 @@ module RBS
35
38
  [buf, dirs, decls]
36
39
  end
37
40
 
41
+ def self.parse_type_params(source, module_type_params: true)
42
+ buf = buffer(source)
43
+ _parse_type_params(buf, 0, buf.content.bytesize, module_type_params)
44
+ end
45
+
38
46
  def self.magic_comment(buf)
39
47
  start_pos = 0
40
48
 
@@ -61,7 +69,7 @@ module RBS
61
69
 
62
70
  def self.lex(source)
63
71
  buf = buffer(source)
64
- list = _lex(buf, buf.last_position)
72
+ list = _lex(buf, buf.content.bytesize)
65
73
  value = list.map do |type, location|
66
74
  Token.new(type: type, location: location)
67
75
  end
@@ -71,7 +79,7 @@ module RBS
71
79
  def self.buffer(source)
72
80
  case source
73
81
  when String
74
- Buffer.new(content: source, name: "a.rbs")
82
+ Buffer.new(content: source, name: Pathname("a.rbs"))
75
83
  when Buffer
76
84
  source
77
85
  end
@@ -110,5 +118,27 @@ module RBS
110
118
  ).each_with_object({}) do |keyword, hash| #$ Hash[String, bot]
111
119
  hash[keyword] = _ = nil
112
120
  end
121
+
122
+ def self.parse_inline_leading_annotation(source, range, variables: [])
123
+ buf = buffer(source)
124
+ byte_range = byte_range(range, buf.content)
125
+ _parse_inline_leading_annotation(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables)
126
+ end
127
+
128
+ def self.parse_inline_trailing_annotation(source, range, variables: [])
129
+ buf = buffer(source)
130
+ byte_range = byte_range(range, buf.content)
131
+ _parse_inline_trailing_annotation(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables)
132
+ end
133
+
134
+ def self.byte_range(char_range, content)
135
+ start_offset = char_range.begin
136
+ end_offset = char_range.end
137
+
138
+ start_prefix = content[0, start_offset] or raise if start_offset
139
+ end_prefix = content[0, end_offset] or raise if end_offset
140
+
141
+ start_prefix&.bytesize...end_prefix&.bytesize
142
+ end
113
143
  end
114
144
  end
@@ -5,6 +5,30 @@ module RBS
5
5
  module Helpers
6
6
  private
7
7
 
8
+ def parse_comments(string, include_trailing:)
9
+ Prism.parse_comments(string, version: "current").yield_self do |prism_comments| # steep:ignore UnexpectedKeywordArgument
10
+ prism_comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment]
11
+ # Skip EmbDoc comments
12
+ next unless comment.is_a?(Prism::InlineComment)
13
+ # skip like `module Foo # :nodoc:`
14
+ next if comment.trailing? && !include_trailing
15
+
16
+ line = comment.location.start_line
17
+ body = "#{comment.location.slice}\n"
18
+ body = body[2..-1] or raise
19
+ body = "\n" if body.empty?
20
+
21
+ comment = AST::Comment.new(string: body, location: nil)
22
+ if prev_comment = hash.delete(line - 1)
23
+ hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
24
+ location: nil)
25
+ else
26
+ hash[line] = comment
27
+ end
28
+ end
29
+ end
30
+ end
31
+
8
32
  def block_from_body(node)
9
33
  _, args_node, body_node = node.children
10
34
  _pre_num, _pre_init, _opt, _first_post, _post_num, _post_init, _rest, _kw, _kwrest, block_var = args_from_node(args_node)
@@ -74,32 +74,7 @@ module RBS
74
74
 
75
75
  def parse(string)
76
76
  # @type var comments: Hash[Integer, AST::Comment]
77
- comments = Ripper.lex(string).yield_self do |tokens|
78
- code_lines = {} #: Hash[Integer, bool]
79
- tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
80
- case token[1]
81
- when :on_sp, :on_ignored_nl
82
- # skip
83
- when :on_comment
84
- line = token[0][0]
85
- # skip like `module Foo # :nodoc:`
86
- next if code_lines[line]
87
- body = token[2][2..-1] or raise
88
-
89
- body = "\n" if body.empty?
90
-
91
- comment = AST::Comment.new(string: body, location: nil)
92
- if prev_comment = hash.delete(line - 1)
93
- hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
94
- location: nil)
95
- else
96
- hash[line] = comment
97
- end
98
- else
99
- code_lines[token[0][0]] = true
100
- end
101
- end
102
- end
77
+ comments = parse_comments(string, include_trailing: false)
103
78
 
104
79
  process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, context: Context.initial
105
80
  end
@@ -372,8 +347,8 @@ module RBS
372
347
  end
373
348
 
374
349
  value_node = node.children.last
375
- type = if value_node.nil?
376
- # Give up type prediction when node is MASGN.
350
+ type = if value_node.nil? || value_node.type == :SELF
351
+ # Give up type prediction when node is MASGN or SELF.
377
352
  Types::Bases::Any.new(location: nil)
378
353
  else
379
354
  literal_to_type(value_node)
@@ -9,49 +9,40 @@ module RBS
9
9
  attr_reader :modules
10
10
  attr_reader :last_sig
11
11
 
12
+ class Context
13
+ attr_accessor :singleton
14
+ attr_accessor :visibility
15
+
16
+ def initialize(singleton:, visibility:)
17
+ @singleton = singleton
18
+ @visibility = visibility
19
+ end
20
+ end
21
+
12
22
  def initialize
13
23
  @decls = []
14
24
 
15
25
  @modules = []
26
+ @contexts = []
27
+ @emitted_visibility = {}
16
28
  end
17
29
 
18
30
  def parse(string)
19
- comments = Ripper.lex(string).yield_self do |tokens|
20
- tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
21
- if token[1] == :on_comment
22
- line = token[0][0]
23
- body = token[2][2..-1] or raise
24
-
25
- body = "\n" if body.empty?
26
-
27
- comment = AST::Comment.new(string: body, location: nil)
28
- if (prev_comment = hash.delete(line - 1))
29
- hash[line] = AST::Comment.new(
30
- string: prev_comment.string + comment.string,
31
- location: nil
32
- )
33
- else
34
- hash[line] = comment
35
- end
36
- end
37
- end
38
- end
31
+ comments = parse_comments(string, include_trailing: true)
39
32
  process RubyVM::AbstractSyntaxTree.parse(string), comments: comments
40
33
  end
41
34
 
42
- def nested_name(name)
43
- (current_namespace + const_to_name(name).to_namespace).to_type_name.relative!
44
- end
45
-
46
- def current_namespace
47
- modules.inject(Namespace.empty) do |parent, mod|
48
- parent + mod.name.to_namespace
35
+ def append_decl(decl)
36
+ if mod = current_module
37
+ mod.members << decl
38
+ else
39
+ decls << decl
49
40
  end
50
41
  end
51
42
 
52
43
  def push_class(name, super_class, comment:)
53
44
  class_decl = AST::Declarations::Class.new(
54
- name: nested_name(name),
45
+ name: const_to_name(name),
55
46
  super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
56
47
  type_params: [],
57
48
  members: [],
@@ -60,17 +51,20 @@ module RBS
60
51
  comment: comment
61
52
  )
62
53
 
54
+ append_decl class_decl
63
55
  modules << class_decl
64
- decls << class_decl
56
+ @contexts << Context.new(singleton: false, visibility: :public)
57
+ @emitted_visibility[class_decl.object_id] = :public
65
58
 
66
59
  yield
67
60
  ensure
61
+ @contexts.pop
68
62
  modules.pop
69
63
  end
70
64
 
71
65
  def push_module(name, comment:)
72
66
  module_decl = AST::Declarations::Module.new(
73
- name: nested_name(name),
67
+ name: const_to_name(name),
74
68
  type_params: [],
75
69
  members: [],
76
70
  annotations: [],
@@ -79,11 +73,14 @@ module RBS
79
73
  comment: comment
80
74
  )
81
75
 
76
+ append_decl module_decl
82
77
  modules << module_decl
83
- decls << module_decl
78
+ @contexts << Context.new(singleton: false, visibility: :public)
79
+ @emitted_visibility[module_decl.object_id] = :public
84
80
 
85
81
  yield
86
82
  ensure
83
+ @contexts.pop
87
84
  modules.pop
88
85
  end
89
86
 
@@ -95,6 +92,47 @@ module RBS
95
92
  current_module or raise
96
93
  end
97
94
 
95
+ def current_context
96
+ @contexts.last
97
+ end
98
+
99
+ def current_context!
100
+ current_context or raise
101
+ end
102
+
103
+ # Visibility of a member, given as `private def ...` in RBS
104
+ #
105
+ # Returns `nil` for members in a visibility _section_, which `sync_visibility` emits instead.
106
+ def member_visibility(context)
107
+ # RBS visibility sections don't apply to singleton members, so they need their own visibility.
108
+ if context.singleton && context.visibility != :public
109
+ :private
110
+ end
111
+ end
112
+
113
+ def sync_visibility(visibility)
114
+ # Visibility sections don't apply to singleton members in RBS.
115
+ return if current_context!.singleton
116
+
117
+ # RBS has no protected visibility. Private is the conservative fallback.
118
+ visibility = :private if visibility == :protected
119
+
120
+ mod = current_module!
121
+ return if @emitted_visibility[mod.object_id] == visibility
122
+
123
+ member = case visibility
124
+ when :public
125
+ AST::Members::Public.new(location: nil)
126
+ when :private
127
+ AST::Members::Private.new(location: nil)
128
+ else
129
+ raise "Unexpected visibility: #{visibility}"
130
+ end
131
+
132
+ mod.members << member
133
+ @emitted_visibility[mod.object_id] = visibility
134
+ end
135
+
98
136
  def push_sig(node)
99
137
  if last_sig = @last_sig
100
138
  last_sig << node
@@ -126,6 +164,15 @@ module RBS
126
164
  push_module node.children[0], comment: comment do
127
165
  process node.children[1], outer: outer + [node], comments: comments
128
166
  end
167
+ when :SCLASS
168
+ if node.children[0].type == :SELF
169
+ @contexts << Context.new(singleton: true, visibility: :public)
170
+ begin
171
+ process node.children[1], outer: outer + [node], comments: comments
172
+ ensure
173
+ @contexts.pop
174
+ end
175
+ end
129
176
  when :FCALL
130
177
  case node.children[0]
131
178
  when :include
@@ -144,9 +191,9 @@ module RBS
144
191
  end
145
192
  when :extend
146
193
  each_arg node.children[1] do |arg|
147
- if arg.type == :CONST || arg.type == :COLON2
194
+ if arg.type == :CONST || arg.type == :COLON2 || arg.type == :COLON3
148
195
  name = const_to_name(arg)
149
- unless name.to_s == "T::Generic" || name.to_s == "T::Sig"
196
+ unless ["T::Generic", "T::Helpers", "T::Sig"].include?(name.to_s.delete_prefix("::"))
150
197
  member = AST::Members::Extend.new(
151
198
  name: name,
152
199
  args: [],
@@ -161,6 +208,10 @@ module RBS
161
208
  when :sig
162
209
  out = outer.last or raise
163
210
  push_sig out.children.last.children.last
211
+ when :attr_reader, :attr_writer, :attr_accessor
212
+ process_attribute node, comments: comments
213
+ when :private, :protected, :public
214
+ process_visibility node, outer: outer, comments: comments
164
215
  when :alias_method
165
216
  new, old = each_arg(node.children[1]).map {|x| x.children[0] }
166
217
  current_module!.members << AST::Members::Alias.new(
@@ -168,10 +219,15 @@ module RBS
168
219
  old_name: old,
169
220
  location: nil,
170
221
  annotations: [],
171
- kind: :instance,
222
+ kind: current_context!.singleton ? :singleton : :instance,
172
223
  comment: nil
173
224
  )
174
225
  end
226
+ when :VCALL
227
+ case node.children[0]
228
+ when :private, :protected, :public
229
+ current_context!.visibility = node.children[0]
230
+ end
175
231
  when :DEFS
176
232
  sigs = pop_sig
177
233
 
@@ -197,6 +253,8 @@ module RBS
197
253
  sigs = pop_sig
198
254
 
199
255
  if sigs
256
+ context = current_context!
257
+ sync_visibility(context.visibility)
200
258
  comment = join_comments(sigs, comments)
201
259
 
202
260
  args = node.children[1]
@@ -207,10 +265,10 @@ module RBS
207
265
  location: nil,
208
266
  annotations: [],
209
267
  overloads: types.map {|type| AST::Members::MethodDefinition::Overload.new(annotations: [], method_type: type) },
210
- kind: :instance,
268
+ kind: context.singleton ? :singleton : :instance,
211
269
  comment: comment,
212
270
  overloading: false,
213
- visibility: nil
271
+ visibility: member_visibility(context)
214
272
  )
215
273
  end
216
274
 
@@ -235,16 +293,13 @@ module RBS
235
293
  variance: variance || :invariant,
236
294
  location: nil,
237
295
  upper_bound: nil,
296
+ lower_bound: nil,
238
297
  default_type: nil
239
298
  )
240
299
  end
241
300
  else
242
301
  name = node.children[0].yield_self do |n|
243
- if n.is_a?(Symbol)
244
- TypeName.new(namespace: current_namespace, name: n)
245
- else
246
- const_to_name(n)
247
- end
302
+ n.is_a?(Symbol) ? TypeName.new(namespace: Namespace.empty, name: n) : const_to_name(n)
248
303
  end
249
304
  value_node = node.children.last
250
305
  type = if value_node && value_node.type == :CALL && value_node.children[1] == :let
@@ -253,7 +308,7 @@ module RBS
253
308
  else
254
309
  Types::Bases::Any.new(location: nil)
255
310
  end
256
- decls << AST::Declarations::Constant.new(
311
+ append_decl AST::Declarations::Constant.new(
257
312
  name: name,
258
313
  type: type,
259
314
  location: nil,
@@ -262,12 +317,13 @@ module RBS
262
317
  )
263
318
  end
264
319
  when :ALIAS
320
+ sync_visibility(current_context!.visibility)
265
321
  current_module!.members << AST::Members::Alias.new(
266
322
  new_name: node.children[0].children[0],
267
323
  old_name: node.children[1].children[0],
268
324
  location: nil,
269
325
  annotations: [],
270
- kind: :instance,
326
+ kind: current_context!.singleton ? :singleton : :instance,
271
327
  comment: nil
272
328
  )
273
329
  else
@@ -277,6 +333,93 @@ module RBS
277
333
  end
278
334
  end
279
335
 
336
+ def process_visibility(node, outer:, comments:)
337
+ visibility = node.children[0]
338
+ args = each_arg(node.children[1]).to_a
339
+ context = current_context!
340
+
341
+ if args.empty?
342
+ context.visibility = visibility
343
+ else
344
+ previous_visibility = context.visibility
345
+ context.visibility = visibility
346
+
347
+ begin
348
+ args.each do |arg|
349
+ if arg.type == :DEFN || arg.type == :DEFS
350
+ process arg, outer: outer + [node], comments: comments
351
+ end
352
+ end
353
+ ensure
354
+ context.visibility = previous_visibility
355
+ end
356
+ end
357
+ end
358
+
359
+ def process_attribute(node, comments:)
360
+ sigs = pop_sig
361
+ kind = node.children[0]
362
+ context = current_context!
363
+ sync_visibility(context.visibility)
364
+
365
+ type = attribute_type(kind, sigs)
366
+ comment = join_comments(sigs, comments) if sigs
367
+ member_class = case kind
368
+ when :attr_reader
369
+ AST::Members::AttrReader
370
+ when :attr_writer
371
+ AST::Members::AttrWriter
372
+ when :attr_accessor
373
+ AST::Members::AttrAccessor
374
+ else
375
+ raise "Unexpected attribute kind: #{kind}"
376
+ end
377
+
378
+ each_arg node.children[1] do |arg|
379
+ if name = symbol_literal_node?(arg)
380
+ current_module!.members << member_class.new(
381
+ name: name,
382
+ type: type,
383
+ ivar_name: nil,
384
+ kind: context.singleton ? :singleton : :instance,
385
+ annotations: [],
386
+ location: nil,
387
+ comment: comment,
388
+ visibility: member_visibility(context)
389
+ )
390
+ end
391
+ end
392
+ end
393
+
394
+ def attribute_type(kind, sigs)
395
+ any = Types::Bases::Any.new(location: nil)
396
+ return any unless sigs
397
+
398
+ method_types = sigs.filter_map do |sig|
399
+ method_type(nil, sig, variables: current_module!.type_params, overloads: sigs.size)
400
+ end
401
+ function = method_types.last&.type
402
+ return any unless function.is_a?(Types::Function)
403
+
404
+ parameter_type = function.required_positionals.first&.type
405
+ return_type = function.return_type
406
+
407
+ case kind
408
+ when :attr_reader
409
+ return_type
410
+ when :attr_writer
411
+ parameter_type || return_type
412
+ when :attr_accessor
413
+ if return_type.is_a?(Types::Bases::Any) || return_type.is_a?(Types::Bases::Void)
414
+ parameter_type || any
415
+ else
416
+ return_type
417
+ end
418
+ else
419
+ any
420
+ end
421
+ end
422
+
280
423
  def method_type(args_node, type_node, variables:, overloads:)
281
424
  if type_node
282
425
  if type_node.type == :CALL
@@ -332,6 +475,7 @@ module RBS
332
475
  name: name,
333
476
  variance: :invariant,
334
477
  upper_bound: nil,
478
+ lower_bound: nil,
335
479
  location: nil,
336
480
  default_type: nil
337
481
  )
@@ -480,8 +624,10 @@ module RBS
480
624
  case
481
625
  when type.is_a?(Types::ClassInstance) && type.name.name == BuiltinNames::BasicObject.name.name
482
626
  Types::Bases::Any.new(location: nil)
483
- when type.is_a?(Types::ClassInstance) && type.name.to_s == "T::Boolean"
627
+ when type.is_a?(Types::ClassInstance) && type.name.to_s.delete_prefix("::") == "T::Boolean"
484
628
  Types::Bases::Bool.new(location: nil)
629
+ when type.is_a?(Types::ClassInstance) && type.name.to_s.delete_prefix("::") == "T::Class"
630
+ Types::Bases::Any.new(location: nil)
485
631
  else
486
632
  type
487
633
  end
@@ -499,6 +645,11 @@ module RBS
499
645
  Types::ClassInstance.new(name: const_to_name(type_node), args: [], location: nil)
500
646
  when call_node?(type_node, name: :[], receiver: -> (_) { true })
501
647
  # The type_node represents a type application
648
+ receiver = type_node.children[0]
649
+ if [:CONST, :COLON2, :COLON3].include?(receiver.type) && const_to_name(receiver).to_s.delete_prefix("::") == "T::Class"
650
+ return Types::Bases::Any.new(location: nil)
651
+ end
652
+
502
653
  type = type_of(type_node.children[0], variables: variables)
503
654
  type.is_a?(Types::ClassInstance) or raise
504
655
 
@@ -576,7 +727,7 @@ module RBS
576
727
 
577
728
  type_name = TypeName.new(name: node.children[1], namespace: namespace)
578
729
 
579
- case type_name.to_s
730
+ case type_name.to_s.delete_prefix("::")
580
731
  when "T::Array"
581
732
  BuiltinNames::Array.name
582
733
  when "T::Hash"