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
@@ -9,49 +9,40 @@ module RBS
9
9
  attr_reader :modules
10
10
  attr_reader :last_sig
11
11
 
12
+ class Context
13
+ attr_accessor :singleton
14
+ attr_accessor :visibility
15
+
16
+ def initialize(singleton:, visibility:)
17
+ @singleton = singleton
18
+ @visibility = visibility
19
+ end
20
+ end
21
+
12
22
  def initialize
13
23
  @decls = []
14
24
 
15
25
  @modules = []
26
+ @contexts = []
27
+ @emitted_visibility = {}
16
28
  end
17
29
 
18
30
  def parse(string)
19
- comments = Ripper.lex(string).yield_self do |tokens|
20
- tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
21
- if token[1] == :on_comment
22
- line = token[0][0]
23
- body = token[2][2..-1] or raise
24
-
25
- body = "\n" if body.empty?
26
-
27
- comment = AST::Comment.new(string: body, location: nil)
28
- if (prev_comment = hash.delete(line - 1))
29
- hash[line] = AST::Comment.new(
30
- string: prev_comment.string + comment.string,
31
- location: nil
32
- )
33
- else
34
- hash[line] = comment
35
- end
36
- end
37
- end
38
- end
31
+ comments = parse_comments(string, include_trailing: true)
39
32
  process RubyVM::AbstractSyntaxTree.parse(string), comments: comments
40
33
  end
41
34
 
42
- def nested_name(name)
43
- (current_namespace + const_to_name(name).to_namespace).to_type_name.relative!
44
- end
45
-
46
- def current_namespace
47
- modules.inject(Namespace.empty) do |parent, mod|
48
- parent + mod.name.to_namespace
35
+ def append_decl(decl)
36
+ if mod = current_module
37
+ mod.members << decl
38
+ else
39
+ decls << decl
49
40
  end
50
41
  end
51
42
 
52
43
  def push_class(name, super_class, comment:)
53
44
  class_decl = AST::Declarations::Class.new(
54
- name: nested_name(name),
45
+ name: const_to_name(name),
55
46
  super_class: super_class && AST::Declarations::Class::Super.new(name: const_to_name(super_class), args: [], location: nil),
56
47
  type_params: [],
57
48
  members: [],
@@ -60,17 +51,20 @@ module RBS
60
51
  comment: comment
61
52
  )
62
53
 
54
+ append_decl class_decl
63
55
  modules << class_decl
64
- decls << class_decl
56
+ @contexts << Context.new(singleton: false, visibility: :public)
57
+ @emitted_visibility[class_decl.object_id] = :public
65
58
 
66
59
  yield
67
60
  ensure
61
+ @contexts.pop
68
62
  modules.pop
69
63
  end
70
64
 
71
65
  def push_module(name, comment:)
72
66
  module_decl = AST::Declarations::Module.new(
73
- name: nested_name(name),
67
+ name: const_to_name(name),
74
68
  type_params: [],
75
69
  members: [],
76
70
  annotations: [],
@@ -79,11 +73,14 @@ module RBS
79
73
  comment: comment
80
74
  )
81
75
 
76
+ append_decl module_decl
82
77
  modules << module_decl
83
- decls << module_decl
78
+ @contexts << Context.new(singleton: false, visibility: :public)
79
+ @emitted_visibility[module_decl.object_id] = :public
84
80
 
85
81
  yield
86
82
  ensure
83
+ @contexts.pop
87
84
  modules.pop
88
85
  end
89
86
 
@@ -95,6 +92,47 @@ module RBS
95
92
  current_module or raise
96
93
  end
97
94
 
