rbs 3.9.4 → 4.1.1

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 (348) 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/.github/dependabot.yml +16 -14
  6. data/.github/workflows/bundle-update.yml +63 -0
  7. data/.github/workflows/c-check.yml +66 -0
  8. data/.github/workflows/comments.yml +5 -3
  9. data/.github/workflows/dependabot.yml +2 -2
  10. data/.github/workflows/jruby.yml +79 -0
  11. data/.github/workflows/release-gems.yml +164 -0
  12. data/.github/workflows/ruby.yml +84 -30
  13. data/.github/workflows/rust.yml +186 -0
  14. data/.github/workflows/truffleruby.yml +54 -0
  15. data/.github/workflows/typecheck.yml +5 -2
  16. data/.github/workflows/wasm.yml +55 -0
  17. data/.github/workflows/windows.yml +9 -3
  18. data/.gitignore +16 -0
  19. data/.rubocop.yml +2 -2
  20. data/CHANGELOG.md +430 -0
  21. data/Dockerfile.jruby +53 -0
  22. data/README.md +41 -4
  23. data/Rakefile +777 -60
  24. data/Steepfile +11 -0
  25. data/config.yml +660 -62
  26. data/core/array.rbs +541 -398
  27. data/core/basic_object.rbs +9 -8
  28. data/core/binding.rbs +0 -2
  29. data/core/builtin.rbs +9 -8
  30. data/core/class.rbs +11 -8
  31. data/core/comparable.rbs +55 -34
  32. data/core/complex.rbs +104 -78
  33. data/core/dir.rbs +61 -49
  34. data/core/encoding.rbs +12 -15
  35. data/core/enumerable.rbs +297 -196
  36. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  37. data/core/enumerator/product.rbs +5 -5
  38. data/core/enumerator.rbs +91 -28
  39. data/core/errno.rbs +11 -2
  40. data/core/errors.rbs +58 -29
  41. data/core/exception.rbs +13 -13
  42. data/core/fiber.rbs +74 -54
  43. data/core/file.rbs +260 -1151
  44. data/core/file_constants.rbs +463 -0
  45. data/core/file_stat.rbs +534 -0
  46. data/core/file_test.rbs +3 -3
  47. data/core/float.rbs +257 -116
  48. data/core/gc.rbs +425 -281
  49. data/core/hash.rbs +1151 -829
  50. data/core/integer.rbs +156 -195
  51. data/core/io/buffer.rbs +53 -42
  52. data/core/io/wait.rbs +13 -35
  53. data/core/io.rbs +220 -154
  54. data/core/kernel.rbs +239 -163
  55. data/core/marshal.rbs +4 -4
  56. data/core/match_data.rbs +16 -14
  57. data/core/math.rbs +107 -66
  58. data/core/method.rbs +69 -33
  59. data/core/module.rbs +302 -150
  60. data/core/nil_class.rbs +7 -6
  61. data/core/numeric.rbs +77 -63
  62. data/core/object.rbs +9 -11
  63. data/core/object_space/weak_key_map.rbs +7 -7
  64. data/core/object_space.rbs +30 -23
  65. data/core/pathname.rbs +1312 -0
  66. data/core/proc.rbs +95 -58
  67. data/core/process.rbs +222 -202
  68. data/core/ractor.rbs +364 -518
  69. data/core/random.rbs +21 -3
  70. data/core/range.rbs +181 -79
  71. data/core/rational.rbs +60 -89
  72. data/core/rbs/ops.rbs +154 -0
  73. data/core/rbs/unnamed/argf.rbs +63 -56
  74. data/core/rbs/unnamed/env_class.rbs +19 -14
  75. data/core/rbs/unnamed/main_class.rbs +123 -0
  76. data/core/rbs/unnamed/random.rbs +11 -118
  77. data/core/regexp.rbs +258 -214
  78. data/core/ruby.rbs +53 -0
  79. data/core/ruby_vm.rbs +78 -34
  80. data/core/rubygems/config_file.rbs +5 -5
  81. data/core/rubygems/errors.rbs +6 -70
  82. data/core/rubygems/requirement.rbs +5 -15
  83. data/core/rubygems/rubygems.rbs +18 -81
  84. data/core/rubygems/specification.rbs +8 -0
  85. data/core/rubygems/version.rbs +2 -163
  86. data/core/set.rbs +493 -363
  87. data/core/signal.rbs +26 -16
  88. data/core/string.rbs +3234 -1285
  89. data/core/struct.rbs +43 -42
  90. data/core/symbol.rbs +41 -34
  91. data/core/thread.rbs +139 -83
  92. data/core/time.rbs +81 -50
  93. data/core/trace_point.rbs +41 -35
  94. data/core/true_class.rbs +2 -2
  95. data/core/unbound_method.rbs +24 -16
  96. data/core/warning.rbs +7 -7
  97. data/docs/CONTRIBUTING.md +2 -1
  98. data/docs/aliases.md +79 -0
  99. data/docs/collection.md +3 -3
  100. data/docs/config.md +171 -0
  101. data/docs/encoding.md +56 -0
  102. data/docs/gem.md +0 -1
  103. data/docs/inline.md +634 -0
  104. data/docs/rbs_by_example.md +20 -20
  105. data/docs/release.md +151 -0
  106. data/docs/rust.md +96 -0
  107. data/docs/sigs.md +3 -3
  108. data/docs/syntax.md +48 -18
  109. data/docs/type_fingerprint.md +21 -0
  110. data/docs/wasm_serialization.md +80 -0
  111. data/exe/rbs +1 -1
  112. data/ext/rbs_extension/ast_translation.c +1855 -0
  113. data/ext/rbs_extension/ast_translation.h +41 -0
  114. data/ext/rbs_extension/class_constants.c +187 -0
  115. data/{include/rbs/constants.h → ext/rbs_extension/class_constants.h} +23 -1
  116. data/ext/rbs_extension/compat.h +10 -0
  117. data/ext/rbs_extension/extconf.rb +26 -1
  118. data/ext/rbs_extension/legacy_location.c +299 -0
  119. data/ext/rbs_extension/legacy_location.h +82 -0
  120. data/ext/rbs_extension/main.c +603 -23
  121. data/ext/rbs_extension/rbs_extension.h +6 -21
  122. data/ext/rbs_extension/rbs_string_bridging.c +9 -0
  123. data/ext/rbs_extension/rbs_string_bridging.h +24 -0
  124. data/include/rbs/ast.h +1047 -0
  125. data/include/rbs/defines.h +99 -0
  126. data/include/rbs/lexer.h +207 -0
  127. data/include/rbs/location.h +40 -0
  128. data/include/rbs/parser.h +153 -0
  129. data/include/rbs/serialize.h +39 -0
  130. data/include/rbs/string.h +47 -0
  131. data/include/rbs/util/rbs_allocator.h +59 -0
  132. data/include/rbs/util/rbs_assert.h +20 -0
  133. data/include/rbs/util/rbs_buffer.h +83 -0
  134. data/include/rbs/util/rbs_constant_pool.h +6 -70
  135. data/include/rbs/util/rbs_encoding.h +282 -0
  136. data/include/rbs/util/rbs_unescape.h +24 -0
  137. data/include/rbs.h +9 -2
  138. data/lib/rbs/annotate/formatter.rb +3 -13
  139. data/lib/rbs/annotate/rdoc_annotator.rb +30 -32
  140. data/lib/rbs/annotate/rdoc_source.rb +1 -1
  141. data/lib/rbs/ast/annotation.rb +1 -1
  142. data/lib/rbs/ast/comment.rb +1 -1
  143. data/lib/rbs/ast/declarations.rb +10 -10
  144. data/lib/rbs/ast/members.rb +14 -14
  145. data/lib/rbs/ast/ruby/annotations.rb +451 -0
  146. data/lib/rbs/ast/ruby/comment_block.rb +247 -0
  147. data/lib/rbs/ast/ruby/declarations.rb +291 -0
  148. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
  149. data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  150. data/lib/rbs/ast/ruby/members.rb +762 -0
  151. data/lib/rbs/ast/type_param.rb +24 -4
  152. data/lib/rbs/buffer.rb +142 -20
  153. data/lib/rbs/cli/diff.rb +16 -15
  154. data/lib/rbs/cli/validate.rb +63 -126
  155. data/lib/rbs/cli.rb +59 -29
  156. data/lib/rbs/collection/config/lockfile_generator.rb +28 -3
  157. data/lib/rbs/collection/sources/git.rb +7 -0
  158. data/lib/rbs/definition.rb +6 -1
  159. data/lib/rbs/definition_builder/ancestor_builder.rb +121 -65
  160. data/lib/rbs/definition_builder/method_builder.rb +74 -33
  161. data/lib/rbs/definition_builder.rb +177 -20
  162. data/lib/rbs/diff.rb +7 -1
  163. data/lib/rbs/environment/class_entry.rb +69 -0
  164. data/lib/rbs/environment/module_entry.rb +66 -0
  165. data/lib/rbs/environment.rb +410 -215
  166. data/lib/rbs/environment_loader.rb +2 -8
  167. data/lib/rbs/errors.rb +31 -21
  168. data/lib/rbs/inline_parser/comment_association.rb +117 -0
  169. data/lib/rbs/inline_parser.rb +568 -0
  170. data/lib/rbs/location_aux.rb +36 -4
  171. data/lib/rbs/locator.rb +5 -1
  172. data/lib/rbs/method_type.rb +5 -3
  173. data/lib/rbs/namespace.rb +47 -18
  174. data/lib/rbs/parser_aux.rb +37 -7
  175. data/lib/rbs/prototype/helpers.rb +57 -0
  176. data/lib/rbs/prototype/rb.rb +3 -28
  177. data/lib/rbs/prototype/rbi.rb +196 -45
  178. data/lib/rbs/prototype/runtime.rb +12 -2
  179. data/lib/rbs/resolver/constant_resolver.rb +2 -2
  180. data/lib/rbs/resolver/type_name_resolver.rb +120 -44
  181. data/lib/rbs/rewriter.rb +70 -0
  182. data/lib/rbs/source.rb +99 -0
  183. data/lib/rbs/subtractor.rb +7 -4
  184. data/lib/rbs/test/type_check.rb +25 -3
  185. data/lib/rbs/type_name.rb +34 -21
  186. data/lib/rbs/types.rb +91 -79
  187. data/lib/rbs/unit_test/convertibles.rb +1 -0
  188. data/lib/rbs/unit_test/type_assertions.rb +44 -8
  189. data/lib/rbs/validator.rb +2 -2
  190. data/lib/rbs/version.rb +1 -1
  191. data/lib/rbs/wasm/deserializer.rb +213 -0
  192. data/lib/rbs/wasm/location.rb +61 -0
  193. data/lib/rbs/wasm/parser.rb +137 -0
  194. data/lib/rbs/wasm/runtime.rb +196 -0
  195. data/lib/rbs/wasm/serialization_schema.rb +110 -0
  196. data/lib/rbs.rb +25 -2
  197. data/lib/rbs_jars.rb +39 -0
  198. data/lib/rdoc/discover.rb +1 -1
  199. data/lib/rdoc_plugin/parser.rb +8 -3
  200. data/rbs.gemspec +37 -5
  201. data/schema/typeParam.json +17 -1
  202. data/sig/ancestor_builder.rbs +1 -1
  203. data/sig/annotate/formatter.rbs +2 -2
  204. data/sig/annotate/rdoc_annotater.rbs +13 -10
  205. data/sig/ast/ruby/annotations.rbs +470 -0
  206. data/sig/ast/ruby/comment_block.rbs +127 -0
  207. data/sig/ast/ruby/declarations.rbs +158 -0
  208. data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  209. data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  210. data/sig/ast/ruby/members.rbs +198 -0
  211. data/sig/buffer.rbs +81 -5
  212. data/sig/cli/diff.rbs +5 -11
  213. data/sig/cli/validate.rbs +12 -8
  214. data/sig/cli.rbs +18 -18
  215. data/sig/collection/config/lockfile_generator.rbs +2 -0
  216. data/sig/definition.rbs +6 -0
  217. data/sig/definition_builder.rbs +3 -1
  218. data/sig/environment/class_entry.rbs +50 -0
  219. data/sig/environment/module_entry.rbs +50 -0
  220. data/sig/environment.rbs +94 -87
  221. data/sig/errors.rbs +26 -20
  222. data/sig/inline_parser/comment_association.rbs +71 -0
  223. data/sig/inline_parser.rbs +126 -0
  224. data/sig/location.rbs +32 -7
  225. data/sig/locator.rbs +0 -2
  226. data/sig/manifest.yaml +0 -2
  227. data/sig/method_builder.rbs +9 -4
  228. data/sig/namespace.rbs +20 -5
  229. data/sig/parser.rbs +77 -13
  230. data/sig/prototype/helpers.rbs +2 -0
  231. data/sig/prototype/rbi.rbs +33 -4
  232. data/sig/resolver/type_name_resolver.rbs +36 -10
  233. data/sig/rewriter.rbs +45 -0
  234. data/sig/source.rbs +48 -0
  235. data/sig/type_param.rbs +13 -8
  236. data/sig/typename.rbs +15 -5
  237. data/sig/types.rbs +10 -8
  238. data/sig/unit_test/spy.rbs +0 -8
  239. data/sig/unit_test/type_assertions.rbs +15 -0
  240. data/sig/wasm/deserializer.rbs +66 -0
  241. data/sig/wasm/serialization_schema.rbs +13 -0
  242. data/src/ast.c +1628 -0
  243. data/src/lexer.c +3221 -0
  244. data/src/lexer.re +155 -0
  245. data/src/lexstate.c +221 -0
  246. data/src/location.c +31 -0
  247. data/src/parser.c +4258 -0
  248. data/src/serialize.c +958 -0
  249. data/src/string.c +41 -0
  250. data/src/util/rbs_allocator.c +171 -0
  251. data/src/util/rbs_assert.c +19 -0
  252. data/src/util/rbs_buffer.c +54 -0
  253. data/src/util/rbs_constant_pool.c +18 -92
  254. data/src/util/rbs_encoding.c +21308 -0
  255. data/src/util/rbs_unescape.c +167 -0
  256. data/stdlib/abbrev/0/array.rbs +1 -1
  257. data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
  258. data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
  259. data/stdlib/cgi/0/core.rbs +9 -393
  260. data/stdlib/cgi/0/manifest.yaml +1 -0
  261. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  262. data/stdlib/coverage/0/coverage.rbs +7 -4
  263. data/stdlib/csv/0/csv.rbs +5 -5
  264. data/stdlib/date/0/date.rbs +92 -79
  265. data/stdlib/date/0/date_time.rbs +25 -24
  266. data/stdlib/delegate/0/delegator.rbs +11 -7
  267. data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
  268. data/stdlib/digest/0/digest.rbs +117 -1
  269. data/stdlib/erb/0/erb.rbs +748 -347
  270. data/stdlib/etc/0/etc.rbs +73 -54
  271. data/stdlib/fileutils/0/fileutils.rbs +179 -160
  272. data/stdlib/forwardable/0/forwardable.rbs +13 -10
  273. data/stdlib/io-console/0/io-console.rbs +2 -2
  274. data/stdlib/ipaddr/0/ipaddr.rbs +0 -5
  275. data/stdlib/json/0/json.rbs +232 -185
  276. data/stdlib/monitor/0/monitor.rbs +5 -5
  277. data/stdlib/net-http/0/net-http.rbs +162 -134
  278. data/stdlib/objspace/0/objspace.rbs +17 -34
  279. data/stdlib/open-uri/0/open-uri.rbs +48 -8
  280. data/stdlib/open3/0/open3.rbs +469 -10
  281. data/stdlib/openssl/0/openssl.rbs +521 -397
  282. data/stdlib/optparse/0/optparse.rbs +26 -17
  283. data/stdlib/pathname/0/pathname.rbs +11 -1381
  284. data/stdlib/pp/0/pp.rbs +9 -8
  285. data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
  286. data/stdlib/pstore/0/pstore.rbs +35 -30
  287. data/stdlib/psych/0/psych.rbs +65 -12
  288. data/stdlib/psych/0/store.rbs +2 -4
  289. data/stdlib/pty/0/pty.rbs +9 -6
  290. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  291. data/stdlib/rdoc/0/code_object.rbs +4 -3
  292. data/stdlib/rdoc/0/comment.rbs +2 -0
  293. data/stdlib/rdoc/0/options.rbs +76 -0
  294. data/stdlib/rdoc/0/parser.rbs +1 -1
  295. data/stdlib/rdoc/0/rdoc.rbs +7 -5
  296. data/stdlib/rdoc/0/store.rbs +2 -2
  297. data/stdlib/resolv/0/resolv.rbs +26 -69
  298. data/stdlib/ripper/0/ripper.rbs +25 -19
  299. data/stdlib/securerandom/0/manifest.yaml +2 -0
  300. data/stdlib/securerandom/0/securerandom.rbs +7 -20
  301. data/stdlib/shellwords/0/shellwords.rbs +3 -3
  302. data/stdlib/singleton/0/singleton.rbs +3 -0
  303. data/stdlib/socket/0/addrinfo.rbs +9 -9
  304. data/stdlib/socket/0/basic_socket.rbs +3 -3
  305. data/stdlib/socket/0/ip_socket.rbs +10 -8
  306. data/stdlib/socket/0/socket.rbs +23 -10
  307. data/stdlib/socket/0/tcp_server.rbs +1 -1
  308. data/stdlib/socket/0/tcp_socket.rbs +11 -3
  309. data/stdlib/socket/0/udp_socket.rbs +1 -1
  310. data/stdlib/socket/0/unix_server.rbs +1 -1
  311. data/stdlib/stringio/0/stringio.rbs +1209 -95
  312. data/stdlib/strscan/0/string_scanner.rbs +101 -80
  313. data/stdlib/tempfile/0/manifest.yaml +3 -0
  314. data/stdlib/tempfile/0/tempfile.rbs +25 -21
  315. data/stdlib/time/0/time.rbs +8 -6
  316. data/stdlib/timeout/0/timeout.rbs +58 -7
  317. data/stdlib/tsort/0/cyclic.rbs +4 -1
  318. data/stdlib/tsort/0/interfaces.rbs +8 -8
  319. data/stdlib/tsort/0/tsort.rbs +16 -15
  320. data/stdlib/uri/0/common.rbs +42 -20
  321. data/stdlib/uri/0/file.rbs +3 -3
  322. data/stdlib/uri/0/generic.rbs +21 -18
  323. data/stdlib/uri/0/http.rbs +2 -2
  324. data/stdlib/uri/0/ldap.rbs +2 -2
  325. data/stdlib/uri/0/mailto.rbs +3 -3
  326. data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
  327. data/stdlib/zlib/0/deflate.rbs +4 -3
  328. data/stdlib/zlib/0/gzip_reader.rbs +8 -8
  329. data/stdlib/zlib/0/gzip_writer.rbs +14 -12
  330. data/stdlib/zlib/0/inflate.rbs +1 -1
  331. data/stdlib/zlib/0/need_dict.rbs +1 -1
  332. data/wasm/README.md +60 -0
  333. data/wasm/rbs_wasm.c +423 -0
  334. metadata +131 -19
  335. data/ext/rbs_extension/lexer.c +0 -2728
  336. data/ext/rbs_extension/lexer.h +0 -179
  337. data/ext/rbs_extension/lexer.re +0 -147
  338. data/ext/rbs_extension/lexstate.c +0 -175
  339. data/ext/rbs_extension/location.c +0 -325
  340. data/ext/rbs_extension/location.h +0 -85
  341. data/ext/rbs_extension/parser.c +0 -2982
  342. data/ext/rbs_extension/parser.h +0 -18
  343. data/ext/rbs_extension/parserstate.c +0 -411
  344. data/ext/rbs_extension/parserstate.h +0 -163
  345. data/ext/rbs_extension/unescape.c +0 -32
  346. data/include/rbs/ruby_objs.h +0 -72
  347. data/src/constants.c +0 -153
  348. data/src/ruby_objs.c +0 -799
