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
@@ -11,13 +11,19 @@
11
11
  #include "rbs_string_bridging.h"
12
12
  #include "legacy_location.h"
13
13
 
14
- #define RBS_LOC_CHILDREN_SIZE(cap) (sizeof(rbs_loc_children) + sizeof(rbs_loc_entry) * ((cap) - 1))
14
+ VALUE EMPTY_ARRAY;
15
+ VALUE EMPTY_HASH;
16
+
17
+ #define RBS_LOCATION_CHILDREN_SIZE(cap) (sizeof(rbs_location_children) + sizeof(rbs_location_entry) * ((cap) - 1))
18
+ #define RBS_LOCATION_REQUIRED_P(loc, i) ((loc)->children->required_p & (1 << (i)))
19
+ #define RBS_LOCATION_OPTIONAL_P(loc, i) (!RBS_LOCATION_REQUIRED_P((loc), (i)))
15
20
 
16
21
  rbs_translation_context_t rbs_translation_context_create(rbs_constant_pool_t *constant_pool, VALUE buffer, rb_encoding *ruby_encoding) {
17
22
  return (rbs_translation_context_t) {
18
23
  .constant_pool = constant_pool,
19
24
  .buffer = buffer,
20
25
  .encoding = ruby_encoding,
26
+ .reusable_kwargs_hash = rb_hash_new(),
21
27
  };
22
28
  }
23
29
 
@@ -32,6 +38,10 @@ VALUE rbs_node_list_to_ruby_array(rbs_translation_context_t ctx, rbs_node_list_t
32
38
  }
33
39
 
34
40
  VALUE rbs_hash_to_ruby_hash(rbs_translation_context_t ctx, rbs_hash_t *rbs_hash) {
41
+ if (!rbs_hash->head) {
42
+ return EMPTY_HASH;
43
+ }
44
+
35
45
  VALUE ruby_hash = rb_hash_new();
36
46
 
37
47
  for (rbs_hash_node_t *n = rbs_hash->head; n != NULL; n = n->next) {
@@ -43,34 +53,118 @@ VALUE rbs_hash_to_ruby_hash(rbs_translation_context_t ctx, rbs_hash_t *rbs_hash)
43
53
  return ruby_hash;
44
54
  }
45
55
 
46
- VALUE rbs_loc_to_ruby_location(rbs_translation_context_t ctx, rbs_location_t *source_loc) {
47
- if (source_loc == NULL) {
56
+ VALUE rbs_location_range_to_ruby_location(rbs_translation_context_t ctx, rbs_location_range range) {
57
+ if (RBS_LOCATION_NULL_RANGE_P(range)) {
48
58
  return Qnil;
49
59
  }
50
60
 
51
- VALUE new_loc = rbs_new_location(ctx.buffer, source_loc->rg);
52
- rbs_loc *new_loc_struct = rbs_check_location(new_loc);
61
+ return rbs_new_location2(ctx.buffer, range.start_char, range.end_char);
62
+ }
63
+
64
+ VALUE rbs_location_range_list_to_ruby_array(rbs_translation_context_t ctx, rbs_location_range_list_t *list) {
65
+ if (list == NULL) {
66
+ return EMPTY_ARRAY;
67
+ }
68
+
69
+ VALUE ruby_array = rb_ary_new();
53
70
 
54
- if (source_loc->children != NULL) {
55
- rbs_loc_legacy_alloc_children(new_loc_struct, source_loc->children->cap);
56
- memcpy(new_loc_struct->children, source_loc->children, RBS_LOC_CHILDREN_SIZE(source_loc->children->cap));
71
+ for (rbs_location_range_list_node_t *n = list->head; n != NULL; n = n->next) {
72
+ rb_ary_push(ruby_array, rbs_location_range_to_ruby_location(ctx, n->range));
57
73
  }
58
74
 
59
- return new_loc;
75
+ return ruby_array;
60
76
  }
61
77
 
62
- VALUE rbs_location_list_to_ruby_array(rbs_translation_context_t ctx, rbs_location_list_t *list) {
63
- VALUE ruby_array = rb_ary_new();
78
+ VALUE rbs_attr_ivar_name_to_ruby(rbs_translation_context_t ctx, rbs_attr_ivar_name_t ivar_name) {
79
+ switch (ivar_name.tag) {
80
+ case RBS_ATTR_IVAR_NAME_TAG_NAME: {
81
+ rbs_constant_t *constant = rbs_constant_pool_id_to_constant(ctx.constant_pool, ivar_name.name);
82
+ assert(constant != NULL && "constant is NULL");
83
+ assert(constant->start != NULL && "constant->start is NULL");
64
84
 
65
- if (list == NULL) {
66
- return ruby_array;
85
+ return ID2SYM(rb_intern3((const char *) constant->start, constant->length, ctx.encoding));
86
+ }
87
+ case RBS_ATTR_IVAR_NAME_TAG_UNSPECIFIED:
88
+ return Qnil;
89
+ case RBS_ATTR_IVAR_NAME_TAG_EMPTY:
90
+ return Qfalse;
91
+ default:
92
+ rb_fatal("unknown enum rbs_attr_ivar_name_tag ivar_name.tag: %d", ivar_name.tag);
67
93
  }
94
+ }
68
95
 
69
- for (rbs_location_list_node_t *n = list->head; n != NULL; n = n->next) {
70
- rb_ary_push(ruby_array, rbs_loc_to_ruby_location(ctx, n->loc));
96
+ VALUE rbs_attribute_visibility_to_ruby(enum rbs_attribute_visibility value) {
97
+ switch (value) {
98
+ case RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED:
99
+ return Qnil;
100
+ case RBS_ATTRIBUTE_VISIBILITY_PUBLIC:
101
+ return rb_id2sym(rb_intern("public"));
102
+ case RBS_ATTRIBUTE_VISIBILITY_PRIVATE:
103
+ return rb_id2sym(rb_intern("private"));
104
+ default:
105
+ rb_fatal("unknown enum rbs_attribute_visibility value: %d", value);
71
106
  }
107
+ }
72
108
 
73
- return ruby_array;
109
+ VALUE rbs_attribute_kind_to_ruby(enum rbs_attribute_kind value) {
110
+ switch (value) {
111
+ case RBS_ATTRIBUTE_KIND_INSTANCE:
112
+ return rb_id2sym(rb_intern("instance"));
113
+ case RBS_ATTRIBUTE_KIND_SINGLETON:
114
+ return rb_id2sym(rb_intern("singleton"));
115
+ default:
116
+ rb_fatal("unknown enum rbs_attribute_kind value: %d", value);
117
+ }
118
+ }
119
+
120
+ VALUE rbs_alias_kind_to_ruby(enum rbs_alias_kind value) {
121
+ switch (value) {
122
+ case RBS_ALIAS_KIND_INSTANCE:
123
+ return rb_id2sym(rb_intern("instance"));
124
+ case RBS_ALIAS_KIND_SINGLETON:
125
+ return rb_id2sym(rb_intern("singleton"));
126
+ default:
127
+ rb_fatal("unknown enum rbs_alias_kind value: %d", value);
128
+ }
129
+ }
130
+
131
+ VALUE rbs_method_definition_kind_to_ruby(enum rbs_method_definition_kind value) {
132
+ switch (value) {
133
+ case RBS_METHOD_DEFINITION_KIND_INSTANCE:
134
+ return rb_id2sym(rb_intern("instance"));
135
+ case RBS_METHOD_DEFINITION_KIND_SINGLETON:
136
+ return rb_id2sym(rb_intern("singleton"));
137
+ case RBS_METHOD_DEFINITION_KIND_SINGLETON_INSTANCE:
138
+ return rb_id2sym(rb_intern("singleton_instance"));
139
+ default:
140
+ rb_fatal("unknown enum rbs_method_definition_kind value: %d", value);
141
+ }
142
+ }
143
+
144
+ VALUE rbs_method_definition_visibility_to_ruby(enum rbs_method_definition_visibility value) {
145
+ switch (value) {
146
+ case RBS_METHOD_DEFINITION_VISIBILITY_UNSPECIFIED:
147
+ return Qnil;
148
+ case RBS_METHOD_DEFINITION_VISIBILITY_PUBLIC:
149
+ return rb_id2sym(rb_intern("public"));
150
+ case RBS_METHOD_DEFINITION_VISIBILITY_PRIVATE:
151
+ return rb_id2sym(rb_intern("private"));
152
+ default:
153
+ rb_fatal("unknown enum rbs_method_definition_visibility value: %d", value);
154
+ }
155
+ }
156
+
157
+ VALUE rbs_type_param_variance_to_ruby(enum rbs_type_param_variance value) {
158
+ switch (value) {
159
+ case RBS_TYPE_PARAM_VARIANCE_INVARIANT:
160
+ return rb_id2sym(rb_intern("invariant"));
161
+ case RBS_TYPE_PARAM_VARIANCE_COVARIANT:
162
+ return rb_id2sym(rb_intern("covariant"));
163
+ case RBS_TYPE_PARAM_VARIANCE_CONTRAVARIANT:
164
+ return rb_id2sym(rb_intern("contravariant"));
165
+ default:
166
+ rb_fatal("unknown enum rbs_type_param_variance value: %d", value);
167
+ }
74
168
  }
75
169
 
76
170
  #ifdef RB_PASS_KEYWORDS
@@ -83,6 +177,30 @@ VALUE rbs_location_list_to_ruby_array(rbs_translation_context_t ctx, rbs_locatio
83
177
  rb_class_new_instance(argc, argv, receiver)
84
178
  #endif
85
179
 
180
+ // Route Namespace / TypeName construction through the Ruby-side
181
+ // flyweight cache (`RBS::Namespace.[]` / `RBS::TypeName.[]`) so that
182
+ // structurally equal values produced by the parser share canonical
183
+ // instances. An in-C trie walk was tried but did not beat
184
+ // `rb_funcallv` on Ruby 4.0+, where method dispatch is well optimized.
185
+ static ID id_intern_brackets;
186
+
187
+ static inline ID intern_brackets(void) {
188
+ if (!id_intern_brackets) id_intern_brackets = rb_intern("[]");
189
+ return id_intern_brackets;
190
+ }
191
+
192
+ static VALUE rbs_intern_namespace(rbs_translation_context_t ctx, rbs_namespace_t *node) {
193
+ VALUE args[2];
194
+ args[0] = rbs_node_list_to_ruby_array(ctx, node->path);
195
+ args[1] = node->absolute ? Qtrue : Qfalse;
196
+ return rb_funcallv(RBS_Namespace, intern_brackets(), 2, args);
197
+ }
198
+
199
+ static VALUE rbs_intern_type_name(VALUE namespace, VALUE name) {
200
+ VALUE args[2] = { namespace, name };
201
+ return rb_funcallv(RBS_TypeName, intern_brackets(), 2, args);
202
+ }
203
+
86
204
  VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instance) {
87
205
  if (instance == NULL) return Qnil;
88
206
 
@@ -90,15 +208,17 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
90
208
  case RBS_AST_ANNOTATION: {
91
209
  rbs_ast_annotation_t *node = (rbs_ast_annotation_t *) instance;
92
210
 
93
- VALUE h = rb_hash_new();
94
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
95
- rb_hash_aset(h, ID2SYM(rb_intern("string")), rbs_string_to_ruby_string(&node->string, ctx.encoding));
211
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
212
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
213
+ VALUE arg_string = rbs_string_to_ruby_string(&node->string, ctx.encoding);
96
214
 
97
- return CLASS_NEW_INSTANCE(
98
- RBS_AST_Annotation,
99
- 1,
100
- &h
101
- );
215
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
216
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
217
+ VALUE h = ctx.reusable_kwargs_hash;
218
+ rb_hash_clear(h);
219
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
220
+ rb_hash_aset(h, ID2SYM(rb_intern("string")), arg_string);
221
+ return CLASS_NEW_INSTANCE(RBS_AST_Annotation, 1, &h);
102
222
  }
103
223
  case RBS_AST_BOOL: {
104
224
  return ((rbs_ast_bool_t *) instance)->value ? Qtrue : Qfalse;
@@ -106,241 +226,395 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
106
226
  case RBS_AST_COMMENT: {
107
227
  rbs_ast_comment_t *node = (rbs_ast_comment_t *) instance;
108
228
 
109
- VALUE h = rb_hash_new();
110
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
111
- rb_hash_aset(h, ID2SYM(rb_intern("string")), rbs_string_to_ruby_string(&node->string, ctx.encoding));
229
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
230
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
231
+ VALUE arg_string = rbs_string_to_ruby_string(&node->string, ctx.encoding);
112
232
 
113
- return CLASS_NEW_INSTANCE(
114
- RBS_AST_Comment,
115
- 1,
116
- &h
117
- );
233
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
234
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
235
+ VALUE h = ctx.reusable_kwargs_hash;
236
+ rb_hash_clear(h);
237
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
238
+ rb_hash_aset(h, ID2SYM(rb_intern("string")), arg_string);
239
+ return CLASS_NEW_INSTANCE(RBS_AST_Comment, 1, &h);
118
240
  }
119
241
  case RBS_AST_DECLARATIONS_CLASS: {
120
242
  rbs_ast_declarations_class_t *node = (rbs_ast_declarations_class_t *) instance;
121
243
 
122
- VALUE h = rb_hash_new();
123
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
124
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
125
- rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params));
126
- rb_hash_aset(h, ID2SYM(rb_intern("super_class")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->super_class)); // rbs_ast_declarations_class_super
127
- rb_hash_aset(h, ID2SYM(rb_intern("members")), rbs_node_list_to_ruby_array(ctx, node->members));
128
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
129
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
244
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
245
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
246
+ rbs_loc *loc = rbs_check_location(arg_location);
247
+ {
248
+ rbs_loc_legacy_alloc_children(loc, 5);
249
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
250
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
251
+ rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
252
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
253
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("lt"), (rbs_loc_range) { .start = node->lt_range.start_char, .end = node->lt_range.end_char });
254
+ }
255
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
256
+ VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
257
+ VALUE arg_super_class = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->super_class); // rbs_ast_declarations_class_super
258
+ VALUE arg_members = rbs_node_list_to_ruby_array(ctx, node->members);
259
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
260
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
130
261
 
131
262
  rb_funcall(
132
263
  RBS_AST_TypeParam,
133
264
  rb_intern("resolve_variables"),
134
265
  1,
135
- rb_hash_lookup(h, ID2SYM(rb_intern("type_params")))
136
- );
137
- return CLASS_NEW_INSTANCE(
138
- RBS_AST_Declarations_Class,
139
- 1,
140
- &h
141
- );
266
+ arg_type_params
267
+ );
268
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
269
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
270
+ VALUE h = ctx.reusable_kwargs_hash;
271
+ rb_hash_clear(h);
272
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
273
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
274
+ rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
275
+ rb_hash_aset(h, ID2SYM(rb_intern("super_class")), arg_super_class);
276
+ rb_hash_aset(h, ID2SYM(rb_intern("members")), arg_members);
277
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
278
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
279
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Class, 1, &h);
142
280
  }
143
281
  case RBS_AST_DECLARATIONS_CLASS_SUPER: {
144
282
  rbs_ast_declarations_class_super_t *node = (rbs_ast_declarations_class_super_t *) instance;
145
283
 
146
- VALUE h = rb_hash_new();
147
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
148
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
149
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
150
-
151
- return CLASS_NEW_INSTANCE(
152
- RBS_AST_Declarations_Class_Super,
153
- 1,
154
- &h
155
- );
284
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
285
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
286
+ rbs_loc *loc = rbs_check_location(arg_location);
287
+ {
288
+ rbs_loc_legacy_alloc_children(loc, 2);
289
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
290
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
291
+ }
292
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
293
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
294
+
295
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
296
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
297
+ VALUE h = ctx.reusable_kwargs_hash;
298
+ rb_hash_clear(h);
299
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
300
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
301
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
302
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Class_Super, 1, &h);
156
303
  }
157
304
  case RBS_AST_DECLARATIONS_CLASS_ALIAS: {
158
305
  rbs_ast_declarations_class_alias_t *node = (rbs_ast_declarations_class_alias_t *) instance;
159
306
 
160
- VALUE h = rb_hash_new();
161
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
162
- rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_type_name
163
- rb_hash_aset(h, ID2SYM(rb_intern("old_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name)); // rbs_type_name
164
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
165
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
166
-
167
- return CLASS_NEW_INSTANCE(
168
- RBS_AST_Declarations_ClassAlias,
169
- 1,
170
- &h
171
- );
307
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
308
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
309
+ rbs_loc *loc = rbs_check_location(arg_location);
310
+ {
311
+ rbs_loc_legacy_alloc_children(loc, 4);
312
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
313
+ rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
314
+ rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char });
315
+ rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char });
316
+ }
317
+ VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_type_name
318
+ VALUE arg_old_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name); // rbs_type_name
319
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
320
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
321
+
322
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
323
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
324
+ VALUE h = ctx.reusable_kwargs_hash;
325
+ rb_hash_clear(h);
326
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
327
+ rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
328
+ rb_hash_aset(h, ID2SYM(rb_intern("old_name")), arg_old_name);
329
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
330
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
331
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_ClassAlias, 1, &h);
172
332
  }
