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,568 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class InlineParser
5
+ class Result
6
+ attr_reader :buffer, :prism_result, :declarations, :diagnostics
7
+
8
+ def initialize(buffer, prism)
9
+ @buffer = buffer
10
+ @prism_result = prism
11
+ @declarations = []
12
+ @diagnostics = []
13
+ end
14
+
15
+ def type_fingerprint
16
+ declarations.map(&:type_fingerprint)
17
+ end
18
+ end
19
+
20
+ module Diagnostic
21
+ class Base
22
+ attr_reader :message, :location
23
+
24
+ def initialize(location, message)
25
+ @location = location
26
+ @message = message
27
+ end
28
+ end
29
+
30
+ NotImplementedYet = _ = Class.new(Base)
31
+ NonConstantClassName = _ = Class.new(Base)
32
+ NonConstantModuleName = _ = Class.new(Base)
33
+ NonConstantSuperClassName = _ = Class.new(Base)
34
+ TopLevelMethodDefinition = _ = Class.new(Base)
35
+ TopLevelAttributeDefinition = _ = Class.new(Base)
36
+ NonConstantConstantDeclaration = _ = Class.new(Base)
37
+ UnusedInlineAnnotation = _ = Class.new(Base)
38
+ AnnotationSyntaxError = _ = Class.new(Base)
39
+ MixinMultipleArguments = _ = Class.new(Base)
40
+ MixinNonConstantModule = _ = Class.new(Base)
41
+ AttributeNonSymbolName = _ = Class.new(Base)
42
+ ClassModuleAliasDeclarationMissingTypeName = _ = Class.new(Base)
43
+ end
44
+
45
+ def self.parse(buffer, prism)
46
+ result = Result.new(buffer, prism)
47
+
48
+ parser = Parser.new(result)
49
+ parser.visit(prism.value)
50
+ parser.comments.each_unassociated_block do |block|
51
+ parser.report_unused_block(block)
52
+ end
53
+
54
+ result
55
+ end
56
+
57
+ class Parser < Prism::Visitor
58
+ attr_reader :module_nesting, :result, :comments
59
+
60
+ include AST::Ruby::Helpers::ConstantHelper
61
+ include AST::Ruby::Helpers::LocationHelper
62
+
63
+ def initialize(result)
64
+ @result = result
65
+ @module_nesting = []
66
+ @comments = CommentAssociation.build(result.buffer, result.prism_result)
67
+ end
68
+
69
+ def buffer
70
+ result.buffer
71
+ end
72
+
73
+ def current_module
74
+ module_nesting.last
75
+ end
76
+
77
+ def current_module!
78
+ current_module || raise("#current_module is nil")
79
+ end
80
+
81
+ def diagnostics
82
+ result.diagnostics
83
+ end
84
+
85
+ def push_module_nesting(mod)
86
+ module_nesting.push(mod)
87
+ yield
88
+ ensure
89
+ module_nesting.pop()
90
+ end
91
+
92
+ def skip_node?(node)
93
+ if ref = comments.leading_block(node)
94
+ if ref.block.each_paragraph([]).any? { _1.is_a?(AST::Ruby::Annotations::SkipAnnotation) }
95
+ ref.associate!
96
+ return true
97
+ end
98
+ end
99
+
100
+ false
101
+ end
102
+
103
+ def visit_class_node(node)
104
+ return if skip_node?(node)
105
+
106
+ unless class_name = constant_as_type_name(node.constant_path)
107
+ diagnostics << Diagnostic::NonConstantClassName.new(
108
+ rbs_location(node.constant_path.location),
109
+ "Class name must be a constant"
110
+ )
111
+ return
112
+ end
113
+
114
+ # Parse super class if present
115
+ super_class = if node.superclass
116
+ node.inheritance_operator_loc or raise
117
+ parse_super_class(node.superclass, node.inheritance_operator_loc)
118
+ end
119
+
120
+ class_decl = AST::Ruby::Declarations::ClassDecl.new(buffer, class_name, node, super_class)
121
+ insert_declaration(class_decl)
122
+ visit_class_or_module_body(class_decl, node)
123
+ end
124
+
125
+ def visit_module_node(node)
126
+ return if skip_node?(node)
127
+
128
+ unless module_name = constant_as_type_name(node.constant_path)
129
+ diagnostics << Diagnostic::NonConstantModuleName.new(
130
+ rbs_location(node.constant_path.location),
131
+ "Module name must be a constant"
132
+ )
133
+ return
134
+ end
135
+
136
+ module_decl = AST::Ruby::Declarations::ModuleDecl.new(buffer, module_name, node)
137
+
138
+ if leading_ref = comments.leading_block(node)
139
+ unused_annotations = [] #: Array[AST::Ruby::CommentBlock::AnnotationSyntaxError | AST::Ruby::Annotations::leading_annotation]
140
+
141
+ leading_ref.block.each_paragraph([]) do |paragraph|
142
+ case paragraph
143
+ when AST::Ruby::Annotations::ModuleSelfAnnotation
144
+ module_decl.members << AST::Ruby::Members::ModuleSelfMember.new(buffer, paragraph)
145
+ when Location
146
+ # Skip
147
+ when AST::Ruby::CommentBlock::AnnotationSyntaxError
148
+ unused_annotations << paragraph
149
+ when AST::Ruby::Annotations::SkipAnnotation
150
+ # Already handled by skip_node?
151
+ else
152
+ unused_annotations << paragraph
153
+ end
154
+ end
155
+
156
+ unless unused_annotations.empty?
157
+ report_unused_annotation(*unused_annotations)
158
+ end
159
+
160
+ leading_ref.associate!
161
+ end
162
+
163
+ insert_declaration(module_decl)
164
+ visit_class_or_module_body(module_decl, node)
165
+ end
166
+
167
+ def visit_class_or_module_body(decl, node)
168
+ push_module_nesting(decl) do
169
+ visit_child_nodes(node)
170
+
171
+ node.child_nodes.each do |child_node|
172
+ if child_node
173
+ comments.each_enclosed_block(child_node) do |block|
174
+ report_unused_block(block)
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ comments.each_enclosed_block(node) do |block|
181
+ unused_annotations = [] #: Array[AST::Ruby::CommentBlock::AnnotationSyntaxError | AST::Ruby::Annotations::leading_annotation]
182
+
183
+ block.each_paragraph([]) do |paragraph|
184
+ case paragraph
185
+ when AST::Ruby::Annotations::InstanceVariableAnnotation
186
+ decl.members << AST::Ruby::Members::InstanceVariableMember.new(buffer, paragraph)
187
+ when Location
188
+ # Skip
189
+ when AST::Ruby::CommentBlock::AnnotationSyntaxError
190
+ unused_annotations << paragraph
191
+ else
192
+ unused_annotations << paragraph
193
+ end
194
+ end
195
+
196
+ report_unused_annotation(*unused_annotations)
197
+ end
198
+
199
+ decl.members.sort_by! { _1.location.start_line }
200
+ end
201
+
202
+ def visit_def_node(node)
203
+ return if skip_node?(node)
204
+
205
+ if node.receiver && !node.receiver.is_a?(Prism::SelfNode)
206
+ diagnostics << Diagnostic::NotImplementedYet.new(
207
+ rbs_location(node.receiver.location),
208
+ "Method definition with non-self receiver is not supported"
209
+ )
210
+ return
211
+ end
212
+
213
+ kind = node.receiver ? :singleton : :instance #: :singleton | :instance
214
+
215
+ case current = current_module
216
+ when AST::Ruby::Declarations::ClassDecl, AST::Ruby::Declarations::ModuleDecl
217
+ leading_block = comments.leading_block!(node)
218
+
219
+ if node.end_keyword_loc
220
+ # Not an end-less def
221
+ end_loc = node.rparen_loc || node.parameters&.location || node.name_loc
222
+ trailing_block = comments.trailing_block!(end_loc)
223
+ end
224
+
225
+ method_type, leading_unuseds, trailing_unused = AST::Ruby::Members::MethodTypeAnnotation.build(leading_block, trailing_block, [], node)
226
+ report_unused_annotation(trailing_unused, *leading_unuseds)
227
+
228
+ defn = AST::Ruby::Members::DefMember.new(buffer, node.name, node, method_type, leading_block, kind: kind)
229
+ current.members << defn
230
+
231
+ # Skip other comments in `def` node
232
+ comments.each_enclosed_block(node) do |block|
233
+ report_unused_block(block)
234
+ end
235
+ else
236
+ diagnostics << Diagnostic::TopLevelMethodDefinition.new(
237
+ rbs_location(node.name_loc),
238
+ "Top-level method definition is not supported"
239
+ )
240
+ end
241
+ end
242
+
243
+ def visit_call_node(node)
244
+ return unless node.receiver.nil? # Only handle top-level calls like include, extend, prepend, attr_*
245
+
246
+ case node.name
247
+ when :include, :extend, :prepend
248
+ return if skip_node?(node)
249
+
250
+ case current = current_module
251
+ when AST::Ruby::Declarations::ClassDecl, AST::Ruby::Declarations::ModuleDecl
252
+ parse_mixin_call(node)
253
+ end
254
+ when :attr_reader, :attr_writer, :attr_accessor
255
+ return if skip_node?(node)
256
+
257
+ case current = current_module
258
+ when AST::Ruby::Declarations::ClassDecl, AST::Ruby::Declarations::ModuleDecl
259
+ parse_attribute_call(node)
260
+ when nil
261
+ # Top-level attribute definition
262
+ diagnostics << Diagnostic::TopLevelAttributeDefinition.new(
263
+ rbs_location(node.message_loc || node.location),
264
+ "Top-level attribute definition is not supported"
265
+ )
266
+ end
267
+ else
268
+ visit_child_nodes(node)
269
+ end
270
+ end
271
+
272
+ def visit_constant_write_node(node)
273
+ return if skip_node?(node)
274
+
275
+ # Parse constant declaration (both top-level and in classes/modules)
276
+ parse_constant_declaration(node)
277
+ end
278
+
279
+ def visit_constant_path_write_node(node)
280
+ return if skip_node?(node)
281
+
282
+ parse_constant_declaration(node)
283
+ end
284
+
285
+ def parse_mixin_call(node)
286
+ # Check for multiple arguments
287
+ if node.arguments && node.arguments.arguments.length > 1
288
+ diagnostics << Diagnostic::MixinMultipleArguments.new(
289
+ rbs_location(node.location),
290
+ "Mixing multiple modules with one call is not supported"
291
+ )
292
+ return
293
+ end
294
+
295
+ # Check for missing arguments
296
+ unless node.arguments && node.arguments.arguments.length == 1
297
+ # This shouldn't happen in valid Ruby code, but handle it gracefully
298
+ return
299
+ end
300
+
301
+ first_arg = node.arguments.arguments.first
302
+
303
+ # Check if the argument is a constant
304
+ unless module_name = constant_as_type_name(first_arg)
305
+ diagnostics << Diagnostic::MixinNonConstantModule.new(
306
+ rbs_location(first_arg.location),
307
+ "Module name must be a constant"
308
+ )
309
+ return
310
+ end
311
+
312
+ # Look for type application annotation in trailing comments
313
+ # For single-line calls like "include Bar #[String]", the annotation is trailing
314
+ trailing_block = comments.trailing_block!(node.location)
315
+ annotation = nil
316
+
317
+ if trailing_block
318
+ case trailing_annotation = trailing_block.trailing_annotation([])
319
+ when AST::Ruby::Annotations::TypeApplicationAnnotation
320
+ annotation = trailing_annotation
321
+ else
322
+ report_unused_annotation(trailing_annotation)
323
+ end
324
+ end
325
+
326
+ # Create the appropriate member based on the method name
327
+ member = case node.name
328
+ when :include
329
+ AST::Ruby::Members::IncludeMember.new(buffer, node, module_name, annotation)
330
+ when :extend
331
+ AST::Ruby::Members::ExtendMember.new(buffer, node, module_name, annotation)
332
+ when :prepend
333
+ AST::Ruby::Members::PrependMember.new(buffer, node, module_name, annotation)
334
+ else
335
+ raise "Unexpected mixin method: #{node.name}"
336
+ end
337
+
338
+ current_module!.members << member
339
+ end
340
+
341
+ def parse_attribute_call(node)
342
+ # Get the name nodes (arguments to attr_*)
343
+ unless node.arguments && !node.arguments.arguments.empty?
344
+ return # No arguments, nothing to do
345
+ end
346
+
347
+ name_nodes = [] #: Array[Prism::SymbolNode]
348
+ node.arguments.arguments.each do |arg|
349
+ case arg
350
+ when Prism::SymbolNode
351
+ name_nodes << arg
352
+ else
353
+ # Non-symbol argument, report error
354
+ diagnostics << Diagnostic::AttributeNonSymbolName.new(
355
+ rbs_location(arg.location),
356
+ "Attribute name must be a symbol"
357
+ )
358
+ end
359
+ end
360
+
361
+ return if name_nodes.empty?
362
+
363
+ # Look for leading comment block
364
+ leading_block = comments.leading_block!(node)
365
+
366
+ # Look for trailing type annotation (#: Type)
367
+ trailing_block = comments.trailing_block!(node.location)
368
+ type_annotation = nil
369
+
370
+ if trailing_block
371
+ case annotation = trailing_block.trailing_annotation([])
372
+ when AST::Ruby::Annotations::NodeTypeAssertion
373
+ type_annotation = annotation
374
+ when AST::Ruby::CommentBlock::AnnotationSyntaxError
375
+ diagnostics << Diagnostic::AnnotationSyntaxError.new(
376
+ annotation.location, "Syntax error: " + annotation.error.error_message
377
+ )
378
+ end
379
+ end
380
+
381
+ # Report unused leading annotations since @rbs annotations are not used for attributes
382
+ if leading_block
383
+ report_unused_block(leading_block)
384
+ end
385
+
386
+ # Create the appropriate member type
387
+ member = case node.name
388
+ when :attr_reader
389
+ AST::Ruby::Members::AttrReaderMember.new(buffer, node, name_nodes, leading_block, type_annotation)
390
+ when :attr_writer
391
+ AST::Ruby::Members::AttrWriterMember.new(buffer, node, name_nodes, leading_block, type_annotation)
392
+ when :attr_accessor
393
+ AST::Ruby::Members::AttrAccessorMember.new(buffer, node, name_nodes, leading_block, type_annotation)
394
+ else
395
+ raise "Unexpected attribute method: #{node.name}"
396
+ end
397
+
398
+ current_module!.members << member
399
+ end
400
+
401
+ def parse_constant_declaration(node)
402
+ # Create TypeName for the constant
403
+ unless constant_name = constant_as_type_name(node)
404
+ location =
405
+ case node
406
+ when Prism::ConstantWriteNode
407
+ node.name_loc
408
+ when Prism::ConstantPathWriteNode
409
+ node.target.location
410
+ end
411
+
412
+ diagnostics << Diagnostic::NonConstantConstantDeclaration.new(
413
+ rbs_location(location),
414
+ "Constant name must be a constant"
415
+ )
416
+ return
417
+ end
418
+
419
+ # Look for leading comment block
420
+ leading_block = comments.leading_block!(node)
421
+ report_unused_block(leading_block) if leading_block
422
+
423
+ # Look for trailing type annotation (#: Type)
424
+ trailing_block = comments.trailing_block!(node.location)
425
+ type_annotation = nil
426
+ alias_annotation = nil
427
+
428
+ if trailing_block
429
+ case annotation = trailing_block.trailing_annotation([])
430
+ when AST::Ruby::Annotations::NodeTypeAssertion
431
+ type_annotation = annotation
432
+ when AST::Ruby::Annotations::ClassAliasAnnotation, AST::Ruby::Annotations::ModuleAliasAnnotation
433
+ alias_annotation = annotation
434
+ when AST::Ruby::CommentBlock::AnnotationSyntaxError
435
+ diagnostics << Diagnostic::AnnotationSyntaxError.new(
436
+ annotation.location, "Syntax error: " + annotation.error.error_message
437
+ )
438
+ end
439
+ end
440
+
441
+ # Handle class/module alias declarations
442
+ if alias_annotation
443
+ # Try to infer the old name from the right-hand side
444
+ infered_old_name = constant_as_type_name(node.value)
445
+
446
+ # Check if we have either an explicit type name or can infer one
447
+ if alias_annotation.type_name.nil? && infered_old_name.nil?
448
+ message =
449
+ if alias_annotation.is_a?(AST::Ruby::Annotations::ClassAliasAnnotation)
450
+ "Class name is missing in class alias declaration"
451
+ else
452
+ "Module name is missing in module alias declaration"
453
+ end
454
+
455
+ diagnostics << Diagnostic::ClassModuleAliasDeclarationMissingTypeName.new(
456
+ alias_annotation.location,
457
+ message
458
+ )
459
+ return
460
+ end
461
+
462
+ # Create class/module alias declaration
463
+ alias_decl = AST::Ruby::Declarations::ClassModuleAliasDecl.new(
464
+ buffer,
465
+ node,
466
+ constant_name,
467
+ infered_old_name,
468
+ leading_block,
469
+ alias_annotation
470
+ )
471
+
472
+ # Insert the alias declaration appropriately
473
+
474
+ if current_module
475
+ current_module.members << alias_decl
476
+ else
477
+ result.declarations << alias_decl
478
+ end
479
+ else
480
+ # Create regular constant declaration
481
+ constant_decl = AST::Ruby::Declarations::ConstantDecl.new(
482
+ buffer,
483
+ constant_name,
484
+ node,
485
+ leading_block,
486
+ type_annotation
487
+ )
488
+
489
+ # Insert the constant declaration appropriately
490
+ if current_module
491
+ current_module.members << constant_decl
492
+ else
493
+ result.declarations << constant_decl
494
+ end
495
+ end
496
+ end
497
+
498
+ def insert_declaration(decl)
499
+ if current_module
500
+ current_module.members << decl
501
+ else
502
+ result.declarations << decl
503
+ end
504
+ end
505
+
506
+ def report_unused_annotation(*annotations)
507
+ annotations.each do |annotation|
508
+ case annotation
509
+ when AST::Ruby::CommentBlock::AnnotationSyntaxError
510
+ diagnostics << Diagnostic::AnnotationSyntaxError.new(
511
+ annotation.location, "Syntax error: " + annotation.error.error_message
512
+ )
513
+ when AST::Ruby::Annotations::Base
514
+ diagnostics << Diagnostic::UnusedInlineAnnotation.new(
515
+ annotation.location, "Unused inline rbs annotation"
516
+ )
517
+ end
518
+ end
519
+ end
520
+
521
+ def report_unused_block(block)
522
+ return unless block.leading?
523
+
524
+ block.each_paragraph([]) do |paragraph|
525
+ case paragraph
526
+ when Location
527
+ # noop
528
+ else
529
+ report_unused_annotation(paragraph)
530
+ end
531
+ end
532
+ end
533
+
534
+ def parse_super_class(super_class_expr, inheritance_operator_loc)
535
+ # Check if the superclass is a constant
536
+ unless super_class_name = constant_as_type_name(super_class_expr)
537
+ diagnostics << Diagnostic::NonConstantSuperClassName.new(
538
+ rbs_location(super_class_expr.location),
539
+ "Super class name must be a constant"
540
+ )
541
+ return nil
542
+ end
543
+
544
+ # Look for type application annotation in trailing comments
545
+ # For example: class StringArray < Array #[String]
546
+ trailing_block = comments.trailing_block!(super_class_expr.location)
547
+ type_annotation = nil
548
+
549
+ if trailing_block
550
+ case annotation = trailing_block.trailing_annotation([])
551
+ when AST::Ruby::Annotations::TypeApplicationAnnotation
552
+ type_annotation = annotation
553
+ else
554
+ report_unused_annotation(annotation)
555
+ end
556
+ end
557
+
558
+ # Create SuperClass object
559
+ AST::Ruby::Declarations::ClassDecl::SuperClass.new(
560
+ rbs_location(super_class_expr.location),
561
+ rbs_location(inheritance_operator_loc),
562
+ super_class_name,
563
+ type_annotation
564
+ )
565
+ end
566
+ end
567
+ end
568
+ end
@@ -28,6 +28,14 @@ module RBS
28
28
 