@@ -107,14 +107,14 @@ end
107
107
  For now, it's safe to ignore them, but they're included for completeness.
108
108
 
109
109
  ```rbs
110
- class Array[Elem]
110
+ class Array[E]
111
111
  def *: (String) -> String
112
- | (Integer) -> Array[Elem]
112
+ | (Integer) -> Array[E]
113
113
  end
114
114
  ```
115
115
 
116
116
  `Array`'s `*` method, when given a `String` returns a `String`. When given an
117
- `Integer`, it returns an `Array` of the same contained type `Elem` (in our example case, `Elem` corresponds to `Integer`).
117
+ `Integer`, it returns an `Array` of the same contained type `E` (in our example case, `E` corresponds to `Integer`).
118
118
 
119
119
  ### Union types
120
120
 
@@ -150,9 +150,9 @@ end
150
150
  ```
151
151
 
152
152
  ```rbs
153
- class Enumerable[Elem]
154
- def first: () -> Elem?
155
- | (Integer) -> Array[Elem]
153
+ class Enumerable[E]
154
+ def first: () -> E?
155
+ | (Integer) -> Array[E]
156
156
  end
157
157
  ```
158
158
 
@@ -160,12 +160,12 @@ end
160
160
 
161
161
  When called with no arguments, the return value will either be an instance of
162
162
  whatever type is contained in the enumerable, or `nil`. We represent that with
163
- the type variable `Elem`, and the `?` suffix nilable marker.
163
+ the type variable `E`, and the `?` suffix nilable marker.
164
164
 
165
165
  When called with an `Integer` positional argument, the return value will be an
166
166
  `Array` of whatever type is contained.
167
167
 
168
- The `?` syntax is a convenient shorthand for a union with nil. An equivalent union type would be `(Elem | nil)`.
168
+ The `?` syntax is a convenient shorthand for a union with nil. An equivalent union type would be `(E | nil)`.
169
169
 
170
170
  ### Keyword Arguments
171
171
 
@@ -222,9 +222,9 @@ end
222
222
  ```