173
333
  case RBS_AST_DECLARATIONS_CONSTANT: {
174
334
  rbs_ast_declarations_constant_t *node = (rbs_ast_declarations_constant_t *) instance;
175
335
 
176
- VALUE h = rb_hash_new();
177
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
178
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
179
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
180
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
181
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
182
-
183
- return CLASS_NEW_INSTANCE(
184
- RBS_AST_Declarations_Constant,
185
- 1,
186
- &h
187
- );
336
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
337
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
338
+ rbs_loc *loc = rbs_check_location(arg_location);
339
+ {
340
+ rbs_loc_legacy_alloc_children(loc, 2);
341
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
342
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
343
+ }
344
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
345
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
346
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
347
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
348
+
349
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
350
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
351
+ VALUE h = ctx.reusable_kwargs_hash;
352
+ rb_hash_clear(h);
353
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
354
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
355
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
356
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
357
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
358
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Constant, 1, &h);
188
359
  }
189
360
  case RBS_AST_DECLARATIONS_GLOBAL: {
190
361
  rbs_ast_declarations_global_t *node = (rbs_ast_declarations_global_t *) instance;
191
362
 
192
- VALUE h = rb_hash_new();
193
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
194
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
195
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
196
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
197
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
198
-
199
- return CLASS_NEW_INSTANCE(
200
- RBS_AST_Declarations_Global,
201
- 1,
202
- &h
203
- );
363
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
364
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
365
+ rbs_loc *loc = rbs_check_location(arg_location);
366
+ {
367
+ rbs_loc_legacy_alloc_children(loc, 2);
368
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
369
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
370
+ }
371
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
372
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
373
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
374
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
375
+
376
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
377
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
378
+ VALUE h = ctx.reusable_kwargs_hash;
379
+ rb_hash_clear(h);
380
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
381
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
382
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
383
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
384
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
385
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Global, 1, &h);
204
386
  }
205
387
  case RBS_AST_DECLARATIONS_INTERFACE: {
206
388
  rbs_ast_declarations_interface_t *node = (rbs_ast_declarations_interface_t *) instance;
207
389
 
208
- VALUE h = rb_hash_new();
209
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
210
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
211
- rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params));
212
- rb_hash_aset(h, ID2SYM(rb_intern("members")), rbs_node_list_to_ruby_array(ctx, node->members));
213
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
214
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
390
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
391
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
392
+ rbs_loc *loc = rbs_check_location(arg_location);
393
+ {
394
+ rbs_loc_legacy_alloc_children(loc, 4);
395
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
396
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
397
+ rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
398
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
399
+ }
400
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
401
+ VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
402
+ VALUE arg_members = rbs_node_list_to_ruby_array(ctx, node->members);
403
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
404
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
215
405
 
216
406
  rb_funcall(
217
407
  RBS_AST_TypeParam,
218
408
  rb_intern("resolve_variables"),
219
409
  1,
220
- rb_hash_lookup(h, ID2SYM(rb_intern("type_params")))
221
- );
222
- return CLASS_NEW_INSTANCE(
223
- RBS_AST_Declarations_Interface,
224
- 1,
225
- &h
410
+ arg_type_params
226
411
  );
412
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
413
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
414
+ VALUE h = ctx.reusable_kwargs_hash;
415
+ rb_hash_clear(h);
416
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
417
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
418
+ rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
419
+ rb_hash_aset(h, ID2SYM(rb_intern("members")), arg_members);
420
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
421
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
422
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Interface, 1, &h);
227
423
  }
228
424
  case RBS_AST_DECLARATIONS_MODULE: {
229
425
  rbs_ast_declarations_module_t *node = (rbs_ast_declarations_module_t *) instance;
230
426
 
231
- VALUE h = rb_hash_new();
232
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
233
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
234
- rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params));
235
- rb_hash_aset(h, ID2SYM(rb_intern("self_types")), rbs_node_list_to_ruby_array(ctx, node->self_types));
236
- rb_hash_aset(h, ID2SYM(rb_intern("members")), rbs_node_list_to_ruby_array(ctx, node->members));
237
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
238
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
427
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
428
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
429
+ rbs_loc *loc = rbs_check_location(arg_location);
430
+ {
431
+ rbs_loc_legacy_alloc_children(loc, 6);
432
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
433
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
434
+ rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char });
435
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
436
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
437
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("self_types"), (rbs_loc_range) { .start = node->self_types_range.start_char, .end = node->self_types_range.end_char });
438
+ }
439
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
440
+ VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
441
+ VALUE arg_self_types = rbs_node_list_to_ruby_array(ctx, node->self_types);
442
+ VALUE arg_members = rbs_node_list_to_ruby_array(ctx, node->members);
443
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
444
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
239
445
 
240
446
  rb_funcall(
241
447
  RBS_AST_TypeParam,
242
448
  rb_intern("resolve_variables"),
243
449
  1,
244
- rb_hash_lookup(h, ID2SYM(rb_intern("type_params")))
245
- );
246
- return CLASS_NEW_INSTANCE(
247
- RBS_AST_Declarations_Module,
248
- 1,
249
- &h
250
- );
450
+ arg_type_params
451
+ );
452
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
453
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
454
+ VALUE h = ctx.reusable_kwargs_hash;
455
+ rb_hash_clear(h);
456
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
457
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
458
+ rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
459
+ rb_hash_aset(h, ID2SYM(rb_intern("self_types")), arg_self_types);
460
+ rb_hash_aset(h, ID2SYM(rb_intern("members")), arg_members);
461
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
462
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
463
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Module, 1, &h);
251
464
  }
252
465
  case RBS_AST_DECLARATIONS_MODULE_SELF: {
253
466
  rbs_ast_declarations_module_self_t *node = (rbs_ast_declarations_module_self_t *) instance;
254
467
 
255
- VALUE h = rb_hash_new();
256
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
257
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
258
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
259
-
260
- return CLASS_NEW_INSTANCE(
261
- RBS_AST_Declarations_Module_Self,
262
- 1,
263
- &h
264
- );
468
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
469
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
470
+ rbs_loc *loc = rbs_check_location(arg_location);
471
+ {
472
+ rbs_loc_legacy_alloc_children(loc, 2);
473
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
474
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
475
+ }
476
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
477
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
478
+
479
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
480
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
481
+ VALUE h = ctx.reusable_kwargs_hash;
482
+ rb_hash_clear(h);
483
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
484
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
485
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
486
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_Module_Self, 1, &h);
265
487
  }
266
488
  case RBS_AST_DECLARATIONS_MODULE_ALIAS: {
267
489
  rbs_ast_declarations_module_alias_t *node = (rbs_ast_declarations_module_alias_t *) instance;
268
490
 
269
- VALUE h = rb_hash_new();
270
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
271
- rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_type_name
272
- rb_hash_aset(h, ID2SYM(rb_intern("old_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name)); // rbs_type_name
273
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
274
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
275
-
276
- return CLASS_NEW_INSTANCE(
277
- RBS_AST_Declarations_ModuleAlias,
278
- 1,
279
- &h
280
- );
491
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
492
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
493
+ rbs_loc *loc = rbs_check_location(arg_location);
494
+ {
495
+ rbs_loc_legacy_alloc_children(loc, 4);
496
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
497
+ rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
498
+ rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char });
499
+ rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char });
500
+ }
501
+ VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_type_name
502
+ VALUE arg_old_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name); // rbs_type_name
503
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
504
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
505
+
506
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
507
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
508
+ VALUE h = ctx.reusable_kwargs_hash;
509
+ rb_hash_clear(h);
510
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
511
+ rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
512
+ rb_hash_aset(h, ID2SYM(rb_intern("old_name")), arg_old_name);
513
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
514
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
515
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_ModuleAlias, 1, &h);
281
516
  }
