rbs 4.0.0.dev.4 → 4.0.0

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 (281) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +14 -14
  3. data/.github/workflows/bundle-update.yml +60 -0
  4. data/.github/workflows/c-check.yml +18 -11
  5. data/.github/workflows/comments.yml +5 -3
  6. data/.github/workflows/dependabot.yml +2 -2
  7. data/.github/workflows/ruby.yml +27 -34
  8. data/.github/workflows/rust.yml +95 -0
  9. data/.github/workflows/typecheck.yml +2 -2
  10. data/.github/workflows/windows.yml +2 -2
  11. data/.rubocop.yml +1 -1
  12. data/CHANGELOG.md +323 -0
  13. data/README.md +1 -1
  14. data/Rakefile +43 -33
  15. data/Steepfile +1 -0
  16. data/config.yml +426 -24
  17. data/core/array.rbs +307 -227
  18. data/core/basic_object.rbs +9 -8
  19. data/core/binding.rbs +0 -2
  20. data/core/builtin.rbs +2 -2
  21. data/core/class.rbs +6 -5
  22. data/core/comparable.rbs +55 -34
  23. data/core/complex.rbs +104 -78
  24. data/core/dir.rbs +61 -49
  25. data/core/encoding.rbs +12 -15
  26. data/core/enumerable.rbs +179 -87
  27. data/core/enumerator/arithmetic_sequence.rbs +70 -0
  28. data/core/enumerator.rbs +65 -2
  29. data/core/errno.rbs +11 -2
  30. data/core/errors.rbs +58 -29
  31. data/core/exception.rbs +13 -13
  32. data/core/fiber.rbs +74 -54
  33. data/core/file.rbs +280 -177
  34. data/core/file_test.rbs +3 -3
  35. data/core/float.rbs +257 -92
  36. data/core/gc.rbs +425 -281
  37. data/core/hash.rbs +1045 -739
  38. data/core/integer.rbs +135 -137
  39. data/core/io/buffer.rbs +53 -42
  40. data/core/io/wait.rbs +13 -35
  41. data/core/io.rbs +192 -144
  42. data/core/kernel.rbs +216 -155
  43. data/core/marshal.rbs +4 -4
  44. data/core/match_data.rbs +15 -13
  45. data/core/math.rbs +107 -66
  46. data/core/method.rbs +69 -33
  47. data/core/module.rbs +244 -106
  48. data/core/nil_class.rbs +7 -6
  49. data/core/numeric.rbs +74 -63
  50. data/core/object.rbs +9 -11
  51. data/core/object_space.rbs +30 -23
  52. data/core/pathname.rbs +1322 -0
  53. data/core/proc.rbs +95 -58
  54. data/core/process.rbs +222 -202
  55. data/core/ractor.rbs +371 -515
  56. data/core/random.rbs +21 -3
  57. data/core/range.rbs +159 -57
  58. data/core/rational.rbs +60 -89
  59. data/core/rbs/unnamed/argf.rbs +60 -53
  60. data/core/rbs/unnamed/env_class.rbs +19 -14
  61. data/core/rbs/unnamed/main_class.rbs +123 -0
  62. data/core/rbs/unnamed/random.rbs +11 -118
  63. data/core/regexp.rbs +258 -214
  64. data/core/ruby.rbs +53 -0
  65. data/core/ruby_vm.rbs +38 -34
  66. data/core/rubygems/config_file.rbs +5 -5
  67. data/core/rubygems/errors.rbs +4 -71
  68. data/core/rubygems/requirement.rbs +5 -5
  69. data/core/rubygems/rubygems.rbs +16 -82
  70. data/core/rubygems/version.rbs +2 -3
  71. data/core/set.rbs +490 -360
  72. data/core/signal.rbs +26 -16
  73. data/core/string.rbs +3234 -1285
  74. data/core/struct.rbs +27 -26
  75. data/core/symbol.rbs +41 -34
  76. data/core/thread.rbs +135 -67
  77. data/core/time.rbs +81 -50
  78. data/core/trace_point.rbs +41 -35
  79. data/core/true_class.rbs +2 -2
  80. data/core/unbound_method.rbs +24 -16
  81. data/core/warning.rbs +7 -7
  82. data/docs/aliases.md +79 -0
  83. data/docs/collection.md +3 -3
  84. data/docs/config.md +171 -0
  85. data/docs/encoding.md +56 -0
  86. data/docs/gem.md +0 -1
  87. data/docs/inline.md +576 -0
  88. data/docs/sigs.md +3 -3
  89. data/docs/syntax.md +46 -16
  90. data/docs/type_fingerprint.md +21 -0
  91. data/exe/rbs +1 -1
  92. data/ext/rbs_extension/ast_translation.c +544 -116
  93. data/ext/rbs_extension/ast_translation.h +3 -0
  94. data/ext/rbs_extension/class_constants.c +16 -2
  95. data/ext/rbs_extension/class_constants.h +8 -0
  96. data/ext/rbs_extension/extconf.rb +5 -1
  97. data/ext/rbs_extension/legacy_location.c +33 -56
  98. data/ext/rbs_extension/legacy_location.h +37 -0
  99. data/ext/rbs_extension/main.c +44 -35
  100. data/include/rbs/ast.h +448 -173
  101. data/include/rbs/defines.h +27 -0
  102. data/include/rbs/lexer.h +30 -11
  103. data/include/rbs/location.h +25 -44
  104. data/include/rbs/parser.h +6 -6
  105. data/include/rbs/string.h +0 -2
  106. data/include/rbs/util/rbs_allocator.h +34 -13
  107. data/include/rbs/util/rbs_assert.h +12 -1
  108. data/include/rbs/util/rbs_constant_pool.h +0 -3
  109. data/include/rbs/util/rbs_encoding.h +2 -0
  110. data/include/rbs/util/rbs_unescape.h +2 -1
  111. data/include/rbs.h +8 -0
  112. data/lib/rbs/ast/annotation.rb +1 -1
  113. data/lib/rbs/ast/comment.rb +1 -1
  114. data/lib/rbs/ast/declarations.rb +10 -10
  115. data/lib/rbs/ast/members.rb +14 -14
  116. data/lib/rbs/ast/ruby/annotations.rb +293 -3
  117. data/lib/rbs/ast/ruby/comment_block.rb +24 -0
  118. data/lib/rbs/ast/ruby/declarations.rb +198 -3
  119. data/lib/rbs/ast/ruby/helpers/constant_helper.rb +4 -0
  120. data/lib/rbs/ast/ruby/members.rb +532 -22
  121. data/lib/rbs/ast/type_param.rb +24 -4
  122. data/lib/rbs/buffer.rb +20 -15
  123. data/lib/rbs/cli/diff.rb +16 -15
  124. data/lib/rbs/cli/validate.rb +38 -106
  125. data/lib/rbs/cli.rb +52 -19
  126. data/lib/rbs/collection/config/lockfile_generator.rb +14 -2
  127. data/lib/rbs/collection/sources/git.rb +1 -0
  128. data/lib/rbs/definition.rb +1 -1
  129. data/lib/rbs/definition_builder/ancestor_builder.rb +62 -9
  130. data/lib/rbs/definition_builder/method_builder.rb +20 -0
  131. data/lib/rbs/definition_builder.rb +147 -25
  132. data/lib/rbs/diff.rb +7 -1
  133. data/lib/rbs/environment.rb +227 -74
  134. data/lib/rbs/environment_loader.rb +0 -6
  135. data/lib/rbs/errors.rb +27 -18
  136. data/lib/rbs/inline_parser.rb +342 -6
  137. data/lib/rbs/location_aux.rb +1 -1
  138. data/lib/rbs/locator.rb +5 -1
  139. data/lib/rbs/method_type.rb +5 -3
  140. data/lib/rbs/parser_aux.rb +20 -7
  141. data/lib/rbs/prototype/helpers.rb +57 -0
  142. data/lib/rbs/prototype/rb.rb +3 -28
  143. data/lib/rbs/prototype/rbi.rb +3 -20
  144. data/lib/rbs/prototype/runtime.rb +8 -0
  145. data/lib/rbs/resolver/constant_resolver.rb +2 -2
  146. data/lib/rbs/resolver/type_name_resolver.rb +116 -38
  147. data/lib/rbs/subtractor.rb +3 -1
  148. data/lib/rbs/test/type_check.rb +19 -2
  149. data/lib/rbs/type_name.rb +1 -1
  150. data/lib/rbs/types.rb +88 -78
  151. data/lib/rbs/unit_test/type_assertions.rb +35 -8
  152. data/lib/rbs/validator.rb +2 -2
  153. data/lib/rbs/version.rb +1 -1
  154. data/lib/rbs.rb +1 -2
  155. data/lib/rdoc/discover.rb +1 -1
  156. data/lib/rdoc_plugin/parser.rb +1 -1
  157. data/rbs.gemspec +4 -3
  158. data/rust/.gitignore +1 -0
  159. data/rust/Cargo.lock +378 -0
  160. data/rust/Cargo.toml +7 -0
  161. data/rust/ruby-rbs/Cargo.toml +22 -0
  162. data/rust/ruby-rbs/build.rs +764 -0
  163. data/rust/ruby-rbs/examples/locations.rs +60 -0
  164. data/rust/ruby-rbs/src/lib.rs +1 -0
  165. data/rust/ruby-rbs/src/node/mod.rs +742 -0
  166. data/rust/ruby-rbs/tests/sanity.rs +47 -0
  167. data/rust/ruby-rbs/vendor/rbs/config.yml +1 -0
  168. data/rust/ruby-rbs-sys/Cargo.toml +23 -0
  169. data/rust/ruby-rbs-sys/build.rs +204 -0
  170. data/rust/ruby-rbs-sys/src/lib.rs +50 -0
  171. data/rust/ruby-rbs-sys/vendor/rbs/include +1 -0
  172. data/rust/ruby-rbs-sys/vendor/rbs/src +1 -0
  173. data/rust/ruby-rbs-sys/wrapper.h +1 -0
  174. data/schema/typeParam.json +17 -1
  175. data/sig/ast/ruby/annotations.rbs +315 -4
  176. data/sig/ast/ruby/comment_block.rbs +8 -0
  177. data/sig/ast/ruby/declarations.rbs +102 -4
  178. data/sig/ast/ruby/members.rbs +108 -2
  179. data/sig/cli/diff.rbs +5 -11
  180. data/sig/cli/validate.rbs +12 -8
  181. data/sig/cli.rbs +18 -18
  182. data/sig/definition.rbs +6 -1
  183. data/sig/definition_builder.rbs +2 -0
  184. data/sig/environment.rbs +70 -12
  185. data/sig/errors.rbs +13 -14
  186. data/sig/inline_parser.rbs +39 -2
  187. data/sig/locator.rbs +0 -2
  188. data/sig/manifest.yaml +0 -1
  189. data/sig/method_builder.rbs +3 -1
  190. data/sig/parser.rbs +31 -13
  191. data/sig/prototype/helpers.rbs +2 -0
  192. data/sig/resolver/type_name_resolver.rbs +35 -7
  193. data/sig/source.rbs +3 -3
  194. data/sig/type_param.rbs +13 -8
  195. data/sig/types.rbs +6 -7
  196. data/sig/unit_test/spy.rbs +0 -8
  197. data/sig/unit_test/type_assertions.rbs +11 -0
  198. data/src/ast.c +410 -153
  199. data/src/lexer.c +1392 -1313
  200. data/src/lexer.re +3 -0
  201. data/src/lexstate.c +58 -37
  202. data/src/location.c +8 -48
  203. data/src/parser.c +977 -516
  204. data/src/string.c +0 -48
  205. data/src/util/rbs_allocator.c +89 -71
  206. data/src/util/rbs_assert.c +1 -1
  207. data/src/util/rbs_buffer.c +2 -2
  208. data/src/util/rbs_constant_pool.c +10 -14
  209. data/src/util/rbs_encoding.c +4 -8
  210. data/src/util/rbs_unescape.c +56 -20
  211. data/stdlib/bigdecimal/0/big_decimal.rbs +116 -98
  212. data/stdlib/bigdecimal-math/0/big_math.rbs +169 -8
  213. data/stdlib/cgi/0/core.rbs +9 -393
  214. data/stdlib/cgi/0/manifest.yaml +1 -0
  215. data/stdlib/cgi-escape/0/escape.rbs +171 -0
  216. data/stdlib/coverage/0/coverage.rbs +7 -4
  217. data/stdlib/date/0/date.rbs +92 -79
  218. data/stdlib/date/0/date_time.rbs +25 -24
  219. data/stdlib/delegate/0/delegator.rbs +10 -7
  220. data/stdlib/did_you_mean/0/did_you_mean.rbs +17 -16
  221. data/stdlib/digest/0/digest.rbs +110 -0
  222. data/stdlib/erb/0/erb.rbs +748 -347
  223. data/stdlib/etc/0/etc.rbs +55 -50
  224. data/stdlib/fileutils/0/fileutils.rbs +158 -139
  225. data/stdlib/forwardable/0/forwardable.rbs +13 -10
  226. data/stdlib/io-console/0/io-console.rbs +2 -2
  227. data/stdlib/json/0/json.rbs +217 -136
  228. data/stdlib/monitor/0/monitor.rbs +3 -3
  229. data/stdlib/net-http/0/net-http.rbs +162 -134
  230. data/stdlib/objspace/0/objspace.rbs +17 -34
  231. data/stdlib/open-uri/0/open-uri.rbs +48 -8
  232. data/stdlib/open3/0/open3.rbs +469 -10
  233. data/stdlib/openssl/0/openssl.rbs +475 -357
  234. data/stdlib/optparse/0/optparse.rbs +26 -17
  235. data/stdlib/pathname/0/pathname.rbs +11 -1381
  236. data/stdlib/pp/0/pp.rbs +9 -8
  237. data/stdlib/prettyprint/0/prettyprint.rbs +7 -7
  238. data/stdlib/pstore/0/pstore.rbs +35 -30
  239. data/stdlib/psych/0/psych.rbs +65 -12
  240. data/stdlib/psych/0/store.rbs +2 -4
  241. data/stdlib/pty/0/pty.rbs +9 -6
  242. data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  243. data/stdlib/rdoc/0/code_object.rbs +2 -1
  244. data/stdlib/rdoc/0/parser.rbs +1 -1
  245. data/stdlib/rdoc/0/rdoc.rbs +1 -1
  246. data/stdlib/rdoc/0/store.rbs +1 -1
  247. data/stdlib/resolv/0/resolv.rbs +25 -68
  248. data/stdlib/ripper/0/ripper.rbs +22 -19
  249. data/stdlib/securerandom/0/manifest.yaml +2 -0
  250. data/stdlib/securerandom/0/securerandom.rbs +7 -20
  251. data/stdlib/shellwords/0/shellwords.rbs +2 -2
  252. data/stdlib/singleton/0/singleton.rbs +3 -0
  253. data/stdlib/socket/0/addrinfo.rbs +7 -7
  254. data/stdlib/socket/0/basic_socket.rbs +3 -3
  255. data/stdlib/socket/0/ip_socket.rbs +10 -8
  256. data/stdlib/socket/0/socket.rbs +23 -10
  257. data/stdlib/socket/0/tcp_server.rbs +1 -1
  258. data/stdlib/socket/0/tcp_socket.rbs +11 -3
  259. data/stdlib/socket/0/udp_socket.rbs +1 -1
  260. data/stdlib/socket/0/unix_server.rbs +1 -1
  261. data/stdlib/stringio/0/stringio.rbs +1177 -85
  262. data/stdlib/strscan/0/string_scanner.rbs +27 -25
  263. data/stdlib/tempfile/0/tempfile.rbs +25 -21
  264. data/stdlib/time/0/time.rbs +8 -6
  265. data/stdlib/timeout/0/timeout.rbs +63 -7
  266. data/stdlib/tsort/0/cyclic.rbs +3 -0
  267. data/stdlib/tsort/0/tsort.rbs +7 -6
  268. data/stdlib/uri/0/common.rbs +42 -20
  269. data/stdlib/uri/0/file.rbs +3 -3
  270. data/stdlib/uri/0/generic.rbs +26 -18
  271. data/stdlib/uri/0/http.rbs +2 -2
  272. data/stdlib/uri/0/ldap.rbs +2 -2
  273. data/stdlib/uri/0/mailto.rbs +3 -3
  274. data/stdlib/uri/0/rfc2396_parser.rbs +12 -12
  275. data/stdlib/zlib/0/deflate.rbs +4 -3
  276. data/stdlib/zlib/0/gzip_reader.rbs +6 -6
  277. data/stdlib/zlib/0/gzip_writer.rbs +14 -12
  278. data/stdlib/zlib/0/inflate.rbs +1 -1
  279. data/stdlib/zlib/0/need_dict.rbs +1 -1
  280. data/stdlib/zlib/0/zstream.rbs +1 -0
  281. metadata +50 -6
