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
@@ -5,14 +5,16 @@ require_relative "parser/token"
5
5
 
6
6
  module RBS
7
7
  class Parser
8
- def self.parse_type(source, range: 0..., variables: [], require_eof: false)
8
+ def self.parse_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false, void_allowed: true, self_allowed: true, classish_allowed: true)
9
9
  buf = buffer(source)
10
- _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
10
+ byte_range = byte_range(range, buf.content) if range
11
+ _parse_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof, void_allowed, self_allowed, classish_allowed)
11
12
  end
12
13
 
13
- def self.parse_method_type(source, range: 0..., variables: [], require_eof: false)
14
+ def self.parse_method_type(source, range: nil, byte_range: 0..., variables: [], require_eof: false)
14
15
  buf = buffer(source)
15
- _parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
16
+ byte_range = byte_range(range, buf.content) if range
17
+ _parse_method_type(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables, require_eof)
16
18
  end
17
19
 
18
20
  def self.parse_signature(source)
@@ -25,7 +27,8 @@ module RBS
25
27
  else
26
28
  0
27
29
  end
28
- dirs, decls = _parse_signature(buf, start_pos, buf.last_position)
30
+ content = buf.content
31
+ dirs, decls = _parse_signature(buf, start_pos, content.bytesize)
29
32
 
30
33
  if resolved
31
34
  dirs = dirs.dup if dirs.frozen?
@@ -37,7 +40,7 @@ module RBS
37
40
 
38
41
  def self.parse_type_params(source, module_type_params: true)
39
42
  buf = buffer(source)
40
- _parse_type_params(buf, 0, buf.last_position, module_type_params)
43
+ _parse_type_params(buf, 0, buf.content.bytesize, module_type_params)
41
44
  end
42
45
 
43
46
  def self.magic_comment(buf)
@@ -66,7 +69,7 @@ module RBS
66
69
 
67
70
  def self.lex(source)
68
71
  buf = buffer(source)
69
- list = _lex(buf, buf.last_position)
72
+ list = _lex(buf, buf.content.bytesize)
70
73
  value = list.map do |type, location|
71
74
  Token.new(type: type, location: location)
72
75
  end
@@ -125,5 +128,15 @@ module RBS
125
128
  buf = buffer(source)
126
129
  _parse_inline_trailing_annotation(buf, range.begin || 0, range.end || buf.last_position, variables)
127
130
  end
131
+
132
+ def self.byte_range(char_range, content)
133
+ start_offset = char_range.begin
134
+ end_offset = char_range.end
135
+
136
+ start_prefix = content[0, start_offset] or raise if start_offset
137
+ end_prefix = content[0, end_offset] or raise if end_offset
138
+
139
+ start_prefix&.bytesize...end_prefix&.bytesize
140
+ end
128
141
  end
129
142
  end
@@ -5,6 +5,63 @@ module RBS
5
5
  module Helpers
6
6
  private
7
7
 
8
+ # Prism can't parse Ruby 3.2 code
9
+ if RUBY_VERSION >= "3.3"
10
+ def parse_comments(string, include_trailing:)
11
+ Prism.parse_comments(string, version: "current").yield_self do |prism_comments| # steep:ignore UnexpectedKeywordArgument
12
+ prism_comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment]
13
+ # Skip EmbDoc comments
14
+ next unless comment.is_a?(Prism::InlineComment)
15
+ # skip like `module Foo # :nodoc:`
16
+ next if comment.trailing? && !include_trailing
17
+
18
+ line = comment.location.start_line
19
+ body = "#{comment.location.slice}\n"
20
+ body = body[2..-1] or raise
21
+ body = "\n" if body.empty?
22
+
23
+ comment = AST::Comment.new(string: body, location: nil)
24
+ if prev_comment = hash.delete(line - 1)
25
+ hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
26
+ location: nil)
27
+ else
28
+ hash[line] = comment
29
+ end
30
+ end
31
+ end
32
+ end
33
+ else
34
+ require "ripper"
35
+ def parse_comments(string, include_trailing:)
36
+ Ripper.lex(string).yield_self do |tokens|
37
+ code_lines = {} #: Hash[Integer, bool]
38
+ tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
39
+ case token[1]
40
+ when :on_sp, :on_ignored_nl
41
+ # skip
42
+ when :on_comment
43
+ line = token[0][0]
44
+ # skip like `module Foo # :nodoc:`
45
+ next if code_lines[line] && !include_trailing
46
+ body = token[2][2..-1] or raise
47
+
48
+ body = "\n" if body.empty?
49
+
50
+ comment = AST::Comment.new(string: body, location: nil)
51
+ if prev_comment = hash.delete(line - 1)
52
+ hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
53
+ location: nil)
54
+ else
55
+ hash[line] = comment
56
+ end
57
+ else
58
+ code_lines[token[0][0]] = true
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
8
65
  def block_from_body(node)