282
517
  case RBS_AST_DECLARATIONS_TYPE_ALIAS: {
283
518
  rbs_ast_declarations_type_alias_t *node = (rbs_ast_declarations_type_alias_t *) instance;
284
519
 
285
- VALUE h = rb_hash_new();
286
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
287
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
288
- rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params));
289
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
290
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
291
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
520
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
521
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
522
+ rbs_loc *loc = rbs_check_location(arg_location);
523
+ {
524
+ rbs_loc_legacy_alloc_children(loc, 4);
525
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
526
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
527
+ rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char });
528
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
529
+ }
530
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
531
+ VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
532
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
533
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
534
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
292
535
 
293
536
  rb_funcall(
294
537
  RBS_AST_TypeParam,
295
538
  rb_intern("resolve_variables"),
296
539
  1,
297
- rb_hash_lookup(h, ID2SYM(rb_intern("type_params")))
298
- );
299
- return CLASS_NEW_INSTANCE(
300
- RBS_AST_Declarations_TypeAlias,
301
- 1,
302
- &h
540
+ arg_type_params
303
541
  );
542
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
543
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
544
+ VALUE h = ctx.reusable_kwargs_hash;
545
+ rb_hash_clear(h);
546
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
547
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
548
+ rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
549
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
550
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
551
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
552
+ return CLASS_NEW_INSTANCE(RBS_AST_Declarations_TypeAlias, 1, &h);
304
553
  }
305
554
  case RBS_AST_DIRECTIVES_USE: {
306
555
  rbs_ast_directives_use_t *node = (rbs_ast_directives_use_t *) instance;
307
556
 
308
- VALUE h = rb_hash_new();
309
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
310
- rb_hash_aset(h, ID2SYM(rb_intern("clauses")), rbs_node_list_to_ruby_array(ctx, node->clauses));
311
-
312
- return CLASS_NEW_INSTANCE(
313
- RBS_AST_Directives_Use,
314
- 1,
315
- &h
316
- );
557
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
558
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
559
+ rbs_loc *loc = rbs_check_location(arg_location);
560
+ {
561
+ rbs_loc_legacy_alloc_children(loc, 1);
562
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
563
+ }
564
+ VALUE arg_clauses = rbs_node_list_to_ruby_array(ctx, node->clauses);
565
+
566
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
567
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
568
+ VALUE h = ctx.reusable_kwargs_hash;
569
+ rb_hash_clear(h);
570
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
571
+ rb_hash_aset(h, ID2SYM(rb_intern("clauses")), arg_clauses);
572
+ return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use, 1, &h);
317
573
  }
318
574
  case RBS_AST_DIRECTIVES_USE_SINGLE_CLAUSE: {
319
575
  rbs_ast_directives_use_single_clause_t *node = (rbs_ast_directives_use_single_clause_t *) instance;
320
576
 
321
- VALUE h = rb_hash_new();
322
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
323
- rb_hash_aset(h, ID2SYM(rb_intern("type_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name)); // rbs_type_name
324
- rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_ast_symbol
325
-
326
- return CLASS_NEW_INSTANCE(
327
- RBS_AST_Directives_Use_SingleClause,
328
- 1,
329
- &h
330
- );
577
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
578
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
579
+ rbs_loc *loc = rbs_check_location(arg_location);
580
+ {
581
+ rbs_loc_legacy_alloc_children(loc, 3);
582
+ rbs_loc_legacy_add_required_child(loc, rb_intern("type_name"), (rbs_loc_range) { .start = node->type_name_range.start_char, .end = node->type_name_range.end_char });
583
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
584
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
585
+ }
586
+ VALUE arg_type_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name); // rbs_type_name
587
+ VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_ast_symbol
588
+
589
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
590
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
591
+ VALUE h = ctx.reusable_kwargs_hash;
592
+ rb_hash_clear(h);
593
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
594
+ rb_hash_aset(h, ID2SYM(rb_intern("type_name")), arg_type_name);
595
+ rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
596
+ return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use_SingleClause, 1, &h);
331
597
  }
332
598
  case RBS_AST_DIRECTIVES_USE_WILDCARD_CLAUSE: {
333
599
  rbs_ast_directives_use_wildcard_clause_t *node = (rbs_ast_directives_use_wildcard_clause_t *) instance;
334
600
 
335
- VALUE h = rb_hash_new();
336
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
337
- rb_hash_aset(h, ID2SYM(rb_intern("namespace")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace)); // rbs_namespace
338
-
339
- return CLASS_NEW_INSTANCE(
340
- RBS_AST_Directives_Use_WildcardClause,
341
- 1,
342
- &h
343
- );
601
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
602
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
603
+ rbs_loc *loc = rbs_check_location(arg_location);
604
+ {
605
+ rbs_loc_legacy_alloc_children(loc, 2);
606
+ rbs_loc_legacy_add_required_child(loc, rb_intern("namespace"), (rbs_loc_range) { .start = node->namespace_range.start_char, .end = node->namespace_range.end_char });
607
+ rbs_loc_legacy_add_required_child(loc, rb_intern("star"), (rbs_loc_range) { .start = node->star_range.start_char, .end = node->star_range.end_char });
608
+ }
609
+ VALUE arg_namespace = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace); // rbs_namespace
610
+
611
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
612
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
613
+ VALUE h = ctx.reusable_kwargs_hash;
614
+ rb_hash_clear(h);
615
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
616
+ rb_hash_aset(h, ID2SYM(rb_intern("namespace")), arg_namespace);
617
+ return CLASS_NEW_INSTANCE(RBS_AST_Directives_Use_WildcardClause, 1, &h);
344
618
  }
345
619
  case RBS_AST_INTEGER: {
346
620
  rbs_ast_integer_t *integer_node = (rbs_ast_integer_t *) instance;
@@ -353,301 +627,707 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
353
627
  case RBS_AST_MEMBERS_ALIAS: {
354
628
  rbs_ast_members_alias_t *node = (rbs_ast_members_alias_t *) instance;
355
629
 
356
- VALUE h = rb_hash_new();
357
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
358
- rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_ast_symbol
359
- rb_hash_aset(h, ID2SYM(rb_intern("old_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name)); // rbs_ast_symbol
360
- rb_hash_aset(h, ID2SYM(rb_intern("kind")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->kind)); // rbs_keyword
361
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
362
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
363
-
364
- return CLASS_NEW_INSTANCE(
365
- RBS_AST_Members_Alias,
366
- 1,
367
- &h
368
- );
630
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
631
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
632
+ rbs_loc *loc = rbs_check_location(arg_location);
633
+ {
634
+ rbs_loc_legacy_alloc_children(loc, 5);
635
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
636
+ rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char });
637
+ rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char });
638
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("new_kind"), (rbs_loc_range) { .start = node->new_kind_range.start_char, .end = node->new_kind_range.end_char });
639
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("old_kind"), (rbs_loc_range) { .start = node->old_kind_range.start_char, .end = node->old_kind_range.end_char });
640
+ }
641
+ VALUE arg_new_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name); // rbs_ast_symbol
642
+ VALUE arg_old_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name); // rbs_ast_symbol
643
+ VALUE arg_kind = rbs_alias_kind_to_ruby(node->kind); // alias_kind
644
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
645
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
646
+
647
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
648
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
649
+ VALUE h = ctx.reusable_kwargs_hash;
650
+ rb_hash_clear(h);
651
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
652
+ rb_hash_aset(h, ID2SYM(rb_intern("new_name")), arg_new_name);
653
+ rb_hash_aset(h, ID2SYM(rb_intern("old_name")), arg_old_name);
654
+ rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
655
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
656
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
657
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_Alias, 1, &h);
369
658
  }
370
659
  case RBS_AST_MEMBERS_ATTR_ACCESSOR: {
371
660
  rbs_ast_members_attr_accessor_t *node = (rbs_ast_members_attr_accessor_t *) instance;
372
661
 
373
- VALUE h = rb_hash_new();
374
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
375
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
376
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
377
- rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->ivar_name)); // rbs_node
378
- rb_hash_aset(h, ID2SYM(rb_intern("kind")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->kind)); // rbs_keyword
379
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
380
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
381
- rb_hash_aset(h, ID2SYM(rb_intern("visibility")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->visibility)); // rbs_keyword
382
-
383
- return CLASS_NEW_INSTANCE(
384
- RBS_AST_Members_AttrAccessor,
385
- 1,
386
- &h
387
- );
662
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
663
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
664
+ rbs_loc *loc = rbs_check_location(arg_location);
665
+ {
666
+ rbs_loc_legacy_alloc_children(loc, 7);
667
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
668
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
669
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
670
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
671
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char });
672
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char });
673
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
674
+ }
675
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
676
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
677
+ VALUE arg_ivar_name = rbs_attr_ivar_name_to_ruby(ctx, node->ivar_name); // rbs_attr_ivar_name_t
678
+ VALUE arg_kind = rbs_attribute_kind_to_ruby(node->kind); // attribute_kind
679
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
680
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
681
+ VALUE arg_visibility = rbs_attribute_visibility_to_ruby(node->visibility); // attribute_visibility
682
+
683
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
684
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
685
+ VALUE h = ctx.reusable_kwargs_hash;
686
+ rb_hash_clear(h);
687
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
688
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
689
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
690
+ rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
691
+ rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
692
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
693
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
694
+ rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
695
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_AttrAccessor, 1, &h);
388
696
  }
389
697
  case RBS_AST_MEMBERS_ATTR_READER: {
390
698
  rbs_ast_members_attr_reader_t *node = (rbs_ast_members_attr_reader_t *) instance;
391
699
 
392
- VALUE h = rb_hash_new();
393
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
394
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
395
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
396
- rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->ivar_name)); // rbs_node
397
- rb_hash_aset(h, ID2SYM(rb_intern("kind")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->kind)); // rbs_keyword
398
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
399
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
400
- rb_hash_aset(h, ID2SYM(rb_intern("visibility")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->visibility)); // rbs_keyword
401
-
402
- return CLASS_NEW_INSTANCE(
403
- RBS_AST_Members_AttrReader,
404
- 1,
405
- &h
406
- );
700
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
701
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
702
+ rbs_loc *loc = rbs_check_location(arg_location);
703
+ {
704
+ rbs_loc_legacy_alloc_children(loc, 7);
705
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
706
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
707
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
708
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
709
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char });
710
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char });
711
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
712
+ }
713
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
714
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
715
+ VALUE arg_ivar_name = rbs_attr_ivar_name_to_ruby(ctx, node->ivar_name); // rbs_attr_ivar_name_t
716
+ VALUE arg_kind = rbs_attribute_kind_to_ruby(node->kind); // attribute_kind
717
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
718
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
719
+ VALUE arg_visibility = rbs_attribute_visibility_to_ruby(node->visibility); // attribute_visibility
720
+
721
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
722
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
723
+ VALUE h = ctx.reusable_kwargs_hash;
724
+ rb_hash_clear(h);
725
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
726
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
727
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
728
+ rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
729
+ rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
730
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
731
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
732
+ rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
733
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_AttrReader, 1, &h);
407
734
  }
408
735
  case RBS_AST_MEMBERS_ATTR_WRITER: {
409
736
  rbs_ast_members_attr_writer_t *node = (rbs_ast_members_attr_writer_t *) instance;
410
737
 
411
- VALUE h = rb_hash_new();
412
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
413
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
414
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
415
- rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->ivar_name)); // rbs_node
416
- rb_hash_aset(h, ID2SYM(rb_intern("kind")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->kind)); // rbs_keyword
417
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
418
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
419
- rb_hash_aset(h, ID2SYM(rb_intern("visibility")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->visibility)); // rbs_keyword
420
-
421
- return CLASS_NEW_INSTANCE(
422
- RBS_AST_Members_AttrWriter,
423
- 1,
424
- &h
425
- );
738
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
739
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
740
+ rbs_loc *loc = rbs_check_location(arg_location);
741
+ {
742
+ rbs_loc_legacy_alloc_children(loc, 7);
743
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
744
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
745
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
746
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
747
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char });
748
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char });
749
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
750
+ }
751
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
752
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
753
+ VALUE arg_ivar_name = rbs_attr_ivar_name_to_ruby(ctx, node->ivar_name); // rbs_attr_ivar_name_t
754
+ VALUE arg_kind = rbs_attribute_kind_to_ruby(node->kind); // attribute_kind
755
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
756
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
757
+ VALUE arg_visibility = rbs_attribute_visibility_to_ruby(node->visibility); // attribute_visibility
758
+
759
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
760
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
761
+ VALUE h = ctx.reusable_kwargs_hash;
762
+ rb_hash_clear(h);
763
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
764
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
765
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
766
+ rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
767
+ rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
768
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
769
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
770
+ rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
771
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_AttrWriter, 1, &h);
426
772
  }
