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
@@ -2,6 +2,7 @@
2
2
  #include "rbs/util/rbs_assert.h"
3
3
  #include "rbs/util/rbs_allocator.h"
4
4
  #include "rbs/util/rbs_constant_pool.h"
5
+ #include "rbs/serialize.h"
5
6
  #include "ast_translation.h"
6
7
  #include "legacy_location.h"
7
8
  #include "rbs_string_bridging.h"
@@ -16,7 +17,7 @@
16
17
  * ```
17
18
  * */
18
19
  static NORETURN(void) raise_error(rbs_error_t *error, VALUE buffer) {
19
- rbs_assert(error != NULL, "raise_error() called with NULL error");
20
+ RBS_ASSERT(error != NULL, "raise_error() called with NULL error");
20
21
 
21
22
  if (!error->syntax_error) {
22
23
  rb_raise(rb_eRuntimeError, "Unexpected error");
@@ -67,10 +68,12 @@ static void declare_type_variables(rbs_parser_t *parser, VALUE variables, VALUE
67
68
  }
68
69
 
69
70
  VALUE name_str = rb_sym2str(symbol);
71
+ uint8_t *copied_name = (uint8_t *) malloc((size_t) RSTRING_LEN(name_str));
72
+ memcpy((void *) copied_name, RSTRING_PTR(name_str), RSTRING_LEN(name_str));
70
73
 
71
- rbs_constant_id_t id = rbs_constant_pool_insert_shared(
74
+ rbs_constant_id_t id = rbs_constant_pool_insert_owned(
72
75
  &parser->constant_pool,
73
- (const uint8_t *) RSTRING_PTR(name_str),
76
+ copied_name,
74
77
  RSTRING_LEN(name_str)
75
78
  );
76
79
 
@@ -85,6 +88,23 @@ struct parse_type_arg {
85
88
  rb_encoding *encoding;
86
89
  rbs_parser_t *parser;
87
90
  VALUE require_eof;
91
+ VALUE void_allowed;
92
+ VALUE self_allowed;
93
+ VALUE classish_allowed;
94
+ };
95
+
96
+ struct parse_method_type_arg {
97
+ VALUE buffer;
98
+ rb_encoding *encoding;
99
+ rbs_parser_t *parser;
100
+ VALUE require_eof;
101
+ };
102
+
103
+ struct parse_signature_arg {
104
+ VALUE buffer;
105
+ rb_encoding *encoding;
106
+ rbs_parser_t *parser;
107
+ VALUE require_eof;
88
108
  };
89
109
 
90
110
  static VALUE ensure_free_parser(VALUE parser) {
@@ -100,8 +120,12 @@ static VALUE parse_type_try(VALUE a) {
100
120
  return Qnil;
101
121
  }
102
122
 
123
+ bool void_allowed = RTEST(arg->void_allowed);
124
+ bool self_allowed = RTEST(arg->self_allowed);
125
+ bool classish_allowed = RTEST(arg->classish_allowed);
126
+
103
127
  rbs_node_t *type;
104
- rbs_parse_type(parser, &type);
128
+ rbs_parse_type(parser, &type, void_allowed, self_allowed, classish_allowed);
105
129
 
106
130
  raise_error_if_any(parser, arg->buffer);
107
131
 
@@ -122,10 +146,17 @@ static VALUE parse_type_try(VALUE a) {
122
146
  return rbs_struct_to_ruby_value(ctx, type);
123
147
  }
124
148
 
125
- static rbs_lexer_t *alloc_lexer_from_buffer(rbs_allocator_t *allocator, VALUE string, rb_encoding *encoding, int start_pos, int end_pos) {
149
+ static void validate_position_range(int start_pos, int end_pos) {
126
150
  if (start_pos < 0 || end_pos < 0) {
127
151
  rb_raise(rb_eArgError, "negative position range: %d...%d", start_pos, end_pos);
128
152
  }
153
+ if (start_pos > end_pos) {
154
+ rb_raise(rb_eArgError, "invalid position range: %d...%d", start_pos, end_pos);
155
+ }
156
+ }
157
+
158
+ static rbs_lexer_t *alloc_lexer_from_buffer(rbs_allocator_t *allocator, VALUE string, rb_encoding *encoding, int start_pos, int end_pos) {
159
+ validate_position_range(start_pos, end_pos);
129
160
 
130
161
  const char *encoding_name = rb_enc_name(encoding);
131
162
 
@@ -139,9 +170,7 @@ static rbs_lexer_t *alloc_lexer_from_buffer(rbs_allocator_t *allocator, VALUE st
139
170
  }
140
171
 
141
172
  static rbs_parser_t *alloc_parser_from_buffer(VALUE buffer, int start_pos, int end_pos) {
142
- if (start_pos < 0 || end_pos < 0) {
143
- rb_raise(rb_eArgError, "negative position range: %d...%d", start_pos, end_pos);
144
- }
173
+ validate_position_range(start_pos, end_pos);
145
174
 
146
175
  VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
147
176
  StringValue(string);
@@ -157,7 +186,7 @@ static rbs_parser_t *alloc_parser_from_buffer(VALUE buffer, int start_pos, int e
157
186
  );
158
187
  }
159
188
 
160
- static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof) {
189
+ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed, VALUE self_allowed, VALUE classish_allowed) {
161
190
  VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
162
191
  StringValue(string);
163
192
  rb_encoding *encoding = rb_enc_get(string);
@@ -168,7 +197,10 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL
168
197
  .buffer = buffer,
169
198
  .encoding = encoding,
170
199
  .parser = parser,
171
- .require_eof = require_eof
200
+ .require_eof = require_eof,
201
+ .void_allowed = void_allowed,
202
+ .self_allowed = self_allowed,
203
+ .classish_allowed = classish_allowed
172
204
  };
173
205
 
174
206
  VALUE result = rb_ensure(parse_type_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
@@ -179,7 +211,7 @@ static VALUE rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VAL
179
211
  }
180
212
 
181
213
  static VALUE parse_method_type_try(VALUE a) {
182
- struct parse_type_arg *arg = (struct parse_type_arg *) a;
214
+ struct parse_method_type_arg *arg = (struct parse_method_type_arg *) a;
183
215
  rbs_parser_t *parser = arg->parser;
184
216
 
185
217
  if (parser->next_token.type == pEOF) {
@@ -187,18 +219,10 @@ static VALUE parse_method_type_try(VALUE a) {
187
219
  }
188
220
 
189
221
  rbs_method_type_t *method_type = NULL;
190
- rbs_parse_method_type(parser, &method_type);
222
+ rbs_parse_method_type(parser, &method_type, RB_TEST(arg->require_eof), true);
191
223
 
192
224
  raise_error_if_any(parser, arg->buffer);
193
225
 
194
- if (RB_TEST(arg->require_eof)) {
195
- rbs_parser_advance(parser);
196
- if (parser->current_token.type != pEOF) {
197
- rbs_parser_set_error(parser, parser->current_token, true, "expected a token `%s`", rbs_token_type_str(pEOF));
198
- raise_error(parser->error, arg->buffer);
199
- }
200
- }
201
-
202
226
  rbs_translation_context_t ctx = rbs_translation_context_create(
203
227
  &parser->constant_pool,
204
228
  arg->buffer,
@@ -215,7 +239,7 @@ static VALUE rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_p
215
239
 
216
240
  rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
217
241
  declare_type_variables(parser, variables, buffer);
218
- struct parse_type_arg arg = {
242
+ struct parse_method_type_arg arg = {
219
243
  .buffer = buffer,
220
244
  .encoding = encoding,
221
245
  .parser = parser,
@@ -230,7 +254,7 @@ static VALUE rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_p
230
254
  }
231
255
 
232
256
  static VALUE parse_signature_try(VALUE a) {
233
- struct parse_type_arg *arg = (struct parse_type_arg *) a;
257
+ struct parse_signature_arg *arg = (struct parse_signature_arg *) a;
234
258
  rbs_parser_t *parser = arg->parser;
235
259
 
236
260
  rbs_signature_t *signature = NULL;
@@ -253,7 +277,7 @@ static VALUE rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE start_pos
253
277
  rb_encoding *encoding = rb_enc_get(string);
254
278
 
255
279
  rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
256
- struct parse_type_arg arg = {
280
+ struct parse_signature_arg arg = {
257
281
  .buffer = buffer,
258
282
  .encoding = encoding,
259
283
  .parser = parser,
@@ -267,6 +291,132 @@ static VALUE rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE start_pos
267
291
  return result;
268
292
  }
269
293
 
294
+ // Serialize a parsed node into a binary Ruby string using the same encoder the
295
+ // WebAssembly build uses. These `_*_to_bytes` entry points exist so the
296
+ // round-trip (parse -> serialize -> deserialize) can be exercised on CRuby,
297
+ // where it can be compared against the direct C -> Ruby translation.
298
+ static VALUE serialized_node_to_string(rbs_parser_t *parser, rbs_node_t *node) {
299
+ rbs_string_t bytes = rbs_serialize_node(parser->allocator, &parser->constant_pool, node);
300
+ return rb_str_new(bytes.start, (long) rbs_string_len(bytes));
301
+ }
302
+
303
+ static VALUE parse_type_to_bytes_try(VALUE a) {
304
+ struct parse_type_arg *arg = (struct parse_type_arg *) a;
305
+ rbs_parser_t *parser = arg->parser;
306
+
307
+ if (parser->next_token.type == pEOF) {
308
+ return Qnil;
309
+ }
310
+
311
+ rbs_node_t *type;
312
+ rbs_parse_type(parser, &type, RTEST(arg->void_allowed), RTEST(arg->self_allowed), RTEST(arg->classish_allowed));
313
+
314
+ raise_error_if_any(parser, arg->buffer);
315
+
316
+ if (RB_TEST(arg->require_eof)) {
317
+ rbs_parser_advance(parser);
318
+ if (parser->current_token.type != pEOF) {
319
+ rbs_parser_set_error(parser, parser->current_token, true, "expected a token `%s`", rbs_token_type_str(pEOF));
320
+ raise_error(parser->error, arg->buffer);
321
+ }
322
+ }
323
+
324
+ return serialized_node_to_string(parser, type);
325
+ }
326
+
327
+ static VALUE rbsparser_parse_type_to_bytes(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof, VALUE void_allowed, VALUE self_allowed, VALUE classish_allowed) {
328
+ VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
329
+ StringValue(string);
330
+ rb_encoding *encoding = rb_enc_get(string);
331
+
332
+ rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
333
+ declare_type_variables(parser, variables, buffer);
334
+ struct parse_type_arg arg = {
335
+ .buffer = buffer,
336
+ .encoding = encoding,
337
+ .parser = parser,
338
+ .require_eof = require_eof,
339
+ .void_allowed = void_allowed,
340
+ .self_allowed = self_allowed,
341
+ .classish_allowed = classish_allowed
342
+ };
343
+
344
+ VALUE result = rb_ensure(parse_type_to_bytes_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
345
+
346
+ RB_GC_GUARD(string);
347
+
348
+ return result;
349
+ }
350
+
351
+ static VALUE parse_method_type_to_bytes_try(VALUE a) {
352
+ struct parse_method_type_arg *arg = (struct parse_method_type_arg *) a;
353
+ rbs_parser_t *parser = arg->parser;
354
+
355
+ if (parser->next_token.type == pEOF) {
356
+ return Qnil;
357
+ }
358
+
359
+ rbs_method_type_t *method_type = NULL;
360
+ rbs_parse_method_type(parser, &method_type, RB_TEST(arg->require_eof), true);
361
+
362
+ raise_error_if_any(parser, arg->buffer);
363
+
364
+ return serialized_node_to_string(parser, (rbs_node_t *) method_type);
365
+ }
366
+
367
+ static VALUE rbsparser_parse_method_type_to_bytes(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof) {
368
+ VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
369
+ StringValue(string);
370
+ rb_encoding *encoding = rb_enc_get(string);
371
+
372
+ rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
373
+ declare_type_variables(parser, variables, buffer);
374
+ struct parse_method_type_arg arg = {
375
+ .buffer = buffer,
376
+ .encoding = encoding,
377
+ .parser = parser,
378
+ .require_eof = require_eof
379
+ };
380
+
381
+ VALUE result = rb_ensure(parse_method_type_to_bytes_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
382
+
383
+ RB_GC_GUARD(string);
384
+
385
+ return result;
386
+ }
387
+
388
+ static VALUE parse_signature_to_bytes_try(VALUE a) {
389
+ struct parse_signature_arg *arg = (struct parse_signature_arg *) a;
390
+ rbs_parser_t *parser = arg->parser;
391
+
392
+ rbs_signature_t *signature = NULL;
393
+ rbs_parse_signature(parser, &signature);
394
+
395
+ raise_error_if_any(parser, arg->buffer);
396
+
397
+ return serialized_node_to_string(parser, (rbs_node_t *) signature);
398
+ }
399
+
400
+ static VALUE rbsparser_parse_signature_to_bytes(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos) {
401
+ VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
402
+ StringValue(string);
403
+ rb_encoding *encoding = rb_enc_get(string);
404
+
405
+ rbs_parser_t *parser = alloc_parser_from_buffer(buffer, FIX2INT(start_pos), FIX2INT(end_pos));
406
+ struct parse_signature_arg arg = {
407
+ .buffer = buffer,
408
+ .encoding = encoding,
409
+ .parser = parser,
410
+ .require_eof = false
411
+ };
412
+
413
+ VALUE result = rb_ensure(parse_signature_to_bytes_try, (VALUE) &arg, ensure_free_parser, (VALUE) parser);
414
+
415
+ RB_GC_GUARD(string);
416
+
417
+ return result;
418
+ }
419
+
270
420
  struct parse_type_params_arg {
271
421
  VALUE buffer;
272
422
  rb_encoding *encoding;
@@ -429,12 +579,19 @@ static VALUE rbsparser_lex(VALUE self, VALUE buffer, VALUE end_pos) {
429
579
  void rbs__init_parser(void) {
430
580
  RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject);
431
581
  rb_gc_register_mark_object(RBS_Parser);
432
- VALUE empty_array = rb_obj_freeze(rb_ary_new());
433
- rb_gc_register_mark_object(empty_array);
434
582
 
435
- rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 5);
583
+ EMPTY_ARRAY = rb_obj_freeze(rb_ary_new());
584
+ rb_gc_register_mark_object(EMPTY_ARRAY);
585
+
586
+ EMPTY_HASH = rb_obj_freeze(rb_hash_new());
587
+ rb_gc_register_mark_object(EMPTY_HASH);
588
+
589
+ rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 8);
436
590
  rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5);
437
591
  rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
592
+ rb_define_singleton_method(RBS_Parser, "_parse_type_to_bytes", rbsparser_parse_type_to_bytes, 8);
593
+ rb_define_singleton_method(RBS_Parser, "_parse_method_type_to_bytes", rbsparser_parse_method_type_to_bytes, 5);
594
+ rb_define_singleton_method(RBS_Parser, "_parse_signature_to_bytes", rbsparser_parse_signature_to_bytes, 3);
438
595
  rb_define_singleton_method(RBS_Parser, "_parse_type_params", rbsparser_parse_type_params, 4);
439
596
  rb_define_singleton_method(RBS_Parser, "_parse_inline_leading_annotation", rbsparser_parse_inline_leading_annotation, 4);
440
597
  rb_define_singleton_method(RBS_Parser, "_parse_inline_trailing_annotation", rbsparser_parse_inline_trailing_annotation, 4);
@@ -442,7 +599,6 @@ void rbs__init_parser(void) {
442
599
  }
443
600
 
444
601
  static void Deinit_rbs_extension(ruby_vm_t *_) {
445
- rbs_constant_pool_free(RBS_GLOBAL_CONSTANT_POOL);
446
602
  }
447
603
 
448
604
  void Init_rbs_extension(void) {
@@ -453,17 +609,5 @@ void Init_rbs_extension(void) {
453
609
  rbs__init_location();
454
610
  rbs__init_parser();
455
611
 
456
- /* Calculated based on the number of unique strings used with the `INTERN` macro in `parser.c`.
457
- *
458
- * ```bash
459
- * grep -o 'INTERN("\([^"]*\)")' ext/rbs_extension/parser.c \
460
- * | sed 's/INTERN("\(.*\)")/\1/' \
461
- * | sort -u \
462
- * | wc -l
463
- * ```
464
- */
465
- const size_t num_uniquely_interned_strings = 26;
466
- rbs_constant_pool_init(RBS_GLOBAL_CONSTANT_POOL, num_uniquely_interned_strings);
467
-
468
612
  ruby_vm_at_exit(Deinit_rbs_extension);
469
613
  }