rbs 4.0.0.dev.4 → 4.1.0.pre.2

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 (306) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +1 -0
  3. data/.github/dependabot.yml +16 -14
  4. data/.github/workflows/bundle-update.yml +63 -0
  5. data/.github/workflows/c-check.yml +21 -11
  6. data/.github/workflows/comments.yml +5 -3
  7. data/.github/workflows/dependabot.yml +2 -2
  8. data/.github/workflows/jruby.yml +67 -0
  9. data/.github/workflows/milestone.yml +83 -0
  10. data/.github/workflows/ruby.yml +63 -24
  11. data/.github/workflows/rust.yml +184 -0
  12. data/.github/workflows/truffleruby.yml +54 -0
  13. data/.github/workflows/typecheck.yml +5 -2
  14. data/.github/workflows/wasm.yml +53 -0
  15. data/.github/workflows/windows.yml +8 -2
  16. data/.gitignore +11 -0
  17. data/.rubocop.yml +1 -1
  18. data/CHANGELOG.md +357 -0
  19. data/README.md +4 -4
  20. data/Rakefile +365 -33
  21. data/Steepfile +8 -0
  22. data/config.yml +450 -24
  23. data/core/array.rbs +443 -363
  24. data/core/basic_object.rbs +9 -8
  25. data/core/binding.rbs +0 -2
  26. data/core/builtin.rbs +9 -8
  27. data/core/class.rbs +11 -8
  28. data/core/comparable.rbs +55 -34
  29. data/core/complex.rbs +104 -78
  30. data/core/dir.rbs +61 -49
  31. data/core/encoding.rbs +12 -15
  32. data/core/enumerable.rbs +288 -196
  33. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  34. data/core/enumerator/product.rbs +5 -5
  35. data/core/enumerator.rbs +91 -28
  36. data/core/errno.rbs +11 -2
  37. data/core/errors.rbs +58 -29
  38. data/core/exception.rbs +13 -13
  39. data/core/fiber.rbs +74 -54
  40. data/core/file.rbs +260 -1151
  41. data/core/file_constants.rbs +463 -0
  42. data/core/file_stat.rbs +534 -0
  43. data/core/file_test.rbs +3 -3
  44. data/core/float.rbs +257 -92
  45. data/core/gc.rbs +425 -281
  46. data/core/hash.rbs +1151 -829
  47. data/core/integer.rbs +156 -195
  48. data/core/io/buffer.rbs +53 -42
  49. data/core/io/wait.rbs +13 -35
  50. data/core/io.rbs +216 -150
  51. data/core/kernel.rbs +239 -163
  52. data/core/marshal.rbs +4 -4
  53. data/core/match_data.rbs +15 -13
  54. data/core/math.rbs +107 -66
  55. data/core/method.rbs +69 -33
  56. data/core/module.rbs +302 -150
  57. data/core/nil_class.rbs +7 -6
  58. data/core/numeric.rbs +77 -63
  59. data/core/object.rbs +9 -11
  60. data/core/object_space/weak_key_map.rbs +7 -7
  61. data/core/object_space.rbs +30 -23
  62. data/core/pathname.rbs +1322 -0
  63. data/core/proc.rbs +95 -58
  64. data/core/process.rbs +222 -202
  65. data/core/ractor.rbs +371 -515
  66. data/core/random.rbs +21 -3
  67. data/core/range.rbs +181 -79
  68. data/core/rational.rbs +60 -89
  69. data/core/rbs/ops.rbs +154 -0
  70. data/core/rbs/unnamed/argf.rbs +63 -56
  71. data/core/rbs/unnamed/env_class.rbs +19 -14
  72. data/core/rbs/unnamed/main_class.rbs +123 -0
  73. data/core/rbs/unnamed/random.rbs +11 -118
  74. data/core/regexp.rbs +258 -214
  75. data/core/ruby.rbs +53 -0
  76. data/core/ruby_vm.rbs +78 -34
  77. data/core/rubygems/config_file.rbs +5 -5
  78. data/core/rubygems/errors.rbs +4 -71
  79. data/core/rubygems/requirement.rbs +5 -5
  80. data/core/rubygems/rubygems.rbs +16 -82
  81. data/core/rubygems/version.rbs +2 -3
  82. data/core/set.rbs +493 -363
  83. data/core/signal.rbs +26 -16
  84. data/core/string.rbs +3234 -1285
  85. data/core/struct.rbs +43 -42
  86. data/core/symbol.rbs +41 -34
  87. data/core/thread.rbs +141 -73
  88. data/core/time.rbs +81 -50
  89. data/core/trace_point.rbs +41 -35
  90. data/core/true_class.rbs +2 -2
  91. data/core/unbound_method.rbs +24 -16
  92. data/core/warning.rbs +7 -7
  93. data/docs/CONTRIBUTING.md +2 -1
  94. data/docs/aliases.md +79 -0
  95. data/docs/collection.md +3 -3
  96. data/docs/config.md +171 -0
  97. data/docs/encoding.md +56 -0
  98. data/docs/gem.md +0 -1
  99. data/docs/inline.md +634 -0
  100. data/docs/rbs_by_example.md +20 -20
  101. data/docs/rust.md +96 -0
  102. data/docs/sigs.md +3 -3
  103. data/docs/syntax.md +48 -18
  104. data/docs/type_fingerprint.md +21 -0
  105. data/docs/wasm_serialization.md +80 -0
  106. data/exe/rbs +1 -1
  107. data/ext/rbs_extension/ast_translation.c +1441 -671
  108. data/ext/rbs_extension/ast_translation.h +7 -0
  109. data/ext/rbs_extension/class_constants.c +18 -2
  110. data/ext/rbs_extension/class_constants.h +9 -0
  111. data/ext/rbs_extension/extconf.rb +6 -1
  112. data/ext/rbs_extension/legacy_location.c +33 -56
  113. data/ext/rbs_extension/legacy_location.h +37 -0
  114. data/ext/rbs_extension/main.c +183 -39
  115. data/include/rbs/ast.h +597 -297
  116. data/include/rbs/defines.h +40 -0
  117. data/include/rbs/lexer.h +31 -11
  118. data/include/rbs/location.h +25 -44
  119. data/include/rbs/parser.h +6 -6
  120. data/include/rbs/serialize.h +39 -0
  121. data/include/rbs/string.h +0 -2
  122. data/include/rbs/util/rbs_allocator.h +34 -13
  123. data/include/rbs/util/rbs_assert.h +12 -1
  124. data/include/rbs/util/rbs_constant_pool.h +0 -3
  125. data/include/rbs/util/rbs_encoding.h +2 -0
  126. data/include/rbs/util/rbs_unescape.h +2 -1
  127. data/include/rbs.h +8 -0
  128. data/lib/rbs/annotate/rdoc_annotator.rb +27 -31
  129. data/lib/rbs/ast/annotation.rb +1 -1
  130. data/lib/rbs/ast/comment.rb +1 -1
  131. data/lib/rbs/ast/declarations.rb +10 -10
  132. data/lib/rbs/ast/members.rb +14 -14
  133. data/lib/rbs/ast/ruby/annotations.rb +335 -3
  134. data/lib/rbs/ast/ruby/comment_block.rb +30 -4
  135. data/lib/rbs/ast/ruby/declarations.rb +209 -4
  136. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +4 -0
  137. data/lib/rbs/ast/ruby/helpers/location_helper.rb +1 -1
  138. data/lib/rbs/ast/ruby/members.rb +571 -22
  139. data/lib/rbs/ast/type_param.rb +24 -4
  140. data/lib/rbs/buffer.rb +66 -24
  141. data/lib/rbs/cli/diff.rb +16 -15
  142. data/lib/rbs/cli/validate.rb +38 -106
  143. data/lib/rbs/cli.rb +55 -24
  144. data/lib/rbs/collection/config/lockfile_generator.rb +28 -3
  145. data/lib/rbs/collection/sources/git.rb +7 -0
  146. data/lib/rbs/definition.rb +1 -1
  147. data/lib/rbs/definition_builder/ancestor_builder.rb +62 -9
  148. data/lib/rbs/definition_builder/method_builder.rb +32 -6
  149. data/lib/rbs/definition_builder.rb +147 -25
  150. data/lib/rbs/diff.rb +7 -1
  151. data/lib/rbs/environment.rb +235 -75
  152. data/lib/rbs/environment_loader.rb +0 -6
  153. data/lib/rbs/errors.rb +27 -18
  154. data/lib/rbs/inline_parser.rb +377 -15
  155. data/lib/rbs/location_aux.rb +1 -1
  156. data/lib/rbs/locator.rb +5 -1
  157. data/lib/rbs/method_type.rb +5 -3
  158. data/lib/rbs/namespace.rb +47 -11
  159. data/lib/rbs/parser_aux.rb +20 -7
  160. data/lib/rbs/prototype/helpers.rb +57 -0
  161. data/lib/rbs/prototype/rb.rb +3 -28
  162. data/lib/rbs/prototype/rbi.rb +3 -20
  163. data/lib/rbs/prototype/runtime.rb +10 -0
  164. data/lib/rbs/resolver/constant_resolver.rb +2 -2
  165. data/lib/rbs/resolver/type_name_resolver.rb +120 -44
  166. data/lib/rbs/rewriter.rb +70 -0
  167. data/lib/rbs/subtractor.rb +3 -1
  168. data/lib/rbs/test/type_check.rb +25 -3
  169. data/lib/rbs/type_name.rb +34 -14
  170. data/lib/rbs/types.rb +88 -78
  171. data/lib/rbs/unit_test/type_assertions.rb +44 -8
  172. data/lib/rbs/validator.rb +2 -2
  173. data/lib/rbs/version.rb +1 -1
  174. data/lib/rbs/wasm/deserializer.rb +213 -0
  175. data/lib/rbs/wasm/location.rb +61 -0
  176. data/lib/rbs/wasm/parser.rb +137 -0
  177. data/lib/rbs/wasm/runtime.rb +217 -0
  178. data/lib/rbs/wasm/serialization_schema.rb +110 -0
  179. data/lib/rbs.rb +13 -2
  180. data/lib/rdoc/discover.rb +1 -1
  181. data/lib/rdoc_plugin/parser.rb +1 -1
  182. data/rbs.gemspec +24 -6
  183. data/schema/typeParam.json +17 -1
  184. data/sig/annotate/rdoc_annotater.rbs +12 -9
  185. data/sig/ast/ruby/annotations.rbs +364 -4
  186. data/sig/ast/ruby/comment_block.rbs +8 -0
  187. data/sig/ast/ruby/declarations.rbs +102 -4
  188. data/sig/ast/ruby/members.rbs +128 -2
  189. data/sig/buffer.rbs +19 -1
  190. data/sig/cli/diff.rbs +5 -11
  191. data/sig/cli/validate.rbs +12 -8
  192. data/sig/cli.rbs +18 -18
  193. data/sig/collection/config/lockfile_generator.rbs +2 -0
  194. data/sig/definition.rbs +6 -1
  195. data/sig/definition_builder.rbs +2 -0
  196. data/sig/environment.rbs +70 -12
  197. data/sig/errors.rbs +13 -14
  198. data/sig/inline_parser.rbs +41 -2
  199. data/sig/locator.rbs +0 -2
  200. data/sig/manifest.yaml +0 -2
  201. data/sig/method_builder.rbs +3 -1
  202. data/sig/namespace.rbs +20 -0
  203. data/sig/parser.rbs +41 -13
  204. data/sig/prototype/helpers.rbs +2 -0
  205. data/sig/resolver/type_name_resolver.rbs +36 -10
  206. data/sig/rewriter.rbs +45 -0
  207. data/sig/source.rbs +3 -3
  208. data/sig/type_param.rbs +13 -8
  209. data/sig/typename.rbs +15 -0
  210. data/sig/types.rbs +6 -7
  211. data/sig/unit_test/spy.rbs +0 -8
  212. data/sig/unit_test/type_assertions.rbs +15 -0
  213. data/sig/wasm/deserializer.rbs +66 -0
  214. data/sig/wasm/serialization_schema.rbs +13 -0
  215. data/src/ast.c +443 -162
  216. data/src/lexer.c +1415 -1313
  217. data/src/lexer.re +4 -0
  218. data/src/lexstate.c +63 -37
  219. data/src/location.c +7 -47
  220. data/src/parser.c +1032 -521
  221. data/src/serialize.c +958 -0
  222. data/src/string.c +0 -48
  223. data/src/util/rbs_allocator.c +89 -74
  224. data/src/util/rbs_assert.c +1 -1
  225. data/src/util/rbs_buffer.c +2 -2
  226. data/src/util/rbs_constant_pool.c +10 -14
  227. data/src/util/rbs_encoding.c +4 -8
  228. data/src/util/rbs_unescape.c +56 -20
  229. data/stdlib/abbrev/0/array.rbs +1 -1
  230. data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
  231. data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
  232. data/stdlib/cgi/0/core.rbs +9 -393
  233. data/stdlib/cgi/0/manifest.yaml +1 -0
  234. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  235. data/stdlib/coverage/0/coverage.rbs +7 -4
  236. data/stdlib/csv/0/csv.rbs +5 -5
  237. data/stdlib/date/0/date.rbs +92 -79
  238. data/stdlib/date/0/date_time.rbs +25 -24
  239. data/stdlib/delegate/0/delegator.rbs +10 -7
  240. data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
  241. data/stdlib/digest/0/digest.rbs +111 -1
  242. data/stdlib/erb/0/erb.rbs +748 -347
  243. data/stdlib/etc/0/etc.rbs +73 -54
  244. data/stdlib/fileutils/0/fileutils.rbs +179 -160
  245. data/stdlib/forwardable/0/forwardable.rbs +13 -10
  246. data/stdlib/io-console/0/io-console.rbs +2 -2
  247. data/stdlib/json/0/json.rbs +223 -142
  248. data/stdlib/monitor/0/monitor.rbs +3 -3
  249. data/stdlib/net-http/0/net-http.rbs +162 -134
  250. data/stdlib/objspace/0/objspace.rbs +17 -34
  251. data/stdlib/open-uri/0/open-uri.rbs +48 -8
  252. data/stdlib/open3/0/open3.rbs +469 -10
  253. data/stdlib/openssl/0/openssl.rbs +482 -364
  254. data/stdlib/optparse/0/optparse.rbs +26 -17
  255. data/stdlib/pathname/0/pathname.rbs +11 -1381
  256. data/stdlib/pp/0/pp.rbs +9 -8
  257. data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
  258. data/stdlib/pstore/0/pstore.rbs +35 -30
  259. data/stdlib/psych/0/psych.rbs +65 -12
  260. data/stdlib/psych/0/store.rbs +2 -4
  261. data/stdlib/pty/0/pty.rbs +9 -6
  262. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  263. data/stdlib/rdoc/0/code_object.rbs +2 -1
  264. data/stdlib/rdoc/0/parser.rbs +1 -1
  265. data/stdlib/rdoc/0/rdoc.rbs +1 -1
  266. data/stdlib/rdoc/0/store.rbs +1 -1
  267. data/stdlib/resolv/0/resolv.rbs +26 -69
  268. data/stdlib/ripper/0/ripper.rbs +22 -19
  269. data/stdlib/securerandom/0/manifest.yaml +2 -0
  270. data/stdlib/securerandom/0/securerandom.rbs +7 -20
  271. data/stdlib/shellwords/0/shellwords.rbs +3 -3
  272. data/stdlib/singleton/0/singleton.rbs +3 -0
  273. data/stdlib/socket/0/addrinfo.rbs +7 -7
  274. data/stdlib/socket/0/basic_socket.rbs +3 -3
  275. data/stdlib/socket/0/ip_socket.rbs +10 -8
  276. data/stdlib/socket/0/socket.rbs +23 -10
  277. data/stdlib/socket/0/tcp_server.rbs +1 -1
  278. data/stdlib/socket/0/tcp_socket.rbs +11 -3
  279. data/stdlib/socket/0/udp_socket.rbs +1 -1
  280. data/stdlib/socket/0/unix_server.rbs +1 -1
  281. data/stdlib/stringio/0/stringio.rbs +1209 -95
  282. data/stdlib/strscan/0/string_scanner.rbs +101 -80
  283. data/stdlib/tempfile/0/tempfile.rbs +25 -21
  284. data/stdlib/time/0/time.rbs +8 -6
  285. data/stdlib/timeout/0/timeout.rbs +63 -7
  286. data/stdlib/tsort/0/cyclic.rbs +4 -1
  287. data/stdlib/tsort/0/interfaces.rbs +8 -8
  288. data/stdlib/tsort/0/tsort.rbs +16 -15
  289. data/stdlib/uri/0/common.rbs +42 -20
  290. data/stdlib/uri/0/file.rbs +3 -3
  291. data/stdlib/uri/0/generic.rbs +26 -18
  292. data/stdlib/uri/0/http.rbs +2 -2
  293. data/stdlib/uri/0/ldap.rbs +2 -2
  294. data/stdlib/uri/0/mailto.rbs +3 -3
  295. data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
  296. data/stdlib/zlib/0/deflate.rbs +4 -3
  297. data/stdlib/zlib/0/gzip_reader.rbs +8 -8
  298. data/stdlib/zlib/0/gzip_writer.rbs +14 -12
  299. data/stdlib/zlib/0/inflate.rbs +1 -1
  300. data/stdlib/zlib/0/need_dict.rbs +1 -1
  301. data/stdlib/zlib/0/zstream.rbs +1 -0
  302. data/wasm/README.md +59 -0
  303. data/wasm/rbs_wasm.c +411 -0
  304. metadata +56 -8
  305. data/.vscode/extensions.json +0 -5
  306. data/.vscode/settings.json +0 -19