223
223
 
224
224
  ```rbs
225
- class Array[Elem]
226
- def filter: () { (Elem) -> boolish } -> ::Array[Elem]
227
- | () -> ::Enumerator[Elem, ::Array[Elem]]
225
+ class Array[E]
226
+ def filter: () { (E) -> boolish } -> ::Array[E]
227
+ | () -> ::Enumerator[E, ::Array[E]]
228
228
  end
229
229
  ```
230
230
 
@@ -264,13 +264,13 @@ a.collect.with_index {|x, i| x * i}
264
264
  ```
265
265
 
266
266
  ```rbs
267
- class Array[Elem]
268
- def collect: [U] () { (Elem) -> U } -> Array[U]
269
- | () -> Enumerator[Elem, Array[untyped]]
267
+ class Array[E]
268
+ def collect: [U] () { (E) -> U } -> Array[U]
269
+ | () -> Enumerator[E, Array[untyped]]
270
270
  end
271
271
  ```
272
272
 
273
- Type variables can also be introduced in methods. Here, in `Array`'s `#collect` method, we introduce a type variable `U`. The block passed to `#collect` will receive a parameter of type `Elem`, and return a value of type `U`. Then `#collect` will return an `Array` of type `U`.
273
+ Type variables can also be introduced in methods. Here, in `Array`'s `#collect` method, we introduce a type variable `U`. The block passed to `#collect` will receive a parameter of type `E`, and return a value of type `U`. Then `#collect` will return an `Array` of type `U`.
274
274
 