data/docs/inline.md ADDED
@@ -0,0 +1,576 @@
1
+ # Inline RBS Type Declaration
2
+
3
+ Inline RBS type declarations allow you to write type annotations directly in your Ruby source files using comments. Instead of maintaining separate `.rbs` files, you can keep your type information alongside your Ruby code, making it easier to keep types and implementation in sync.
4
+
5
+ The following example defines `Calculator` class and `add` instance method. The `@rbs` comment gives the type of the `add` method with the RBS method type syntax.
6
+
7
+ ```ruby
8
+ class Calculator
9
+ # @rbs (Integer, Integer) -> Integer
10
+ def add(a, b)
11
+ a + b
12
+ end
13
+ end
14
+ ```
15
+
16
+ ## Classes
17
+
18
+ Inline RBS supports class definitions from your Ruby code. When you define a class in Ruby, the library recognizes it and the corresponding class definition is generated in RBS.
19
+
20
+ ```ruby
21
+ class App
22
+ end
23
+ ```
24
+
25
+ The `::App` class is defined in RBS and you can use it as a type.
26
+
27
+ ### Non-constant class paths
28
+
29
+ Only classes with constant names are imported. Dynamic or non-constant class definitions are ignored:
30
+
31
+ ```ruby
32
+ # This class is imported
33
+ class MyClass
34
+ end
35
+
36
+ # This is ignored - dynamic class definition
37
+ MyClass = Class.new do
38
+ end
39
+
40
+ # This is also ignored - non-constant class name
41
+ object = Object
42
+ class object::MyClass
43
+ end
44
+ ```
45
+
46
+ ### Class Nesting
47
+
48
+ Nested classes work as expected:
49
+
50
+ ```ruby
51
+ class Client
52
+ class Error
53
+ end
54
+ end
55
+ ```
56
+
57
+ This creates the types `::Client` and `::Client::Error`.
58
+
59
+ ### Inheritance
60
+
61
+ Class declarations can have a super class.
62
+
63
+ ```ruby
64
+ class UsersController < ApplicationController
65
+ end
66
+ ```
67
+
68
+ The super class specification must be a constant.
69
+
70
+ The super class specification allows type applications.
71
+
72
+ ```ruby
73
+ class StringArray < Array #[String]
74
+ end
75
+ ```
76
+
77
+ ### Current Limitations
78
+
79
+ - Generic class definitions are not supported
80
+
81
+ ## Modules
82
+
83
+ Inline RBS supports module definitions from your Ruby code. When you define a module in Ruby, the library recognizes it and the corresponding module definition is generated in RBS.
84
+
85
+ ```ruby
86
+ module Helper
87
+ end
88
+ ```
89
+
90
+ The `::Helper` module is defined in RBS and you can use it as a type.
91
+
92
+ ### Non-constant module paths
93
+
94
+ Only modules with constant names are imported. Dynamic or non-constant module definitions are ignored:
95
+
96
+ ```ruby
97
+ # This module is imported
98
+ module MyModule
99
+ end
100
+
101
+ # This is ignored - dynamic module definition
102
+ MyModule = Module.new do
103
+ end
104
+
105
+ # This is also ignored - non-constant module name
106
+ object = Object
107
+ module object::MyModule
108
+ end
109
+ ```
110
+
111
+ ### Module Nesting
112
+
113
+ Nested modules work as expected:
114
+
115
+ ```ruby
116
+ module API
117
+ module V1
118
+ module Resources
119
+ end
120
+ end
121
+ end
122
+ ```
123
+
124
+ This creates the types `::API`, `::API::V1`, and `::API::V1::Resources`.
125
+
126
+ ### Current Limitations
127
+
128
+ - Generic module definitions are not supported
129
+ - Module self-type constraints are not supported
130
+
131
+ ## Method Definitions
132
+
133
+ Inline RBS supports methods defined using the `def` syntax in Ruby.
134
+
135
+ ```ruby
136
+ class Calculator
137
+ def add(x, y) = x+y
138
+ end
139
+ ```
140
+
141
+ It detects method definitions and allows you to add annotation comments to describe their types.
142
+
143
+ ### Unannotated method definition
144
+
145
+ Methods defined with `def` syntax are detected, but their inferred type depends on whether a super method exists.
146
+
147
+ If there is no super method, the inferred type is `(?) -> untyped` -- it accepts any arguments without type checking and returns an `untyped` object.
148
+
149
+ ```ruby
150
+ class Calculator
151
+ def add(x, y) = x+y
152
+ end
153
+ ```
154
+
155
+ The type of `Calculator#add` is `(?) -> untyped`.
156
+
157
+ If the super class (or an included module) defines a method with the same name, the unannotated method inherits that type.
158
+
159
+ ```ruby
160
+ class Calculator
161
+ # @rbs (Integer, Integer) -> Integer
162
+ def add(x, y) = x + y
163
+ end
164
+
165
+ class ScientificCalculator < Calculator
166
+ def add(x, y) = x + y # No annotation
167
+ end
168
+ ```
169
+
170
+ The type of `ScientificCalculator#add` is `(Integer, Integer) -> Integer`, inherited from `Calculator#add`.
171
+
172
+ ### Method type annotation syntax
173
+
174
+ You can define the type of the method using `@rbs` and `:` syntax.
175
+
176
+ ```ruby
177
+ class Calculator
178
+ # @rbs (Integer, Integer) -> Integer
179
+ def add(x, y) = x + y
180
+
181
+ #: (Integer, Integer) -> Integer
182
+ def subtract(x, y) = x - y
183
+ end
184
+ ```
185
+
186
+ The type of both methods is `(Integer, Integer) -> Integer` -- they take two `Integer` objects and return an `Integer` object.
187
+
188
+ Both syntaxes support method overloading:
189
+
190
+ ```ruby
191
+ class Calculator
192
+ # @rbs (Integer, Integer) -> Integer
193
+ # | (Float, Float) -> Float
194
+ def add(x, y) = x + y
195
+
196
+ #: (Integer, Integer) -> Integer
197
+ #: (Float, Float) -> Float
198
+ def subtract(x, y) = x - y
199
+ end
200
+ ```
201
+
202
+ The type of both methods is `(Integer, Integer) -> Integer | (Float, Float) -> Float`.
203
+
204
+ > [!NOTE]
205
+ > The `@rbs METHOD-TYPE` syntax allows overloads with the `|` operator, just like in RBS files.
206
+ > Multiple `: METHOD-TYPE` declarations are required for overloads.
207
+
208
+ The `@rbs METHOD-TYPE` syntax allows having `...` at the last part.
209
+
210
+ ```ruby
211
+ class Calculator2 < Calculator
212
+ # @rbs (Float, Float) -> Float | ...
213
+ def add(x, y) = x + y
214
+
215
+ # @rbs ...
216
+ def subtract(x, y) = super
217
+ end
218
+ ```
219
+
220
+ #### Doc-style syntax
221
+
222
+ The doc-style syntax allows annotating individual method parameters and the return type using `@rbs NAME: TYPE` comments.
223
+
224
+ The `@rbs PARAM_NAME: T` syntax declares the type of a parameter:
225
+
226
+ ```ruby
227
+ class Calculator
228
+ # @rbs x: Integer
229
+ # @rbs y: Integer
230
+ # @rbs a: String
231
+ # @rbs b: bool
232
+ def add(x, y = 1, a:, b: false)
233
+ pp(x:, y:, a:, b:)
234
+ end
235
+ end
236
+ ```
237
+
238
+ You can add a description after `--`:
239
+
240
+ ```ruby
241
+ class Calculator
242
+ # @rbs x: Integer -- required positional argument
243
+ # @rbs y: Integer -- optional positional argument
244
+ # @rbs a: String -- required keyword argument
245
+ # @rbs b: bool -- optional keyword argument
246
+ def add(x, y = 1, a:, b: false)
247
+ pp(x:, y:, a:, b:)
248
+ end
249
+ end
250
+ ```
251
+
252
+ Types of splat (`*a`) and double-splat (`**b`) parameters can be declared too.
253
+
254
+ ```ruby
255
+ class Foo
256
+ # @rbs *a: String -- The type of `a` is `Array[String]`
257
+ # @rbs **b: bool -- The type of `b` is `Hash[Symbol, bool]`
258
+ def foo(*a, **b)
259
+ end
260
+
261
+ # @rbs *: String -- Parameter name is optional
262
+ # @rbs **: bool -- Parameter name can be omitted in Ruby too
263
+ def bar(*a, **)
264
+ end
265
+ end
266
+ ```
267
+
268
+ Types of block parameter (`&block`) can be declared.
269
+
270
+ ```ruby
271
+ class Foo
272
+ # @rbs &block: () -> void
273
+ def foo(&block)
274
+ end
275
+
276
+ # @rbs &: () -> void -- The parameter name can be omitted
277
+ def bar(&)
278
+ end
279
+
280
+ # @rbs &block: ? () -> untyped -- The `?` prefix is for optional block
281
+ def baz(&block)
282
+ end
283
+ end
284
+ ```
285
+
286
+ The `@rbs return: T` syntax declares the return type of a method:
287
+
288
+ ```ruby
289
+ class Calculator
290
+ # @rbs return: String -- a human-readable representation
291
+ def to_s
292
+ "Calculator"
293
+ end
294
+ end
295
+ ```
296
+
297
+ Both can be combined:
298
+
299
+ ```ruby
300
+ class Calculator
301
+ # @rbs x: Integer -- the first operand
302
+ # @rbs y: Integer -- the second operand
303
+ # @rbs return: Integer
304
+ def add(x, y:)
305
+ x + y
306
+ end
307
+ end
308
+ ```
309
+
310
+ ### Current Limitations
311
+
312
+ - Class methods and singleton methods are not supported
313
+ - Only positional and keyword parameters are supported. Splat parameters (`*x`, `**y`) and block parameter (`&block`) are not supported yet.
314
+ - Method visibility declaration is not supported yet
315
+
316
+ ## Attributes
317
+
318
+ Inline RBS supports Ruby's attribute methods: `attr_reader`, `attr_writer`, and `attr_accessor`.
319
+
320
+ ```ruby
321
+ class Person
322
+ attr_reader :name #: String
323
+ attr_writer :age #: Integer
324
+ attr_accessor :email #: String?
325
+ end
326
+ ```
327
+
328
+ It detects these attribute declarations and generates the corresponding getter and setter methods.
329
+
330
+ The accessor methods and instance variables are defined.
331
+
332
+ ### Unannotated attributes
333
+
334
+ Attributes defined without type annotations are treated as `untyped`:
335
+
336
+ ```ruby
337
+ class Person
338
+ attr_reader :name
339
+ attr_writer :age
340
+ attr_accessor :email
341
+ end
342
+ ```
343
+
344
+ ### Type annotations for attributes
345
+
346
+ You can add type annotations to attributes using the `#:` syntax in trailing comments:
347
+
348
+ ```ruby
349
+ class Person
350
+ attr_reader :name #: String
351
+ attr_writer :age #: Integer
352
+ attr_accessor :email #: String?
353
+ end
354
+ ```
355
+
356
+ This generates the following typed methods:
357
+ - `name: () -> String`
358
+ - `age=: (Integer) -> Integer`
359
+ - `email: () -> String?` and `email=: (String?) -> String?`
360
+
361
+ ### Multiple attributes
362
+
363
+ When declaring multiple attributes in one line, the type annotation applies to all attributes:
364
+
365
+ ```ruby
366
+ class Person
367
+ attr_reader :first_name, :last_name #: String
368
+ attr_accessor :age, :height #: Integer
369
+ end
370
+ ```
371
+
372
+ All attributes in each declaration share the same type.
373
+
374
+ ### Non-symbol attribute names
375
+
376
+ Attribute names must be symbol literals.
377
+
378
+ ```ruby
379
+ class Person
380
+ attr_reader "name" #: String
381
+
382
+ age = :age
383
+ attr_writer age #: Integer
384
+ end
385
+ ```
386
+
387
+ The attribute definitions are ignored because the names are given by string literals and local variables.
388
+
389
+ ### Current Limitations
390
+
391
+ - Attribute visibility is not supported yet. All attributes are _public_
392
+
393
+ ## Mixin
394
+
395
+ Inline RBS supports Ruby's mixin methods: `include`, `extend`, and `prepend`.
396
+
397
+ ```ruby
398
+ module Printable
399
+ # @rbs () -> String
400
+ def to_print
401
+ to_s
402
+ end
403
+ end
404
+
405
+ class Document
406
+ include Printable
407
+ extend Enumerable #[String]
408
+ prepend Trackable
409
+ end
410
+ ```
411
+
412
+ It detects these mixin declarations and adds them to the class or module definition.
413
+
414
+ ### Basic mixin usage
415
+
416
+ Mixins work just like in regular RBS files:
417
+
418
+ ```ruby
419
+ module Helper
420
+ end
421
+
422
+ class MyClass
423
+ include Helper
424
+ extend Helper
425
+ prepend Helper
426
+ end
427
+ ```
428
+
429
+ ### Type arguments for generic modules
430
+
431
+ You can specify type arguments for generic modules using the `#[...]` syntax:
432
+
433
+ ```ruby
434
+ class TodoList
435
+ include Enumerable #[String]
436
+
437
+ # @rbs () { (String) -> void } -> void
438
+ def each(&block)
439
+ @items.each(&block)
440
+ end
441
+ end
442
+ ```
443
+
444
+ ### Module name requirements
445
+
446
+ Only constant module names are supported. Dynamic module references are not allowed:
447
+
448
+ ```ruby
449
+ class MyClass
450
+ include Helper # ✓ Works - constant name
451
+
452
+ mod = Helper
453
+ include mod # ✗ Ignored - non-constant module reference
454
+
455
+ include Helper.new # ✗ Ignored - not a simple constant
456
+ end
457
+ ```
458
+
459
+ ### Module name resolution
460
+
461
+ The module name resolution is based on the nesting of the class/module definitions, unlike Ruby.
462
+
463
+ Modules accessible through ancestors (super-class/included modules) are not supported.
464
+
465
+ ### Current Limitations
466
+
467
+ - Only single module arguments are supported (no `include A, B` syntax)
468
+ - Module names must be constants
469
+
470
+ ## Instance Variables
471
+
472
+ Inline RBS declaration allows defining instance variables.
473
+
474
+ ```ruby
475
+ class Person
476
+ # @rbs @name: String
477
+ # @rbs @age: Integer? --
478
+ # how old is the person?
479
+ # `nil` means it's unspecified.
480
+
481
+ # @rbs (String name, Integer? age) -> void
482
+ def initialize(name, age)
483
+ @name = name
484
+ @age = age
485
+ end
486
+ end
487
+ ```
488
+
489
+ The `@rbs @VAR-NAME: TYPE` syntax enclosed in `class`/`module` syntax declares instance variables.
490
+ You can add the documentation of the variable followed by two hyphones (`--`).
491
+
492
+ Instance variable declarations must be under the `class`/`module` syntax, and they are ignored if written inside method definitions.
493
+
494
+ ### Current Limitations
495
+
496
+ - Only instance variables of class/module instances are allowed
497
+
498
+ ## Constants
499
+
500
+ Constants are supported by inline RBS declaration.
501
+
502
+ ```ruby
503
+ Foo = 123
504
+
505
+ module Bar
506
+ Baz = [1, ""] #: [Integer, String]
507
+ end
508
+
509
+ # Version of the library
510
+ #
511
+ VERSION = "1.2.3".freeze #: String
512
+ ```
513
+
514
+ ### Type Inference for Literal Constants
515
+
516
+ The types of constants may be automatically inferred when the right-hand side consists of literals:
517
+
518
+ - **Integers**: `COUNT = 42` → `Integer`
519
+ - **Floats**: `RATE = 3.14` → `Float`
520
+ - **Booleans**: `ENABLED = true` → `bool`
521
+ - **Strings**: `NAME = "test"` → `String`
522
+ - **Symbols**: `STATUS = :ready` → `:ready`
523
+
524
+ ```ruby
525
+ MAX_SIZE = 100 # Inferred as Integer
526
+ PI = 3.14159 # Inferred as Float
527
+ DEBUG = false # Inferred as bool
528
+ APP_NAME = "MyApp" # Inferred as String
529
+ DEFAULT_MODE = :strict # Inferred as :strict
530
+ ```
531
+
532
+ ### Explicit Type Annotations
533
+
534
+ For more complex types or when you want to override inference, use the `#:` syntax:
535
+
536
+ ```ruby
537
+ ITEMS = [1, "hello"] #: [Integer, String]
538
+ CONFIG = { name: "app", version: 1 } #: { name: String, version: Integer }
539
+ CALLBACK = -> { puts "done" } #: ^() -> void
540
+ ```
541
+
542
+ ### Documentation Comments
543
+
544
+ Comments above constant declarations become part of the constant's documentation:
545
+
546
+ ```ruby
547
+ # The maximum number of retries allowed
548
+ # before giving up on the operation
549
+ MAX_RETRIES = 3
550
+
551
+ # Application configuration loaded from environment
552
+ #
553
+ # This hash contains all the runtime configuration
554
+ # settings for the application.
555
+ CONFIG = load_config() #: Hash[String, untyped]
556
+ ```
557
+
558
+ ## Class/module Aliases
559
+
560
+ Class and module aliases can be defined by assigning existing classes or modules to constants using the `#: class-alias` or `#: module-alias` syntax.
561
+
562
+ ```ruby
563
+ MyObject = Object #: class-alias
564
+
565
+ MyKernel = Kernel #: module-alias
566
+ ```
567
+
568
+ This creates new type names that refer to the same class or module as the original.
569
+
570
+ The annotations can have optional type name to specify the class/module name, for the case it cannot be infered through the right-hand-side of the constant declaration.
571
+
572
+ ```ruby
573
+ MyObject = object #: class-alias Object
574
+
575
+ MyKernel = kernel #: module-alias Kernel
576
+ ```
data/docs/sigs.md CHANGED
@@ -131,10 +131,10 @@ You may need to specify `-r` or `-I` to load signatures.
131
131
  The default is `-I sig`.