427
773
  case RBS_AST_MEMBERS_CLASS_INSTANCE_VARIABLE: {
428
774
  rbs_ast_members_class_instance_variable_t *node = (rbs_ast_members_class_instance_variable_t *) instance;
429
775
 
430
- VALUE h = rb_hash_new();
431
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
432
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
433
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
434
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
435
-
436
- return CLASS_NEW_INSTANCE(
437
- RBS_AST_Members_ClassInstanceVariable,
438
- 1,
439
- &h
440
- );
776
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
777
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
778
+ rbs_loc *loc = rbs_check_location(arg_location);
779
+ {
780
+ rbs_loc_legacy_alloc_children(loc, 3);
781
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
782
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
783
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
784
+ }
785
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
786
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
787
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
788
+
789
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
790
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
791
+ VALUE h = ctx.reusable_kwargs_hash;
792
+ rb_hash_clear(h);
793
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
794
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
795
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
796
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
797
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_ClassInstanceVariable, 1, &h);
441
798
  }
442
799
  case RBS_AST_MEMBERS_CLASS_VARIABLE: {
443
800
  rbs_ast_members_class_variable_t *node = (rbs_ast_members_class_variable_t *) instance;
444
801
 
445
- VALUE h = rb_hash_new();
446
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
447
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
448
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
449
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
450
-
451
- return CLASS_NEW_INSTANCE(
452
- RBS_AST_Members_ClassVariable,
453
- 1,
454
- &h
455
- );
802
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
803
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
804
+ rbs_loc *loc = rbs_check_location(arg_location);
805
+ {
806
+ rbs_loc_legacy_alloc_children(loc, 3);
807
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
808
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
809
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
810
+ }
811
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
812
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
813
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
814
+
815
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
816
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
817
+ VALUE h = ctx.reusable_kwargs_hash;
818
+ rb_hash_clear(h);
819
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
820
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
821
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
822
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
823
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_ClassVariable, 1, &h);
456
824
  }
457
825
  case RBS_AST_MEMBERS_EXTEND: {
458
826
  rbs_ast_members_extend_t *node = (rbs_ast_members_extend_t *) instance;
459
827
 
460
- VALUE h = rb_hash_new();
461
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
462
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
463
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
464
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
465
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
466
-
467
- return CLASS_NEW_INSTANCE(
468
- RBS_AST_Members_Extend,
469
- 1,
470
- &h
471
- );
828
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
829
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
830
+ rbs_loc *loc = rbs_check_location(arg_location);
831
+ {
832
+ rbs_loc_legacy_alloc_children(loc, 3);
833
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
834
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
835
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
836
+ }
837
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
838
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
839
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
840
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
841
+
842
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
843
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
844
+ VALUE h = ctx.reusable_kwargs_hash;
845
+ rb_hash_clear(h);
846
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
847
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
848
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
849
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
850
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
851
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_Extend, 1, &h);
472
852
  }
473
853
  case RBS_AST_MEMBERS_INCLUDE: {
474
854
  rbs_ast_members_include_t *node = (rbs_ast_members_include_t *) instance;
475
855
 
476
- VALUE h = rb_hash_new();
477
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
478
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
479
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
480
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
481
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
482
-
483
- return CLASS_NEW_INSTANCE(
484
- RBS_AST_Members_Include,
485
- 1,
486
- &h
487
- );
856
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
857
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
858
+ rbs_loc *loc = rbs_check_location(arg_location);
859
+ {
860
+ rbs_loc_legacy_alloc_children(loc, 3);
861
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
862
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
863
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
864
+ }
865
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
866
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
867
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
868
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
869
+
870
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
871
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
872
+ VALUE h = ctx.reusable_kwargs_hash;
873
+ rb_hash_clear(h);
874
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
875
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
876
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
877
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
878
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
879
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_Include, 1, &h);
488
880
  }
489
881
  case RBS_AST_MEMBERS_INSTANCE_VARIABLE: {
490
882
  rbs_ast_members_instance_variable_t *node = (rbs_ast_members_instance_variable_t *) instance;
491
883
 
492
- VALUE h = rb_hash_new();
493
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
494
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
495
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
496
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
497
-
498
- return CLASS_NEW_INSTANCE(
499
- RBS_AST_Members_InstanceVariable,
500
- 1,
501
- &h
502
- );
884
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
885
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
886
+ rbs_loc *loc = rbs_check_location(arg_location);
887
+ {
888
+ rbs_loc_legacy_alloc_children(loc, 3);
889
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
890
+ rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char });
891
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
892
+ }
893
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
894
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
895
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
896
+
897
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
898
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
899
+ VALUE h = ctx.reusable_kwargs_hash;
900
+ rb_hash_clear(h);
901
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
902
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
903
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
904
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
905
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_InstanceVariable, 1, &h);
503
906
  }
504
907
  case RBS_AST_MEMBERS_METHOD_DEFINITION: {
505
908
  rbs_ast_members_method_definition_t *node = (rbs_ast_members_method_definition_t *) instance;
506
909
 
507
- VALUE h = rb_hash_new();
508
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
509
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
510
- rb_hash_aset(h, ID2SYM(rb_intern("kind")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->kind)); // rbs_keyword
511
- rb_hash_aset(h, ID2SYM(rb_intern("overloads")), rbs_node_list_to_ruby_array(ctx, node->overloads));
512
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
513
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
514
- rb_hash_aset(h, ID2SYM(rb_intern("overloading")), node->overloading ? Qtrue : Qfalse);
515
- rb_hash_aset(h, ID2SYM(rb_intern("visibility")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->visibility)); // rbs_keyword
516
-
517
- return CLASS_NEW_INSTANCE(
518
- RBS_AST_Members_MethodDefinition,
519
- 1,
520
- &h
521
- );
910
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
911
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
912
+ rbs_loc *loc = rbs_check_location(arg_location);
913
+ {
914
+ rbs_loc_legacy_alloc_children(loc, 5);
915
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
916
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
917
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char });
918
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("overloading"), (rbs_loc_range) { .start = node->overloading_range.start_char, .end = node->overloading_range.end_char });
919
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char });
920
+ }
921
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
922
+ VALUE arg_kind = rbs_method_definition_kind_to_ruby(node->kind); // method_definition_kind
923
+ VALUE arg_overloads = rbs_node_list_to_ruby_array(ctx, node->overloads);
924
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
925
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
926
+ VALUE arg_overloading = node->overloading ? Qtrue : Qfalse;
927
+ VALUE arg_visibility = rbs_method_definition_visibility_to_ruby(node->visibility); // method_definition_visibility
928
+
929
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
930
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
931
+ VALUE h = ctx.reusable_kwargs_hash;
932
+ rb_hash_clear(h);
933
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
934
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
935
+ rb_hash_aset(h, ID2SYM(rb_intern("kind")), arg_kind);
936
+ rb_hash_aset(h, ID2SYM(rb_intern("overloads")), arg_overloads);
937
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
938
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
939
+ rb_hash_aset(h, ID2SYM(rb_intern("overloading")), arg_overloading);
940
+ rb_hash_aset(h, ID2SYM(rb_intern("visibility")), arg_visibility);
941
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_MethodDefinition, 1, &h);
522
942
  }
523
943
  case RBS_AST_MEMBERS_METHOD_DEFINITION_OVERLOAD: {
524
944
  rbs_ast_members_method_definition_overload_t *node = (rbs_ast_members_method_definition_overload_t *) instance;
525
945
 
526
- VALUE h = rb_hash_new();
527
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
528
- rb_hash_aset(h, ID2SYM(rb_intern("method_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->method_type)); // rbs_node
946
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
947
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
948
+ VALUE arg_method_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->method_type); // rbs_node
529
949
 
530
- return CLASS_NEW_INSTANCE(
531
- RBS_AST_Members_MethodDefinition_Overload,
532
- 1,
533
- &h
534
- );
950
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
951
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
952
+ VALUE h = ctx.reusable_kwargs_hash;
953
+ rb_hash_clear(h);
954
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
955
+ rb_hash_aset(h, ID2SYM(rb_intern("method_type")), arg_method_type);
956
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_MethodDefinition_Overload, 1, &h);
535
957
  }
536
958
  case RBS_AST_MEMBERS_PREPEND: {
537
959
  rbs_ast_members_prepend_t *node = (rbs_ast_members_prepend_t *) instance;
538
960
 
539
- VALUE h = rb_hash_new();
540
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
541
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
542
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
543
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
544
- rb_hash_aset(h, ID2SYM(rb_intern("comment")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment)); // rbs_ast_comment
545
-
546
- return CLASS_NEW_INSTANCE(
547
- RBS_AST_Members_Prepend,
548
- 1,
549
- &h
550
- );
961
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
962
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
963
+ rbs_loc *loc = rbs_check_location(arg_location);
964
+ {
965
+ rbs_loc_legacy_alloc_children(loc, 3);
966
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
967
+ rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char });
968
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
969
+ }
970
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
971
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
972
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
973
+ VALUE arg_comment = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->comment); // rbs_ast_comment
974
+
975
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
976
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
977
+ VALUE h = ctx.reusable_kwargs_hash;
978
+ rb_hash_clear(h);
979
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
980
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
981
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
982
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
983
+ rb_hash_aset(h, ID2SYM(rb_intern("comment")), arg_comment);
984
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_Prepend, 1, &h);
551
985
  }
552
986
  case RBS_AST_MEMBERS_PRIVATE: {
553
987
  rbs_ast_members_private_t *node = (rbs_ast_members_private_t *) instance;
554
988
 
555
- VALUE h = rb_hash_new();
556
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
989
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
990
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
557
991
 
558
- return CLASS_NEW_INSTANCE(
559
- RBS_AST_Members_Private,
560
- 1,
561
- &h
562
- );
992
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
993
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
994
+ VALUE h = ctx.reusable_kwargs_hash;
995
+ rb_hash_clear(h);
996
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
997
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_Private, 1, &h);
563
998
  }
564
999
  case RBS_AST_MEMBERS_PUBLIC: {
565
1000
  rbs_ast_members_public_t *node = (rbs_ast_members_public_t *) instance;
566
1001
 
567
- VALUE h = rb_hash_new();
568
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
569
-
570
- return CLASS_NEW_INSTANCE(
571
- RBS_AST_Members_Public,
572
- 1,
573
- &h
574
- );
1002
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1003
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1004
+
1005
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1006
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1007
+ VALUE h = ctx.reusable_kwargs_hash;
1008
+ rb_hash_clear(h);
1009
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1010
+ return CLASS_NEW_INSTANCE(RBS_AST_Members_Public, 1, &h);
1011
+ }
1012
+ case RBS_AST_RUBY_ANNOTATIONS_BLOCK_PARAM_TYPE_ANNOTATION: {
1013
+ rbs_ast_ruby_annotations_block_param_type_annotation_t *node = (rbs_ast_ruby_annotations_block_param_type_annotation_t *) instance;
1014
+
1015
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1016
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1017
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1018
+ VALUE arg_ampersand_location = rbs_location_range_to_ruby_location(ctx, node->ampersand_location);
1019
+ VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location); // optional
1020
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1021
+ VALUE arg_question_location = rbs_location_range_to_ruby_location(ctx, node->question_location); // optional
1022
+ VALUE arg_type_location = rbs_location_range_to_ruby_location(ctx, node->type_location);
1023
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_); // rbs_node
1024
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1025
+
1026
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1027
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1028
+ VALUE h = ctx.reusable_kwargs_hash;
1029
+ rb_hash_clear(h);
1030
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1031
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1032
+ rb_hash_aset(h, ID2SYM(rb_intern("ampersand_location")), arg_ampersand_location);
1033
+ rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
1034
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1035
+ rb_hash_aset(h, ID2SYM(rb_intern("question_location")), arg_question_location);
1036
+ rb_hash_aset(h, ID2SYM(rb_intern("type_location")), arg_type_location);
1037
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1038
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1039
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_BlockParamTypeAnnotation, 1, &h);
1040
+ }
1041
+ case RBS_AST_RUBY_ANNOTATIONS_CLASS_ALIAS_ANNOTATION: {
1042
+ rbs_ast_ruby_annotations_class_alias_annotation_t *node = (rbs_ast_ruby_annotations_class_alias_annotation_t *) instance;
1043
+
1044
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1045
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1046
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1047
+ VALUE arg_keyword_location = rbs_location_range_to_ruby_location(ctx, node->keyword_location);
1048
+ VALUE arg_type_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name); // rbs_type_name
1049
+ VALUE arg_type_name_location = rbs_location_range_to_ruby_location(ctx, node->type_name_location); // optional
1050
+
1051
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1052
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1053
+ VALUE h = ctx.reusable_kwargs_hash;
1054
+ rb_hash_clear(h);
1055
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1056
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1057
+ rb_hash_aset(h, ID2SYM(rb_intern("keyword_location")), arg_keyword_location);
1058
+ rb_hash_aset(h, ID2SYM(rb_intern("type_name")), arg_type_name);
1059
+ rb_hash_aset(h, ID2SYM(rb_intern("type_name_location")), arg_type_name_location);
1060
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ClassAliasAnnotation, 1, &h);
575
1061
  }