9
66
  _, args_node, body_node = node.children
10
67
  _pre_num, _pre_init, _opt, _first_post, _post_num, _post_init, _rest, _kw, _kwrest, block_var = args_from_node(args_node)
@@ -74,32 +74,7 @@ module RBS
74
74
 
75
75
  def parse(string)
76
76
  # @type var comments: Hash[Integer, AST::Comment]
77
- comments = Ripper.lex(string).yield_self do |tokens|
78
- code_lines = {} #: Hash[Integer, bool]
79
- tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
80
- case token[1]
81
- when :on_sp, :on_ignored_nl
82
- # skip
83
- when :on_comment
84
- line = token[0][0]
85
- # skip like `module Foo # :nodoc:`
86
- next if code_lines[line]
87
- body = token[2][2..-1] or raise
88
-
89
- body = "\n" if body.empty?
90
-
91
- comment = AST::Comment.new(string: body, location: nil)
92
- if prev_comment = hash.delete(line - 1)
93
- hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
94
- location: nil)
95
- else
96
- hash[line] = comment
97
- end
98
- else
99
- code_lines[token[0][0]] = true
100
- end
101
- end
102
- end
77
+ comments = parse_comments(string, include_trailing: false)
103
78
 
104
79
  process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, context: Context.initial
105
80
  end
@@ -372,8 +347,8 @@ module RBS
372
347
  end
373
348
 
374
349
  value_node = node.children.last
375
- type = if value_node.nil?
376
- # Give up type prediction when node is MASGN.
350
+ type = if value_node.nil? || value_node.type == :SELF
351
+ # Give up type prediction when node is MASGN or SELF.
377
352
  Types::Bases::Any.new(location: nil)
378
353
  else
379
354
  literal_to_type(value_node)
@@ -16,26 +16,7 @@ module RBS
16
16
  end
17
17
 
18
18
  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
19
+ comments = parse_comments(string, include_trailing: true)
39
20
  process RubyVM::AbstractSyntaxTree.parse(string), comments: comments
40
21
  end
41
22
 
@@ -235,6 +216,7 @@ module RBS
235
216
  variance: variance || :invariant,
236
217
  location: nil,
237
218
  upper_bound: nil,
219
+ lower_bound: nil,
238
220
  default_type: nil
239
221
  )
240
222
  end
@@ -332,6 +314,7 @@ module RBS
332
314
  name: name,
333
315
  variance: :invariant,
334
316
  upper_bound: nil,
317
+ lower_bound: nil,
335
318
  location: nil,
336
319
  default_type: nil
337
320
  )
@@ -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
 