132
132
 
133
133
  ```shell
134
- RBS_TEST_OPT='-r pathname -I sig'
134
+ RBS_TEST_OPT='-r logger -I sig'
135
135
  ```
136
136
 
137
- Replacing `pathname` with the `stdlib` you want to include. For example, if you need to load `Set` and `BigDecimal` in `stdlib`, you would need to have `RBS_TEST_OPT='-r set -r bigdecimal -I sig'`
137
+ Replacing `logger` with the `stdlib` you want to include. For example, if you need to load `Set` and `BigDecimal` in `stdlib`, you would need to have `RBS_TEST_OPT='-r set -r bigdecimal -I sig'`
138
138
 
139
139
  `RBS_TEST_LOGLEVEL` can be used to configure log level. Defaults to `info`.
140
140
 
@@ -148,7 +148,7 @@ So, a typical command line to start the test would look like the following:
148
148
  $ RBS_TEST_LOGLEVEL=error \
149
149
  RBS_TEST_TARGET='Kaigi::*' \
150
150
  RBS_TEST_SKIP='Kaigi::MonkeyPatch' \
151
- RBS_TEST_OPT='-rset -rpathname -Isig -Iprivate' \
151
+ RBS_TEST_OPT='-rlogger -Isig -Iprivate' \
152
152
  RBS_TEST_RAISE=true \