576
1062
  case RBS_AST_RUBY_ANNOTATIONS_COLON_METHOD_TYPE_ANNOTATION: {
577
1063
  rbs_ast_ruby_annotations_colon_method_type_annotation_t *node = (rbs_ast_ruby_annotations_colon_method_type_annotation_t *) instance;
578
1064
 
579
- VALUE h = rb_hash_new();
580
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
581
- rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), rbs_loc_to_ruby_location(ctx, node->prefix_location));
582
- rb_hash_aset(h, ID2SYM(rb_intern("annotations")), rbs_node_list_to_ruby_array(ctx, node->annotations));
583
- rb_hash_aset(h, ID2SYM(rb_intern("method_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->method_type)); // rbs_node
584
-
585
- return CLASS_NEW_INSTANCE(
586
- RBS_AST_Ruby_Annotations_ColonMethodTypeAnnotation,
587
- 1,
588
- &h
589
- );
1065
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1066
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1067
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1068
+ VALUE arg_annotations = rbs_node_list_to_ruby_array(ctx, node->annotations);
1069
+ VALUE arg_method_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->method_type); // rbs_node
1070
+
1071
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1072
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1073
+ VALUE h = ctx.reusable_kwargs_hash;
1074
+ rb_hash_clear(h);
1075
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1076
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1077
+ rb_hash_aset(h, ID2SYM(rb_intern("annotations")), arg_annotations);
1078
+ rb_hash_aset(h, ID2SYM(rb_intern("method_type")), arg_method_type);
1079
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ColonMethodTypeAnnotation, 1, &h);
1080
+ }
1081
+ case RBS_AST_RUBY_ANNOTATIONS_DOUBLE_SPLAT_PARAM_TYPE_ANNOTATION: {
1082
+ rbs_ast_ruby_annotations_double_splat_param_type_annotation_t *node = (rbs_ast_ruby_annotations_double_splat_param_type_annotation_t *) instance;
1083
+
1084
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1085
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1086
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1087
+ VALUE arg_star2_location = rbs_location_range_to_ruby_location(ctx, node->star2_location);
1088
+ VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location); // optional
1089
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1090
+ VALUE arg_param_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->param_type); // rbs_node
1091
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1092
+
1093
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1094
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1095
+ VALUE h = ctx.reusable_kwargs_hash;
1096
+ rb_hash_clear(h);
1097
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1098
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1099
+ rb_hash_aset(h, ID2SYM(rb_intern("star2_location")), arg_star2_location);
1100
+ rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
1101
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1102
+ rb_hash_aset(h, ID2SYM(rb_intern("param_type")), arg_param_type);
1103
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1104
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_DoubleSplatParamTypeAnnotation, 1, &h);
1105
+ }
1106
+ case RBS_AST_RUBY_ANNOTATIONS_INSTANCE_VARIABLE_ANNOTATION: {
1107
+ rbs_ast_ruby_annotations_instance_variable_annotation_t *node = (rbs_ast_ruby_annotations_instance_variable_annotation_t *) instance;
1108
+
1109
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1110
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1111
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1112
+ VALUE arg_ivar_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->ivar_name); // rbs_ast_symbol
1113
+ VALUE arg_ivar_name_location = rbs_location_range_to_ruby_location(ctx, node->ivar_name_location);
1114
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1115
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
1116
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1117
+
1118
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1119
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1120
+ VALUE h = ctx.reusable_kwargs_hash;
1121
+ rb_hash_clear(h);
1122
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1123
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1124
+ rb_hash_aset(h, ID2SYM(rb_intern("ivar_name")), arg_ivar_name);
1125
+ rb_hash_aset(h, ID2SYM(rb_intern("ivar_name_location")), arg_ivar_name_location);
1126
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1127
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1128
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1129
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_InstanceVariableAnnotation, 1, &h);
590
1130
  }
591
1131
  case RBS_AST_RUBY_ANNOTATIONS_METHOD_TYPES_ANNOTATION: {
592
1132
  rbs_ast_ruby_annotations_method_types_annotation_t *node = (rbs_ast_ruby_annotations_method_types_annotation_t *) instance;
593
1133
 
594
- VALUE h = rb_hash_new();
595
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
596
- rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), rbs_loc_to_ruby_location(ctx, node->prefix_location));
597
- rb_hash_aset(h, ID2SYM(rb_intern("overloads")), rbs_node_list_to_ruby_array(ctx, node->overloads));
598
- rb_hash_aset(h, ID2SYM(rb_intern("vertical_bar_locations")), rbs_location_list_to_ruby_array(ctx, node->vertical_bar_locations));
599
-
600
- return CLASS_NEW_INSTANCE(
601
- RBS_AST_Ruby_Annotations_MethodTypesAnnotation,
602
- 1,
603
- &h
604
- );
1134
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1135
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1136
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1137
+ VALUE arg_overloads = rbs_node_list_to_ruby_array(ctx, node->overloads);
1138
+ VALUE arg_vertical_bar_locations = rbs_location_range_list_to_ruby_array(ctx, node->vertical_bar_locations);
1139
+ VALUE arg_dot3_location = rbs_location_range_to_ruby_location(ctx, node->dot3_location); // optional
1140
+
1141
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1142
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1143
+ VALUE h = ctx.reusable_kwargs_hash;
1144
+ rb_hash_clear(h);
1145
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1146
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1147
+ rb_hash_aset(h, ID2SYM(rb_intern("overloads")), arg_overloads);
1148
+ rb_hash_aset(h, ID2SYM(rb_intern("vertical_bar_locations")), arg_vertical_bar_locations);
1149
+ rb_hash_aset(h, ID2SYM(rb_intern("dot3_location")), arg_dot3_location);
1150
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_MethodTypesAnnotation, 1, &h);
1151
+ }
1152
+ case RBS_AST_RUBY_ANNOTATIONS_MODULE_ALIAS_ANNOTATION: {
1153
+ rbs_ast_ruby_annotations_module_alias_annotation_t *node = (rbs_ast_ruby_annotations_module_alias_annotation_t *) instance;
1154
+
1155
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1156
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1157
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1158
+ VALUE arg_keyword_location = rbs_location_range_to_ruby_location(ctx, node->keyword_location);
1159
+ VALUE arg_type_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name); // rbs_type_name
1160
+ VALUE arg_type_name_location = rbs_location_range_to_ruby_location(ctx, node->type_name_location); // optional
1161
+
1162
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1163
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1164
+ VALUE h = ctx.reusable_kwargs_hash;
1165
+ rb_hash_clear(h);
1166
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1167
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1168
+ rb_hash_aset(h, ID2SYM(rb_intern("keyword_location")), arg_keyword_location);
1169
+ rb_hash_aset(h, ID2SYM(rb_intern("type_name")), arg_type_name);
1170
+ rb_hash_aset(h, ID2SYM(rb_intern("type_name_location")), arg_type_name_location);
1171
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ModuleAliasAnnotation, 1, &h);
1172
+ }
1173
+ case RBS_AST_RUBY_ANNOTATIONS_MODULE_SELF_ANNOTATION: {
1174
+ rbs_ast_ruby_annotations_module_self_annotation_t *node = (rbs_ast_ruby_annotations_module_self_annotation_t *) instance;
1175
+
1176
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1177
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1178
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1179
+ VALUE arg_keyword_location = rbs_location_range_to_ruby_location(ctx, node->keyword_location);
1180
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1181
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
1182
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
1183
+ VALUE arg_open_bracket_location = rbs_location_range_to_ruby_location(ctx, node->open_bracket_location); // optional
1184
+ VALUE arg_close_bracket_location = rbs_location_range_to_ruby_location(ctx, node->close_bracket_location); // optional
1185
+ VALUE arg_args_comma_locations = rbs_location_range_list_to_ruby_array(ctx, node->args_comma_locations);
1186
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1187
+
1188
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1189
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1190
+ VALUE h = ctx.reusable_kwargs_hash;
1191
+ rb_hash_clear(h);
1192
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1193
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1194
+ rb_hash_aset(h, ID2SYM(rb_intern("keyword_location")), arg_keyword_location);
1195
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1196
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1197
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
1198
+ rb_hash_aset(h, ID2SYM(rb_intern("open_bracket_location")), arg_open_bracket_location);
1199
+ rb_hash_aset(h, ID2SYM(rb_intern("close_bracket_location")), arg_close_bracket_location);
1200
+ rb_hash_aset(h, ID2SYM(rb_intern("args_comma_locations")), arg_args_comma_locations);
1201
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1202
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ModuleSelfAnnotation, 1, &h);
605
1203
  }
606
1204
  case RBS_AST_RUBY_ANNOTATIONS_NODE_TYPE_ASSERTION: {
607
1205
  rbs_ast_ruby_annotations_node_type_assertion_t *node = (rbs_ast_ruby_annotations_node_type_assertion_t *) instance;
608
1206
 
609
- VALUE h = rb_hash_new();
610
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
611
- rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), rbs_loc_to_ruby_location(ctx, node->prefix_location));
612
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
613
-
614
- return CLASS_NEW_INSTANCE(
615
- RBS_AST_Ruby_Annotations_NodeTypeAssertion,
616
- 1,
617
- &h
618
- );
1207
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1208
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1209
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1210
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
1211
+
1212
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1213
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1214
+ VALUE h = ctx.reusable_kwargs_hash;
1215
+ rb_hash_clear(h);
1216
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1217
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1218
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1219
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_NodeTypeAssertion, 1, &h);
1220
+ }
1221
+ case RBS_AST_RUBY_ANNOTATIONS_PARAM_TYPE_ANNOTATION: {
1222
+ rbs_ast_ruby_annotations_param_type_annotation_t *node = (rbs_ast_ruby_annotations_param_type_annotation_t *) instance;
1223
+
1224
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1225
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1226
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1227
+ VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location);
1228
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1229
+ VALUE arg_param_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->param_type); // rbs_node
1230
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1231
+
1232
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1233
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1234
+ VALUE h = ctx.reusable_kwargs_hash;
1235
+ rb_hash_clear(h);
1236
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1237
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1238
+ rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
1239
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1240
+ rb_hash_aset(h, ID2SYM(rb_intern("param_type")), arg_param_type);
1241
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1242
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ParamTypeAnnotation, 1, &h);
619
1243
  }
620
1244
  case RBS_AST_RUBY_ANNOTATIONS_RETURN_TYPE_ANNOTATION: {
621
1245
  rbs_ast_ruby_annotations_return_type_annotation_t *node = (rbs_ast_ruby_annotations_return_type_annotation_t *) instance;
622
1246
 
623
- VALUE h = rb_hash_new();
624
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
625
- rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), rbs_loc_to_ruby_location(ctx, node->prefix_location));
626
- rb_hash_aset(h, ID2SYM(rb_intern("return_location")), rbs_loc_to_ruby_location(ctx, node->return_location));
627
- rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), rbs_loc_to_ruby_location(ctx, node->colon_location));
628
- rb_hash_aset(h, ID2SYM(rb_intern("return_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type)); // rbs_node
629
- rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), rbs_loc_to_ruby_location(ctx, node->comment_location));
630
-
631
- return CLASS_NEW_INSTANCE(
632
- RBS_AST_Ruby_Annotations_ReturnTypeAnnotation,
633
- 1,
634
- &h
635
- );
1247
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1248
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1249
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1250
+ VALUE arg_return_location = rbs_location_range_to_ruby_location(ctx, node->return_location);
1251
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1252
+ VALUE arg_return_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type); // rbs_node
1253
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1254
+
1255
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1256
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1257
+ VALUE h = ctx.reusable_kwargs_hash;
1258
+ rb_hash_clear(h);
1259
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1260
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1261
+ rb_hash_aset(h, ID2SYM(rb_intern("return_location")), arg_return_location);
1262
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1263
+ rb_hash_aset(h, ID2SYM(rb_intern("return_type")), arg_return_type);
1264
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1265
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_ReturnTypeAnnotation, 1, &h);
636
1266
  }