@@ -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
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class Rewriter
5
+ attr_reader :buffer
6
+
7
+ def initialize(buffer)
8
+ raise "Rewriter only supports toplevel buffers" if buffer.parent
9
+
10
+ @buffer = buffer
11
+ @rewrites = []
12
+ end
13
+
14
+ def rewrite(location, string)
15
+ @rewrites.each do |existing_location, _|
16
+ if location.start_pos < existing_location.end_pos && existing_location.start_pos < location.end_pos
17
+ raise "Overlapping rewrites: #{existing_location} and #{location}"
18
+ end
19
+ end
20
+
21
+ @rewrites << [location, string]
22
+ self
23
+ end
24
+
25
+ def add_comment(*locations, content:)
26
+ earliest = locations.min_by(&:start_pos) or raise "At least one location is required"
27
+ insert_pos = earliest.start_pos
28
+ indent = " " * earliest.start_column
29
+
30
+ formatted = format_comment(content, indent)
31
+
32
+ loc = Location.new(buffer, insert_pos, insert_pos)
33
+ rewrite(loc, "#{formatted}\n#{indent}")
34
+ end
35
+
36
+ def replace_comment(comment, content:)
37
+ location = comment.location or raise "Comment must have a location"
38
+ indent = " " * location.start_column
39
+
40
+ rewrite(location, format_comment(content, indent))
41
+ end
42
+
43
+ def delete_comment(comment)
44
+ location = comment.location or raise "Comment must have a location"
45
+ line_start = location.start_pos - location.start_column
46
+ line_end = location.end_pos + 1
47
+ loc = Location.new(buffer, line_start, line_end)
48
+ rewrite(loc, "")
49
+ end
50
+
51
+ def string
52
+ result = buffer.content.dup
53
+
54
+ @rewrites.sort_by { |location, _| location.start_pos }.reverse_each do |location, replacement|
55
+ result[location.start_pos...location.end_pos] = replacement
56
+ end
57
+
58
+ result
59
+ end
60
+
61
+ private
62
+
63
+ def format_comment(content, indent)
64
+ content.lines.map do |line|
65
+ line = line.chomp
66
+ line.empty? ? "#" : "# #{line}"
67
+ end.join("\n#{indent}")
68
+ end
69
+ end
70
+ end
@@ -107,7 +107,9 @@ module RBS
107
107
  each_member(owner).any? do |m|
108
108
  case m
109
109
  when AST::Members::InstanceVariable
110
- m.name == name
110
+ m.name == name && kind == :instance
111
+ when AST::Members::ClassInstanceVariable
112
+ m.name == name && kind == :singleton
111
113
  when AST::Members::Attribute
112
114
  ivar_name = m.ivar_name == false ? nil : m.ivar_name || :"@#{m.name}"
113
115
  ivar_name == name && m.kind == kind
@@ -245,7 +245,7 @@ module RBS
245
245
  when Types::Bases::Any
246
246
  true
247
247
  when Types::Bases::Bool
248
- val.is_a?(TrueClass) || val.is_a?(FalseClass)
248
+ Test.call(val, IS_AP, TrueClass) || Test.call(val, IS_AP, FalseClass)
249
249
  when Types::Bases::Top
250
250
  true
251
251
  when Types::Bases::Bottom
@@ -264,6 +264,9 @@ module RBS
264
264
  klass = get_class(type.name) or return false
265
265
  if params = builder.env.normalized_module_class_entry(type.name.absolute!)&.type_params
266
266
  args = AST::TypeParam.normalize_args(params, type.args)
267
+ if args.size != params.size
268
+ return false
269
+ end
267
270
  unless args == type.args
268
271
  type = Types::ClassInstance.new(name: type.name, args: args, location: type.location)
269
272
  end
@@ -288,6 +291,19 @@ module RBS
288
291
  values << args
289
292
  nil
290
293
  end
294
+ when nil
295
+ values = []
296
+ count = 10_000
297
+
298
+ ret = val.each do |*args|
299
+ count -= 1
300
+ values << args
301
+ break if count <= 0
302
+ end
303
+
304
+ if count == 0
305
+ ret = self
306
+ end
291
307
  else
292
308
  values = []
293
309
  ret = val.each do |*args|
@@ -323,7 +339,7 @@ module RBS
323
339
  rescue TypeError
324
340
  return false
325
341
  end
326
- val.is_a?(singleton_class)
342
+ Test.call(val, IS_AP, singleton_class)
327
343
  when Types::Interface
328
344
  if (definition = builder.build_interface(type.name.absolute!))
329
345
  definition.methods.each.all? do |method_name, method|
@@ -340,7 +356,12 @@ module RBS
340
356
  when Types::Variable
341
357
  true
342
358
  when Types::Literal
343
- type.literal == val
359
+ begin
360
+ type.literal == val
361
+ rescue NoMethodError
362
+ raise if defined?(val.==)
363
+ false
364
+ end
344
365
  when Types::Union
345
366
  type.types.any? {|type| value(val, type) }
346
367
  when Types::Intersection
@@ -351,6 +372,7 @@ module RBS
351
372
  value(val, builder.expand_alias2(type.name.absolute!, type.args))
352
373
  when Types::Tuple
353
374
  Test.call(val, IS_AP, ::Array) &&
375
+ type.types.length == val.length &&
354
376
  type.types.map.with_index {|ty, index| value(val[index], ty) }.all?
355
377
  when Types::Record
356
378
  Test::call(val, IS_AP, ::Hash) &&