153
153
  RUBYOPT='-rbundler/setup -rrbs/test/setup' \
154
154
  bundle exec rake test
data/docs/syntax.md CHANGED
@@ -3,17 +3,17 @@
3
3
  ## Types
4
4
 
5
5
  ```markdown
6
- _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
- | _interface-name_ _type-arguments_ (Interface type)
8
- | _alias-name_ _type-arguments_ (Alias type)
9
- | `singleton(` _class-name_ `)` (Class singleton type)
10
- | _literal_ (Literal type)
11
- | _type_ `|` _type_ (Union type)
12
- | _type_ `&` _type_ (Intersection type)
13
- | _type_ `?` (Optional type)
14
- | `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
15
- | `[]` | `[` _type_ `,` etc. `]` (Tuples)
16
- | _type-variable_ (Type variables)
6
+ _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
+ | _interface-name_ _type-arguments_ (Interface type)
8
+ | _alias-name_ _type-arguments_ (Alias type)
9
+ | `singleton(` _class-name_ `)` _type-arguments_ (Class singleton type)
10
+ | _literal_ (Literal type)
11
+ | _type_ `|` _type_ (Union type)
12
+ | _type_ `&` _type_ (Intersection type)
13
+ | _type_ `?` (Optional type)
14
+ | `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
15
+ | `[]` | `[` _type_ `,` etc. `]` (Tuples)
16
+ | _type-variable_ (Type variables)
17
17
  | `self`
18
18
  | `instance`
19
19
  | `class`
@@ -85,7 +85,8 @@ Class singleton type denotes _the type of a singleton object of a class_.
85
85
 
86
86
  ```rbs