29
29
  WithChildren = self
30
30
 
31
+ def start_pos
32
+ buffer.absolute_position(_start_pos) || raise
33
+ end
34
+
35
+ def end_pos
36
+ buffer.absolute_position(_end_pos) || raise
37
+ end
38
+
31
39
  def name
32
40
  buffer.name
33
41
  end
@@ -49,11 +57,11 @@ module RBS
49
57
  end
50
58
 
51
59
  def start_loc
52
- @start_loc ||= buffer.pos_to_loc(start_pos)
60
+ @start_loc ||= buffer.top_buffer.pos_to_loc(start_pos)
53
61
  end
54
62
 
55
63
  def end_loc
56
- @end_loc ||= buffer.pos_to_loc(end_pos)
64
+ @end_loc ||= buffer.top_buffer.pos_to_loc(end_pos)
57
65
  end
58
66
 
59
67
  def range
@@ -61,7 +69,7 @@ module RBS
61
69
  end
62
70
 
63
71
  def source
64
- @source ||= (buffer.content[range] || raise)
72
+ @source ||= (buffer.top_buffer.content[range] || raise)
65
73
  end
66
74
 
67
75
  def to_s
@@ -75,7 +83,7 @@ module RBS
75
83
  other.end_pos == end_pos
76
84
  end