95
+ def current_context
96
+ @contexts.last
97
+ end
98
+
99
+ def current_context!
100
+ current_context or raise
101
+ end
102
+
103
+ # Visibility of a member, given as `private def ...` in RBS
104
+ #
105
+ # Returns `nil` for members in a visibility _section_, which `sync_visibility` emits instead.
106
+ def member_visibility(context)
107
+ # RBS visibility sections don't apply to singleton members, so they need their own visibility.
108
+ if context.singleton && context.visibility != :public
109
+ :private
110
+ end
111
+ end
112
+
113
+ def sync_visibility(visibility)
114
+ # Visibility sections don't apply to singleton members in RBS.
115
+ return if current_context!.singleton
116
+
117
+ # RBS has no protected visibility. Private is the conservative fallback.
118
+ visibility = :private if visibility == :protected
119
+
120
+ mod = current_module!
121
+ return if @emitted_visibility[mod.object_id] == visibility
122
+
123
+ member = case visibility
124
+ when :public
125
+ AST::Members::Public.new(location: nil)
126
+ when :private
127
+ AST::Members::Private.new(location: nil)
128
+ else
129
+ raise "Unexpected visibility: #{visibility}"
130
+ end
131
+
132
+ mod.members << member
133
+ @emitted_visibility[mod.object_id] = visibility
134
+ end
135
+
98
136
  def push_sig(node)
99
137
  if last_sig = @last_sig
100
138
  last_sig << node
@@ -126,6 +164,15 @@ module RBS
126
164
  push_module node.children[0], comment: comment do
127
165
  process node.children[1], outer: outer + [node], comments: comments
128
166
  end
167
+ when :SCLASS
168
+ if node.children[0].type == :SELF
169
+ @contexts << Context.new(singleton: true, visibility: :public)
170
+ begin
171
+ process node.children[1], outer: outer + [node], comments: comments
172
+ ensure
173
+ @contexts.pop
174
+ end
175
+ end
129
176
  when :FCALL
130
177
  case node.children[0]
131
178
  when :include
@@ -144,9 +191,9 @@ module RBS
144
191
  end
145
192
  when :extend
146
193
  each_arg node.children[1] do |arg|
147
- if arg.type == :CONST || arg.type == :COLON2
194
+ if arg.type == :CONST || arg.type == :COLON2 || arg.type == :COLON3
148
195
  name = const_to_name(arg)
149
- unless name.to_s == "T::Generic" || name.to_s == "T::Sig"
196
+ unless ["T::Generic", "T::Helpers", "T::Sig"].include?(name.to_s.delete_prefix("::"))
150
197
  member = AST::Members::Extend.new(
151
198
  name: name,
152
199
  args: [],
@@ -161,6 +208,10 @@ module RBS
161
208
  when :sig
162
209
  out = outer.last or raise
163
210
  push_sig out.children.last.children.last
211
+ when :attr_reader, :attr_writer, :attr_accessor
212
+ process_attribute node, comments: comments
213
+ when :private, :protected, :public
214
+ process_visibility node, outer: outer, comments: comments
164
215
  when :alias_method
165
216
  new, old = each_arg(node.children[1]).map {|x| x.children[0] }
166
217
  current_module!.members << AST::Members::Alias.new(
@@ -168,10 +219,15 @@ module RBS
168
219
  old_name: old,
169
220
  location: nil,
170
221
  annotations: [],
171
- kind: :instance,
222
+ kind: current_context!.singleton ? :singleton : :instance,
172
223
  comment: nil
173
224
  )
174
225
  end
226
+ when :VCALL
227
+ case node.children[0]
228
+ when :private, :protected, :public
229
+ current_context!.visibility = node.children[0]
230
+ end
175
231
  when :DEFS
176
232
  sigs = pop_sig
177
233
 
@@ -197,6 +253,8 @@ module RBS
197
253
  sigs = pop_sig
198
254
 
199
255
  if sigs
256
+ context = current_context!
257
+ sync_visibility(context.visibility)
200
258
  comment = join_comments(sigs, comments)
201
259
 
202
260
  args = node.children[1]
@@ -207,10 +265,10 @@ module RBS
207
265
  location: nil,
208
266
  annotations: [],
209
267
  overloads: types.map {|type| AST::Members::MethodDefinition::Overload.new(annotations: [], method_type: type) },
210
- kind: :instance,
268
+ kind: context.singleton ? :singleton : :instance,
211
269
  comment: comment,
212
270
  overloading: false,
213
- visibility: nil
271
+ visibility: member_visibility(context)
214
272
  )
215
273
  end
216
274
 
@@ -235,16 +293,13 @@ module RBS
235
293
  variance: variance || :invariant,
236
294
  location: nil,
237
295
  upper_bound: nil,