87
87
  singleton(String)
88
- singleton(::Hash) # Class singleton type cannot be parametrized.
88
+ singleton(::Hash) # Class singleton type
89
+ singleton(Array)[String] # Class singleton type with type application
89
90
  ```
90
91
 
91
92
  ### Literal type
@@ -650,7 +651,7 @@ _module-type-parameters_ ::= #
650
651
 
651
652
  Class declaration can have type parameters and superclass. When you omit superclass, `::Object` is assumed.
652
653
 
653
- * Super class arguments and generic class upperbounds are not *classish-context* nor *self-context*
654
+ * Super class arguments and generic class bounds are not *classish-context* nor *self-context*
654
655
 
655
656
  ### Module declaration
656
657
 
@@ -668,7 +669,7 @@ end
668
669
 
669
670
  The `Enumerable` module above requires `each` method for enumerating objects.
670
671
 
671
- * Self type arguments and generic class upperbounds are not *classish-context* nor *self-context*
672
+ * Self type arguments and generic class bounds are not *classish-context* nor *self-context*
672
673
 
673
674
  ### Class/module alias declaration
674
675
 
@@ -764,7 +765,8 @@ _module-type-parameter_ ::= _generics-unchecked_ _generics-variance_ _type-varia
764
765
  _method-type-param_ ::= _type-variable_ _generics-bound_
765
766
 
766
767
  _generics-bound_ ::= (No type bound)
767
- | `<` _type_ (The generics parameter is bounded)
768
+ | `<` _type_ (The generics parameter has an upper bound)
769
+ | '>' _type_ (The generics parameter has a lower bound)
768
770
 
769
771
  _default-type_ ::= (No default type)
770
772
  | `=` _type_ (The generics parameter has default type)
@@ -777,6 +779,9 @@ _generics-unchecked_ ::= (Empty)
777
779
  | `unchecked` (Skips variance annotation validation)
778
780
  ```