77
85
 
78
- def to_json(state = _ = nil)
86
+ def to_json(state = nil)
79
87
  {
80
88
  start: {
81
89
  line: start_line,
@@ -134,5 +142,29 @@ module RBS
134
142
  def required_key?(name)
135
143
  _required_keys.include?(name)
136
144
  end
145
+
146
+ def local_location
147
+ loc = Location.new(buffer.detach, _start_pos, _end_pos)
148
+
149
+ each_optional_key do |key|
150
+ value = self[key]
151
+ if value
152
+ loc.add_optional_child(key, value._start_pos...value._end_pos)
153
+ else
154
+ loc.add_optional_child(key, nil)
155
+ end
156
+ end
157
+
158
+ each_required_key do |key|
159
+ value = self[key] or raise
160
+ loc.add_required_child(key, value._start_pos...value._end_pos)
161
+ end
162
+
163
+ loc #: self
164
+ end
165
+
166
+ def local_source
167
+ local_location.source
168
+ end
137
169
  end
138
170
  end
data/lib/rbs/locator.rb CHANGED
@@ -177,6 +177,10 @@ module RBS
177
177
  find_in_type(pos, type: upper_bound, array: array) and return true
178
178
  end
179
179
 
180
+ if lower_bound = type_param.lower_bound_type
181
+ find_in_type(pos, type: lower_bound, array: array) and return true
182
+ end
183
+
180
184
  if default_type = type_param.default_type
181
185
  find_in_type(pos, type: default_type, array: array) and return true
182
186
  end
@@ -234,7 +238,7 @@ module RBS
234
238
 
235
239
  def test_loc(pos, location:)
236
240
  if location
237
- location.range === pos
241
+ location.start_pos <= pos && pos <= location.end_pos
238
242
  else
239
243
  false
240
244
  end
@@ -21,7 +21,7 @@ module RBS
21
21
  other.block == block
22
22
  end
23
23
 
24
- def to_json(state = _ = nil)
24
+ def to_json(state = nil)
25
25
  {
26
26
  type_params: type_params,
27
27
  type: type,
@@ -129,11 +129,13 @@ module RBS
129
129
  end
130
130
 
131
131
  def with_nonreturn_void?
132
- if type.with_nonreturn_void?
132
+ if type.with_nonreturn_void? # steep:ignore DeprecatedReference
133
133
  true
134
134
  else
135
135
  if block = block()
136
- block.type.with_nonreturn_void? || block.self_type&.with_nonreturn_void? || false
136
+ block.type.with_nonreturn_void? || # steep:ignore DeprecatedReference
137
+ block.self_type&.with_nonreturn_void? || # steep:ignore DeprecatedReference
138
+ false
137
139
  else
138
140
  false
139
141
  end