296
+ lower_bound: nil,
238
297
  default_type: nil
239
298
  )
240
299
  end
241
300
  else
242
301
  name = node.children[0].yield_self do |n|
243
- if n.is_a?(Symbol)
244
- TypeName.new(namespace: current_namespace, name: n)
245
- else
246
- const_to_name(n)
247
- end
302
+ n.is_a?(Symbol) ? TypeName.new(namespace: Namespace.empty, name: n) : const_to_name(n)
248
303
  end
249
304
  value_node = node.children.last
250
305
  type = if value_node && value_node.type == :CALL && value_node.children[1] == :let
@@ -253,7 +308,7 @@ module RBS
253
308
  else
254
309
  Types::Bases::Any.new(location: nil)
255
310
  end
256
- decls << AST::Declarations::Constant.new(
311
+ append_decl AST::Declarations::Constant.new(
257
312
  name: name,
258
313
  type: type,
259
314
  location: nil,
@@ -262,12 +317,13 @@ module RBS
262
317
  )
263
318
  end
264
319
  when :ALIAS
320
+ sync_visibility(current_context!.visibility)
265
321
  current_module!.members << AST::Members::Alias.new(
266
322
  new_name: node.children[0].children[0],
267
323
  old_name: node.children[1].children[0],
268
324
  location: nil,
269
325
  annotations: [],
270
- kind: :instance,
326
+ kind: current_context!.singleton ? :singleton : :instance,
271
327
  comment: nil
272
328
  )
273
329
  else
@@ -277,6 +333,93 @@ module RBS
277
333
  end
278
334
  end
279
335
 
336
+ def process_visibility(node, outer:, comments:)
337
+ visibility = node.children[0]
338
+ args = each_arg(node.children[1]).to_a
339
+ context = current_context!
340
+
341
+ if args.empty?
342
+ context.visibility = visibility
343
+ else
344
+ previous_visibility = context.visibility
345
+ context.visibility = visibility
346
+
347
+ begin
348
+ args.each do |arg|
349
+ if arg.type == :DEFN || arg.type == :DEFS
350
+ process arg, outer: outer + [node], comments: comments
351
+ end
352
+ end
353
+ ensure
354
+ context.visibility = previous_visibility
355
+ end
356
+ end
357
+ end
358
+
359
+ def process_attribute(node, comments:)
360
+ sigs = pop_sig
361
+ kind = node.children[0]
362
+ context = current_context!
363
+ sync_visibility(context.visibility)
364
+
365
+ type = attribute_type(kind, sigs)
366
+ comment = join_comments(sigs, comments) if sigs
367
+ member_class = case kind
368
+ when :attr_reader
369
+ AST::Members::AttrReader
370
+ when :attr_writer
371
+ AST::Members::AttrWriter
372
+ when :attr_accessor
373
+ AST::Members::AttrAccessor
374
+ else
375
+ raise "Unexpected attribute kind: #{kind}"
376
+ end
377
+
378
+ each_arg node.children[1] do |arg|
379
+ if name = symbol_literal_node?(arg)
380
+ current_module!.members << member_class.new(
381
+ name: name,
382
+ type: type,
383
+ ivar_name: nil,
384
+ kind: context.singleton ? :singleton : :instance,
385
+ annotations: [],
386
+ location: nil,
387
+ comment: comment,
388
+ visibility: member_visibility(context)
389
+ )
390
+ end
391
+ end
392
+ end
393
+
394
+ def attribute_type(kind, sigs)
395
+ any = Types::Bases::Any.new(location: nil)
396
+ return any unless sigs
397
+
398
+ method_types = sigs.filter_map do |sig|
399
+ method_type(nil, sig, variables: current_module!.type_params, overloads: sigs.size)
400
+ end
401
+ function = method_types.last&.type
402
+ return any unless function.is_a?(Types::Function)
403
+
404
+ parameter_type = function.required_positionals.first&.type
405
+ return_type = function.return_type
406
+
407
+ case kind
408
+ when :attr_reader
409
+ return_type
410
+ when :attr_writer
411
+ parameter_type || return_type
412
+ when :attr_accessor
413
+ if return_type.is_a?(Types::Bases::Any) || return_type.is_a?(Types::Bases::Void)
414
+ parameter_type || any
415
+ else
416
+ return_type
417
+ end
418
+ else
419
+ any
420
+ end
421
+ end
422
+
280
423
  def method_type(args_node, type_node, variables:, overloads:)
281
424
  if type_node
282
425
  if type_node.type == :CALL
@@ -332,6 +475,7 @@ module RBS
332
475
  name: name,
333
476
  variance: :invariant,
334
477
  upper_bound: nil,
478
+ lower_bound: nil,
335
479
  location: nil,
336
480
  default_type: nil
337
481
  )