275
275
  In this example, the method receives its signature from the inferred return type of the passed block. When then block is absent, as in when the method returns an `Enumerator`, we can't infer the type, and so the return value of the enumerator can only be described as `Array[untyped]`.
276
276
 
@@ -284,9 +284,9 @@ In this example, the method receives its signature from the inferred return type
284
284
  ```
285
285
 
286
286
  ```rbs
287
- class Enumerable[Elem]
288
- def partition: () { (Elem) -> boolish } -> [Array[Elem], Array[Elem]]
289
- | () -> ::Enumerator[Elem, [Array[Elem], Array[Elem] ]]
287
+ class Enumerable[E]
288
+ def partition: () { (E) -> boolish } -> [Array[E], Array[E]]
289
+ | () -> ::Enumerator[E, [Array[E], Array[E] ]]
290
290
  end
291
291
  ```
292
292
 
@@ -300,9 +300,9 @@ Tuples can be of any size, and they can have mixed types.
300
300
  ```
301
301
 
302
302
  ```rbs
303
- class Enumerable[Elem]
303
+ class Enumerable[E]
304
304
  def to_h: () -> ::Hash[untyped, untyped]
305
- | [T, U] () { (Elem) -> [T, U] } -> ::Hash[T, U]
305
+ | [T, U] () { (E) -> [T, U] } -> ::Hash[T, U]
306
306
  end
307
307
  ```
308
308
 