779
781
 
782
+ A type parameter can have both upper and lower bounds, which can be specified in either order:
783
+ `[T < UpperBound > LowerBound]` or `[T > LowerBound < UpperBound]`.
784
+
780
785
  RBS allows class/module/interface/type alias definitions and methods to be generic.
781
786
 
782
787
  ```rbs
@@ -834,13 +839,38 @@ class PrettyPrint[T < _Output]
834
839
  end
835
840
  ```
836
841
 
837
- If a type parameter has an upper bound, the type parameter must be instantiated with types that is a subtype of the upper bound.
842
+ If a type parameter has an upper bound, the type parameter must be instantiated with types that are a subtype of the upper bound.
838
843
 
839
844
  ```rbs
840
845
  type str_printer = PrettyPrint[String] # OK
841
846
  type int_printer = PrettyPrint[Integer] # Type error
842
847
  ```
843
848
 
849
+ If a type parameter has a lower bound, the type parameter must be instantiated with types that are a supertype of the lower bound.
850
+
851
+ ```rbs
852
+ class PrettyPrint[T > Numeric]
853
+ end
854
+
855
+ type obj_printer = PrettyPrint[Object] # OK
856
+ type int_printer = PrettyPrint[Integer] # Type error
857
+ ```
858
+
859
+ A type parameter can have both an upper and a lower bound, and these bounds can be specified in any order.
860
+
861
+ ```rbs
862
+ class FlexibleProcessor[T > Integer < Numeric]
863
+ # This class processes types T that are supertypes of Integer but also subtypes of Numeric.
864
+ # This includes Integer, Rational, Complex, Float, and Numeric itself.
865
+ def calculate: (T) -> T
866
+ end
867
+
868
+ type int_processor = FlexibleProcessor[Integer] # OK (Integer > Integer and Integer < Numeric)
869
+ type num_processor = FlexibleProcessor[Numeric] # OK (Numeric > Integer and Numeric < Numeric)
870
+ type obj_processor = FlexibleProcessor[Object] # Type error (Object is not < Numeric)
871
+ type str_processor = FlexibleProcessor[String] # Type error (String is not > Integer)
872
+ ```
873
+
844
874
  The generics type parameter of modules, classes, interfaces, or type aliases can have a default type.
845
875
 
846
876
  ```rbs