@@ -480,8 +624,10 @@ module RBS
480
624
  case
481
625
  when type.is_a?(Types::ClassInstance) && type.name.name == BuiltinNames::BasicObject.name.name
482
626
  Types::Bases::Any.new(location: nil)
483
- when type.is_a?(Types::ClassInstance) && type.name.to_s == "T::Boolean"
627
+ when type.is_a?(Types::ClassInstance) && type.name.to_s.delete_prefix("::") == "T::Boolean"
484
628
  Types::Bases::Bool.new(location: nil)
629
+ when type.is_a?(Types::ClassInstance) && type.name.to_s.delete_prefix("::") == "T::Class"
630
+ Types::Bases::Any.new(location: nil)
485
631
  else
486
632
  type
487
633
  end
@@ -499,6 +645,11 @@ module RBS
499
645
  Types::ClassInstance.new(name: const_to_name(type_node), args: [], location: nil)
500
646
  when call_node?(type_node, name: :[], receiver: -> (_) { true })
501
647
  # The type_node represents a type application
648
+ receiver = type_node.children[0]
649
+ if [:CONST, :COLON2, :COLON3].include?(receiver.type) && const_to_name(receiver).to_s.delete_prefix("::") == "T::Class"
650
+ return Types::Bases::Any.new(location: nil)
651
+ end
652
+
502
653
  type = type_of(type_node.children[0], variables: variables)
503
654
  type.is_a?(Types::ClassInstance) or raise
504
655
 
@@ -576,7 +727,7 @@ module RBS
576
727
 
577
728
  type_name = TypeName.new(name: node.children[1], namespace: namespace)
578
729
 
579
- case type_name.to_s
730
+ case type_name.to_s.delete_prefix("::")
580
731
  when "T::Array"
581
732
  BuiltinNames::Array.name
582
733
  when "T::Hash"
@@ -27,6 +27,10 @@ module RBS
27
27
  method_definition = @builder.build_singleton(module_name.absolute!).methods[method.name]
28
28
  return false unless method_definition
29
29
 
30
+ return false unless method_definition.defs.any? do |type_def|
31
+ type_def.implemented_in&.relative!.to_s == method.owner.to_s.delete_prefix("#<Class:").delete_suffix(">")
32
+ end
33
+
30
34
  method_definition.accessibility == accessibility
31
35
  end
32
36
 
@@ -36,6 +40,10 @@ module RBS
36
40
  method_definition = @builder.build_instance(module_name.absolute!).methods[method.name]
37
41
  return false unless method_definition
38
42
 
43
+ return false unless method_definition.defs.any? do |type_def|
44
+ type_def.implemented_in&.relative!.to_s == method.owner.to_s
45
+ end
46
+
39
47
  method_definition.accessibility == accessibility
40
48
  end
41
49
 
@@ -50,8 +58,8 @@ module RBS
50
58
  type_name_absolute = type_name.absolute!
51
59
  @mixin_decls_cache ||= {} #: Hash[TypeName, Array[AST::Members::Mixin]]
52
60
  @mixin_decls_cache.fetch(type_name_absolute) do
53
- @mixin_decls_cache[type_name_absolute] = @builder.env.class_decls[type_name_absolute].decls.flat_map do |d|
54
- d.decl.members.select { |m| m.kind_of?(AST::Members::Mixin) }
61
+ @mixin_decls_cache[type_name_absolute] = @builder.env.class_decls[type_name_absolute].each_decl.flat_map do |decl|
62
+ decl.members.select { |m| m.kind_of?(AST::Members::Mixin) }
55
63
  end
56
64
  end
57
65
  end