data/docs/release.md ADDED
@@ -0,0 +1,151 @@
1
+ # Releasing RBS
2
+
3
+ A release is a pull request, a tag, and one workflow run. Everything that leaves
4
+ the repository — both gems and the GitHub release — is produced by the `Release
5
+ gems` workflow, so nothing has to be built or pushed from a laptop.
6
+
7
+ Each release ships **two gems**:
8
+
9
+ | Gem | Platform | Parser |
10
+ | --- | --- | --- |
11
+ | `rbs-X.Y.Z.gem` | `ruby` (MRI) | C extension, compiled on install |
12
+ | `rbs-X.Y.Z-java.gem` | `java` (JRuby) | `rbs_parser.wasm`, built by the workflow |
13
+
14
+ The `-java` gem contains no native code — just `rbs_parser.wasm`. The Chicory/ASM
15
+ jars it needs are not shipped in the gem; they are declared as `jar-dependencies`
16
+ requirements and fetched from Maven when the gem is installed. So the gem can be
17
+ built once in any environment and runs on every JRuby.
18
+
19
+ There are three kinds of release, and they differ in what gets written up:
20
+
21
+ | Version | CHANGELOG section | GitHub release |
22
+ | --- | --- | --- |
23
+ | `X.Y.Z` | The whole cycle since the previous release proper, prereleases included | Published |
24
+ | `X.Y.Z.pre.N` | What changed since `X.Y.Z.pre.N-1` | Published, marked as a prerelease |
25
+ | `X.Y.Z.dev.N` | None | None |
26
+
27
+ `.dev.N` releases are cut from the development line for people who need a change
28
+ early, so they are gems and tags and nothing else.
29
+
30
+ ## Prerequisites
31
+
32
+ Push rights to the `rbs` gem on RubyGems are **not** needed: the workflow
33
+ authenticates through a trusted publisher registered for this repository and
34
+ `release-gems.yml`. What is needed is write access to the repository, since that
35
+ is what lets you dispatch the workflow.
36
+
37
+ ## Steps
38
+
39
+ ### 1. Prepare the release
40
+
41
+ Open a pull request that carries everything the release needs:
42
+
43
+ - `lib/rbs/version.rb` — set `RBS::VERSION` to the version being released.
44
+ - `Gemfile.lock` — run `bundle install` after the bump; the lockfile records the version too.
45
+ - `CHANGELOG.md` — add a section for the new version, directly under the `# CHANGELOG` heading.
46
+ Sections are newest first.
47
+
48
+ Label the pull request `skip-changelog`. It carries no change of its own, and without the label it
49
+ shows up in the next release's list — that is why 4.1.0's changelog contains a `Version 4.1.0`
50
+ entry.
51
+
52
+ `rake gem:changelog` lists the pull requests merged since the last release, already formatted:
53
+
54
+ ```console
55
+ $ bundle exec rake gem:changelog | pbcopy
56
+ ```
57
+
58
+ Where it starts follows `RBS::VERSION`, so bump the version first: a prerelease starts from the
59
+ latest tag, and a release proper skips the prerelease tags and starts from the previous release
60
+ proper. Pass a version to override it (`rake 'gem:changelog[4.1.0]'`). Only the list goes to
61
+ STDOUT, so it pipes cleanly. Pull requests labeled `skip-changelog` are left out and reported on
62
+ STDERR, and pull requests that only touch `rust/` are left out because the crates have their own
63
+ release cycle.
64
+
65
+ On a release proper, the `X.Y.Z.pre.N` sections above the previous release are replaced by the one
66
+ section being written — their pull requests are in it, and the notes they were published with stay
67
+ on their own GitHub releases.
68
+
69
+ Sort the list into the sections below. `rake gem:changelog:json` prints the same pull requests with
70
+ the changed files, labels, and body of each, which is what the sorting is based on.
71
+
72
+ ```markdown
73
+ ## X.Y.Z (YYYY-MM-DD)
74
+
75
+ ### Signature updates
76
+
77
+ ### Language updates
78
+
79
+ ### Library changes
80
+
81
+ #### rbs prototype
82
+
83
+ #### rbs collection
84
+
85
+ ### Miscellaneous
86
+ ```
87
+
88
+ The sections always appear in this order; delete the ones that end up empty, which is most of them
89
+ on a small release. Two things scale with the size of the release:
90
+
91
+ - **Summary paragraphs**, above the first section. A patch release usually has none, 4.1.0 has four
92
+ paragraphs, and 4.0.0 has nine.
93
+ - **A list of the types whose signatures changed**, as the first line of `### Signature updates`,
94
+ written as `**Updated classes/modules/methods:**` followed by the names in backticks. Used on
95
+ `X.Y.0` releases only.
96
+
97
+ The date is the day the gem is released, matching the `vX.Y.Z` tag — not the day this pull request
98
+ is opened. Fix it up before step 2 if the pull request sat for a few days.
99
+
100
+ ### 2. Tag the release
101
+
102
+ Once the pull request is merged, tag the merge commit and push the tag:
103
+
104
+ ```console
105
+ $ git switch master && git pull
106
+ $ git tag "v$(ruby -e 'load "lib/rbs/version.rb"; print RBS::VERSION')"
107
+ $ git push origin --tags
108
+ ```
109
+
110
+ The tag comes before anything is published, so that the gems and the release notes describe a
111
+ commit that is already immutable — and because a tag can be deleted, while a version pushed to
112
+ RubyGems can only be yanked.
113
+
114
+ ### 3. Run the `Release gems` workflow against the tag
115
+
116
+ Dispatch [`release-gems.yml`](../.github/workflows/release-gems.yml) from the Actions tab, picking
117
+ the `vX.Y.Z` tag — **not** a branch — in the ref selector. The trusted publisher has no branch
118
+ condition, so the ref you pick is what decides what gets published; the workflow refuses to run
119
+ unless the tag matches `RBS::VERSION`.
120
+
121
+ It then:
122
+
123
+ - builds `rbs-X.Y.Z.gem`,
124
+ - compiles `rbs_parser.wasm` and builds `rbs-X.Y.Z-java.gem`,
125
+ - checks both: platforms, the C extension on one and its absence on the other, and that the wasm
126
+ module made it into the `java` gem,
127
+ - installs the `java` gem on JRuby and parses with it, so the WebAssembly runtime is exercised
128
+ before anything is published,
129
+ - uploads both gems as an artifact,
130
+ - pushes both to RubyGems through trusted publishing,
131
+ - publishes the GitHub release with the notes from CHANGELOG.md, skipping this last step for
132
+ `.dev.N` versions.
133
+
134
+ Dispatching against a branch runs everything up to the artifact and stops, which is how the build
135
+ is exercised without releasing.
136
+
137
+ ### 4. Start the next development cycle
138
+
139
+ Open another pull request setting `RBS::VERSION` to the next prerelease (`4.1.1` → `4.1.2.pre`),
140
+ with `Gemfile.lock` regenerated, labeled `skip-changelog` like the release pull request itself.
141
+ Without it the version on `master` keeps claiming to be the released version for the whole
142
+ development period, and `rake gem:changelog` reads that version to decide where the next changelog
143
+ starts.
144
+
145
+ ## Notes
146
+
147
+ - Prereleases (`X.Y.Z.pre.N`) are only installed with `gem install rbs --pre`;
148
+ a plain `gem install rbs` is unaffected. On JRuby, `gem install rbs [--pre]`
149
+ resolves to the `-java` gem automatically.
150
+ - `Dockerfile.jruby` pins the WASI SDK / Chicory / ASM versions to match the
151
+ `wasm`, `jruby`, and `release-gems` workflows. Keep them in sync when bumping.
data/docs/rust.md ADDED
@@ -0,0 +1,96 @@
1
+ # Rust Crates
2
+
3
+ RBS provides two Rust crates:
4
+
5
+ - **`ruby-rbs-sys`** -- Low-level FFI bindings to the RBS C parser
6
+ - **`ruby-rbs`** -- High-level safe Rust API for parsing RBS signatures
7
+
8
+ Both crates are published to [crates.io](https://crates.io/) and are developed within the `rust/` directory of this repository.
9
+
10
+ ## Vendored RBS Source
11
+
12
+ The Rust crates depend on the RBS C parser source code (`include/`, `src/`) and configuration (`config.yml`) from this repository. These files are vendored into each crate's `vendor/rbs/` directory, which is managed by Rake tasks and not tracked by git.
13
+
14
+ The file `rust/rbs_version` records which version of RBS the Rust crates are pinned to.
15
+
16
+ ## Setup
17
+
18
+ After cloning the repository, set up the vendored source before building the Rust crates:
19
+
20
+ ```bash
21
+ rake rust:rbs:sync # Uses the pinned version from rust/rbs_version
22
+ ```
23
+
24
+ Then build and test:
25
+
26
+ ```bash
27
+ cd rust
28
+ cargo test
29
+ ```
30
+
31
+ ## Rake Tasks
32
+
33
+ ### `rake rust:rbs:sync`
34
+
35
+ Copies the source files from the pinned version into each crate's `vendor/rbs/`. The copied files are made read-only to prevent accidental edits.
36
+
37
+ ### `rake rust:rbs:pin[VERSION]`
38
+
39
+ Records a git tag in `rust/rbs_version`. For example:
40
+
41
+ ```bash
42
+ rake rust:rbs:pin[v4.0.3]
43
+ ```
44
+
45
+ ### `rake rust:publish:ruby-rbs-sys` / `rake rust:publish:ruby-rbs`
46
+
47
+ Publishes each crate to crates.io individually. Each task:
48
+
49
+ 1. Verifies `rust/rbs_version` is set
50
+ 2. Verifies vendor directories contain real files (not symlinks)
51
+ 3. Verifies the git working tree is clean
52
+ 4. Creates a release branch and commits the vendor files
53
+ 5. Runs a dry-run to check packaging
54
+ 6. Publishes the crate
55
+
56
+ Set `RBS_RUST_PUBLISH_DRY_RUN=1` to only run the dry-run step and skip the actual publish to crates.io. This is used in CI to verify that the crates can be packaged correctly.
57
+
58
+ ### `rake rust:rbs:symlink`
59
+
60
+ If your development needs unreleased version of RBS source code, use `rake rust:rbs:symlink` to set up symlinks in vendor directories to refer the worktree source code. Changes to the C parser source are immediately reflected in Rust builds.
61
+
62
+ ## Publishing Workflow
63
+
64
+ 1. Pin the RBS version to release against:
65
+
66
+ ```bash
67
+ rake rust:rbs:pin[v4.0.3]
68
+ ```
69
+
70
+ 2. Sync the vendored source:
71
+
72
+ ```bash
73
+ rake rust:rbs:sync
74
+ ```
75
+
76
+ 3. Update crate versions in `rust/ruby-rbs-sys/Cargo.toml` and `rust/ruby-rbs/Cargo.toml`.
77
+
78
+ 4. Build and test:
79
+
80
+ ```bash
81
+ cd rust && cargo test
82
+ ```
83
+
84
+ 5. Commit the version changes and `rust/rbs_version`:
85
+
86
+ ```bash
87
+ git add rust/rbs_version rust/ruby-rbs-sys/Cargo.toml rust/ruby-rbs/Cargo.toml
88
+ git commit -m "Bump Rust crate versions"
89
+ ```
90
+
91
+ 6. Publish each crate:
92
+
93
+ ```bash
94
+ rake rust:publish:ruby-rbs-sys
95
+ rake rust:publish:ruby-rbs
96
+ ```
data/docs/sigs.md CHANGED
@@ -131,10 +131,10 @@ You may need to specify `-r` or `-I` to load signatures.
131
131
  The default is `-I sig`.
132
132
 
133
133
  ```shell
134
- RBS_TEST_OPT='-r pathname -I sig'
134
+ RBS_TEST_OPT='-r logger -I sig'
135
135
  ```
136
136
 
137
- Replacing `pathname` with the `stdlib` you want to include. For example, if you need to load `Set` and `BigDecimal` in `stdlib`, you would need to have `RBS_TEST_OPT='-r set -r bigdecimal -I sig'`
137
+ Replacing `logger` with the `stdlib` you want to include. For example, if you need to load `Set` and `BigDecimal` in `stdlib`, you would need to have `RBS_TEST_OPT='-r set -r bigdecimal -I sig'`
138
138
 
139
139
  `RBS_TEST_LOGLEVEL` can be used to configure log level. Defaults to `info`.
140
140
 
@@ -148,7 +148,7 @@ So, a typical command line to start the test would look like the following:
148
148
  $ RBS_TEST_LOGLEVEL=error \
149
149
  RBS_TEST_TARGET='Kaigi::*' \
150
150
  RBS_TEST_SKIP='Kaigi::MonkeyPatch' \
151
- RBS_TEST_OPT='-rset -rpathname -Isig -Iprivate' \
151
+ RBS_TEST_OPT='-rlogger -Isig -Iprivate' \
152
152
  RBS_TEST_RAISE=true \
153
153
  RUBYOPT='-rbundler/setup -rrbs/test/setup' \
154
154
  bundle exec rake test
data/docs/syntax.md CHANGED
@@ -3,17 +3,17 @@
3
3
  ## Types
4
4
 
5
5
  ```markdown
6
- _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
- | _interface-name_ _type-arguments_ (Interface type)
8
- | _alias-name_ _type-arguments_ (Alias type)
9
- | `singleton(` _class-name_ `)` (Class singleton type)
10
- | _literal_ (Literal type)
11
- | _type_ `|` _type_ (Union type)
12
- | _type_ `&` _type_ (Intersection type)
13
- | _type_ `?` (Optional type)
14
- | `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
15
- | `[]` | `[` _type_ `,` etc. `]` (Tuples)
16
- | _type-variable_ (Type variables)
6
+ _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
+ | _interface-name_ _type-arguments_ (Interface type)
8
+ | _alias-name_ _type-arguments_ (Alias type)
9
+ | `singleton(` _class-name_ `)` _type-arguments_ (Class singleton type)
10
+ | _literal_ (Literal type)
11
+ | _type_ `|` _type_ (Union type)
12
+ | _type_ `&` _type_ (Intersection type)
13
+ | _type_ `?` (Optional type)
14
+ | `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
15
+ | `[]` | `[` _type_ `,` etc. `]` (Tuples)
16
+ | _type-variable_ (Type variables)
17
17
  | `self`
18
18
  | `instance`
19
19
  | `class`
@@ -85,7 +85,8 @@ Class singleton type denotes _the type of a singleton object of a class_.
85
85
 
86
86
  ```rbs
87
87
  singleton(String)
88
- singleton(::Hash) # Class singleton type cannot be parametrized.
88
+ singleton(::Hash) # Class singleton type
89
+ singleton(Array)[String] # Class singleton type with type application
89
90
  ```
90
91
 
91
92
  ### Literal type
@@ -195,8 +196,8 @@ It is an alias of `top` type, and you can use `boolish` if we want to allow any
195
196
  We can see an example at the definition of `Enumerable#find`:
196
197
 
197
198
  ```rbs
198
- module Enumerable[Elem, Return]
199
- def find: () { (Elem) -> boolish } -> Elem?
199
+ module Enumerable[E, R]
200
+ def find: () { (E) -> boolish } -> E?
200
201
  end
201
202
  ```
202
203
 
@@ -650,7 +651,7 @@ _module-type-parameters_ ::= #
650
651
 
651
652
  Class declaration can have type parameters and superclass. When you omit superclass, `::Object` is assumed.
652
653
 
653
- * Super class arguments and generic class upperbounds are not *classish-context* nor *self-context*
654
+ * Super class arguments and generic class bounds are not *classish-context* nor *self-context*
654
655
 
655
656
  ### Module declaration
656
657
 
@@ -668,7 +669,7 @@ end
668
669
 
669
670
  The `Enumerable` module above requires `each` method for enumerating objects.
670
671
 
671
- * Self type arguments and generic class upperbounds are not *classish-context* nor *self-context*
672
+ * Self type arguments and generic class bounds are not *classish-context* nor *self-context*
672
673
 
673
674
  ### Class/module alias declaration
674
675
 
@@ -764,7 +765,8 @@ _module-type-parameter_ ::= _generics-unchecked_ _generics-variance_ _type-varia
764
765
  _method-type-param_ ::= _type-variable_ _generics-bound_
765
766
 
766
767
  _generics-bound_ ::= (No type bound)
767
- | `<` _type_ (The generics parameter is bounded)
768
+ | `<` _type_ (The generics parameter has an upper bound)
769
+ | '>' _type_ (The generics parameter has a lower bound)
768
770
 
769
771
  _default-type_ ::= (No default type)
770
772
  | `=` _type_ (The generics parameter has default type)
@@ -777,6 +779,9 @@ _generics-unchecked_ ::= (Empty)
777
779
  | `unchecked` (Skips variance annotation validation)
778
780
  ```
779
781
 
782
+ A type parameter can have both upper and lower bounds, which can be specified in either order:
783
+ `[T < UpperBound > LowerBound]` or `[T > LowerBound < UpperBound]`.
784
+
780
785
  RBS allows class/module/interface/type alias definitions and methods to be generic.
781
786
 
782
787
  ```rbs
@@ -834,13 +839,38 @@ class PrettyPrint[T < _Output]
834
839
  end
835
840
  ```
836
841
 
837
- If a type parameter has an upper bound, the type parameter must be instantiated with types that is a subtype of the upper bound.
842
+ If a type parameter has an upper bound, the type parameter must be instantiated with types that are a subtype of the upper bound.
838
843
 
839
844
  ```rbs
840
845
  type str_printer = PrettyPrint[String] # OK
841
846
  type int_printer = PrettyPrint[Integer] # Type error
842
847
  ```
843
848
 
849
+ If a type parameter has a lower bound, the type parameter must be instantiated with types that are a supertype of the lower bound.
850
+
851
+ ```rbs
852
+ class PrettyPrint[T > Numeric]
853
+ end
854
+
855
+ type obj_printer = PrettyPrint[Object] # OK
856
+ type int_printer = PrettyPrint[Integer] # Type error
857
+ ```
858
+
859
+ A type parameter can have both an upper and a lower bound, and these bounds can be specified in any order.
860
+
861
+ ```rbs
862
+ class FlexibleProcessor[T > Integer < Numeric]
863
+ # This class processes types T that are supertypes of Integer but also subtypes of Numeric.
864
+ # This includes Integer, Rational, Complex, Float, and Numeric itself.
865
+ def calculate: (T) -> T
866
+ end
867
+
868
+ type int_processor = FlexibleProcessor[Integer] # OK (Integer > Integer and Integer < Numeric)
869
+ type num_processor = FlexibleProcessor[Numeric] # OK (Numeric > Integer and Numeric < Numeric)
870
+ type obj_processor = FlexibleProcessor[Object] # Type error (Object is not < Numeric)
871
+ type str_processor = FlexibleProcessor[String] # Type error (String is not > Integer)
872
+ ```
873
+
844
874
  The generics type parameter of modules, classes, interfaces, or type aliases can have a default type.
845
875
 
846
876
  ```rbs
@@ -0,0 +1,21 @@
1
+ # Type Fingerprint of RBS Inline AST
2
+
3
+ Type fingerprint of RBS Inline AST is an object that can be used to detect if the RBS Inline AST is updated and the type checker should type check the whole codebase again.
4
+
5
+ 1. If the AST update is related to the type information, the fingerprint is changed -- adding new type, including new module, changing method type, etc. The type checker should type check the codebase with updated type information.
6
+ 2. If the AST updated is not related to the type information, the fingerprint keeps the last value -- changing the method implementation, adding a method call in the top level, adding white spaces and new lines, etc. The type checker can skip updating the type information, and type checking only the implementation of the file is sufficient.
7
+ 3. Documentation comments are considered type related information for now.
8
+
9
+ ## Type Fingerprint Calculation
10
+
11
+ The type fingerprint is calculated by converting AST nodes to standardized data structures that represent only the type-relevant information. Each AST class implements a `type_fingerprint` method that returns mainly arrays and strings.
12
+
13
+ We expect not using the values for something other than change detection. Compare old and new fingerprints, and we can detect the change between the RBS inline AST if the fingerprints are different.
14
+
15
+ The fingerprint methods are implemented across:
16
+
17
+ - `AST::Ruby::Annotations::*#type_fingerprint` - Returns `untyped` (arrays, strings, or nil)
18
+ - `AST::Ruby::Members::*#type_fingerprint` - Returns `untyped` (typically arrays)
19
+ - `AST::Ruby::Declarations::*#type_fingerprint` - Returns `untyped` (typically arrays)
20
+ - `InlineParser::Result#type_fingerprint` - Returns `untyped` (array of declaration fingerprints)
21
+
@@ -0,0 +1,80 @@
1
+ # RBS AST binary serialization
2
+
3
+ This document describes the binary format used to move a parsed RBS AST out of
4
+ the parser and into Ruby objects without going through the Ruby C API. It exists
5
+ so that RBS can run on Ruby implementations that cannot load the C extension
6
+ (notably JRuby): the parser runs inside WebAssembly, serializes the result with
7
+ this format, and the host rebuilds `RBS::AST` objects in pure Ruby.
8
+
9
+ The encoder (`rbs_serialize_node`, `src/serialize.c`) and the schema that drives
10
+ the decoder (`RBS::WASM::SerializationSchema`, `lib/rbs/wasm/serialization_schema.rb`)
11
+ are both generated from `config.yml`, so they always agree. The decoder itself
12
+ is `RBS::WASM::Deserializer`.
13
+
14
+ ## Conventions
15
+
16
+ - All multi-byte integers are **little-endian**.
17
+ - `u8`, `u32` are unsigned; `i32` is signed.
18
+ - `str` is a `u32` byte length followed by that many raw bytes (no terminator).
19
+ - A value is reconstructed to mirror exactly what `ast_translation.c` produces,
20
+ including string encodings: string/integer literal nodes are UTF-8, while
21
+ comments, annotations and symbols use the source buffer's encoding.
22
+
23
+ ## Nodes
24
+
25
+ Every node begins with a `u8` **tag**:
26
+
27
+ - `0` — a NULL node (`nil` on the Ruby side).
28
+ - `1..N` — a node type, in the order they appear in `SerializationSchema::SCHEMA`.
29
+ - `SYMBOL_TAG` (`N + 1`) — an interned symbol, followed by `str` (the symbol's
30
+ bytes). Decoded with `String#to_sym`.
31
+
32
+ A few node types are encoded specially, matching their bespoke handling in
33
+ `ast_translation.c`:
34
+
35
+ | Node | Payload after tag | Decoded as |
36
+ | --- | --- | --- |
37
+ | `RBS::AST::Bool` | `u8` | `true` / `false` |
38
+ | `RBS::AST::Integer` | `str` | `String#to_i` |
39
+ | `RBS::AST::String` | `str` | the string (UTF-8) |
40
+ | `RBS::Types::Record::FieldType` | node, then `u8` | `[type, required]` |
41
+ | `RBS::Signature` | node-list, then node-list | `[directives, declarations]` |
42
+ | `RBS::Namespace` | node-list, then `u8` | `RBS::Namespace[path, absolute]` |
43
+ | `RBS::TypeName` | node, then node | `RBS::TypeName[namespace, name]` |
44
+
45
+ Every other node is encoded generically:
46
+
47
+ 1. If the node exposes a location, its **base location** is written (see below),
48
+ followed by one location range per declared child, in order.
49
+ 2. Each field is written in declaration order, encoded by its type (see below).
50
+
51
+ The decoder constructs `Klass.new(location:, **fields)` (omitting `location:`
52
+ for nodes that do not expose one). For `Class`, `Module`, `Interface`,
53
+ `TypeAlias` and `MethodType`, `RBS::AST::TypeParam.resolve_variables` is applied
54
+ to `type_params` first, exactly as the C translation does.
55
+
56
+ ## Fields
57
+
58
+ | Field type | Encoding |
59
+ | --- | --- |
60
+ | node (`rbs_node`, `rbs_type_name`, `rbs_ast_comment`, `rbs_ast_symbol`, ...) | a node (recursive; NULL allowed) |
61
+ | `rbs_node_list` | `u32` count, then that many nodes |
62
+ | `rbs_hash` | `u32` count, then count × (key node, value node) |
63
+ | `rbs_string` | `str` (source encoding) |
64
+ | `bool` | `u8` |
65
+ | enum | `u8` index into the enum's values (see `SCHEMA`) |
66
+ | `rbs_location_range` | a location range |
67
+ | `rbs_location_range_list` | `u32` count, then that many location ranges |
68
+ | `rbs_attr_ivar_name` | `u8` tag: `0` → `nil`, `1` → `false`, `2` → `str` → symbol |
69
+
70
+ ## Location ranges
71
+
72
+ A location range is a `u8` presence flag:
73
+
74
+ - `0` — null range (`nil`, or a node with no location).
75
+ - `1` — followed by `i32` start and `i32` end **character** positions.
76
+
77
+ The base location and child ranges together let the decoder rebuild an
78
+ `RBS::Location` (with its required/optional children) through the public
79
+ `RBS::Location` API, so the same decoder works whether `RBS::Location` is backed
80
+ by the C extension or a pure-Ruby implementation.
data/exe/rbs CHANGED
@@ -4,4 +4,4 @@ $LOAD_PATH << File.join(__dir__, "../lib")
4
4
  require "rbs"
5
5
  require "rbs/cli"
6
6
 
7
- RBS::CLI.new(stdout: STDOUT, stderr: STDERR).run(ARGV.dup)
7
+ exit RBS::CLI.new(stdout: STDOUT, stderr: STDERR).run(ARGV.dup)