rbs 3.9.4 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. checksums.yaml +4 -4
  2. data/.clang-format +75 -0
  3. data/.clangd +2 -0
  4. data/.dockerignore +37 -0
  5. data/.github/dependabot.yml +16 -14
  6. data/.github/workflows/bundle-update.yml +63 -0
  7. data/.github/workflows/c-check.yml +66 -0
  8. data/.github/workflows/comments.yml +5 -3
  9. data/.github/workflows/dependabot.yml +2 -2
  10. data/.github/workflows/jruby.yml +79 -0
  11. data/.github/workflows/release-gems.yml +164 -0
  12. data/.github/workflows/ruby.yml +84 -30
  13. data/.github/workflows/rust.yml +186 -0
  14. data/.github/workflows/truffleruby.yml +54 -0
  15. data/.github/workflows/typecheck.yml +5 -2
  16. data/.github/workflows/wasm.yml +55 -0
  17. data/.github/workflows/windows.yml +9 -3
  18. data/.gitignore +16 -0
  19. data/.rubocop.yml +2 -2
  20. data/CHANGELOG.md +430 -0
  21. data/Dockerfile.jruby +53 -0
  22. data/README.md +41 -4
  23. data/Rakefile +777 -60
  24. data/Steepfile +11 -0
  25. data/config.yml +660 -62
  26. data/core/array.rbs +541 -398
  27. data/core/basic_object.rbs +9 -8
  28. data/core/binding.rbs +0 -2
  29. data/core/builtin.rbs +9 -8
  30. data/core/class.rbs +11 -8
  31. data/core/comparable.rbs +55 -34
  32. data/core/complex.rbs +104 -78
  33. data/core/dir.rbs +61 -49
  34. data/core/encoding.rbs +12 -15
  35. data/core/enumerable.rbs +297 -196
  36. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  37. data/core/enumerator/product.rbs +5 -5
  38. data/core/enumerator.rbs +91 -28
  39. data/core/errno.rbs +11 -2
  40. data/core/errors.rbs +58 -29
  41. data/core/exception.rbs +13 -13
  42. data/core/fiber.rbs +74 -54
  43. data/core/file.rbs +260 -1151
  44. data/core/file_constants.rbs +463 -0
  45. data/core/file_stat.rbs +534 -0
  46. data/core/file_test.rbs +3 -3
  47. data/core/float.rbs +257 -116
  48. data/core/gc.rbs +425 -281
  49. data/core/hash.rbs +1151 -829
  50. data/core/integer.rbs +156 -195
  51. data/core/io/buffer.rbs +53 -42
  52. data/core/io/wait.rbs +13 -35
  53. data/core/io.rbs +220 -154
  54. data/core/kernel.rbs +239 -163
  55. data/core/marshal.rbs +4 -4
  56. data/core/match_data.rbs +16 -14
  57. data/core/math.rbs +107 -66
  58. data/core/method.rbs +69 -33
  59. data/core/module.rbs +302 -150
  60. data/core/nil_class.rbs +7 -6
  61. data/core/numeric.rbs +77 -63
  62. data/core/object.rbs +9 -11
  63. data/core/object_space/weak_key_map.rbs +7 -7
  64. data/core/object_space.rbs +30 -23
  65. data/core/pathname.rbs +1312 -0
  66. data/core/proc.rbs +95 -58
  67. data/core/process.rbs +222 -202
  68. data/core/ractor.rbs +364 -518
  69. data/core/random.rbs +21 -3
  70. data/core/range.rbs +181 -79
  71. data/core/rational.rbs +60 -89
  72. data/core/rbs/ops.rbs +154 -0
  73. data/core/rbs/unnamed/argf.rbs +63 -56
  74. data/core/rbs/unnamed/env_class.rbs +19 -14
  75. data/core/rbs/unnamed/main_class.rbs +123 -0
  76. data/core/rbs/unnamed/random.rbs +11 -118
  77. data/core/regexp.rbs +258 -214
  78. data/core/ruby.rbs +53 -0
  79. data/core/ruby_vm.rbs +78 -34
  80. data/core/rubygems/config_file.rbs +5 -5
  81. data/core/rubygems/errors.rbs +6 -70
  82. data/core/rubygems/requirement.rbs +5 -15
  83. data/core/rubygems/rubygems.rbs +18 -81
  84. data/core/rubygems/specification.rbs +8 -0
  85. data/core/rubygems/version.rbs +2 -163
  86. data/core/set.rbs +493 -363
  87. data/core/signal.rbs +26 -16
  88. data/core/string.rbs +3234 -1285
  89. data/core/struct.rbs +43 -42
  90. data/core/symbol.rbs +41 -34
  91. data/core/thread.rbs +139 -83
  92. data/core/time.rbs +81 -50
  93. data/core/trace_point.rbs +41 -35
  94. data/core/true_class.rbs +2 -2
  95. data/core/unbound_method.rbs +24 -16
  96. data/core/warning.rbs +7 -7
  97. data/docs/CONTRIBUTING.md +2 -1
  98. data/docs/aliases.md +79 -0
  99. data/docs/collection.md +3 -3
  100. data/docs/config.md +171 -0
  101. data/docs/encoding.md +56 -0
  102. data/docs/gem.md +0 -1
  103. data/docs/inline.md +634 -0
  104. data/docs/rbs_by_example.md +20 -20
  105. data/docs/release.md +151 -0
  106. data/docs/rust.md +96 -0
  107. data/docs/sigs.md +3 -3
  108. data/docs/syntax.md +48 -18
  109. data/docs/type_fingerprint.md +21 -0
  110. data/docs/wasm_serialization.md +80 -0
  111. data/exe/rbs +1 -1
  112. data/ext/rbs_extension/ast_translation.c +1855 -0
  113. data/ext/rbs_extension/ast_translation.h +41 -0
  114. data/ext/rbs_extension/class_constants.c +187 -0
  115. data/{include/rbs/constants.h → ext/rbs_extension/class_constants.h} +23 -1
  116. data/ext/rbs_extension/compat.h +10 -0
  117. data/ext/rbs_extension/extconf.rb +26 -1
  118. data/ext/rbs_extension/legacy_location.c +299 -0
  119. data/ext/rbs_extension/legacy_location.h +82 -0
  120. data/ext/rbs_extension/main.c +603 -23
  121. data/ext/rbs_extension/rbs_extension.h +6 -21
  122. data/ext/rbs_extension/rbs_string_bridging.c +9 -0
  123. data/ext/rbs_extension/rbs_string_bridging.h +24 -0
  124. data/include/rbs/ast.h +1047 -0
  125. data/include/rbs/defines.h +99 -0
  126. data/include/rbs/lexer.h +207 -0
  127. data/include/rbs/location.h +40 -0
  128. data/include/rbs/parser.h +153 -0
  129. data/include/rbs/serialize.h +39 -0
  130. data/include/rbs/string.h +47 -0
  131. data/include/rbs/util/rbs_allocator.h +59 -0
  132. data/include/rbs/util/rbs_assert.h +20 -0
  133. data/include/rbs/util/rbs_buffer.h +83 -0
  134. data/include/rbs/util/rbs_constant_pool.h +6 -70
  135. data/include/rbs/util/rbs_encoding.h +282 -0
  136. data/include/rbs/util/rbs_unescape.h +24 -0
  137. data/include/rbs.h +9 -2
  138. data/lib/rbs/annotate/formatter.rb +3 -13
  139. data/lib/rbs/annotate/rdoc_annotator.rb +30 -32
  140. data/lib/rbs/annotate/rdoc_source.rb +1 -1
  141. data/lib/rbs/ast/annotation.rb +1 -1
  142. data/lib/rbs/ast/comment.rb +1 -1
  143. data/lib/rbs/ast/declarations.rb +10 -10
  144. data/lib/rbs/ast/members.rb +14 -14
  145. data/lib/rbs/ast/ruby/annotations.rb +451 -0
  146. data/lib/rbs/ast/ruby/comment_block.rb +247 -0
  147. data/lib/rbs/ast/ruby/declarations.rb +291 -0
  148. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
  149. data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  150. data/lib/rbs/ast/ruby/members.rb +762 -0
  151. data/lib/rbs/ast/type_param.rb +24 -4
  152. data/lib/rbs/buffer.rb +142 -20
  153. data/lib/rbs/cli/diff.rb +16 -15
  154. data/lib/rbs/cli/validate.rb +63 -126
  155. data/lib/rbs/cli.rb +59 -29
  156. data/lib/rbs/collection/config/lockfile_generator.rb +28 -3
  157. data/lib/rbs/collection/sources/git.rb +7 -0
  158. data/lib/rbs/definition.rb +6 -1
  159. data/lib/rbs/definition_builder/ancestor_builder.rb +121 -65
  160. data/lib/rbs/definition_builder/method_builder.rb +74 -33
  161. data/lib/rbs/definition_builder.rb +177 -20
  162. data/lib/rbs/diff.rb +7 -1
  163. data/lib/rbs/environment/class_entry.rb +69 -0
  164. data/lib/rbs/environment/module_entry.rb +66 -0
  165. data/lib/rbs/environment.rb +410 -215
  166. data/lib/rbs/environment_loader.rb +2 -8
  167. data/lib/rbs/errors.rb +31 -21
  168. data/lib/rbs/inline_parser/comment_association.rb +117 -0
  169. data/lib/rbs/inline_parser.rb +568 -0
  170. data/lib/rbs/location_aux.rb +36 -4
  171. data/lib/rbs/locator.rb +5 -1
  172. data/lib/rbs/method_type.rb +5 -3
  173. data/lib/rbs/namespace.rb +47 -18
  174. data/lib/rbs/parser_aux.rb +37 -7
  175. data/lib/rbs/prototype/helpers.rb +57 -0
  176. data/lib/rbs/prototype/rb.rb +3 -28
  177. data/lib/rbs/prototype/rbi.rb +196 -45
  178. data/lib/rbs/prototype/runtime.rb +12 -2
  179. data/lib/rbs/resolver/constant_resolver.rb +2 -2
  180. data/lib/rbs/resolver/type_name_resolver.rb +120 -44
  181. data/lib/rbs/rewriter.rb +70 -0
  182. data/lib/rbs/source.rb +99 -0
  183. data/lib/rbs/subtractor.rb +7 -4
  184. data/lib/rbs/test/type_check.rb +25 -3
  185. data/lib/rbs/type_name.rb +34 -21
  186. data/lib/rbs/types.rb +91 -79
  187. data/lib/rbs/unit_test/convertibles.rb +1 -0
  188. data/lib/rbs/unit_test/type_assertions.rb +44 -8
  189. data/lib/rbs/validator.rb +2 -2
  190. data/lib/rbs/version.rb +1 -1
  191. data/lib/rbs/wasm/deserializer.rb +213 -0
  192. data/lib/rbs/wasm/location.rb +61 -0
  193. data/lib/rbs/wasm/parser.rb +137 -0
  194. data/lib/rbs/wasm/runtime.rb +196 -0
  195. data/lib/rbs/wasm/serialization_schema.rb +110 -0
  196. data/lib/rbs.rb +25 -2
  197. data/lib/rbs_jars.rb +39 -0
  198. data/lib/rdoc/discover.rb +1 -1
  199. data/lib/rdoc_plugin/parser.rb +8 -3
  200. data/rbs.gemspec +37 -5
  201. data/schema/typeParam.json +17 -1
  202. data/sig/ancestor_builder.rbs +1 -1
  203. data/sig/annotate/formatter.rbs +2 -2
  204. data/sig/annotate/rdoc_annotater.rbs +13 -10
  205. data/sig/ast/ruby/annotations.rbs +470 -0
  206. data/sig/ast/ruby/comment_block.rbs +127 -0
  207. data/sig/ast/ruby/declarations.rbs +158 -0
  208. data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  209. data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  210. data/sig/ast/ruby/members.rbs +198 -0
  211. data/sig/buffer.rbs +81 -5
  212. data/sig/cli/diff.rbs +5 -11
  213. data/sig/cli/validate.rbs +12 -8
  214. data/sig/cli.rbs +18 -18
  215. data/sig/collection/config/lockfile_generator.rbs +2 -0
  216. data/sig/definition.rbs +6 -0
  217. data/sig/definition_builder.rbs +3 -1
  218. data/sig/environment/class_entry.rbs +50 -0
  219. data/sig/environment/module_entry.rbs +50 -0
  220. data/sig/environment.rbs +94 -87
  221. data/sig/errors.rbs +26 -20
  222. data/sig/inline_parser/comment_association.rbs +71 -0
  223. data/sig/inline_parser.rbs +126 -0
  224. data/sig/location.rbs +32 -7
  225. data/sig/locator.rbs +0 -2
  226. data/sig/manifest.yaml +0 -2
  227. data/sig/method_builder.rbs +9 -4
  228. data/sig/namespace.rbs +20 -5
  229. data/sig/parser.rbs +77 -13
  230. data/sig/prototype/helpers.rbs +2 -0
  231. data/sig/prototype/rbi.rbs +33 -4
  232. data/sig/resolver/type_name_resolver.rbs +36 -10
  233. data/sig/rewriter.rbs +45 -0
  234. data/sig/source.rbs +48 -0
  235. data/sig/type_param.rbs +13 -8
  236. data/sig/typename.rbs +15 -5
  237. data/sig/types.rbs +10 -8
  238. data/sig/unit_test/spy.rbs +0 -8
  239. data/sig/unit_test/type_assertions.rbs +15 -0
  240. data/sig/wasm/deserializer.rbs +66 -0
  241. data/sig/wasm/serialization_schema.rbs +13 -0
  242. data/src/ast.c +1628 -0
  243. data/src/lexer.c +3221 -0
  244. data/src/lexer.re +155 -0
  245. data/src/lexstate.c +221 -0
  246. data/src/location.c +31 -0
  247. data/src/parser.c +4258 -0
  248. data/src/serialize.c +958 -0
  249. data/src/string.c +41 -0
  250. data/src/util/rbs_allocator.c +171 -0
  251. data/src/util/rbs_assert.c +19 -0
  252. data/src/util/rbs_buffer.c +54 -0
  253. data/src/util/rbs_constant_pool.c +18 -92
  254. data/src/util/rbs_encoding.c +21308 -0
  255. data/src/util/rbs_unescape.c +167 -0
  256. data/stdlib/abbrev/0/array.rbs +1 -1
  257. data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
  258. data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
  259. data/stdlib/cgi/0/core.rbs +9 -393
  260. data/stdlib/cgi/0/manifest.yaml +1 -0
  261. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  262. data/stdlib/coverage/0/coverage.rbs +7 -4
  263. data/stdlib/csv/0/csv.rbs +5 -5
  264. data/stdlib/date/0/date.rbs +92 -79
  265. data/stdlib/date/0/date_time.rbs +25 -24
  266. data/stdlib/delegate/0/delegator.rbs +11 -7
  267. data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
  268. data/stdlib/digest/0/digest.rbs +117 -1
  269. data/stdlib/erb/0/erb.rbs +748 -347
  270. data/stdlib/etc/0/etc.rbs +73 -54
  271. data/stdlib/fileutils/0/fileutils.rbs +179 -160
  272. data/stdlib/forwardable/0/forwardable.rbs +13 -10
  273. data/stdlib/io-console/0/io-console.rbs +2 -2
  274. data/stdlib/ipaddr/0/ipaddr.rbs +0 -5
  275. data/stdlib/json/0/json.rbs +232 -185
  276. data/stdlib/monitor/0/monitor.rbs +5 -5
  277. data/stdlib/net-http/0/net-http.rbs +162 -134
  278. data/stdlib/objspace/0/objspace.rbs +17 -34
  279. data/stdlib/open-uri/0/open-uri.rbs +48 -8
  280. data/stdlib/open3/0/open3.rbs +469 -10
  281. data/stdlib/openssl/0/openssl.rbs +521 -397
  282. data/stdlib/optparse/0/optparse.rbs +26 -17
  283. data/stdlib/pathname/0/pathname.rbs +11 -1381
  284. data/stdlib/pp/0/pp.rbs +9 -8
  285. data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
  286. data/stdlib/pstore/0/pstore.rbs +35 -30
  287. data/stdlib/psych/0/psych.rbs +65 -12
  288. data/stdlib/psych/0/store.rbs +2 -4
  289. data/stdlib/pty/0/pty.rbs +9 -6
  290. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  291. data/stdlib/rdoc/0/code_object.rbs +4 -3
  292. data/stdlib/rdoc/0/comment.rbs +2 -0
  293. data/stdlib/rdoc/0/options.rbs +76 -0
  294. data/stdlib/rdoc/0/parser.rbs +1 -1
  295. data/stdlib/rdoc/0/rdoc.rbs +7 -5
  296. data/stdlib/rdoc/0/store.rbs +2 -2
  297. data/stdlib/resolv/0/resolv.rbs +26 -69
  298. data/stdlib/ripper/0/ripper.rbs +25 -19
  299. data/stdlib/securerandom/0/manifest.yaml +2 -0
  300. data/stdlib/securerandom/0/securerandom.rbs +7 -20
  301. data/stdlib/shellwords/0/shellwords.rbs +3 -3
  302. data/stdlib/singleton/0/singleton.rbs +3 -0
  303. data/stdlib/socket/0/addrinfo.rbs +9 -9
  304. data/stdlib/socket/0/basic_socket.rbs +3 -3
  305. data/stdlib/socket/0/ip_socket.rbs +10 -8
  306. data/stdlib/socket/0/socket.rbs +23 -10
  307. data/stdlib/socket/0/tcp_server.rbs +1 -1
  308. data/stdlib/socket/0/tcp_socket.rbs +11 -3
  309. data/stdlib/socket/0/udp_socket.rbs +1 -1
  310. data/stdlib/socket/0/unix_server.rbs +1 -1
  311. data/stdlib/stringio/0/stringio.rbs +1209 -95
  312. data/stdlib/strscan/0/string_scanner.rbs +101 -80
  313. data/stdlib/tempfile/0/manifest.yaml +3 -0
  314. data/stdlib/tempfile/0/tempfile.rbs +25 -21
  315. data/stdlib/time/0/time.rbs +8 -6
  316. data/stdlib/timeout/0/timeout.rbs +58 -7
  317. data/stdlib/tsort/0/cyclic.rbs +4 -1
  318. data/stdlib/tsort/0/interfaces.rbs +8 -8
  319. data/stdlib/tsort/0/tsort.rbs +16 -15
  320. data/stdlib/uri/0/common.rbs +42 -20
  321. data/stdlib/uri/0/file.rbs +3 -3
  322. data/stdlib/uri/0/generic.rbs +21 -18
  323. data/stdlib/uri/0/http.rbs +2 -2
  324. data/stdlib/uri/0/ldap.rbs +2 -2
  325. data/stdlib/uri/0/mailto.rbs +3 -3
  326. data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
  327. data/stdlib/zlib/0/deflate.rbs +4 -3
  328. data/stdlib/zlib/0/gzip_reader.rbs +8 -8
  329. data/stdlib/zlib/0/gzip_writer.rbs +14 -12
  330. data/stdlib/zlib/0/inflate.rbs +1 -1
  331. data/stdlib/zlib/0/need_dict.rbs +1 -1
  332. data/wasm/README.md +60 -0
  333. data/wasm/rbs_wasm.c +423 -0
  334. metadata +131 -19
  335. data/ext/rbs_extension/lexer.c +0 -2728
  336. data/ext/rbs_extension/lexer.h +0 -179
  337. data/ext/rbs_extension/lexer.re +0 -147
  338. data/ext/rbs_extension/lexstate.c +0 -175
  339. data/ext/rbs_extension/location.c +0 -325
  340. data/ext/rbs_extension/location.h +0 -85
  341. data/ext/rbs_extension/parser.c +0 -2982
  342. data/ext/rbs_extension/parser.h +0 -18
  343. data/ext/rbs_extension/parserstate.c +0 -411
  344. data/ext/rbs_extension/parserstate.h +0 -163
  345. data/ext/rbs_extension/unescape.c +0 -32
  346. data/include/rbs/ruby_objs.h +0 -72
  347. data/src/constants.c +0 -153
  348. data/src/ruby_objs.c +0 -799
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ # Pure-Ruby implementation of the primitives that back RBS::Location.
5
+ #
6
+ # On CRuby these come from the C extension (ext/rbs_extension/legacy_location.c).
7
+ # JRuby loads this instead, before rbs/location_aux.rb layers the public API on
8
+ # top, so RBS::Location behaves identically without the native extension.
9
+ class Location
10
+ attr_reader :buffer
11
+
12
+ def initialize(buffer, start_pos, end_pos)
13
+ @buffer = buffer
14
+ @start_pos = start_pos
15
+ @end_pos = end_pos
16
+ @required_children = {} #: Hash[Symbol, [ Integer, Integer ]]
17
+ @optional_children = {} #: Hash[Symbol, [ Integer, Integer ]?]
18
+ end
19
+
20
+ def _start_pos
21
+ @start_pos
22
+ end
23
+
24
+ def _end_pos
25
+ @end_pos
26
+ end
27
+
28
+ def _add_required_child(name, start_pos, end_pos)
29
+ @required_children[name] = [start_pos, end_pos]
30
+ end
31
+
32
+ def _add_optional_child(name, start_pos, end_pos)
33
+ @optional_children[name] = [start_pos, end_pos]
34
+ end
35
+
36
+ def _add_optional_no_child(name)
37
+ @optional_children[name] = nil
38
+ end
39
+
40
+ def _required_keys
41
+ @required_children.keys
42
+ end
43
+
44
+ def _optional_keys
45
+ @optional_children.keys
46
+ end
47
+
48
+ def [](name)
49
+ if (range = @required_children[name])
50
+ return Location.new(@buffer, range[0], range[1])
51
+ end
52
+
53
+ if @optional_children.key?(name)
54
+ range = @optional_children[name]
55
+ return range && Location.new(@buffer, range[0], range[1])
56
+ end
57
+
58
+ raise "Unknown child name given: #{name}"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "runtime"
4
+ require_relative "deserializer"
5
+
6
+ module RBS
7
+ # WebAssembly-backed implementation of the parser primitives.
8
+ #
9
+ # On CRuby these come from the C extension (ext/rbs_extension/main.c). JRuby
10
+ # loads this instead: it runs the parser inside WebAssembly, then rebuilds the
11
+ # AST with RBS::WASM::Deserializer. rbs/parser_aux.rb layers the public
12
+ # RBS::Parser API on top, exactly as it does for the C extension.
13
+ class Parser
14
+ class << self
15
+ def _parse_signature(buffer, start_pos, end_pos)
16
+ validate_position_range(start_pos, end_pos)
17
+ encoding = buffer.content.encoding.name
18
+ success, bytes = WASM::Runtime.instance.parse_signature(buffer.content, encoding, start_pos, end_pos)
19
+ raise_parsing_error(buffer, bytes) unless success
20
+
21
+ WASM::Deserializer.deserialize(bytes, buffer)
22
+ end
23
+
24
+ def _parse_type(buffer, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
25
+ validate_position_range(start_pos, end_pos)
26
+ validate_variables(variables)
27
+ encoding = buffer.content.encoding.name
28
+ success, bytes = WASM::Runtime.instance.parse_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
29
+ raise_parsing_error(buffer, bytes) unless success
30
+
31
+ deserialize_or_nil(bytes, buffer)
32
+ end
33
+
34
+ def _parse_method_type(buffer, start_pos, end_pos, variables, require_eof)
35
+ validate_position_range(start_pos, end_pos)
36
+ validate_variables(variables)
37
+ encoding = buffer.content.encoding.name
38
+ success, bytes = WASM::Runtime.instance.parse_method_type(buffer.content, encoding, start_pos, end_pos, variables, require_eof)
39
+ raise_parsing_error(buffer, bytes) unless success
40
+
41
+ deserialize_or_nil(bytes, buffer)
42
+ end
43
+
44
+ def _parse_type_params(buffer, start_pos, end_pos, module_type_params)
45
+ validate_position_range(start_pos, end_pos)
46
+ encoding = buffer.content.encoding.name
47
+ success, bytes = WASM::Runtime.instance.parse_type_params(buffer.content, encoding, start_pos, end_pos, module_type_params)
48
+ raise_parsing_error(buffer, bytes) unless success
49
+
50
+ bytes.empty? ? nil : WASM::Deserializer.deserialize_node_list(bytes, buffer)
51
+ end
52
+
53
+ def _lex(buffer, end_pos)
54
+ encoding = buffer.content.encoding.name
55
+ _success, bytes = WASM::Runtime.instance.lex(buffer.content, encoding, end_pos)
56
+
57
+ WASM::Deserializer.deserialize_tokens(bytes, buffer)
58
+ end
59
+
60
+ def _parse_inline_leading_annotation(buffer, start_pos, end_pos, variables)
61
+ validate_position_range(start_pos, end_pos)
62
+ validate_variables(variables)
63
+ encoding = buffer.content.encoding.name
64
+ success, bytes = WASM::Runtime.instance.parse_inline_leading_annotation(buffer.content, encoding, start_pos, end_pos, variables)
65
+ raise_parsing_error(buffer, bytes) unless success
66
+
67
+ deserialize_or_nil(bytes, buffer)
68
+ end
69
+
70
+ def _parse_inline_trailing_annotation(buffer, start_pos, end_pos, variables)
71
+ validate_position_range(start_pos, end_pos)
72
+ validate_variables(variables)
73
+ encoding = buffer.content.encoding.name
74
+ success, bytes = WASM::Runtime.instance.parse_inline_trailing_annotation(buffer.content, encoding, start_pos, end_pos, variables)
75
+ raise_parsing_error(buffer, bytes) unless success
76
+
77
+ deserialize_or_nil(bytes, buffer)
78
+ end
79
+
80
+ private
81
+
82
+ # Reject negative or reversed ranges before handing them to the parser,
83
+ # matching validate_position_range in the C extension (main.c). A reversed
84
+ # range would otherwise make the lexer loop forever inside WebAssembly.
85
+ def validate_position_range(start_pos, end_pos)
86
+ if start_pos < 0 || end_pos < 0
87
+ raise ArgumentError, "negative position range: #{start_pos}...#{end_pos}"
88
+ end
89
+ if start_pos > end_pos
90
+ raise ArgumentError, "invalid position range: #{start_pos}...#{end_pos}"
91
+ end
92
+ end
93
+
94
+ # Reject anything that is not nil or an Array of Symbols, matching
95
+ # declare_type_variables in the C extension (main.c).
96
+ def validate_variables(variables)
97
+ return if variables.nil?
98
+
99
+ unless variables.is_a?(Array)
100
+ raise TypeError, "wrong argument type #{variables.class} (must be an Array of Symbols or nil)"
101
+ end
102
+
103
+ variables.each do |variable|
104
+ unless variable.is_a?(Symbol)
105
+ raise TypeError, "Type variables Array contains invalid value #{variable.inspect} of type #{variable.class} (must be an Array of Symbols or nil)"
106
+ end
107
+ end
108
+ end
109
+
110
+ # An empty result means the parser reached EOF immediately (`nil`).
111
+ def deserialize_or_nil(bytes, buffer)
112
+ bytes.empty? ? nil : WASM::Deserializer.deserialize(bytes, buffer)
113
+ end
114
+
115
+ # Decodes the error blob written by set_error_result (rbs_wasm.c) and raises
116
+ # the same error the C extension would (see raise_error in main.c).
117
+ def raise_parsing_error(buffer, blob)
118
+ start_char, end_char, syntax_error = blob.unpack("l<l<C")
119
+
120
+ raise "Unexpected error" if syntax_error.zero?
121
+
122
+ offset = 9
123
+ token_type_length = blob.unpack1("L<", offset: offset)
124
+ offset += 4
125
+ token_type = blob.byteslice(offset, token_type_length).to_s.force_encoding(Encoding::UTF_8)
126
+ offset += token_type_length
127
+
128
+ message_length = blob.unpack1("L<", offset: offset)
129
+ offset += 4
130
+ message = blob.byteslice(offset, message_length).to_s.force_encoding(Encoding::UTF_8)
131
+
132
+ location = Location.new(buffer, start_char, end_char)
133
+ raise ParsingError.new(location, message, token_type)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,196 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "java"
4
+ require "monitor"
5
+
6
+ module RBS
7
+ module WASM
8
+ # Loads rbs_parser.wasm into a JVM WebAssembly runtime (Chicory) and drives
9
+ # it. This is the JRuby counterpart of the C extension's main.c: it copies a
10
+ # source string into the module's linear memory, runs the parser, and returns
11
+ # the serialized result for RBS::WASM::Deserializer to rebuild.
12
+ #
13
+ # Chicory is a pure-Java runtime, so there is no native dependency. The
14
+ # `.wasm` ships in the gem; the Chicory jars are fetched from Maven by
15
+ # jar-dependencies (see lib/rbs_jars.rb and rbs.gemspec).
16
+ class Runtime
17
+ include MonitorMixin
18
+
19
+ class << self
20
+ def instance
21
+ @instance ||= new
22
+ end
23
+
24
+ def wasm_path
25
+ ENV["RBS_WASM_PARSER"] || File.expand_path("rbs_parser.wasm", __dir__)
26
+ end
27
+ end
28
+
29
+ def initialize
30
+ super()
31
+ # rbs_jars.rb require_jars the Chicory/ASM jars from the local Maven
32
+ # repository (~/.m2), where jar-dependencies puts them at gem install (or
33
+ # `rake wasm:install_jars` when running from source).
34
+ require "rbs_jars"
35
+ @wasm = build_instance
36
+ @memory = @wasm.memory
37
+ @alloc = @wasm.export("rbs_wasm_alloc")
38
+ @free = @wasm.export("rbs_wasm_free")
39
+ @result_ptr = @wasm.export("rbs_wasm_result_ptr")
40
+ @result_len = @wasm.export("rbs_wasm_result_len")
41
+ @parse_signature = @wasm.export("rbs_wasm_parse_signature")
42
+ @parse_type = @wasm.export("rbs_wasm_parse_type")
43
+ @parse_method_type = @wasm.export("rbs_wasm_parse_method_type")
44
+ @parse_type_params = @wasm.export("rbs_wasm_parse_type_params")
45
+ @parse_inline_leading_annotation = @wasm.export("rbs_wasm_parse_inline_leading_annotation")
46
+ @parse_inline_trailing_annotation = @wasm.export("rbs_wasm_parse_inline_trailing_annotation")
47
+ @lex = @wasm.export("rbs_wasm_lex")
48
+ end
49
+
50
+ # `content` is the whole buffer; `start_pos`/`end_pos` are the character
51
+ # range within it to parse. Each method returns [success, bytes]: on success
52
+ # `bytes` is the serialized AST, otherwise it is the error blob (see
53
+ # set_error_result in rbs_wasm.c).
54
+
55
+ def parse_signature(content, encoding, start_pos, end_pos)
56
+ run(content, encoding) { |ptr, len, enc_ptr, enc_len| @parse_signature.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos)[0] }
57
+ end
58
+
59
+ def parse_type(content, encoding, start_pos, end_pos, variables, require_eof, void_allowed, self_allowed, classish_allowed)
60
+ with_variables(variables) do |vars_ptr, vars_len|
61
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
62
+ @parse_type.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len, bool(require_eof), bool(void_allowed), bool(self_allowed), bool(classish_allowed))[0]
63
+ end
64
+ end
65
+ end
66
+
67
+ def parse_method_type(content, encoding, start_pos, end_pos, variables, require_eof)
68
+ with_variables(variables) do |vars_ptr, vars_len|
69
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
70
+ @parse_method_type.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len, bool(require_eof))[0]
71
+ end
72
+ end
73
+ end
74
+
75
+ def parse_type_params(content, encoding, start_pos, end_pos, module_type_params)
76
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
77
+ @parse_type_params.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, bool(module_type_params))[0]
78
+ end
79
+ end
80
+
81
+ def parse_inline_leading_annotation(content, encoding, start_pos, end_pos, variables)
82
+ with_variables(variables) do |vars_ptr, vars_len|
83
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
84
+ @parse_inline_leading_annotation.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len)[0]
85
+ end
86
+ end
87
+ end
88
+
89
+ def parse_inline_trailing_annotation(content, encoding, start_pos, end_pos, variables)
90
+ with_variables(variables) do |vars_ptr, vars_len|
91
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
92
+ @parse_inline_trailing_annotation.apply(ptr, len, enc_ptr, enc_len, start_pos, end_pos, vars_ptr, vars_len)[0]
93
+ end
94
+ end
95
+ end
96
+
97
+ def lex(content, encoding, end_pos)
98
+ run(content, encoding) do |ptr, len, enc_ptr, enc_len|
99
+ @lex.apply(ptr, len, enc_ptr, enc_len, end_pos)[0]
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ # Copies `source` and its encoding name into linear memory, yields their
106
+ # pointers/lengths to the block (which invokes the parser and returns its
107
+ # status), then reads the result back out. Serialized through the monitor
108
+ # because the module keeps its result in a single shared location.
109
+ def run(source, encoding)
110
+ synchronize do
111
+ bytes = source.b
112
+ length = bytes.bytesize
113
+ name = encoding.to_s.b
114
+ name_length = name.bytesize
115
+ source_ptr = @alloc.apply(length)[0]
116
+ name_ptr = @alloc.apply(name_length)[0]
117
+ begin
118
+ @memory.write(source_ptr, bytes.to_java_bytes)
119
+ @memory.write(name_ptr, name.to_java_bytes) unless name_length.zero?
120
+ status = yield(source_ptr, length, name_ptr, name_length)
121
+ [status == 1, read_result]
122
+ ensure
123
+ @free.apply(source_ptr)
124
+ @free.apply(name_ptr)
125
+ end
126
+ end
127
+ end
128
+
129
+ def read_result
130
+ pointer = @result_ptr.apply[0]
131
+ length = @result_len.apply[0]
132
+ return "".b if length.zero?
133
+
134
+ String.from_java_bytes(@memory.read_bytes(pointer, length)).b
135
+ end
136
+
137
+ # Allocates a buffer of newline-separated variable names and yields its
138
+ # pointer/length. A nil `variables` is passed as length -1 ("no variables").
139
+ def with_variables(variables)
140
+ names = variables&.map(&:to_s)&.join("\n")
141
+
142
+ if names.nil? || names.empty?
143
+ return yield(0, variables.nil? ? -1 : 0)
144
+ end
145
+
146
+ bytes = names.b
147
+ length = bytes.bytesize
148
+ synchronize do
149
+ pointer = @alloc.apply(length)[0]
150
+ begin
151
+ @memory.write(pointer, bytes.to_java_bytes)
152
+ yield(pointer, length)
153
+ ensure
154
+ @free.apply(pointer)
155
+ end
156
+ end
157
+ end
158
+
159
+ def bool(value)
160
+ value ? 1 : 0
161
+ end
162
+
163
+ def build_instance
164
+ parser = Java::ComDylibsoChicoryWasm::Parser
165
+ instance_class = Java::ComDylibsoChicoryRuntime::Instance
166
+ import_values = Java::ComDylibsoChicoryRuntime::ImportValues
167
+ wasi_preview1 = Java::ComDylibsoChicoryWasi::WasiPreview1
168
+ wasi_options = Java::ComDylibsoChicoryWasi::WasiOptions
169
+
170
+ wasm_module = parser.parse(java.io.File.new(self.class.wasm_path))
171
+ wasi = wasi_preview1.builder.with_options(wasi_options.builder.build).build
172
+ imports = import_values.builder.add_function(wasi.to_host_functions).build
173
+
174
+ builder = instance_class.builder(wasm_module).with_import_values(imports)
175
+ if (factory = machine_factory(wasm_module))
176
+ builder = builder.with_machine_factory(factory)
177
+ end
178
+
179
+ wasm = builder.build
180
+ wasm.export("_initialize").apply
181
+ wasm
182
+ end
183
+
184
+ # Chicory's AOT compiler when its jars are present and usable, otherwise nil
185
+ # (the builder then uses the interpreter). NameError covers a missing
186
+ # compiler class; LinkageError covers an incompatible/missing ASM (so a bad
187
+ # jar set degrades to the interpreter instead of crashing).
188
+ def machine_factory(wasm_module)
189
+ Java::ComDylibsoChicoryCompiler::MachineFactoryCompiler.compile(wasm_module)
190
+ rescue NameError, Java::JavaLang::LinkageError
191
+ nil
192
+ end
193
+
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # This file is generated by the templates/template.rb script and should not be
4
+ # modified manually. To change the template see
5
+ # templates/lib/rbs/wasm/serialization_schema.rb.erb
6
+
7
+ module RBS
8
+ module WASM
9
+ # Describes how to decode the binary buffer produced by `rbs_serialize_node`
10
+ # (src/serialize.c) back into RBS::AST objects. RBS::WASM::Deserializer walks
11
+ # this table; the matching encoder is generated from the same config.yml, so
12
+ # the two stay in sync.
13
+ #
14
+ # SCHEMA is indexed by node tag: tag 0 is NULL and SYMBOL_TAG is the
15
+ # interned-symbol tag. Each remaining entry is one of:
16
+ #
17
+ # [:node, class_name, expose_location, loc_children, fields, resolve_type_params]
18
+ # [:bool] / [:integer] / [:string_value] / [:record_field]
19
+ # [:signature] / [:namespace] / [:type_name]
20
+ #
21
+ # where loc_children is [[name, required?], ...] and fields is
22
+ # [[name, reader], ...] with reader one of :node, :node_list, :hash, :string,
23
+ # :bool, :location_range, :location_range_list, :attr_ivar_name, or
24
+ # [:enum, [value_or_nil, ...]].
25
+ module SerializationSchema
26
+ SYMBOL_TAG = 78
27
+
28
+ SCHEMA = [
29
+ nil, # tag 0 is reserved for NULL
30
+ [:node, "RBS::AST::Annotation", true, nil, [[:string, :string]], false],
31
+ [:bool],
32
+ [:node, "RBS::AST::Comment", true, nil, [[:string, :string]], false],
33
+ [:node, "RBS::AST::Declarations::Class", true, [[:keyword, true], [:name, true], [:end, true], [:type_params, false], [:lt, false]], [[:name, :node], [:type_params, :node_list], [:super_class, :node], [:members, :node_list], [:annotations, :node_list], [:comment, :node]], true],
34
+ [:node, "RBS::AST::Declarations::Class::Super", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
35
+ [:node, "RBS::AST::Declarations::ClassAlias", true, [[:keyword, true], [:new_name, true], [:eq, true], [:old_name, true]], [[:new_name, :node], [:old_name, :node], [:comment, :node], [:annotations, :node_list]], false],
36
+ [:node, "RBS::AST::Declarations::Constant", true, [[:name, true], [:colon, true]], [[:name, :node], [:type, :node], [:comment, :node], [:annotations, :node_list]], false],
37
+ [:node, "RBS::AST::Declarations::Global", true, [[:name, true], [:colon, true]], [[:name, :node], [:type, :node], [:comment, :node], [:annotations, :node_list]], false],
38
+ [:node, "RBS::AST::Declarations::Interface", true, [[:keyword, true], [:name, true], [:end, true], [:type_params, false]], [[:name, :node], [:type_params, :node_list], [:members, :node_list], [:annotations, :node_list], [:comment, :node]], true],
39
+ [:node, "RBS::AST::Declarations::Module", true, [[:keyword, true], [:name, true], [:end, true], [:type_params, false], [:colon, false], [:self_types, false]], [[:name, :node], [:type_params, :node_list], [:self_types, :node_list], [:members, :node_list], [:annotations, :node_list], [:comment, :node]], true],
40
+ [:node, "RBS::AST::Declarations::Module::Self", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
41
+ [:node, "RBS::AST::Declarations::ModuleAlias", true, [[:keyword, true], [:new_name, true], [:eq, true], [:old_name, true]], [[:new_name, :node], [:old_name, :node], [:comment, :node], [:annotations, :node_list]], false],
42
+ [:node, "RBS::AST::Declarations::TypeAlias", true, [[:keyword, true], [:name, true], [:eq, true], [:type_params, false]], [[:name, :node], [:type_params, :node_list], [:type, :node], [:annotations, :node_list], [:comment, :node]], true],
43
+ [:node, "RBS::AST::Directives::Use", true, [[:keyword, true]], [[:clauses, :node_list]], false],
44
+ [:node, "RBS::AST::Directives::Use::SingleClause", true, [[:type_name, true], [:keyword, false], [:new_name, false]], [[:type_name, :node], [:new_name, :node]], false],
45
+ [:node, "RBS::AST::Directives::Use::WildcardClause", true, [[:namespace, true], [:star, true]], [[:namespace, :node]], false],
46
+ [:integer],
47
+ [:node, "RBS::AST::Members::Alias", true, [[:keyword, true], [:new_name, true], [:old_name, true], [:new_kind, false], [:old_kind, false]], [[:new_name, :node], [:old_name, :node], [:kind, [:enum, [:instance, :singleton]]], [:annotations, :node_list], [:comment, :node]], false],
48
+ [:node, "RBS::AST::Members::AttrAccessor", true, [[:keyword, true], [:name, true], [:colon, true], [:kind, false], [:ivar, false], [:ivar_name, false], [:visibility, false]], [[:name, :node], [:type, :node], [:ivar_name, :attr_ivar_name], [:kind, [:enum, [:instance, :singleton]]], [:annotations, :node_list], [:comment, :node], [:visibility, [:enum, [nil, :public, :private]]]], false],
49
+ [:node, "RBS::AST::Members::AttrReader", true, [[:keyword, true], [:name, true], [:colon, true], [:kind, false], [:ivar, false], [:ivar_name, false], [:visibility, false]], [[:name, :node], [:type, :node], [:ivar_name, :attr_ivar_name], [:kind, [:enum, [:instance, :singleton]]], [:annotations, :node_list], [:comment, :node], [:visibility, [:enum, [nil, :public, :private]]]], false],
50
+ [:node, "RBS::AST::Members::AttrWriter", true, [[:keyword, true], [:name, true], [:colon, true], [:kind, false], [:ivar, false], [:ivar_name, false], [:visibility, false]], [[:name, :node], [:type, :node], [:ivar_name, :attr_ivar_name], [:kind, [:enum, [:instance, :singleton]]], [:annotations, :node_list], [:comment, :node], [:visibility, [:enum, [nil, :public, :private]]]], false],
51
+ [:node, "RBS::AST::Members::ClassInstanceVariable", true, [[:name, true], [:colon, true], [:kind, false]], [[:name, :node], [:type, :node], [:comment, :node]], false],
52
+ [:node, "RBS::AST::Members::ClassVariable", true, [[:name, true], [:colon, true], [:kind, false]], [[:name, :node], [:type, :node], [:comment, :node]], false],
53
+ [:node, "RBS::AST::Members::Extend", true, [[:name, true], [:keyword, true], [:args, false]], [[:name, :node], [:args, :node_list], [:annotations, :node_list], [:comment, :node]], false],
54
+ [:node, "RBS::AST::Members::Include", true, [[:name, true], [:keyword, true], [:args, false]], [[:name, :node], [:args, :node_list], [:annotations, :node_list], [:comment, :node]], false],
55
+ [:node, "RBS::AST::Members::InstanceVariable", true, [[:name, true], [:colon, true], [:kind, false]], [[:name, :node], [:type, :node], [:comment, :node]], false],
56
+ [:node, "RBS::AST::Members::MethodDefinition", true, [[:keyword, true], [:name, true], [:kind, false], [:overloading, false], [:visibility, false]], [[:name, :node], [:kind, [:enum, [:instance, :singleton, :singleton_instance]]], [:overloads, :node_list], [:annotations, :node_list], [:comment, :node], [:overloading, :bool], [:visibility, [:enum, [nil, :public, :private]]]], false],
57
+ [:node, "RBS::AST::Members::MethodDefinition::Overload", false, nil, [[:annotations, :node_list], [:method_type, :node]], false],
58
+ [:node, "RBS::AST::Members::Prepend", true, [[:name, true], [:keyword, true], [:args, false]], [[:name, :node], [:args, :node_list], [:annotations, :node_list], [:comment, :node]], false],
59
+ [:node, "RBS::AST::Members::Private", true, nil, nil, false],
60
+ [:node, "RBS::AST::Members::Public", true, nil, nil, false],
61
+ [:node, "RBS::AST::Ruby::Annotations::BlockParamTypeAnnotation", true, nil, [[:prefix_location, :location_range], [:ampersand_location, :location_range], [:name_location, :location_range], [:colon_location, :location_range], [:question_location, :location_range], [:type_location, :location_range], [:type, :node], [:comment_location, :location_range]], false],
62
+ [:node, "RBS::AST::Ruby::Annotations::ClassAliasAnnotation", true, nil, [[:prefix_location, :location_range], [:keyword_location, :location_range], [:type_name, :node], [:type_name_location, :location_range]], false],
63
+ [:node, "RBS::AST::Ruby::Annotations::ColonMethodTypeAnnotation", true, nil, [[:prefix_location, :location_range], [:annotations, :node_list], [:method_type, :node]], false],
64
+ [:node, "RBS::AST::Ruby::Annotations::DoubleSplatParamTypeAnnotation", true, nil, [[:prefix_location, :location_range], [:star2_location, :location_range], [:name_location, :location_range], [:colon_location, :location_range], [:param_type, :node], [:comment_location, :location_range]], false],
65
+ [:node, "RBS::AST::Ruby::Annotations::InstanceVariableAnnotation", true, nil, [[:prefix_location, :location_range], [:ivar_name, :node], [:ivar_name_location, :location_range], [:colon_location, :location_range], [:type, :node], [:comment_location, :location_range]], false],
66
+ [:node, "RBS::AST::Ruby::Annotations::MethodTypesAnnotation", true, nil, [[:prefix_location, :location_range], [:overloads, :node_list], [:vertical_bar_locations, :location_range_list], [:dot3_location, :location_range]], false],
67
+ [:node, "RBS::AST::Ruby::Annotations::ModuleAliasAnnotation", true, nil, [[:prefix_location, :location_range], [:keyword_location, :location_range], [:type_name, :node], [:type_name_location, :location_range]], false],
68
+ [:node, "RBS::AST::Ruby::Annotations::ModuleSelfAnnotation", true, nil, [[:prefix_location, :location_range], [:keyword_location, :location_range], [:colon_location, :location_range], [:name, :node], [:args, :node_list], [:open_bracket_location, :location_range], [:close_bracket_location, :location_range], [:args_comma_locations, :location_range_list], [:comment_location, :location_range]], false],
69
+ [:node, "RBS::AST::Ruby::Annotations::NodeTypeAssertion", true, nil, [[:prefix_location, :location_range], [:type, :node]], false],
70
+ [:node, "RBS::AST::Ruby::Annotations::ParamTypeAnnotation", true, nil, [[:prefix_location, :location_range], [:name_location, :location_range], [:colon_location, :location_range], [:param_type, :node], [:comment_location, :location_range]], false],
71
+ [:node, "RBS::AST::Ruby::Annotations::ReturnTypeAnnotation", true, nil, [[:prefix_location, :location_range], [:return_location, :location_range], [:colon_location, :location_range], [:return_type, :node], [:comment_location, :location_range]], false],
72
+ [:node, "RBS::AST::Ruby::Annotations::SkipAnnotation", true, nil, [[:prefix_location, :location_range], [:skip_location, :location_range], [:comment_location, :location_range]], false],
73
+ [:node, "RBS::AST::Ruby::Annotations::SplatParamTypeAnnotation", true, nil, [[:prefix_location, :location_range], [:star_location, :location_range], [:name_location, :location_range], [:colon_location, :location_range], [:param_type, :node], [:comment_location, :location_range]], false],
74
+ [:node, "RBS::AST::Ruby::Annotations::TypeApplicationAnnotation", true, nil, [[:prefix_location, :location_range], [:type_args, :node_list], [:close_bracket_location, :location_range], [:comma_locations, :location_range_list]], false],
75
+ [:string_value],
76
+ [:node, "RBS::AST::TypeParam", true, [[:name, true], [:variance, false], [:unchecked, false], [:upper_bound, false], [:lower_bound, false], [:default, false]], [[:name, :node], [:variance, [:enum, [:invariant, :covariant, :contravariant]]], [:upper_bound, :node], [:lower_bound, :node], [:default_type, :node], [:unchecked, :bool]], false],
77
+ [:node, "RBS::MethodType", true, [[:type, true], [:type_params, false]], [[:type_params, :node_list], [:type, :node], [:block, :node]], true],
78
+ [:namespace],
79
+ [:signature],
80
+ [:type_name],
81
+ [:node, "RBS::Types::Alias", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
82
+ [:node, "RBS::Types::Bases::Any", true, nil, [[:todo, :bool]], false],
83
+ [:node, "RBS::Types::Bases::Bool", true, nil, nil, false],
84
+ [:node, "RBS::Types::Bases::Bottom", true, nil, nil, false],
85
+ [:node, "RBS::Types::Bases::Class", true, nil, nil, false],
86
+ [:node, "RBS::Types::Bases::Instance", true, nil, nil, false],
87
+ [:node, "RBS::Types::Bases::Nil", true, nil, nil, false],
88
+ [:node, "RBS::Types::Bases::Self", true, nil, nil, false],
89
+ [:node, "RBS::Types::Bases::Top", true, nil, nil, false],
90
+ [:node, "RBS::Types::Bases::Void", true, nil, nil, false],
91
+ [:node, "RBS::Types::Block", true, nil, [[:type, :node], [:required, :bool], [:self_type, :node]], false],
92
+ [:node, "RBS::Types::ClassInstance", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
93
+ [:node, "RBS::Types::ClassSingleton", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
94
+ [:node, "RBS::Types::Function", false, nil, [[:required_positionals, :node_list], [:optional_positionals, :node_list], [:rest_positionals, :node], [:trailing_positionals, :node_list], [:required_keywords, :hash], [:optional_keywords, :hash], [:rest_keywords, :node], [:return_type, :node]], false],
95
+ [:node, "RBS::Types::Function::Param", true, [[:name, false]], [[:type, :node], [:name, :node]], false],
96
+ [:node, "RBS::Types::Interface", true, [[:name, true], [:args, false]], [[:name, :node], [:args, :node_list]], false],
97
+ [:node, "RBS::Types::Intersection", true, nil, [[:types, :node_list]], false],
98
+ [:node, "RBS::Types::Literal", true, nil, [[:literal, :node]], false],
99
+ [:node, "RBS::Types::Optional", true, nil, [[:type, :node]], false],
100
+ [:node, "RBS::Types::Proc", true, nil, [[:type, :node], [:block, :node], [:self_type, :node]], false],
101
+ [:node, "RBS::Types::Record", true, nil, [[:all_fields, :hash]], false],
102
+ [:record_field],
103
+ [:node, "RBS::Types::Tuple", true, nil, [[:types, :node_list]], false],
104
+ [:node, "RBS::Types::Union", true, nil, [[:types, :node_list]], false],
105
+ [:node, "RBS::Types::UntypedFunction", false, nil, [[:return_type, :node]], false],
106
+ [:node, "RBS::Types::Variable", true, nil, [[:name, :node]], false],
107
+ ].freeze
108
+ end
109
+ end
110
+ end
data/lib/rbs.rb CHANGED
@@ -4,12 +4,16 @@ require "rbs/version"
4
4
 
5
5
  require "set"
6
6
  require "json"
7
+ # Always require pathname: `Pathname()` (Kernel#Pathname) is only defined once
8
+ # pathname is loaded. Guarding on `defined?(Pathname)` is wrong because another
9
+ # library (e.g. Bundler) can define the Pathname constant without that method,
10
+ # which left RBS::EnvironmentLoader's `Pathname(...)` undefined on JRuby.
7
11
  require "pathname"
8
12
  require "pp"
9
- require "ripper"
10
13
  require "logger"
11
14
  require "tsort"
12
15
  require "strscan"
16
+ require "prism"
13
17
 
14
18
  require "rbs/errors"
15
19
  require "rbs/buffer"
@@ -24,8 +28,19 @@ require "rbs/ast/declarations"
24
28
  require "rbs/ast/members"
25
29
  require "rbs/ast/annotation"
26
30
  require "rbs/ast/visitor"
31
+ require "rbs/ast/ruby/comment_block"
32
+ require "rbs/ast/ruby/helpers/constant_helper"
33
+ require "rbs/ast/ruby/helpers/location_helper"
34
+ require "rbs/ast/ruby/annotations"
35
+ require "rbs/ast/ruby/declarations"
36
+ require "rbs/ast/ruby/members"
37
+ require "rbs/source"
38
+ require "rbs/inline_parser"
39
+ require "rbs/inline_parser/comment_association"
27
40
  require "rbs/environment"
28
41
  require "rbs/environment/use_map"
42
+ require "rbs/environment/class_entry"
43
+ require "rbs/environment/module_entry"
29
44
  require "rbs/environment_loader"
30
45
  require "rbs/builtin_names"
31
46
  require "rbs/definition"
@@ -40,6 +55,7 @@ require "rbs/resolver/constant_resolver"
40
55
  require "rbs/resolver/type_name_resolver"
41
56
  require "rbs/ast/comment"
42
57
  require "rbs/writer"
58
+ require "rbs/rewriter"
43
59
  require "rbs/prototype/helpers"
44
60
  require "rbs/prototype/rbi"
45
61
  require "rbs/prototype/rb"
@@ -57,7 +73,14 @@ require "rbs/type_alias_dependency"
57
73
  require "rbs/type_alias_regularity"
58
74
  require "rbs/collection"
59
75
 
60
- require "rbs_extension"
76
+ if RUBY_ENGINE == "jruby"
77
+ # JRuby cannot load the MRI C extension. Run the parser in WebAssembly and
78
+ # provide pure-Ruby implementations of RBS::Location and RBS::Parser instead.
79
+ require "rbs/wasm/location"
80
+ require "rbs/wasm/parser"
81
+ else
82
+ require "rbs_extension"
83
+ end
61
84
  require "rbs/parser_aux"
62
85
  require "rbs/location_aux"
63
86
 
data/lib/rbs_jars.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the file jar-dependencies generates from the `jar` requirements in
4
+ # rbs.gemspec, kept with hand edits:
5
+ # 1. the `com.dylibso.chicory:runtime` require_jar line is corrected -- the
6
+ # generator mangles that artifact id to `jar` (it collides with a Maven
7
+ # scope keyword), which breaks loading;
8
+ # 2. the "# this is a generated file" marker is dropped so jar-dependencies
9
+ # does not regenerate (and re-break) this file at gem install;
10
+ # 3. a frozen_string_literal magic comment is added (rubocop).
11
+ # `rake wasm:install_jars` downloads the jars into ~/.m2; to refresh the list
12
+ # after a version bump, regenerate the file and re-apply these edits.
13
+ begin
14
+ require 'jar_dependencies'
15
+ rescue LoadError
16
+ require 'com/dylibso/chicory/compiler/1.7.5/compiler-1.7.5.jar'
17
+ require 'com/dylibso/chicory/runtime/1.7.5/runtime-1.7.5.jar'
18
+ require 'com/dylibso/chicory/wasm/1.7.5/wasm-1.7.5.jar'
19
+ require 'org/ow2/asm/asm/9.9.1/asm-9.9.1.jar'
20
+ require 'org/ow2/asm/asm-commons/9.9.1/asm-commons-9.9.1.jar'
21
+ require 'org/ow2/asm/asm-tree/9.9.1/asm-tree-9.9.1.jar'
22
+ require 'org/ow2/asm/asm-util/9.9.1/asm-util-9.9.1.jar'
23
+ require 'org/ow2/asm/asm-analysis/9.9.1/asm-analysis-9.9.1.jar'
24
+ require 'com/dylibso/chicory/wasi/1.7.5/wasi-1.7.5.jar'
25
+ require 'com/dylibso/chicory/log/1.7.5/log-1.7.5.jar'
26
+ end
27
+
28
+ if defined? Jars
29
+ require_jar 'com.dylibso.chicory', 'compiler', '1.7.5'
30
+ require_jar 'com.dylibso.chicory', 'runtime', '1.7.5'
31
+ require_jar 'com.dylibso.chicory', 'wasm', '1.7.5'
32
+ require_jar 'org.ow2.asm', 'asm', '9.9.1'
33
+ require_jar 'org.ow2.asm', 'asm-commons', '9.9.1'
34
+ require_jar 'org.ow2.asm', 'asm-tree', '9.9.1'
35
+ require_jar 'org.ow2.asm', 'asm-util', '9.9.1'
36
+ require_jar 'org.ow2.asm', 'asm-analysis', '9.9.1'
37
+ require_jar 'com.dylibso.chicory', 'wasi', '1.7.5'
38
+ require_jar 'com.dylibso.chicory', 'log', '1.7.5'
39
+ end
data/lib/rdoc/discover.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  begin
4
- gem 'rdoc', '~> 6.4'
4
+ gem 'rdoc', '>= 6.16'
5
5
  require 'rdoc_plugin/parser'
6
6
  module RDoc
7
7
  class Parser
@@ -14,6 +14,11 @@ module RBS
14
14
  end
15
15
 
16
16
  def scan
17
+ Kernel.warn(
18
+ "The RBS RDoc parser plugin is deprecated and will be removed from RBS. " \
19
+ "RDoc 8.0 provides RBS parsing directly."
20
+ )
21
+
17
22
  _, _, decls = ::RBS::Parser.parse_signature(@content)
18
23
  decls.each do |decl|
19
24
  parse_member(decl: decl, context: @top_level)
@@ -76,7 +81,7 @@ module RBS
76
81
  method.visibility = decl.visibility
77
82
  method.call_seq = decl.overloads.map {|overload| "#{decl.name.to_s}#{overload.method_type.to_s}" }.join("\n")
78
83
  if loc = decl.location
79
- method.start_collecting_tokens
84
+ method.start_collecting_tokens(:ruby)
80
85
  method.add_token({ line_no: 1, char_no: 1, kind: :on_comment, text: "# File #{@top_level.relative_name}, line(s) #{loc.start_line}:#{loc.end_line}\n" })
81
86
  method.add_token({ line_no: 1, char_no: 1, text: loc.source })
82
87
  method.line = loc.start_line
@@ -86,7 +91,7 @@ module RBS
86
91
  end
87
92
 
88
93
  def parse_method_alias_decl(decl:, context:, outer_name: nil)
89
- alias_def = RDoc::Alias.new(nil, decl.old_name.to_s, decl.new_name.to_s, nil, decl.kind == :singleton)
94
+ alias_def = RDoc::Alias.new(nil, decl.old_name.to_s, decl.new_name.to_s, nil, singleton: decl.kind == :singleton)
90
95
  alias_def.comment = construct_comment(context: context, comment: comment_string(decl)) if decl.comment
91
96
  context.add_alias(alias_def)
92
97
  end
@@ -100,7 +105,7 @@ module RBS
100
105
  when ::RBS::AST::Members::AttrAccessor
101
106
  'RW'
102
107
  end
103
- attribute = RDoc::Attr.new(nil, decl.name.to_s, rw, nil, decl.kind == :singleton)
108
+ attribute = RDoc::Attr.new(nil, decl.name.to_s, rw, nil, singleton: decl.kind == :singleton)
104
109
  attribute.visibility = decl.visibility
105
110
  attribute.comment = construct_comment(context: context, comment: comment_string(decl)) if decl.comment
106
111
  context.add_attribute(attribute)