@@ -69,6 +77,8 @@ module RBS
69
77
  attr_accessor :outline
70
78
 
71
79
  def initialize(patterns:, env:, merge:, todo: false, owners_included: [])
80
+ Kernel.warn("RBS::Prototype::Runtime is deprecated. See https://github.com/ruby/rbs/issues/2841")
81
+
72
82
  @patterns = patterns
73
83
  @decls = nil
74
84
  @modules = {}
@@ -32,7 +32,7 @@ module RBS
32
32
  end
33
33
 
34
34
  environment.class_alias_decls.each do |name, entry|
35
- normalized_entry = environment.normalized_module_class_entry(name) or next
35
+ normalized_entry = environment.module_class_entry(name, normalized: true) or next
36
36
  constant = constant_of_module(name, normalized_entry)
37
37
 
38
38
  # Insert class/module aliases into `children_table` and `toplevel` table
@@ -176,7 +176,7 @@ module RBS
176
176
  end
177
177
 
178
178
  def constants_from_ancestors(module_name, constants:)
179
- entry = builder.env.normalized_module_class_entry(module_name) or raise
179
+ entry = builder.env.module_class_entry(module_name, normalized: true) or raise
180
180
 
181
181
  if entry.is_a?(Environment::ClassEntry) || entry.is_a?(Environment::ModuleEntry)
182
182
  constants.merge!(table.children(BuiltinNames::Object.name) || raise)
@@ -5,85 +5,161 @@ module RBS
5
5
  class TypeNameResolver
6
6
  attr_reader :all_names
7
7
  attr_reader :cache
8
- attr_reader :env
8
+ attr_reader :aliases
9
9
 
10
- def initialize(env)
11
- @all_names = Set[]
10
+ def initialize(all_names, aliases)
11
+ @all_names = all_names
12
+ @aliases = aliases
12
13
  @cache = {}
13
- @env = env
14
+ end
15
+
16
+ def self.build(env)
17
+ all_names = Set.new #: Set[TypeName]
14
18
 
15
19
  all_names.merge(env.class_decls.keys)
16
20
  all_names.merge(env.interface_decls.keys)
17
21
  all_names.merge(env.type_alias_decls.keys)
18
- all_names.merge(env.class_alias_decls.keys)
19
- end
20
22
 
21
- def try_cache(query)
22
- cache.fetch(query) do
23
- result = yield
24
- cache[query] = result
23
+ aliases = {} #: Hash[TypeName, [TypeName, context]]
24
+
25
+ env.class_alias_decls.each do |name, entry|
26
+ aliases[name] = [entry.decl.old_name, entry.context]
25
27
  end
28
+
29
+ new(all_names, aliases)
30
+ end
31
+
32
+ def try_cache(type_name, context)
33
+ inner = cache[context] ||= {}
34
+ inner.fetch(type_name) { inner[type_name] = yield }
26
35
  end
27
36
 
28
37
  def resolve(type_name, context:)
29
- if type_name.absolute?
38
+ if type_name.absolute? && has_type_name?(type_name)
30
39
  return type_name
31
40
  end
32
41
 
33
- try_cache([type_name, context]) do
34
- head, tail = partition(type_name)
35
-
36
- head = resolve_in(head, context)
42
+ try_cache(type_name, context) do
43
+ if type_name.class?
44
+ resolve_namespace0(type_name, context, Set.new) || nil
45
+ else
46
+ namespace = type_name.namespace
37
47
 
38
- if head
39
- if tail
40
- absolute_name = tail.with_prefix(head.to_namespace)
41
- if env.normalize_type_name?(absolute_name)
42
- absolute_name
43
- end
48
+ if namespace.empty?
49
+ resolve_type_name(type_name.name, context)
44
50
  else
45
- head
51
+ if namespace = resolve_namespace0(namespace.to_type_name, context, Set.new)
52
+ type_name = TypeName[namespace.to_namespace, type_name.name]
53
+ has_type_name?(type_name)
54
+ end
46
55
  end
47
56
  end
48
57
  end
49
58
  end
50
59
 