637
1267
  case RBS_AST_RUBY_ANNOTATIONS_SKIP_ANNOTATION: {
638
1268
  rbs_ast_ruby_annotations_skip_annotation_t *node = (rbs_ast_ruby_annotations_skip_annotation_t *) instance;
639
1269
 
640
- VALUE h = rb_hash_new();
641
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
642
- rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), rbs_loc_to_ruby_location(ctx, node->prefix_location));
643
- rb_hash_aset(h, ID2SYM(rb_intern("skip_location")), rbs_loc_to_ruby_location(ctx, node->skip_location));
644
- rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), rbs_loc_to_ruby_location(ctx, node->comment_location));
645
-
646
- return CLASS_NEW_INSTANCE(
647
- RBS_AST_Ruby_Annotations_SkipAnnotation,
648
- 1,
649
- &h
650
- );
1270
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1271
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1272
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1273
+ VALUE arg_skip_location = rbs_location_range_to_ruby_location(ctx, node->skip_location);
1274
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1275
+
1276
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1277
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1278
+ VALUE h = ctx.reusable_kwargs_hash;
1279
+ rb_hash_clear(h);
1280
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1281
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1282
+ rb_hash_aset(h, ID2SYM(rb_intern("skip_location")), arg_skip_location);
1283
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1284
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_SkipAnnotation, 1, &h);
1285
+ }
1286
+ case RBS_AST_RUBY_ANNOTATIONS_SPLAT_PARAM_TYPE_ANNOTATION: {
1287
+ rbs_ast_ruby_annotations_splat_param_type_annotation_t *node = (rbs_ast_ruby_annotations_splat_param_type_annotation_t *) instance;
1288
+
1289
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1290
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1291
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1292
+ VALUE arg_star_location = rbs_location_range_to_ruby_location(ctx, node->star_location);
1293
+ VALUE arg_name_location = rbs_location_range_to_ruby_location(ctx, node->name_location); // optional
1294
+ VALUE arg_colon_location = rbs_location_range_to_ruby_location(ctx, node->colon_location);
1295
+ VALUE arg_param_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->param_type); // rbs_node
1296
+ VALUE arg_comment_location = rbs_location_range_to_ruby_location(ctx, node->comment_location); // optional
1297
+
1298
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1299
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1300
+ VALUE h = ctx.reusable_kwargs_hash;
1301
+ rb_hash_clear(h);
1302
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1303
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1304
+ rb_hash_aset(h, ID2SYM(rb_intern("star_location")), arg_star_location);
1305
+ rb_hash_aset(h, ID2SYM(rb_intern("name_location")), arg_name_location);
1306
+ rb_hash_aset(h, ID2SYM(rb_intern("colon_location")), arg_colon_location);
1307
+ rb_hash_aset(h, ID2SYM(rb_intern("param_type")), arg_param_type);
1308
+ rb_hash_aset(h, ID2SYM(rb_intern("comment_location")), arg_comment_location);
1309
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_SplatParamTypeAnnotation, 1, &h);
1310
+ }
1311
+ case RBS_AST_RUBY_ANNOTATIONS_TYPE_APPLICATION_ANNOTATION: {
1312
+ rbs_ast_ruby_annotations_type_application_annotation_t *node = (rbs_ast_ruby_annotations_type_application_annotation_t *) instance;
1313
+
1314
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1315
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1316
+ VALUE arg_prefix_location = rbs_location_range_to_ruby_location(ctx, node->prefix_location);
1317
+ VALUE arg_type_args = rbs_node_list_to_ruby_array(ctx, node->type_args);
1318
+ VALUE arg_close_bracket_location = rbs_location_range_to_ruby_location(ctx, node->close_bracket_location);
1319
+ VALUE arg_comma_locations = rbs_location_range_list_to_ruby_array(ctx, node->comma_locations);
1320
+
1321
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1322
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1323
+ VALUE h = ctx.reusable_kwargs_hash;
1324
+ rb_hash_clear(h);
1325
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1326
+ rb_hash_aset(h, ID2SYM(rb_intern("prefix_location")), arg_prefix_location);
1327
+ rb_hash_aset(h, ID2SYM(rb_intern("type_args")), arg_type_args);
1328
+ rb_hash_aset(h, ID2SYM(rb_intern("close_bracket_location")), arg_close_bracket_location);
1329
+ rb_hash_aset(h, ID2SYM(rb_intern("comma_locations")), arg_comma_locations);
1330
+ return CLASS_NEW_INSTANCE(RBS_AST_Ruby_Annotations_TypeApplicationAnnotation, 1, &h);
651
1331
  }
652
1332
  case RBS_AST_STRING: {
653
1333
  rbs_ast_string_t *string_node = (rbs_ast_string_t *) instance;
@@ -658,53 +1338,71 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
658
1338
  case RBS_AST_TYPE_PARAM: {
659
1339
  rbs_ast_type_param_t *node = (rbs_ast_type_param_t *) instance;
660
1340
 
661
- VALUE h = rb_hash_new();
662
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
663
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
664
- rb_hash_aset(h, ID2SYM(rb_intern("variance")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->variance)); // rbs_keyword
665
- rb_hash_aset(h, ID2SYM(rb_intern("upper_bound")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->upper_bound)); // rbs_node
666
- rb_hash_aset(h, ID2SYM(rb_intern("default_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->default_type)); // rbs_node
667
- rb_hash_aset(h, ID2SYM(rb_intern("unchecked")), node->unchecked ? Qtrue : Qfalse);
668
-
669
- return CLASS_NEW_INSTANCE(
670
- RBS_AST_TypeParam,
671
- 1,
672
- &h
673
- );
1341
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1342
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1343
+ rbs_loc *loc = rbs_check_location(arg_location);
1344
+ {
1345
+ rbs_loc_legacy_alloc_children(loc, 6);
1346
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
1347
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("variance"), (rbs_loc_range) { .start = node->variance_range.start_char, .end = node->variance_range.end_char });
1348
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("unchecked"), (rbs_loc_range) { .start = node->unchecked_range.start_char, .end = node->unchecked_range.end_char });
1349
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("upper_bound"), (rbs_loc_range) { .start = node->upper_bound_range.start_char, .end = node->upper_bound_range.end_char });
1350
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("lower_bound"), (rbs_loc_range) { .start = node->lower_bound_range.start_char, .end = node->lower_bound_range.end_char });
1351
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("default"), (rbs_loc_range) { .start = node->default_range.start_char, .end = node->default_range.end_char });
1352
+ }
1353
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
1354
+ VALUE arg_variance = rbs_type_param_variance_to_ruby(node->variance); // type_param_variance
1355
+ VALUE arg_upper_bound = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->upper_bound); // rbs_node
1356
+ VALUE arg_lower_bound = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->lower_bound); // rbs_node
1357
+ VALUE arg_default_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->default_type); // rbs_node
1358
+ VALUE arg_unchecked = node->unchecked ? Qtrue : Qfalse;
1359
+
1360
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1361
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1362
+ VALUE h = ctx.reusable_kwargs_hash;
1363
+ rb_hash_clear(h);
1364
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1365
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1366
+ rb_hash_aset(h, ID2SYM(rb_intern("variance")), arg_variance);
1367
+ rb_hash_aset(h, ID2SYM(rb_intern("upper_bound")), arg_upper_bound);
1368
+ rb_hash_aset(h, ID2SYM(rb_intern("lower_bound")), arg_lower_bound);
1369
+ rb_hash_aset(h, ID2SYM(rb_intern("default_type")), arg_default_type);
1370
+ rb_hash_aset(h, ID2SYM(rb_intern("unchecked")), arg_unchecked);
1371
+ return CLASS_NEW_INSTANCE(RBS_AST_TypeParam, 1, &h);
674
1372
  }
675
1373
  case RBS_METHOD_TYPE: {
676
1374
  rbs_method_type_t *node = (rbs_method_type_t *) instance;
677
1375
 
678
- VALUE h = rb_hash_new();
679
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
680
- rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params));
681
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
682
- rb_hash_aset(h, ID2SYM(rb_intern("block")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->block)); // rbs_types_block
1376
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1377
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1378
+ rbs_loc *loc = rbs_check_location(arg_location);
1379
+ {
1380
+ rbs_loc_legacy_alloc_children(loc, 2);
1381
+ rbs_loc_legacy_add_required_child(loc, rb_intern("type"), (rbs_loc_range) { .start = node->type_range.start_char, .end = node->type_range.end_char });
1382
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char });
1383
+ }
1384
+ VALUE arg_type_params = rbs_node_list_to_ruby_array(ctx, node->type_params);
1385
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
1386
+ VALUE arg_block = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->block); // rbs_types_block
683
1387
 
684
1388
  rb_funcall(
685
1389
  RBS_AST_TypeParam,
686
1390
  rb_intern("resolve_variables"),
687
1391
  1,
688
- rb_hash_lookup(h, ID2SYM(rb_intern("type_params")))
689
- );
690
- return CLASS_NEW_INSTANCE(
691
- RBS_MethodType,
692
- 1,
693
- &h
1392
+ arg_type_params
694
1393
  );
1394
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1395
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1396
+ VALUE h = ctx.reusable_kwargs_hash;
1397
+ rb_hash_clear(h);
1398
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1399
+ rb_hash_aset(h, ID2SYM(rb_intern("type_params")), arg_type_params);
1400
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1401
+ rb_hash_aset(h, ID2SYM(rb_intern("block")), arg_block);
1402
+ return CLASS_NEW_INSTANCE(RBS_MethodType, 1, &h);
695
1403
  }
696
1404
  case RBS_NAMESPACE: {
697
- rbs_namespace_t *node = (rbs_namespace_t *) instance;
698
-
699
- VALUE h = rb_hash_new();
700
- rb_hash_aset(h, ID2SYM(rb_intern("path")), rbs_node_list_to_ruby_array(ctx, node->path));
701
- rb_hash_aset(h, ID2SYM(rb_intern("absolute")), node->absolute ? Qtrue : Qfalse);
702
-
703
- return CLASS_NEW_INSTANCE(
704
- RBS_Namespace,
705
- 1,
706
- &h
707
- );
1405
+ return rbs_intern_namespace(ctx, (rbs_namespace_t *) instance);
708
1406
  }
709
1407
  case RBS_SIGNATURE: {
710
1408
  rbs_signature_t *signature = (rbs_signature_t *) instance;
@@ -716,295 +1414,367 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
716
1414
  }
717
1415
  case RBS_TYPE_NAME: {
718
1416
  rbs_type_name_t *node = (rbs_type_name_t *) instance;
719
-
720
- VALUE h = rb_hash_new();
721
- rb_hash_aset(h, ID2SYM(rb_intern("namespace")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace)); // rbs_namespace
722
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
723
-
724
- return CLASS_NEW_INSTANCE(
725
- RBS_TypeName,
726
- 1,
727
- &h
728
- );
1417
+ VALUE ns = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace);
1418
+ VALUE name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name);
1419
+ return rbs_intern_type_name(ns, name);
729
1420
  }
730
1421
  case RBS_TYPES_ALIAS: {
731
1422
  rbs_types_alias_t *node = (rbs_types_alias_t *) instance;
732
1423
 
733
- VALUE h = rb_hash_new();
734
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
735
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
736
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
737
-
738
- return CLASS_NEW_INSTANCE(
739
- RBS_Types_Alias,
740
- 1,
741
- &h
742
- );
1424
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1425
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1426
+ rbs_loc *loc = rbs_check_location(arg_location);
1427
+ {
1428
+ rbs_loc_legacy_alloc_children(loc, 2);
1429
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
1430
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
1431
+ }
1432
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
1433
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
1434
+
1435
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1436
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1437
+ VALUE h = ctx.reusable_kwargs_hash;
1438
+ rb_hash_clear(h);
1439
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1440
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1441
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
1442
+ return CLASS_NEW_INSTANCE(RBS_Types_Alias, 1, &h);
743
1443
  }