data/wasm/rbs_wasm.c ADDED
@@ -0,0 +1,411 @@
1
+ /**
2
+ * @file rbs_wasm.c
3
+ *
4
+ * WebAssembly entry points for the RBS parser.
5
+ *
6
+ * The parser in `src/` is plain, self-contained C with no dependency on the
7
+ * Ruby C API, so it compiles to WebAssembly as-is. This file exposes a small,
8
+ * stable ABI so the parser can be driven from a WebAssembly host (a JVM-based
9
+ * runtime running under JRuby).
10
+ *
11
+ * The flow is: the host writes a UTF-8 source string into linear memory
12
+ * (`rbs_wasm_alloc`), calls one of the `rbs_wasm_parse_*` functions, and reads
13
+ * the result back out (`rbs_wasm_result_ptr` / `rbs_wasm_result_len`). On
14
+ * success the result is the serialized AST (see `rbs_serialize_node` and
15
+ * `docs/wasm_serialization.md`); on a parse error it is an error blob (see
16
+ * `set_error_result`). `RBS::WASM` on the Ruby side decodes both.
17
+ *
18
+ * Built as a "reactor": no `main`, and the host calls `_initialize` once before
19
+ * invoking any export.
20
+ */
21
+
22
+ #include <stdint.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+
26
+ #include "rbs/parser.h"
27
+ #include "rbs/serialize.h"
28
+ #include "rbs/string.h"
29
+ #include "rbs/util/rbs_buffer.h"
30
+ #include "rbs/util/rbs_encoding.h"
31
+
32
+ // The result of the most recent parse, living in linear memory until the next
33
+ // call replaces it. WebAssembly is little-endian, so the multi-byte integers
34
+ // written below match the little-endian format the Ruby decoder expects.
35
+ static char *result_buffer = NULL;
36
+ static int32_t result_length = 0;
37
+
38
+ // Replace the current result with a fresh `length`-byte buffer and return a
39
+ // pointer to it for the caller to fill in.
40
+ static char *allocate_result(size_t length) {
41
+ free(result_buffer);
42
+ result_buffer = (char *) malloc(length == 0 ? 1 : length);
43
+ result_length = (int32_t) length;
44
+ return result_buffer;
45
+ }
46
+
47
+ /**
48
+ * Allocate `size` bytes in linear memory and return the offset. The host uses
49
+ * this to reserve space for an input string before calling a parse function.
50
+ */
51
+ __attribute__((export_name("rbs_wasm_alloc"))) void *rbs_wasm_alloc(size_t size) {
52
+ return malloc(size);
53
+ }
54
+
55
+ /**
56
+ * Free a region previously returned by `rbs_wasm_alloc`.
57
+ */
58
+ __attribute__((export_name("rbs_wasm_free"))) void rbs_wasm_free(void *ptr) {
59
+ free(ptr);
60
+ }
61
+
62
+ /**
63
+ * Offset of the most recent parse result in linear memory.
64
+ */
65
+ __attribute__((export_name("rbs_wasm_result_ptr")))
66
+ int32_t
67
+ rbs_wasm_result_ptr(void) {
68
+ return (int32_t) (intptr_t) result_buffer;
69
+ }
70
+
71
+ /**
72
+ * Length, in bytes, of the most recent parse result.
73
+ */
74
+ __attribute__((export_name("rbs_wasm_result_len")))
75
+ int32_t
76
+ rbs_wasm_result_len(void) {
77
+ return result_length;
78
+ }
79
+
80
+ // Encode the parser's error into the result buffer:
81
+ //
82
+ // [i32 start_char][i32 end_char][u8 syntax_error]
83
+ // [u32 token_type_len][token_type bytes][u32 message_len][message bytes]
84
+ //
85
+ // Always returns 0, the failure status for the parse functions.
86
+ static int set_error_result(rbs_parser_t *parser) {
87
+ rbs_error_t *error = parser->error;
88
+ const char *token_type = rbs_token_type_str(error->token.type);
89
+ const char *message = error->message;
90
+ uint32_t token_type_len = (uint32_t) strlen(token_type);
91
+ uint32_t message_len = (uint32_t) strlen(message);
92
+
93
+ int32_t start_char = error->token.range.start.char_pos;
94
+ int32_t end_char = error->token.range.end.char_pos;
95
+ uint8_t syntax_error = error->syntax_error ? 1 : 0;
96
+
97
+ size_t total = 4 + 4 + 1 + 4 + token_type_len + 4 + message_len;
98
+ char *p = allocate_result(total);
99
+
100
+ memcpy(p, &start_char, 4);
101
+ p += 4;
102
+ memcpy(p, &end_char, 4);
103
+ p += 4;
104
+ *p++ = (char) syntax_error;
105
+ memcpy(p, &token_type_len, 4);
106
+ p += 4;
107
+ memcpy(p, token_type, token_type_len);
108
+ p += token_type_len;
109
+ memcpy(p, &message_len, 4);
110
+ p += 4;
111
+ memcpy(p, message, message_len);
112
+
113
+ return 0;
114
+ }
115
+
116
+ static int set_serialized_result(rbs_parser_t *parser, rbs_node_t *node) {
117
+ rbs_string_t bytes = rbs_serialize_node(parser->allocator, &parser->constant_pool, node);
118
+ size_t length = rbs_string_len(bytes);
119
+ memcpy(allocate_result(length), bytes.start, length);
120
+ return 1;
121
+ }
122
+
123
+ // A reversed or out-of-bounds range would make the lexer loop forever, which
124
+ // would hang the whole host. Hosts are expected to validate too (RBS::Parser
125
+ // raises on bad ranges), but guard here so a stray caller can never wedge the VM.
126
+ static bool range_is_valid(int start_pos, int end_pos, int length) {
127
+ return start_pos >= 0 && end_pos >= 0 && start_pos <= end_pos && end_pos <= length;
128
+ }
129
+
130
+ // Resolve a Ruby encoding name (e.g. "UTF-8", "EUC-JP") to an rbs encoding,
131
+ // falling back to UTF-8 when none is given or the name is not recognised.
132
+ static const rbs_encoding_t *resolve_encoding(const char *name, int name_length) {
133
+ if (name_length > 0) {
134
+ const rbs_encoding_t *encoding = rbs_encoding_find((const uint8_t *) name, (const uint8_t *) (name + name_length));
135
+ if (encoding != NULL) return encoding;
136
+ }
137
+ return RBS_ENCODING_UTF_8_ENTRY;
138
+ }
139
+
140
+ // Declare type variables from a buffer of newline-separated names. A negative
141
+ // length means "no variables given" (the parser keeps its default table).
142
+ static void declare_variables(rbs_parser_t *parser, const char *variables, int variables_length) {
143
+ if (variables_length < 0) return;
144
+
145
+ rbs_parser_push_typevar_table(parser, true);
146
+
147
+ const char *cursor = variables;
148
+ const char *end = variables + variables_length;
149
+ const char *name_start = cursor;
150
+
151
+ while (cursor <= end) {
152
+ if (cursor == end || *cursor == '\n') {
153
+ size_t name_length = (size_t) (cursor - name_start);
154
+ if (name_length > 0) {
155
+ uint8_t *copied = (uint8_t *) malloc(name_length);
156
+ memcpy(copied, name_start, name_length);
157
+ rbs_constant_id_t id = rbs_constant_pool_insert_owned(&parser->constant_pool, copied, name_length);
158
+ (void) rbs_parser_insert_typevar(parser, id);
159
+ }
160
+ name_start = cursor + 1;
161
+ }
162
+ cursor++;
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Parse an RBS signature from a source buffer.
168
+ *
169
+ * `source`/`length` is the whole buffer content; `encoding`/`encoding_length` is
170
+ * its Ruby encoding name; `start_pos`/`end_pos` are the character range within it
171
+ * to parse, so reported locations are absolute (this mirrors
172
+ * RBS::Parser._parse_signature).
173
+ *
174
+ * @return 1 on success (result is the serialized AST), 0 on a parse error
175
+ * (result is an error blob).
176
+ */
177
+ __attribute__((export_name("rbs_wasm_parse_signature"))) int rbs_wasm_parse_signature(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos) {
178
+ if (!range_is_valid(start_pos, end_pos, length)) {
179
+ allocate_result(0);
180
+ return 0;
181
+ }
182
+
183
+ rbs_string_t string = rbs_string_new(source, source + length);
184
+ rbs_parser_t *parser = rbs_parser_new(string, resolve_encoding(encoding, encoding_length), start_pos, end_pos);
185
+
186
+ rbs_signature_t *signature = NULL;
187
+ rbs_parse_signature(parser, &signature);
188
+
189
+ int status;
190
+ if (parser->error == NULL) {
191
+ status = set_serialized_result(parser, (rbs_node_t *) signature);
192
+ } else {
193
+ status = set_error_result(parser);
194
+ }
195
+
196
+ rbs_parser_free(parser);
197
+ return status;
198
+ }
199
+
200
+ /**
201
+ * Parse a single RBS type.
202
+ *
203
+ * @param variables Newline-separated type variable names (length < 0 for none).
204
+ * @return 1 on success, 0 on a parse error. On success with an empty result
205
+ * (`rbs_wasm_result_len` == 0), the input was empty (`nil`).
206
+ */
207
+ __attribute__((export_name("rbs_wasm_parse_type"))) int rbs_wasm_parse_type(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos, const char *variables, int variables_length, int require_eof, int void_allowed, int self_allowed, int classish_allowed) {
208
+ if (!range_is_valid(start_pos, end_pos, length)) {
209
+ allocate_result(0);
210
+ return 0;
211
+ }
212
+
213
+ rbs_string_t string = rbs_string_new(source, source + length);
214
+ rbs_parser_t *parser = rbs_parser_new(string, resolve_encoding(encoding, encoding_length), start_pos, end_pos);
215
+ declare_variables(parser, variables, variables_length);
216
+
217
+ int status;
218
+ if (parser->next_token.type == pEOF) {
219
+ allocate_result(0);
220
+ status = 1;
221
+ } else {
222
+ rbs_node_t *type = NULL;
223
+ rbs_parse_type(parser, &type, void_allowed != 0, self_allowed != 0, classish_allowed != 0);
224
+
225
+ if (parser->error == NULL && require_eof) {
226
+ rbs_parser_advance(parser);
227
+ if (parser->current_token.type != pEOF) {
228
+ rbs_parser_set_error(parser, parser->current_token, true, "expected a token `%s`", rbs_token_type_str(pEOF));
229
+ }
230
+ }
231
+
232
+ status = parser->error == NULL ? set_serialized_result(parser, type) : set_error_result(parser);
233
+ }
234
+
235
+ rbs_parser_free(parser);
236
+ return status;
237
+ }
238
+
239
+ /**
240
+ * Parse a single RBS method type.
241
+ *
242
+ * @param variables Newline-separated type variable names (length < 0 for none).
243
+ * @return 1 on success, 0 on a parse error. On success with an empty result,
244
+ * the input was empty (`nil`).
245
+ */
246
+ __attribute__((export_name("rbs_wasm_parse_method_type"))) int rbs_wasm_parse_method_type(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos, const char *variables, int variables_length, int require_eof) {
247
+ if (!range_is_valid(start_pos, end_pos, length)) {
248
+ allocate_result(0);
249
+ return 0;
250
+ }
251
+
252
+ rbs_string_t string = rbs_string_new(source, source + length);
253
+ rbs_parser_t *parser = rbs_parser_new(string, resolve_encoding(encoding, encoding_length), start_pos, end_pos);
254
+ declare_variables(parser, variables, variables_length);
255
+
256
+ int status;
257
+ if (parser->next_token.type == pEOF) {
258
+ allocate_result(0);
259
+ status = 1;
260
+ } else {
261
+ rbs_method_type_t *method_type = NULL;
262
+ rbs_parse_method_type(parser, &method_type, require_eof != 0, true);
263
+
264
+ status = parser->error == NULL ? set_serialized_result(parser, (rbs_node_t *) method_type) : set_error_result(parser);
265
+ }
266
+
267
+ rbs_parser_free(parser);
268
+ return status;
269
+ }
270
+
271
+ /**
272
+ * Parse a type parameter list (e.g. `[T < Comparable]`). On success the result
273
+ * is a serialized node list; an empty result means the input was empty (`nil`).
274
+ */
275
+ __attribute__((export_name("rbs_wasm_parse_type_params"))) int rbs_wasm_parse_type_params(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos, int module_type_params) {
276
+ if (!range_is_valid(start_pos, end_pos, length)) {
277
+ allocate_result(0);
278
+ return 0;
279
+ }
280
+
281
+ rbs_string_t string = rbs_string_new(source, source + length);
282
+ rbs_parser_t *parser = rbs_parser_new(string, resolve_encoding(encoding, encoding_length), start_pos, end_pos);
283
+
284
+ int status;
285
+ if (parser->next_token.type == pEOF) {
286
+ allocate_result(0);
287
+ status = 1;
288
+ } else {
289
+ rbs_node_list_t *params = NULL;
290
+ rbs_parse_type_params(parser, module_type_params != 0, &params);
291
+
292
+ if (parser->error == NULL) {
293
+ rbs_string_t bytes = rbs_serialize_node_list(parser->allocator, &parser->constant_pool, params);
294
+ size_t n = rbs_string_len(bytes);
295
+ memcpy(allocate_result(n), bytes.start, n);
296
+ status = 1;
297
+ } else {
298
+ status = set_error_result(parser);
299
+ }
300
+ }
301
+
302
+ rbs_parser_free(parser);
303
+ return status;
304
+ }
305
+
306
+ // Shared body for the leading/trailing inline annotation parsers.
307
+ static int parse_inline_annotation(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos, const char *variables, int variables_length, bool leading) {
308
+ if (!range_is_valid(start_pos, end_pos, length)) {
309
+ allocate_result(0);
310
+ return 0;
311
+ }
312
+
313
+ rbs_string_t string = rbs_string_new(source, source + length);
314
+ rbs_parser_t *parser = rbs_parser_new(string, resolve_encoding(encoding, encoding_length), start_pos, end_pos);
315
+ declare_variables(parser, variables, variables_length);
316
+
317
+ rbs_ast_ruby_annotations_t *annotation = NULL;
318
+ bool success = leading ? rbs_parse_inline_leading_annotation(parser, &annotation) : rbs_parse_inline_trailing_annotation(parser, &annotation);
319
+
320
+ int status;
321
+ if (parser->error != NULL) {
322
+ status = set_error_result(parser);
323
+ } else if (!success || annotation == NULL) {
324
+ allocate_result(0);
325
+ status = 1;
326
+ } else {
327
+ status = set_serialized_result(parser, (rbs_node_t *) annotation);
328
+ }
329
+
330
+ rbs_parser_free(parser);
331
+ return status;
332
+ }
333
+
334
+ /**
335
+ * Parse an inline leading annotation. On success the result is a serialized
336
+ * node; an empty result means there was no annotation (`nil`).
337
+ */
338
+ __attribute__((export_name("rbs_wasm_parse_inline_leading_annotation"))) int rbs_wasm_parse_inline_leading_annotation(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos, const char *variables, int variables_length) {
339
+ return parse_inline_annotation(source, length, encoding, encoding_length, start_pos, end_pos, variables, variables_length, true);
340
+ }
341
+
342
+ /**
343
+ * Parse an inline trailing annotation. See rbs_wasm_parse_inline_leading_annotation.
344
+ */
345
+ __attribute__((export_name("rbs_wasm_parse_inline_trailing_annotation"))) int rbs_wasm_parse_inline_trailing_annotation(const char *source, int length, const char *encoding, int encoding_length, int start_pos, int end_pos, const char *variables, int variables_length) {
346
+ return parse_inline_annotation(source, length, encoding, encoding_length, start_pos, end_pos, variables, variables_length, false);
347
+ }
348
+
349
+ static void w_lex_u32(rbs_allocator_t *allocator, rbs_buffer_t *buffer, uint32_t value) {
350
+ unsigned char bytes[4] = {
351
+ (unsigned char) (value & 0xff),
352
+ (unsigned char) ((value >> 8) & 0xff),
353
+ (unsigned char) ((value >> 16) & 0xff),
354
+ (unsigned char) ((value >> 24) & 0xff),
355
+ };
356
+ rbs_buffer_append_string(allocator, buffer, (const char *) bytes, 4);
357
+ }
358
+
359
+ /**
360
+ * Lex the source into tokens. The result is a sequence of records, with no
361
+ * leading count (the host reads until the buffer is exhausted):
362
+ *
363
+ * [u32 type_name_len][type_name bytes][i32 start_char][i32 end_char]
364
+ *
365
+ * The final token is always pEOF, mirroring RBS::Parser._lex.
366
+ *
367
+ * @return 1 always (lexing does not report parse errors here).
368
+ */
369
+ __attribute__((export_name("rbs_wasm_lex"))) int rbs_wasm_lex(const char *source, int length, const char *encoding, int encoding_length, int end_pos) {
370
+ rbs_allocator_t *allocator = rbs_allocator_init();
371
+ rbs_lexer_t *lexer = rbs_lexer_new(allocator, rbs_string_new(source, source + length), resolve_encoding(encoding, encoding_length), 0, end_pos);
372
+
373
+ rbs_buffer_t buffer;
374
+ rbs_buffer_init(allocator, &buffer);
375
+
376
+ rbs_token_t token = NullToken;
377
+ while (token.type != pEOF) {
378
+ token = rbs_lexer_next_token(lexer);
379
+
380
+ const char *type_name = rbs_token_type_str(token.type);
381
+ uint32_t type_name_length = (uint32_t) strlen(type_name);
382
+ w_lex_u32(allocator, &buffer, type_name_length);
383
+ rbs_buffer_append_string(allocator, &buffer, type_name, type_name_length);
384
+ w_lex_u32(allocator, &buffer, (uint32_t) token.range.start.char_pos);
385
+ w_lex_u32(allocator, &buffer, (uint32_t) token.range.end.char_pos);
386
+ }
387
+
388
+ rbs_string_t bytes = rbs_buffer_to_string(&buffer);
389
+ size_t n = rbs_string_len(bytes);
390
+ memcpy(allocate_result(n), bytes.start, n);
391
+
392
+ rbs_allocator_free(allocator);
393
+ return 1;
394
+ }
395
+
396
+ /**
397
+ * Parse a small, fixed RBS document, used as a build smoke test
398
+ * (`wasmtime run --invoke rbs_wasm_selftest rbs_parser.wasm`).
399
+ *
400
+ * @return 1 if the sample parsed successfully, 0 otherwise.
401
+ */
402
+ __attribute__((export_name("rbs_wasm_selftest"))) int rbs_wasm_selftest(void) {
403
+ static const char source[] =
404
+ "class User\n"
405
+ " attr_reader name: String\n"
406
+ " def initialize: (String name) -> void\n"
407
+ "end\n";
408
+
409
+ int length = (int) (sizeof(source) - 1);
410
+ return rbs_wasm_parse_signature(source, length, "UTF-8", 5, 0, length);
411
+ }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbs
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.dev.4
4
+ version: 4.1.0.pre.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-05-20 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: logger
@@ -29,14 +29,28 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 1.3.0
32
+ version: 1.6.0
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 1.3.0
39
+ version: 1.6.0
40
+ - !ruby/object:Gem::Dependency
41
+ name: tsort
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
40
54
  description: RBS is the language for type signatures for Ruby and standard library
41
55
  definitions.
42
56
  email:
@@ -50,16 +64,20 @@ files:
50
64
  - ".clang-format"
51
65
  - ".clangd"
52
66
  - ".github/dependabot.yml"
67
+ - ".github/workflows/bundle-update.yml"
53
68
  - ".github/workflows/c-check.yml"
54
69
  - ".github/workflows/comments.yml"
55
70
  - ".github/workflows/dependabot.yml"
71
+ - ".github/workflows/jruby.yml"
72
+ - ".github/workflows/milestone.yml"
56
73
  - ".github/workflows/ruby.yml"
74
+ - ".github/workflows/rust.yml"
75
+ - ".github/workflows/truffleruby.yml"
57
76
  - ".github/workflows/typecheck.yml"
77
+ - ".github/workflows/wasm.yml"
58
78
  - ".github/workflows/windows.yml"
59
79
  - ".gitignore"
60
80
  - ".rubocop.yml"
61
- - ".vscode/extensions.json"
62
- - ".vscode/settings.json"
63
81
  - BSDL
64
82
  - CHANGELOG.md
65
83
  - COPYING
@@ -80,6 +98,7 @@ files:
80
98
  - core/encoding.rbs
81
99
  - core/enumerable.rbs
82
100
  - core/enumerator.rbs
101
+ - core/enumerator/arithmetic_sequence.rbs
83
102
  - core/enumerator/product.rbs
84
103
  - core/env.rbs
85
104
  - core/errno.rbs
@@ -89,6 +108,8 @@ files:
89
108
  - core/fiber.rbs
90
109
  - core/fiber_error.rbs
91
110
  - core/file.rbs
111
+ - core/file_constants.rbs
112
+ - core/file_stat.rbs
92
113
  - core/file_test.rbs
93
114
  - core/float.rbs
94
115
  - core/gc.rbs
@@ -109,6 +130,7 @@ files:
109
130
  - core/object.rbs
110
131
  - core/object_space.rbs
111
132
  - core/object_space/weak_key_map.rbs
133
+ - core/pathname.rbs
112
134
  - core/proc.rbs
113
135
  - core/process.rbs
114
136
  - core/ractor.rbs
@@ -116,11 +138,14 @@ files:
116
138
  - core/range.rbs
117
139
  - core/rational.rbs
118
140
  - core/rb_config.rbs
141
+ - core/rbs/ops.rbs
119
142
  - core/rbs/unnamed/argf.rbs
120
143
  - core/rbs/unnamed/env_class.rbs
144
+ - core/rbs/unnamed/main_class.rbs
121
145
  - core/rbs/unnamed/random.rbs
122
146
  - core/refinement.rbs
123
147
  - core/regexp.rbs
148
+ - core/ruby.rbs
124
149
  - core/ruby_vm.rbs
125
150
  - core/rubygems/basic_specification.rbs
126
151
  - core/rubygems/config_file.rbs
@@ -150,16 +175,23 @@ files:
150
175
  - core/unbound_method.rbs
151
176
  - core/warning.rbs
152
177
  - docs/CONTRIBUTING.md
178
+ - docs/aliases.md
153
179
  - docs/architecture.md
154
180
  - docs/collection.md
181
+ - docs/config.md
155
182
  - docs/data_and_struct.md
183
+ - docs/encoding.md
156
184
  - docs/gem.md
185
+ - docs/inline.md
157
186
  - docs/rbs_by_example.md
158
187
  - docs/repo.md
188
+ - docs/rust.md
159
189
  - docs/sigs.md
160
190
  - docs/stdlib.md
161
191
  - docs/syntax.md
162
192
  - docs/tools.md
193
+ - docs/type_fingerprint.md
194
+ - docs/wasm_serialization.md
163
195
  - exe/rbs
164
196
  - ext/rbs_extension/ast_translation.c
165
197
  - ext/rbs_extension/ast_translation.h
@@ -180,6 +212,7 @@ files:
180
212
  - include/rbs/lexer.h
181
213
  - include/rbs/location.h
182
214
  - include/rbs/parser.h
215
+ - include/rbs/serialize.h
183
216
  - include/rbs/string.h
184
217
  - include/rbs/util/rbs_allocator.h
185
218
  - include/rbs/util/rbs_assert.h
@@ -260,6 +293,7 @@ files:
260
293
  - lib/rbs/repository.rb
261
294
  - lib/rbs/resolver/constant_resolver.rb
262
295
  - lib/rbs/resolver/type_name_resolver.rb
296
+ - lib/rbs/rewriter.rb
263
297
  - lib/rbs/sorter.rb
264
298
  - lib/rbs/source.rb
265
299
  - lib/rbs/substitution.rb
@@ -286,6 +320,11 @@ files:
286
320
  - lib/rbs/variance_calculator.rb
287
321
  - lib/rbs/vendorer.rb
288
322
  - lib/rbs/version.rb
323
+ - lib/rbs/wasm/deserializer.rb
324
+ - lib/rbs/wasm/location.rb
325
+ - lib/rbs/wasm/parser.rb
326
+ - lib/rbs/wasm/runtime.rb
327
+ - lib/rbs/wasm/serialization_schema.rb
289
328
  - lib/rbs/writer.rb
290
329
  - lib/rdoc/discover.rb
291
330
  - lib/rdoc_plugin/parser.rb
@@ -361,6 +400,7 @@ files:
361
400
  - sig/resolver/constant_resolver.rbs
362
401
  - sig/resolver/context.rbs
363
402
  - sig/resolver/type_name_resolver.rbs
403
+ - sig/rewriter.rbs
364
404
  - sig/shims/bundler.rbs
365
405
  - sig/shims/enumerable.rbs
366
406
  - sig/shims/rubygems.rbs
@@ -388,6 +428,8 @@ files:
388
428
  - sig/vendorer.rbs
389
429
  - sig/version.rbs
390
430
  - sig/visitor.rbs
431
+ - sig/wasm/deserializer.rbs
432
+ - sig/wasm/serialization_schema.rbs
391
433
  - sig/writer.rbs
392
434
  - src/ast.c
393
435
  - src/lexer.c
@@ -395,6 +437,7 @@ files:
395
437
  - src/lexstate.c
396
438
  - src/location.c
397
439
  - src/parser.c
440
+ - src/serialize.c
398
441
  - src/string.c
399
442
  - src/util/rbs_allocator.c
400
443
  - src/util/rbs_assert.c
@@ -409,6 +452,7 @@ files:
409
452
  - stdlib/bigdecimal-math/0/big_math.rbs
410
453
  - stdlib/bigdecimal-math/0/manifest.yaml
411
454
  - stdlib/bigdecimal/0/big_decimal.rbs
455
+ - stdlib/cgi-escape/0/escape.rbs
412
456
  - stdlib/cgi/0/core.rbs
413
457
  - stdlib/cgi/0/manifest.yaml
414
458
  - stdlib/coverage/0/coverage.rbs
@@ -504,6 +548,7 @@ files:
504
548
  - stdlib/psych/0/psych.rbs
505
549
  - stdlib/psych/0/store.rbs
506
550
  - stdlib/pty/0/pty.rbs
551
+ - stdlib/random-formatter/0/random-formatter.rbs
507
552
  - stdlib/rdoc/0/code_object.rbs
508
553
  - stdlib/rdoc/0/comment.rbs
509
554
  - stdlib/rdoc/0/context.rbs
@@ -517,6 +562,7 @@ files:
517
562
  - stdlib/resolv/0/manifest.yaml
518
563
  - stdlib/resolv/0/resolv.rbs
519
564
  - stdlib/ripper/0/ripper.rbs
565
+ - stdlib/securerandom/0/manifest.yaml
520
566
  - stdlib/securerandom/0/securerandom.rbs
521
567
  - stdlib/shellwords/0/shellwords.rbs
522
568
  - stdlib/singleton/0/singleton.rbs
@@ -574,6 +620,8 @@ files:
574
620
  - stdlib/zlib/0/version_error.rbs
575
621
  - stdlib/zlib/0/zlib.rbs
576
622
  - stdlib/zlib/0/zstream.rbs
623
+ - wasm/README.md
624
+ - wasm/rbs_wasm.c
577
625
  homepage: https://github.com/ruby/rbs
578
626
  licenses:
579
627
  - BSD-2-Clause
@@ -589,14 +637,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
589
637
  requirements:
590
638
  - - ">="
591
639
  - !ruby/object:Gem::Version
592
- version: '3.1'
640
+ version: '3.2'
593
641
  required_rubygems_version: !ruby/object:Gem::Requirement
594
642
  requirements:
595
643
  - - ">="
596
644
  - !ruby/object:Gem::Version
597
645
  version: '0'
598
646
  requirements: []
599
- rubygems_version: 3.6.2
647
+ rubygems_version: 4.0.3
600
648
  specification_version: 4
601
649
  summary: Type signature for Ruby.
602
650
  test_files: []
@@ -1,5 +0,0 @@
1
- {
2
- "recommendations": [
3
- "llvm-vs-code-extensions.vscode-clangd"
4
- ]
5
- }
@@ -1,19 +0,0 @@
1
- {
2
- "clangd.onConfigChanged": "restart",
3
- "[c]": {
4
- "editor.formatOnSave": true,
5
- "editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
6
- },
7
- "[cpp]": {
8
- "editor.formatOnSave": true,
9
- "editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
10
- },
11
- "[h]": {
12
- "editor.formatOnSave": true,
13
- "editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
14
- },
15
- "[hpp]": {
16
- "editor.formatOnSave": true,
17
- "editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
18
- }
19
- }