51
- def partition(type_name)
52
- if type_name.namespace.empty?
53
- head = type_name.name
54
- tail = nil
55
- else
56
- head, *tail = type_name.namespace.path
60
+ def resolve_namespace(type_name, context:)
61
+ if type_name.absolute? && has_type_name?(type_name)
62
+ return type_name
63
+ end
57
64
 
58
- head or raise
65
+ unless type_name.class?
66
+ raise "Type name must be a class name: #{type_name}"
67
+ end
59
68
 
60
- tail = TypeName.new(
61
- name: type_name.name,
62
- namespace: Namespace.new(absolute: false, path: tail)
63
- )
69
+ try_cache(type_name, context) do
70
+ ns = resolve_namespace0(type_name, context, Set.new) or return ns
64
71
  end
72
+ end
65
73
 
66
- [head, tail]
74
+ def has_type_name?(full_name)
75
+ if all_names.include?(full_name)
76
+ full_name
77
+ end
67
78
  end
68
79
 
69
- def resolve_in(head, context)
80
+ def aliased_name?(type_name)
81
+ if aliases.key?(type_name)
82
+ type_name
83
+ end
84
+ end
85
+
86
+ def resolve_type_name(type_name, context)
70
87
  if context
71
- parent, child = context
72
- case child
88
+ outer, inner = context
89
+ case inner
73
90
  when false
74
- resolve_in(head, parent)
91
+ resolve_type_name(type_name, outer)
92
+ else
93
+ has_type_name?(inner) or raise "Context must be normalized: #{inner.inspect}"
94
+ has_type_name?(TypeName[inner.to_namespace, type_name]) || resolve_type_name(type_name, outer)
95
+ end
96
+ else
97
+ type_name = TypeName[Namespace.root, type_name]
98
+ has_type_name?(type_name)
99
+ end
100
+ end
101
+
102
+ def resolve_head_namespace(head, context)
103
+ if context
104
+ outer, inner = context
105
+ case inner
106
+ when false
107
+ resolve_head_namespace(head, outer)
75
108
  when TypeName
76
- name = TypeName.new(name: head, namespace: child.to_namespace)
77
- has_name?(name) || resolve_in(head, parent)
109
+ has_type_name?(inner) or raise "Context must be normalized: #{inner.inspect}"
110
+ type_name = TypeName[inner.to_namespace, head]
111
+ has_type_name?(type_name) || aliased_name?(type_name) || resolve_head_namespace(head, outer)
78
112
  end
79
113
  else
80
- has_name?(TypeName.new(name: head, namespace: Namespace.root))
114
+ type_name = TypeName[Namespace.root, head]
115
+ has_type_name?(type_name) || aliased_name?(type_name)
81
116
  end
82
117
  end
83
118
 
84
- def has_name?(full_name)
85
- if all_names.include?(full_name)
86
- full_name
119
+ def normalize_namespace(type_name, rhs, context, visited)
120
+ if visited.include?(type_name)
121
+ # Cycle detected
122
+ return false
123
+ end
124
+
125
+ visited << type_name
126
+
127
+ begin
128
+ resolve_namespace0(rhs, context, visited)
129
+ ensure
130
+ visited.delete(type_name)
131
+ end
132
+ end
133
+
134
+ def resolve_namespace0(type_name, context, visited)
135
+ head, *tail = [*type_name.namespace.path, type_name.name]
136
+
137
+ head = head #: Symbol
138
+
139
+ head =
140
+ if type_name.absolute?
141
+ root_name = TypeName[Namespace.root, head]
142
+ has_type_name?(root_name) || aliased_name?(root_name)
143
+ else
144
+ resolve_head_namespace(head, context)
145
+ end
146
+
147
+ if head
148
+ if (rhs, context = aliases.fetch(head, nil))
149
+ head = normalize_namespace(head, rhs, context, visited) or return head
150
+ end
151
+
152
+ tail.inject(head) do |namespace, name|
153
+ type_name = TypeName[namespace.to_namespace, name]
154
+ case
155
+ when has_type_name?(type_name)
156
+ type_name
157
+ when (rhs, context = aliases.fetch(type_name, nil))
158
+ m = normalize_namespace(type_name, rhs, context, visited) or return m
159
+ else
160
+ return nil
161
+ end
162
+ end
87
163
  end
88
164
  end
89
165
  end