744
1444
  case RBS_TYPES_BASES_ANY: {
745
1445
  rbs_types_bases_any_t *node = (rbs_types_bases_any_t *) instance;
746
1446
 
747
- VALUE h = rb_hash_new();
748
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
749
- rb_hash_aset(h, ID2SYM(rb_intern("todo")), node->todo ? Qtrue : Qfalse);
1447
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1448
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1449
+ VALUE arg_todo = node->todo ? Qtrue : Qfalse;
750
1450
 
751
- return CLASS_NEW_INSTANCE(
752
- RBS_Types_Bases_Any,
753
- 1,
754
- &h
755
- );
1451
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1452
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1453
+ VALUE h = ctx.reusable_kwargs_hash;
1454
+ rb_hash_clear(h);
1455
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1456
+ rb_hash_aset(h, ID2SYM(rb_intern("todo")), arg_todo);
1457
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Any, 1, &h);
756
1458
  }
757
1459
  case RBS_TYPES_BASES_BOOL: {
758
1460
  rbs_types_bases_bool_t *node = (rbs_types_bases_bool_t *) instance;
759
1461
 
760
- VALUE h = rb_hash_new();
761
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1462
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1463
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
762
1464
 
763
- return CLASS_NEW_INSTANCE(
764
- RBS_Types_Bases_Bool,
765
- 1,
766
- &h
767
- );
1465
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1466
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1467
+ VALUE h = ctx.reusable_kwargs_hash;
1468
+ rb_hash_clear(h);
1469
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1470
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Bool, 1, &h);
768
1471
  }
769
1472
  case RBS_TYPES_BASES_BOTTOM: {
770
1473
  rbs_types_bases_bottom_t *node = (rbs_types_bases_bottom_t *) instance;
771
1474
 
772
- VALUE h = rb_hash_new();
773
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1475
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1476
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
774
1477
 
775
- return CLASS_NEW_INSTANCE(
776
- RBS_Types_Bases_Bottom,
777
- 1,
778
- &h
779
- );
1478
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1479
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1480
+ VALUE h = ctx.reusable_kwargs_hash;
1481
+ rb_hash_clear(h);
1482
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1483
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Bottom, 1, &h);
780
1484
  }
781
1485
  case RBS_TYPES_BASES_CLASS: {
782
1486
  rbs_types_bases_class_t *node = (rbs_types_bases_class_t *) instance;
783
1487
 
784
- VALUE h = rb_hash_new();
785
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1488
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1489
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
786
1490
 
787
- return CLASS_NEW_INSTANCE(
788
- RBS_Types_Bases_Class,
789
- 1,
790
- &h
791
- );
1491
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1492
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1493
+ VALUE h = ctx.reusable_kwargs_hash;
1494
+ rb_hash_clear(h);
1495
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1496
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Class, 1, &h);
792
1497
  }
793
1498
  case RBS_TYPES_BASES_INSTANCE: {
794
1499
  rbs_types_bases_instance_t *node = (rbs_types_bases_instance_t *) instance;
795
1500
 
796
- VALUE h = rb_hash_new();
797
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1501
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1502
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
798
1503
 
799
- return CLASS_NEW_INSTANCE(
800
- RBS_Types_Bases_Instance,
801
- 1,
802
- &h
803
- );
1504
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1505
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1506
+ VALUE h = ctx.reusable_kwargs_hash;
1507
+ rb_hash_clear(h);
1508
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1509
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Instance, 1, &h);
804
1510
  }
805
1511
  case RBS_TYPES_BASES_NIL: {
806
1512
  rbs_types_bases_nil_t *node = (rbs_types_bases_nil_t *) instance;
807
1513
 
808
- VALUE h = rb_hash_new();
809
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1514
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1515
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
810
1516
 
811
- return CLASS_NEW_INSTANCE(
812
- RBS_Types_Bases_Nil,
813
- 1,
814
- &h
815
- );
1517
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1518
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1519
+ VALUE h = ctx.reusable_kwargs_hash;
1520
+ rb_hash_clear(h);
1521
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1522
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Nil, 1, &h);
816
1523
  }
817
1524
  case RBS_TYPES_BASES_SELF: {
818
1525
  rbs_types_bases_self_t *node = (rbs_types_bases_self_t *) instance;
819
1526
 
820
- VALUE h = rb_hash_new();
821
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1527
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1528
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
822
1529
 
823
- return CLASS_NEW_INSTANCE(
824
- RBS_Types_Bases_Self,
825
- 1,
826
- &h
827
- );
1530
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1531
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1532
+ VALUE h = ctx.reusable_kwargs_hash;
1533
+ rb_hash_clear(h);
1534
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1535
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Self, 1, &h);
828
1536
  }
829
1537
  case RBS_TYPES_BASES_TOP: {
830
1538
  rbs_types_bases_top_t *node = (rbs_types_bases_top_t *) instance;
831
1539
 
832
- VALUE h = rb_hash_new();
833
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1540
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1541
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
834
1542
 
835
- return CLASS_NEW_INSTANCE(
836
- RBS_Types_Bases_Top,
837
- 1,
838
- &h
839
- );
1543
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1544
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1545
+ VALUE h = ctx.reusable_kwargs_hash;
1546
+ rb_hash_clear(h);
1547
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1548
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Top, 1, &h);
840
1549
  }
841
1550
  case RBS_TYPES_BASES_VOID: {
842
1551
  rbs_types_bases_void_t *node = (rbs_types_bases_void_t *) instance;
843
1552
 
844
- VALUE h = rb_hash_new();
845
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1553
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1554
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
846
1555
 
847
- return CLASS_NEW_INSTANCE(
848
- RBS_Types_Bases_Void,
849
- 1,
850
- &h
851
- );
1556
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1557
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1558
+ VALUE h = ctx.reusable_kwargs_hash;
1559
+ rb_hash_clear(h);
1560
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1561
+ return CLASS_NEW_INSTANCE(RBS_Types_Bases_Void, 1, &h);
852
1562
  }
853
1563
  case RBS_TYPES_BLOCK: {
854
1564
  rbs_types_block_t *node = (rbs_types_block_t *) instance;
855
1565
 
856
- VALUE h = rb_hash_new();
857
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
858
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
859
- rb_hash_aset(h, ID2SYM(rb_intern("required")), node->required ? Qtrue : Qfalse);
860
- rb_hash_aset(h, ID2SYM(rb_intern("self_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->self_type)); // rbs_node
861
-
862
- return CLASS_NEW_INSTANCE(
863
- RBS_Types_Block,
864
- 1,
865
- &h
866
- );
1566
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1567
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1568
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
1569
+ VALUE arg_required = node->required ? Qtrue : Qfalse;
1570
+ VALUE arg_self_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->self_type); // rbs_node
1571
+
1572
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1573
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1574
+ VALUE h = ctx.reusable_kwargs_hash;
1575
+ rb_hash_clear(h);
1576
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1577
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1578
+ rb_hash_aset(h, ID2SYM(rb_intern("required")), arg_required);
1579
+ rb_hash_aset(h, ID2SYM(rb_intern("self_type")), arg_self_type);
1580
+ return CLASS_NEW_INSTANCE(RBS_Types_Block, 1, &h);
867
1581
  }
868
1582
  case RBS_TYPES_CLASS_INSTANCE: {
869
1583
  rbs_types_class_instance_t *node = (rbs_types_class_instance_t *) instance;
870
1584
 
871
- VALUE h = rb_hash_new();
872
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
873
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
874
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
875
-
876
- return CLASS_NEW_INSTANCE(
877
- RBS_Types_ClassInstance,
878
- 1,
879
- &h
880
- );
1585
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1586
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1587
+ rbs_loc *loc = rbs_check_location(arg_location);
1588
+ {
1589
+ rbs_loc_legacy_alloc_children(loc, 2);
1590
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
1591
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
1592
+ }
1593
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
1594
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
1595
+
1596
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1597
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1598
+ VALUE h = ctx.reusable_kwargs_hash;
1599
+ rb_hash_clear(h);
1600
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1601
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1602
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
1603
+ return CLASS_NEW_INSTANCE(RBS_Types_ClassInstance, 1, &h);
881
1604
  }
882
1605
  case RBS_TYPES_CLASS_SINGLETON: {
883
1606
  rbs_types_class_singleton_t *node = (rbs_types_class_singleton_t *) instance;
884
1607
 
885
- VALUE h = rb_hash_new();
886
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
887
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
888
-
889
- return CLASS_NEW_INSTANCE(
890
- RBS_Types_ClassSingleton,
891
- 1,
892
- &h
893
- );
1608
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1609
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1610
+ rbs_loc *loc = rbs_check_location(arg_location);
1611
+ {
1612
+ rbs_loc_legacy_alloc_children(loc, 2);
1613
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
1614
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
1615
+ }
1616
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
1617
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
1618
+
1619
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1620
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1621
+ VALUE h = ctx.reusable_kwargs_hash;
1622
+ rb_hash_clear(h);
1623
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1624
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1625
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
1626
+ return CLASS_NEW_INSTANCE(RBS_Types_ClassSingleton, 1, &h);
894
1627
  }
895
1628
  case RBS_TYPES_FUNCTION: {
896
1629
  rbs_types_function_t *node = (rbs_types_function_t *) instance;
897
1630
 
898
- VALUE h = rb_hash_new();
899
- rb_hash_aset(h, ID2SYM(rb_intern("required_positionals")), rbs_node_list_to_ruby_array(ctx, node->required_positionals));
900
- rb_hash_aset(h, ID2SYM(rb_intern("optional_positionals")), rbs_node_list_to_ruby_array(ctx, node->optional_positionals));
901
- rb_hash_aset(h, ID2SYM(rb_intern("rest_positionals")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rest_positionals)); // rbs_node
902
- rb_hash_aset(h, ID2SYM(rb_intern("trailing_positionals")), rbs_node_list_to_ruby_array(ctx, node->trailing_positionals));
903
- rb_hash_aset(h, ID2SYM(rb_intern("required_keywords")), rbs_hash_to_ruby_hash(ctx, node->required_keywords));
904
- rb_hash_aset(h, ID2SYM(rb_intern("optional_keywords")), rbs_hash_to_ruby_hash(ctx, node->optional_keywords));
905
- rb_hash_aset(h, ID2SYM(rb_intern("rest_keywords")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rest_keywords)); // rbs_node
906
- rb_hash_aset(h, ID2SYM(rb_intern("return_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type)); // rbs_node
907
-
908
- return CLASS_NEW_INSTANCE(
909
- RBS_Types_Function,
910
- 1,
911
- &h
912
- );
1631
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1632
+ VALUE arg_required_positionals = rbs_node_list_to_ruby_array(ctx, node->required_positionals);
1633
+ VALUE arg_optional_positionals = rbs_node_list_to_ruby_array(ctx, node->optional_positionals);
1634
+ VALUE arg_rest_positionals = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rest_positionals); // rbs_node
1635
+ VALUE arg_trailing_positionals = rbs_node_list_to_ruby_array(ctx, node->trailing_positionals);
1636
+ VALUE arg_required_keywords = rbs_hash_to_ruby_hash(ctx, node->required_keywords);
1637
+ VALUE arg_optional_keywords = rbs_hash_to_ruby_hash(ctx, node->optional_keywords);
1638
+ VALUE arg_rest_keywords = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rest_keywords); // rbs_node
1639
+ VALUE arg_return_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type); // rbs_node
1640
+
1641
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1642
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1643
+ VALUE h = ctx.reusable_kwargs_hash;
1644
+ rb_hash_clear(h);
1645
+ rb_hash_aset(h, ID2SYM(rb_intern("required_positionals")), arg_required_positionals);
1646
+ rb_hash_aset(h, ID2SYM(rb_intern("optional_positionals")), arg_optional_positionals);
1647
+ rb_hash_aset(h, ID2SYM(rb_intern("rest_positionals")), arg_rest_positionals);
1648
+ rb_hash_aset(h, ID2SYM(rb_intern("trailing_positionals")), arg_trailing_positionals);
1649
+ rb_hash_aset(h, ID2SYM(rb_intern("required_keywords")), arg_required_keywords);
1650
+ rb_hash_aset(h, ID2SYM(rb_intern("optional_keywords")), arg_optional_keywords);
1651
+ rb_hash_aset(h, ID2SYM(rb_intern("rest_keywords")), arg_rest_keywords);
1652
+ rb_hash_aset(h, ID2SYM(rb_intern("return_type")), arg_return_type);
1653
+ return CLASS_NEW_INSTANCE(RBS_Types_Function, 1, &h);
913
1654
  }
914
1655
  case RBS_TYPES_FUNCTION_PARAM: {
915
1656
  rbs_types_function_param_t *node = (rbs_types_function_param_t *) instance;
916
1657
 
917
- VALUE h = rb_hash_new();
918
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
919
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
920
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
921
-
922
- return CLASS_NEW_INSTANCE(
923
- RBS_Types_Function_Param,
924
- 1,
925
- &h
926
- );
1658
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1659
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1660
+ rbs_loc *loc = rbs_check_location(arg_location);
1661
+ {
1662
+ rbs_loc_legacy_alloc_children(loc, 1);
1663
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
1664
+ }
1665
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
1666
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
1667
+
1668
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1669
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1670
+ VALUE h = ctx.reusable_kwargs_hash;
1671
+ rb_hash_clear(h);
1672
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1673
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1674
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1675
+ return CLASS_NEW_INSTANCE(RBS_Types_Function_Param, 1, &h);
927
1676
  }
928
1677
  case RBS_TYPES_INTERFACE: {
929
1678
  rbs_types_interface_t *node = (rbs_types_interface_t *) instance;
930
1679
 
931
- VALUE h = rb_hash_new();
932
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
933
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name
934
- rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args));
935
-
936
- return CLASS_NEW_INSTANCE(
937
- RBS_Types_Interface,
938
- 1,
939
- &h
940
- );
1680
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1681
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1682
+ rbs_loc *loc = rbs_check_location(arg_location);
1683
+ {
1684
+ rbs_loc_legacy_alloc_children(loc, 2);
1685
+ rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char });
1686
+ rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char });
1687
+ }
1688
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_type_name
1689
+ VALUE arg_args = rbs_node_list_to_ruby_array(ctx, node->args);
1690
+
1691
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1692
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1693
+ VALUE h = ctx.reusable_kwargs_hash;
1694
+ rb_hash_clear(h);
1695
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1696
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1697
+ rb_hash_aset(h, ID2SYM(rb_intern("args")), arg_args);
1698
+ return CLASS_NEW_INSTANCE(RBS_Types_Interface, 1, &h);
941
1699
  }
942
1700
  case RBS_TYPES_INTERSECTION: {
943
1701
  rbs_types_intersection_t *node = (rbs_types_intersection_t *) instance;
944
1702
 
945
- VALUE h = rb_hash_new();
946
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
947
- rb_hash_aset(h, ID2SYM(rb_intern("types")), rbs_node_list_to_ruby_array(ctx, node->types));
1703
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1704
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1705
+ VALUE arg_types = rbs_node_list_to_ruby_array(ctx, node->types);
948
1706
 
949
- return CLASS_NEW_INSTANCE(
950
- RBS_Types_Intersection,
951
- 1,
952
- &h
953
- );
1707
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1708
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1709
+ VALUE h = ctx.reusable_kwargs_hash;
1710
+ rb_hash_clear(h);
1711
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1712
+ rb_hash_aset(h, ID2SYM(rb_intern("types")), arg_types);
1713
+ return CLASS_NEW_INSTANCE(RBS_Types_Intersection, 1, &h);
954
1714
  }
955
1715
  case RBS_TYPES_LITERAL: {
956
1716
  rbs_types_literal_t *node = (rbs_types_literal_t *) instance;
957
1717
 
958
- VALUE h = rb_hash_new();
959
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
960
- rb_hash_aset(h, ID2SYM(rb_intern("literal")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->literal)); // rbs_node
1718
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1719
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1720
+ VALUE arg_literal = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->literal); // rbs_node
961
1721
 
962
- return CLASS_NEW_INSTANCE(
963
- RBS_Types_Literal,
964
- 1,
965
- &h
966
- );
1722
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1723
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1724
+ VALUE h = ctx.reusable_kwargs_hash;
1725
+ rb_hash_clear(h);
1726
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1727
+ rb_hash_aset(h, ID2SYM(rb_intern("literal")), arg_literal);
1728
+ return CLASS_NEW_INSTANCE(RBS_Types_Literal, 1, &h);
967
1729
  }
968
1730
  case RBS_TYPES_OPTIONAL: {
969
1731
  rbs_types_optional_t *node = (rbs_types_optional_t *) instance;
970
1732
 
971
- VALUE h = rb_hash_new();
972
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
973
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
1733
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1734
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1735
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
974
1736
 
975
- return CLASS_NEW_INSTANCE(
976
- RBS_Types_Optional,
977
- 1,
978
- &h
979
- );
1737
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1738
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1739
+ VALUE h = ctx.reusable_kwargs_hash;
1740
+ rb_hash_clear(h);
1741
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1742
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1743
+ return CLASS_NEW_INSTANCE(RBS_Types_Optional, 1, &h);
980
1744
  }
981
1745
  case RBS_TYPES_PROC: {
982
1746
  rbs_types_proc_t *node = (rbs_types_proc_t *) instance;
983
1747
 
984
- VALUE h = rb_hash_new();
985
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
986
- rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node
987
- rb_hash_aset(h, ID2SYM(rb_intern("block")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->block)); // rbs_types_block
988
- rb_hash_aset(h, ID2SYM(rb_intern("self_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->self_type)); // rbs_node
989
-
990
- return CLASS_NEW_INSTANCE(
991
- RBS_Types_Proc,
992
- 1,
993
- &h
994
- );
1748
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1749
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1750
+ VALUE arg_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type); // rbs_node
1751
+ VALUE arg_block = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->block); // rbs_types_block
1752
+ VALUE arg_self_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->self_type); // rbs_node
1753
+
1754
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1755
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1756
+ VALUE h = ctx.reusable_kwargs_hash;
1757
+ rb_hash_clear(h);
1758
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1759
+ rb_hash_aset(h, ID2SYM(rb_intern("type")), arg_type);
1760
+ rb_hash_aset(h, ID2SYM(rb_intern("block")), arg_block);
1761
+ rb_hash_aset(h, ID2SYM(rb_intern("self_type")), arg_self_type);
1762
+ return CLASS_NEW_INSTANCE(RBS_Types_Proc, 1, &h);
995
1763
  }
996
1764
  case RBS_TYPES_RECORD: {
997
1765
  rbs_types_record_t *node = (rbs_types_record_t *) instance;
998
1766
 
999
- VALUE h = rb_hash_new();
1000
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1001
- rb_hash_aset(h, ID2SYM(rb_intern("all_fields")), rbs_hash_to_ruby_hash(ctx, node->all_fields));
1767
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1768
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1769
+ VALUE arg_all_fields = rbs_hash_to_ruby_hash(ctx, node->all_fields);
1002
1770
 
1003
- return CLASS_NEW_INSTANCE(
1004
- RBS_Types_Record,
1005
- 1,
1006
- &h
1007
- );
1771
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1772
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1773
+ VALUE h = ctx.reusable_kwargs_hash;
1774
+ rb_hash_clear(h);
1775
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1776
+ rb_hash_aset(h, ID2SYM(rb_intern("all_fields")), arg_all_fields);
1777
+ return CLASS_NEW_INSTANCE(RBS_Types_Record, 1, &h);
1008
1778
  }
1009
1779
  case RBS_TYPES_RECORD_FIELD_TYPE: {
1010
1780
  rbs_types_record_field_type_t *record_fieldtype = (rbs_types_record_field_type_t *) instance;
@@ -1017,63 +1787,63 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan
1017
1787
  case RBS_TYPES_TUPLE: {
1018
1788
  rbs_types_tuple_t *node = (rbs_types_tuple_t *) instance;
1019
1789
 
1020
- VALUE h = rb_hash_new();
1021
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1022
- rb_hash_aset(h, ID2SYM(rb_intern("types")), rbs_node_list_to_ruby_array(ctx, node->types));
1790
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1791
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1792
+ VALUE arg_types = rbs_node_list_to_ruby_array(ctx, node->types);
1023
1793
 
1024
- return CLASS_NEW_INSTANCE(
1025
- RBS_Types_Tuple,
1026
- 1,
1027
- &h
1028
- );
1794
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1795
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1796
+ VALUE h = ctx.reusable_kwargs_hash;
1797
+ rb_hash_clear(h);
1798
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1799
+ rb_hash_aset(h, ID2SYM(rb_intern("types")), arg_types);
1800
+ return CLASS_NEW_INSTANCE(RBS_Types_Tuple, 1, &h);
1029
1801
  }
1030
1802
  case RBS_TYPES_UNION: {
1031
1803
  rbs_types_union_t *node = (rbs_types_union_t *) instance;
1032
1804
 
1033
- VALUE h = rb_hash_new();
1034
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1035
- rb_hash_aset(h, ID2SYM(rb_intern("types")), rbs_node_list_to_ruby_array(ctx, node->types));
1805
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1806
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1807
+ VALUE arg_types = rbs_node_list_to_ruby_array(ctx, node->types);
1036
1808
 
1037
- return CLASS_NEW_INSTANCE(
1038
- RBS_Types_Union,
1039
- 1,
1040
- &h
1041
- );
1809
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1810
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1811
+ VALUE h = ctx.reusable_kwargs_hash;
1812
+ rb_hash_clear(h);
1813
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1814
+ rb_hash_aset(h, ID2SYM(rb_intern("types")), arg_types);
1815
+ return CLASS_NEW_INSTANCE(RBS_Types_Union, 1, &h);
1042
1816
  }
1043
1817
  case RBS_TYPES_UNTYPED_FUNCTION: {
1044
1818
  rbs_types_untyped_function_t *node = (rbs_types_untyped_function_t *) instance;
1045
1819
 
1046
- VALUE h = rb_hash_new();
1047
- rb_hash_aset(h, ID2SYM(rb_intern("return_type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type)); // rbs_node
1820
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1821
+ VALUE arg_return_type = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->return_type); // rbs_node
1048
1822
 
1049
- return CLASS_NEW_INSTANCE(
1050
- RBS_Types_UntypedFunction,
1051
- 1,
1052
- &h
1053
- );
1823
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1824
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1825
+ VALUE h = ctx.reusable_kwargs_hash;
1826
+ rb_hash_clear(h);
1827
+ rb_hash_aset(h, ID2SYM(rb_intern("return_type")), arg_return_type);
1828
+ return CLASS_NEW_INSTANCE(RBS_Types_UntypedFunction, 1, &h);
1054
1829
  }
1055
1830
  case RBS_TYPES_VARIABLE: {
1056
1831
  rbs_types_variable_t *node = (rbs_types_variable_t *) instance;
1057
1832
 
1058
- VALUE h = rb_hash_new();
1059
- rb_hash_aset(h, ID2SYM(rb_intern("location")), rbs_loc_to_ruby_location(ctx, node->base.location));
1060
- rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol
1061
-
1062
- return CLASS_NEW_INSTANCE(
1063
- RBS_Types_Variable,
1064
- 1,
1065
- &h
1066
- );
1067
- }
1068
- case RBS_KEYWORD: {
1069
- rbs_constant_t *constant = rbs_constant_pool_id_to_constant(RBS_GLOBAL_CONSTANT_POOL, ((rbs_keyword_t *) instance)->constant_id);
1070
- assert(constant != NULL && "constant is NULL");
1071
- assert(constant->start != NULL && "constant->start is NULL");
1833
+ // Compute child VALUEs into locals variables first, before any recursion into `rbs_struct_to_ruby_value()`.
1834
+ VALUE arg_location = rbs_location_range_to_ruby_location(ctx, node->base.location);
1835
+ VALUE arg_name = rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name); // rbs_ast_symbol
1072
1836
 
1073
- return ID2SYM(rb_intern2((const char *) constant->start, constant->length));
1837
+ // Claim the shared kwargs hash, clear it, fill it, and hand it to `.new`.
1838
+ // Must not recurse between `rb_hash_clear()` and `CLASS_NEW_INSTANCE()`.
1839
+ VALUE h = ctx.reusable_kwargs_hash;
1840
+ rb_hash_clear(h);
1841
+ rb_hash_aset(h, ID2SYM(rb_intern("location")), arg_location);
1842
+ rb_hash_aset(h, ID2SYM(rb_intern("name")), arg_name);
1843
+ return CLASS_NEW_INSTANCE(RBS_Types_Variable, 1, &h);
1074
1844
  }
1075
1845
  case RBS_AST_SYMBOL: {
1076
- rbs_constant_t *constant = rbs_constant_pool_id_to_constant(ctx.constant_pool, ((rbs_keyword_t *) instance)->constant_id);
1846
+ rbs_constant_t *constant = rbs_constant_pool_id_to_constant(ctx.constant_pool, ((rbs_ast_symbol_t *) instance)->constant_id);
1077
1847
  assert(constant != NULL && "constant is NULL");
1078
1848
  assert(constant->start != NULL && "constant->start is NULL");
1079
1849