rbs 4.1.0.pre.2-java → 4.1.1.dev.1-java

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +37 -0
  3. data/.github/dependabot.yml +1 -1
  4. data/.github/workflows/bundle-update.yml +2 -2
  5. data/.github/workflows/c-check.yml +11 -6
  6. data/.github/workflows/comments.yml +2 -2
  7. data/.github/workflows/dependabot.yml +1 -1
  8. data/.github/workflows/jruby.yml +15 -3
  9. data/.github/workflows/release-gems.yml +164 -0
  10. data/.github/workflows/ruby.yml +4 -4
  11. data/.github/workflows/rust.yml +10 -8
  12. data/.github/workflows/truffleruby.yml +1 -1
  13. data/.github/workflows/typecheck.yml +2 -2
  14. data/.github/workflows/wasm.yml +4 -2
  15. data/.github/workflows/windows.yml +2 -2
  16. data/.gitignore +3 -2
  17. data/CHANGELOG.md +88 -0
  18. data/Dockerfile.jruby +53 -0
  19. data/Rakefile +340 -60
  20. data/Steepfile +2 -0
  21. data/config.yml +2 -0
  22. data/core/array.rbs +228 -165
  23. data/core/float.rbs +0 -24
  24. data/core/match_data.rbs +1 -1
  25. data/core/pathname.rbs +0 -10
  26. data/core/ractor.rbs +0 -10
  27. data/core/rubygems/errors.rbs +4 -1
  28. data/core/rubygems/requirement.rbs +0 -10
  29. data/core/rubygems/rubygems.rbs +4 -1
  30. data/core/rubygems/specification.rbs +8 -0
  31. data/core/rubygems/version.rbs +0 -160
  32. data/core/thread.rbs +3 -8
  33. data/docs/CONTRIBUTING.md +1 -1
  34. data/docs/release.md +151 -0
  35. data/ext/rbs_extension/ast_translation.c +2 -2
  36. data/ext/rbs_extension/legacy_location.c +11 -6
  37. data/include/rbs/ast.h +4 -4
  38. data/lib/rbs/parser_aux.rb +4 -2
  39. data/lib/rbs/prototype/rbi.rb +193 -25
  40. data/lib/rbs/version.rb +1 -1
  41. data/lib/rbs/wasm/rbs_parser.wasm +0 -0
  42. data/lib/rbs/wasm/runtime.rb +7 -28
  43. data/lib/rbs_jars.rb +39 -0
  44. data/lib/rdoc_plugin/parser.rb +5 -0
  45. data/rbs.gemspec +16 -3
  46. data/sig/prototype/rbi.rbs +33 -4
  47. data/src/ast.c +2 -2
  48. data/src/lexer.c +97 -93
  49. data/src/lexer.re +1 -1
  50. data/src/lexstate.c +6 -2
  51. data/src/parser.c +6 -3
  52. data/src/util/rbs_allocator.c +13 -4
  53. data/stdlib/delegate/0/delegator.rbs +2 -1
  54. data/stdlib/digest/0/digest.rbs +10 -4
  55. data/stdlib/erb/0/erb.rbs +1 -1
  56. data/stdlib/ipaddr/0/ipaddr.rbs +0 -5
  57. data/stdlib/monitor/0/monitor.rbs +2 -2
  58. data/stdlib/openssl/0/openssl.rbs +39 -33
  59. data/stdlib/tempfile/0/manifest.yaml +3 -0
  60. data/stdlib/timeout/0/timeout.rbs +0 -5
  61. data/stdlib/uri/0/generic.rbs +0 -5
  62. data/stdlib/zlib/0/zstream.rbs +0 -1
  63. data/wasm/README.md +4 -3
  64. data/wasm/rbs_wasm.c +12 -0
  65. metadata +25 -14
  66. data/.github/workflows/milestone.yml +0 -83
  67. data/lib/rbs/wasm/jars/asm-analysis.jar +0 -0
  68. data/lib/rbs/wasm/jars/asm-commons.jar +0 -0
  69. data/lib/rbs/wasm/jars/asm-tree.jar +0 -0
  70. data/lib/rbs/wasm/jars/asm-util.jar +0 -0
  71. data/lib/rbs/wasm/jars/asm.jar +0 -0
  72. data/lib/rbs/wasm/jars/compiler.jar +0 -0
  73. data/lib/rbs/wasm/jars/log.jar +0 -0
  74. data/lib/rbs/wasm/jars/runtime.jar +0 -0
  75. data/lib/rbs/wasm/jars/wasi.jar +0 -0
  76. data/lib/rbs/wasm/jars/wasm.jar +0 -0
data/core/float.rbs CHANGED
@@ -1222,8 +1222,6 @@ Float::EPSILON: Float
1222
1222
  #
1223
1223
  Float::INFINITY: Float
1224
1224
 
1225
- Float::Infinity: Float
1226
-
1227
1225
  # <!-- rdoc-file=numeric.c -->
1228
1226
  # The number of base digits for the `double` data type.
1229
1227
  #
@@ -1292,25 +1290,3 @@ Float::NAN: Float
1292
1290
  # decimal.
1293
1291
  #
1294
1292
  Float::RADIX: Integer
1295
-
1296
- # Deprecated, do not use.
1297
- #
1298
- # Represents the rounding mode for floating point addition at the start time.
1299
- #
1300
- # Usually defaults to 1, rounding to the nearest number.
1301
- #
1302
- # Other modes include:
1303
- #
1304
- # -1
1305
- # : Indeterminable
1306
- # 0
1307
- # : Rounding towards zero
1308
- # 1
1309
- # : Rounding to the nearest number
1310
- # 2
1311
- # : Rounding towards positive infinity
1312
- # 3
1313
- # : Rounding towards negative infinity
1314
- #
1315
- #
1316
- Float::ROUNDS: Integer
data/core/match_data.rbs CHANGED
@@ -92,7 +92,7 @@ class MatchData
92
92
  # #<MatchData "hoge" foo:nil foo:"oge" foo:nil>
93
93
  # m[:foo] #=> "oge"
94
94
  #
95
- def []: (capture backref, ?nil) -> String?
95
+ def []: %a{implicitly-returns-nil} (capture backref, ?nil) -> String
96
96
  | (int start, int length) -> Array[String?]
97
97
  | (range[int?] range) -> Array[String?]
98
98
 
data/core/pathname.rbs CHANGED
@@ -234,11 +234,6 @@ class Pathname
234
234
  #
235
235
  def +: (Pathname | String | _ToStr other) -> Pathname
236
236
 
237
- # <!--
238
- # rdoc-file=pathname_builtin.rb
239
- # - /(other)
240
- # -->
241
- #
242
237
  alias / +
243
238
 
244
239
  # <!--
@@ -271,11 +266,6 @@ class Pathname
271
266
  #
272
267
  def ==: (untyped) -> bool
273
268
 
274
- # <!--
275
- # rdoc-file=pathname_builtin.rb
276
- # - ===(other)
277
- # -->
278
- #
279
269
  def ===: (untyped) -> bool
280
270
 
281
271
  # <!--
data/core/ractor.rbs CHANGED
@@ -470,11 +470,6 @@ class Ractor
470
470
  #
471
471
  def self.store_if_absent: [A] (Symbol) { (nil) -> A } -> A
472
472
 
473
- # <!--
474
- # rdoc-file=ractor.rb
475
- # - <<(...)
476
- # -->
477
- #
478
473
  alias << send
479
474
 
480
475
  # <!--
@@ -746,11 +741,6 @@ class Ractor
746
741
  # Port objects transmit messages between Ractors.
747
742
  #
748
743
  class Port[T = untyped]
749
- # <!--
750
- # rdoc-file=ractor.rb
751
- # - <<(obj, move: false)
752
- # -->
753
- #
754
744
  alias << send
755
745
 
756
746
  # <!--
@@ -17,7 +17,7 @@
17
17
  # Further RubyGems documentation can be found at:
18
18
  #
19
19
  # * [RubyGems Guides](https://guides.rubygems.org)
20
- # * [RubyGems API](https://www.rubydoc.info/github/ruby/rubygems) (also
20
+ # * [RubyGems API](https://guides.rubygems.org/rubygems-org-api/) (also
21
21
  # available from `gem server`)
22
22
  #
23
23
  # ## RubyGems Plugins
@@ -90,6 +90,9 @@
90
90
  #
91
91
  # -The RubyGems Team
92
92
  #
93
+ # <!-- rdoc-file=lib/rubygems/version.rb -->
94
+ # Workaround for directly loading Gem::Version in some cases
95
+ #
93
96
  module Gem
94
97
  # <!-- rdoc-file=lib/rubygems/errors.rb -->
95
98
  # Raised when RubyGems is unable to load or activate a gem. Contains the name
@@ -123,18 +123,8 @@ module Gem
123
123
  #
124
124
  def satisfied_by?: (Gem::Version version) -> bool
125
125
 
126
- # <!--
127
- # rdoc-file=lib/rubygems/requirement.rb
128
- # - ===(version)
129
- # -->
130
- #
131
126
  alias === satisfied_by?
132
127
 
133
- # <!--
134
- # rdoc-file=lib/rubygems/requirement.rb
135
- # - =~(version)
136
- # -->
137
- #
138
128
  alias =~ satisfied_by?
139
129
 
140
130
  # <!--
@@ -17,7 +17,7 @@
17
17
  # Further RubyGems documentation can be found at:
18
18
  #
19
19
  # * [RubyGems Guides](https://guides.rubygems.org)
20
- # * [RubyGems API](https://www.rubydoc.info/github/ruby/rubygems) (also
20
+ # * [RubyGems API](https://guides.rubygems.org/rubygems-org-api/) (also
21
21
  # available from `gem server`)
22
22
  #
23
23
  # ## RubyGems Plugins
@@ -90,6 +90,9 @@
90
90
  #
91
91
  # -The RubyGems Team
92
92
  #
93
+ # <!-- rdoc-file=lib/rubygems/version.rb -->
94
+ # Workaround for directly loading Gem::Version in some cases
95
+ #
93
96
  module Gem
94
97
  interface _HashLike[K, V]
95
98
  def each_pair: () { ([ K, V ]) -> untyped } -> self
@@ -19,5 +19,13 @@
19
19
  # #metadata for restrictions on the format and size of metadata items you may
20
20
  # add to a specification.
21
21
  #
22
+ # Specifications must be deterministic, as in the example above. For instance,
23
+ # you cannot define attributes conditionally:
24
+ #
25
+ # # INVALID: do not do this.
26
+ # unless RUBY_ENGINE == "jruby"
27
+ # s.extensions << "ext/example/extconf.rb"
28
+ # end
29
+ #
22
30
  class Gem::Specification < Gem::BasicSpecification
23
31
  end
@@ -1,165 +1,5 @@
1
1
  %a{annotate:rdoc:skip}
2
2
  module Gem
3
- # <!-- rdoc-file=lib/rubygems/version.rb -->
4
- # The Version class processes string versions into comparable values. A version
5
- # string should normally be a series of numbers separated by periods. Each part
6
- # (digits separated by periods) is considered its own number, and these are used
7
- # for sorting. So for instance, 3.10 sorts higher than 3.2 because ten is
8
- # greater than two.
9
- #
10
- # If any part contains letters (currently only a-z are supported) then that
11
- # version is considered prerelease. Versions with a prerelease part in the Nth
12
- # part sort less than versions with N-1 parts. Prerelease parts are sorted
13
- # alphabetically using the normal Ruby string sorting rules. If a prerelease
14
- # part contains both letters and numbers, it will be broken into multiple parts
15
- # to provide expected sort behavior (1.0.a10 becomes 1.0.a.10, and is greater
16
- # than 1.0.a9).
17
- #
18
- # Prereleases sort between real releases (newest to oldest):
19
- #
20
- # 1. 1.0
21
- # 2. 1.0.b1
22
- # 3. 1.0.a.2
23
- # 4. 0.9
24
- #
25
- # If you want to specify a version restriction that includes both prereleases
26
- # and regular releases of the 1.x series this is the best way:
27
- #
28
- # s.add_dependency 'example', '>= 1.0.0.a', '< 2.0.0'
29
- #
30
- # ## How Software Changes
31
- #
32
- # Users expect to be able to specify a version constraint that gives them some
33
- # reasonable expectation that new versions of a library will work with their
34
- # software if the version constraint is true, and not work with their software
35
- # if the version constraint is false. In other words, the perfect system will
36
- # accept all compatible versions of the library and reject all incompatible
37
- # versions.
38
- #
39
- # Libraries change in 3 ways (well, more than 3, but stay focused here!).
40
- #
41
- # 1. The change may be an implementation detail only and have no effect on the
42
- # client software.
43
- # 2. The change may add new features, but do so in a way that client software
44
- # written to an earlier version is still compatible.
45
- # 3. The change may change the public interface of the library in such a way
46
- # that old software is no longer compatible.
47
- #
48
- # Some examples are appropriate at this point. Suppose I have a Stack class
49
- # that supports a `push` and a `pop` method.
50
- #
51
- # ### Examples of Category 1 changes:
52
- #
53
- # * Switch from an array based implementation to a linked-list based
54
- # implementation.
55
- # * Provide an automatic (and transparent) backing store for large stacks.
56
- #
57
- # ### Examples of Category 2 changes might be:
58
- #
59
- # * Add a `depth` method to return the current depth of the stack.
60
- # * Add a `top` method that returns the current top of stack (without changing
61
- # the stack).
62
- # * Change `push` so that it returns the item pushed (previously it had no
63
- # usable return value).
64
- #
65
- # ### Examples of Category 3 changes might be:
66
- #
67
- # * Changes `pop` so that it no longer returns a value (you must use `top` to
68
- # get the top of the stack).
69
- # * Rename the methods to `push_item` and `pop_item`.
70
- #
71
- # ## RubyGems Rational Versioning
72
- #
73
- # * Versions shall be represented by three non-negative integers, separated by
74
- # periods (e.g. 3.1.4). The first integers is the "major" version number,
75
- # the second integer is the "minor" version number, and the third integer is
76
- # the "build" number.
77
- #
78
- # * A category 1 change (implementation detail) will increment the build
79
- # number.
80
- #
81
- # * A category 2 change (backwards compatible) will increment the minor
82
- # version number and reset the build number.
83
- #
84
- # * A category 3 change (incompatible) will increment the major build number
85
- # and reset the minor and build numbers.
86
- #
87
- # * Any "public" release of a gem should have a different version. Normally
88
- # that means incrementing the build number. This means a developer can
89
- # generate builds all day long, but as soon as they make a public release,
90
- # the version must be updated.
91
- #
92
- # ### Examples
93
- #
94
- # Let's work through a project lifecycle using our Stack example from above.
95
- #
96
- # Version 0.0.1
97
- # : The initial Stack class is release.
98
- #
99
- # Version 0.0.2
100
- # : Switched to a linked=list implementation because it is cooler.
101
- #
102
- # Version 0.1.0
103
- # : Added a `depth` method.
104
- #
105
- # Version 1.0.0
106
- # : Added `top` and made `pop` return nil (`pop` used to return the old top
107
- # item).
108
- #
109
- # Version 1.1.0
110
- # : `push` now returns the value pushed (it used it return nil).
111
- #
112
- # Version 1.1.1
113
- # : Fixed a bug in the linked list implementation.
114
- #
115
- # Version 1.1.2
116
- # : Fixed a bug introduced in the last fix.
117
- #
118
- #
119
- # Client A needs a stack with basic push/pop capability. They write to the
120
- # original interface (no `top`), so their version constraint looks like:
121
- #
122
- # gem 'stack', '>= 0.0'
123
- #
124
- # Essentially, any version is OK with Client A. An incompatible change to the
125
- # library will cause them grief, but they are willing to take the chance (we
126
- # call Client A optimistic).
127
- #
128
- # Client B is just like Client A except for two things: (1) They use the `depth`
129
- # method and (2) they are worried about future incompatibilities, so they write
130
- # their version constraint like this:
131
- #
132
- # gem 'stack', '~> 0.1'
133
- #
134
- # The `depth` method was introduced in version 0.1.0, so that version or
135
- # anything later is fine, as long as the version stays below version 1.0 where
136
- # incompatibilities are introduced. We call Client B pessimistic because they
137
- # are worried about incompatible future changes (it is OK to be pessimistic!).
138
- #
139
- # ## Preventing Version Catastrophe:
140
- #
141
- # From:
142
- # https://www.zenspider.com/ruby/2008/10/rubygems-how-to-preventing-catastrophe.
143
- # html
144
- #
145
- # Let's say you're depending on the fnord gem version 2.y.z. If you specify your
146
- # dependency as ">= 2.0.0" then, you're good, right? What happens if fnord 3.0
147
- # comes out and it isn't backwards compatible with 2.y.z? Your stuff will break
148
- # as a result of using ">=". The better route is to specify your dependency with
149
- # an "approximate" version specifier ("~>"). They're a tad confusing, so here is
150
- # how the dependency specifiers work:
151
- #
152
- # Specification From ... To (exclusive)
153
- # ">= 3.0" 3.0 ... &infin;
154
- # "~> 3.0" 3.0 ... 4.0
155
- # "~> 3.0.0" 3.0.0 ... 3.1
156
- # "~> 3.5" 3.5 ... 4.0
157
- # "~> 3.5.0" 3.5.0 ... 3.6
158
- # "~> 3" 3.0 ... 4.0
159
- #
160
- # For the last example, single-digit versions are automatically extended with a
161
- # zero to give a sensible result.
162
- #
163
3
  class Version
164
4
  include Comparable
165
5
 
data/core/thread.rbs CHANGED
@@ -1565,10 +1565,10 @@ class Thread::Mutex < Object
1565
1565
 
1566
1566
  # <!--
1567
1567
  # rdoc-file=thread_sync.rb
1568
- # - mutex.lock -> self
1568
+ # - mutex.unlock -> self
1569
1569
  # -->
1570
- # Attempts to grab the lock and waits if it isn't available. Raises
1571
- # `ThreadError` if `mutex` was locked by the current thread.
1570
+ # Releases the lock. Raises `ThreadError` if `mutex` wasn't locked by the
1571
+ # current thread.
1572
1572
  #
1573
1573
  def unlock: () -> self
1574
1574
  end
@@ -1751,11 +1751,6 @@ end
1751
1751
  # See Thread::Queue for an example of how a Thread::SizedQueue works.
1752
1752
  #
1753
1753
  class Thread::SizedQueue[E = untyped] < Thread::Queue[E]
1754
- # <!--
1755
- # rdoc-file=thread_sync.rb
1756
- # - <<(object, non_block = false, timeout: nil)
1757
- # -->
1758
- #
1759
1754
  alias << push
1760
1755
 
1761
1756
  # <!--
data/docs/CONTRIBUTING.md CHANGED
@@ -13,7 +13,7 @@ The RBS repository contains the type definitions of Core API and Standard Librar
13
13
  There are some discussions whether if it is the best to have them in this repository, but we have them and continue updating the files meanwhile.
14
14
 
15
15
  The target version of the bundled type definitions is the [latest _release_ of Ruby](https://www.ruby-lang.org/en/downloads/branches/) -- `4.0` as of 2026.
16
- Note, however, that the CI currently retains the tests on Ruby 3.2 as well.
16
+ Note, however, that the CI runs the tests on every non-EOL Ruby -- `3.3` and later as of 2026.
17
17
 
18
18
  **The core API** type definitions are in `core` directory.
19
19
  You will find the familiar class names in the directory, like `string.rbs` or `array.rbs`.
data/docs/release.md ADDED
@@ -0,0 +1,151 @@
1
+ # Releasing RBS
2
+
3
+ A release is a pull request, a tag, and one workflow run. Everything that leaves
4
+ the repository — both gems and the GitHub release — is produced by the `Release
5
+ gems` workflow, so nothing has to be built or pushed from a laptop.
6
+
7
+ Each release ships **two gems**:
8
+
9
+ | Gem | Platform | Parser |
10
+ | --- | --- | --- |
11
+ | `rbs-X.Y.Z.gem` | `ruby` (MRI) | C extension, compiled on install |
12
+ | `rbs-X.Y.Z-java.gem` | `java` (JRuby) | `rbs_parser.wasm`, built by the workflow |
13
+
14
+ The `-java` gem contains no native code — just `rbs_parser.wasm`. The Chicory/ASM
15
+ jars it needs are not shipped in the gem; they are declared as `jar-dependencies`
16
+ requirements and fetched from Maven when the gem is installed. So the gem can be
17
+ built once in any environment and runs on every JRuby.
18
+
19
+ There are three kinds of release, and they differ in what gets written up:
20
+
21
+ | Version | CHANGELOG section | GitHub release |
22
+ | --- | --- | --- |
23
+ | `X.Y.Z` | The whole cycle since the previous release proper, prereleases included | Published |
24
+ | `X.Y.Z.pre.N` | What changed since `X.Y.Z.pre.N-1` | Published, marked as a prerelease |
25
+ | `X.Y.Z.dev.N` | None | None |
26
+
27
+ `.dev.N` releases are cut from the development line for people who need a change
28
+ early, so they are gems and tags and nothing else.
29
+
30
+ ## Prerequisites
31
+
32
+ Push rights to the `rbs` gem on RubyGems are **not** needed: the workflow
33
+ authenticates through a trusted publisher registered for this repository and
34
+ `release-gems.yml`. What is needed is write access to the repository, since that
35
+ is what lets you dispatch the workflow.
36
+
37
+ ## Steps
38
+
39
+ ### 1. Prepare the release
40
+
41
+ Open a pull request that carries everything the release needs:
42
+
43
+ - `lib/rbs/version.rb` — set `RBS::VERSION` to the version being released.
44
+ - `Gemfile.lock` — run `bundle install` after the bump; the lockfile records the version too.
45
+ - `CHANGELOG.md` — add a section for the new version, directly under the `# CHANGELOG` heading.
46
+ Sections are newest first.
47
+
48
+ Label the pull request `skip-changelog`. It carries no change of its own, and without the label it
49
+ shows up in the next release's list — that is why 4.1.0's changelog contains a `Version 4.1.0`
50
+ entry.
51
+
52
+ `rake gem:changelog` lists the pull requests merged since the last release, already formatted:
53
+
54
+ ```console
55
+ $ bundle exec rake gem:changelog | pbcopy
56
+ ```
57
+
58
+ Where it starts follows `RBS::VERSION`, so bump the version first: a prerelease starts from the
59
+ latest tag, and a release proper skips the prerelease tags and starts from the previous release
60
+ proper. Pass a version to override it (`rake 'gem:changelog[4.1.0]'`). Only the list goes to
61
+ STDOUT, so it pipes cleanly. Pull requests labeled `skip-changelog` are left out and reported on
62
+ STDERR, and pull requests that only touch `rust/` are left out because the crates have their own
63
+ release cycle.
64
+
65
+ On a release proper, the `X.Y.Z.pre.N` sections above the previous release are replaced by the one
66
+ section being written — their pull requests are in it, and the notes they were published with stay
67
+ on their own GitHub releases.
68
+
69
+ Sort the list into the sections below. `rake gem:changelog:json` prints the same pull requests with
70
+ the changed files, labels, and body of each, which is what the sorting is based on.
71
+
72
+ ```markdown
73
+ ## X.Y.Z (YYYY-MM-DD)
74
+
75
+ ### Signature updates
76
+
77
+ ### Language updates
78
+
79
+ ### Library changes
80
+
81
+ #### rbs prototype
82
+
83
+ #### rbs collection
84
+
85
+ ### Miscellaneous
86
+ ```
87
+
88
+ The sections always appear in this order; delete the ones that end up empty, which is most of them
89
+ on a small release. Two things scale with the size of the release:
90
+
91
+ - **Summary paragraphs**, above the first section. A patch release usually has none, 4.1.0 has four
92
+ paragraphs, and 4.0.0 has nine.
93
+ - **A list of the types whose signatures changed**, as the first line of `### Signature updates`,
94
+ written as `**Updated classes/modules/methods:**` followed by the names in backticks. Used on
95
+ `X.Y.0` releases only.
96
+
97
+ The date is the day the gem is released, matching the `vX.Y.Z` tag — not the day this pull request
98
+ is opened. Fix it up before step 2 if the pull request sat for a few days.
99
+
100
+ ### 2. Tag the release
101
+
102
+ Once the pull request is merged, tag the merge commit and push the tag:
103
+
104
+ ```console
105
+ $ git switch master && git pull
106
+ $ git tag "v$(ruby -e 'load "lib/rbs/version.rb"; print RBS::VERSION')"
107
+ $ git push origin --tags
108
+ ```
109
+
110
+ The tag comes before anything is published, so that the gems and the release notes describe a
111
+ commit that is already immutable — and because a tag can be deleted, while a version pushed to
112
+ RubyGems can only be yanked.
113
+
114
+ ### 3. Run the `Release gems` workflow against the tag
115
+
116
+ Dispatch [`release-gems.yml`](../.github/workflows/release-gems.yml) from the Actions tab, picking
117
+ the `vX.Y.Z` tag — **not** a branch — in the ref selector. The trusted publisher has no branch
118
+ condition, so the ref you pick is what decides what gets published; the workflow refuses to run
119
+ unless the tag matches `RBS::VERSION`.
120
+
121
+ It then:
122
+
123
+ - builds `rbs-X.Y.Z.gem`,
124
+ - compiles `rbs_parser.wasm` and builds `rbs-X.Y.Z-java.gem`,
125
+ - checks both: platforms, the C extension on one and its absence on the other, and that the wasm
126
+ module made it into the `java` gem,
127
+ - installs the `java` gem on JRuby and parses with it, so the WebAssembly runtime is exercised
128
+ before anything is published,
129
+ - uploads both gems as an artifact,
130
+ - pushes both to RubyGems through trusted publishing,
131
+ - publishes the GitHub release with the notes from CHANGELOG.md, skipping this last step for
132
+ `.dev.N` versions.
133
+
134
+ Dispatching against a branch runs everything up to the artifact and stops, which is how the build
135
+ is exercised without releasing.
136
+
137
+ ### 4. Start the next development cycle
138
+
139
+ Open another pull request setting `RBS::VERSION` to the next prerelease (`4.1.1` → `4.1.2.pre`),
140
+ with `Gemfile.lock` regenerated, labeled `skip-changelog` like the release pull request itself.
141
+ Without it the version on `master` keeps claiming to be the released version for the whole
142
+ development period, and `rake gem:changelog` reads that version to decide where the next changelog
143
+ starts.
144
+
145
+ ## Notes
146
+
147
+ - Prereleases (`X.Y.Z.pre.N`) are only installed with `gem install rbs --pre`;
148
+ a plain `gem install rbs` is unaffected. On JRuby, `gem install rbs [--pre]`
149
+ resolves to the `-java` gem automatically.
150
+ - `Dockerfile.jruby` pins the WASI SDK / Chicory / ASM versions to match the
151
+ `wasm`, `jruby`, and `release-gems` workflows. Keep them in sync when bumping.
@@ -196,8 +196,8 @@ static VALUE rbs_intern_namespace(rbs_translation_context_t ctx, rbs_namespace_t
196
196
  return rb_funcallv(RBS_Namespace, intern_brackets(), 2, args);
197
197
  }
198
198
 
199
- static VALUE rbs_intern_type_name(VALUE namespace, VALUE name) {
200
- VALUE args[2] = { namespace, name };
199
+ static VALUE rbs_intern_type_name(VALUE type_namespace, VALUE name) {
200
+ VALUE args[2] = { type_namespace, name };
201
201
  return rb_funcallv(RBS_TypeName, intern_brackets(), 2, args);
202
202
  }
203
203
 
@@ -91,7 +91,7 @@ static rb_data_type_t location_type = {
91
91
  { rbs_loc_mark, (RUBY_DATA_FUNC) rbs_loc_free, rbs_loc_memsize },
92
92
  0,
93
93
  0,
94
- RUBY_TYPED_FREE_IMMEDIATELY
94
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
95
95
  };
96
96
 
97
97
  static VALUE location_s_allocate(VALUE klass) {
@@ -114,10 +114,11 @@ static VALUE location_initialize(VALUE self, VALUE buffer, VALUE start_pos, VALU
114
114
  int end = FIX2INT(end_pos);
115
115
 
116
116
  *loc = (rbs_loc) {
117
- .buffer = buffer,
117
+ .buffer = Qnil,
118
118
  .rg = (rbs_loc_range) { start, end },
119
119
  .children = NULL,
120
120
  };
121
+ RB_OBJ_WRITE(self, &loc->buffer, buffer);
121
122
 
122
123
  return Qnil;
123
124
  }
@@ -127,10 +128,11 @@ static VALUE location_initialize_copy(VALUE self, VALUE other) {
127
128
  rbs_loc *other_loc = rbs_check_location(other);
128
129
 
129
130
  *self_loc = (rbs_loc) {
130
- .buffer = other_loc->buffer,
131
+ .buffer = Qnil,
131
132
  .rg = other_loc->rg,
132
133
  .children = NULL,
133
134
  };
135
+ RB_OBJ_WRITE(self, &self_loc->buffer, other_loc->buffer);
134
136
 
135
137
  if (other_loc->children != NULL) {
136
138
  rbs_loc_legacy_alloc_children(self_loc, other_loc->children->cap);
@@ -193,7 +195,8 @@ VALUE rbs_new_location(VALUE buffer, rbs_range_t rg) {
193
195
  rbs_loc *loc;
194
196
  VALUE obj = TypedData_Make_Struct(RBS_Location, rbs_loc, &location_type, loc);
195
197
 
196
- rbs_loc_init(loc, buffer, (rbs_loc_range) { rg.start.char_pos, rg.end.char_pos });
198
+ rbs_loc_init(loc, Qnil, (rbs_loc_range) { rg.start.char_pos, rg.end.char_pos });
199
+ RB_OBJ_WRITE(obj, &loc->buffer, buffer);
197
200
 
198
201
  return obj;
199
202
  }
@@ -202,7 +205,8 @@ VALUE rbs_new_location2(VALUE buffer, int start_char, int end_char) {
202
205
  rbs_loc *loc;
203
206
  VALUE obj = TypedData_Make_Struct(RBS_Location, rbs_loc, &location_type, loc);
204
207
 
205
- rbs_loc_init(loc, buffer, (rbs_loc_range) { .start = start_char, .end = end_char });
208
+ rbs_loc_init(loc, Qnil, (rbs_loc_range) { .start = start_char, .end = end_char });
209
+ RB_OBJ_WRITE(obj, &loc->buffer, buffer);
206
210
 
207
211
  return obj;
208
212
  }
@@ -211,7 +215,8 @@ static VALUE rbs_new_location_from_loc_range(VALUE buffer, rbs_loc_range rg) {
211
215
  rbs_loc *loc;
212
216
  VALUE obj = TypedData_Make_Struct(RBS_Location, rbs_loc, &location_type, loc);
213
217
 
214
- rbs_loc_init(loc, buffer, rg);
218
+ rbs_loc_init(loc, Qnil, rg);
219
+ RB_OBJ_WRITE(obj, &loc->buffer, buffer);
215
220
 
216
221
  return obj;
217
222
  }
data/include/rbs/ast.h CHANGED
@@ -583,7 +583,7 @@ typedef struct rbs_ast_ruby_annotations_class_alias_annotation {
583
583
 
584
584
  rbs_location_range prefix_location;
585
585
  rbs_location_range keyword_location;
586
- struct rbs_type_name *RBS_NONNULL type_name;
586
+ struct rbs_type_name *RBS_NULLABLE type_name;
587
587
  rbs_location_range type_name_location;
588
588
  } rbs_ast_ruby_annotations_class_alias_annotation_t;
589
589
 
@@ -631,7 +631,7 @@ typedef struct rbs_ast_ruby_annotations_module_alias_annotation {
631
631
 
632
632
  rbs_location_range prefix_location;
633
633
  rbs_location_range keyword_location;
634
- struct rbs_type_name *RBS_NONNULL type_name;
634
+ struct rbs_type_name *RBS_NULLABLE type_name;
635
635
  rbs_location_range type_name_location;
636
636
  } rbs_ast_ruby_annotations_module_alias_annotation_t;
637
637
 
@@ -998,12 +998,12 @@ rbs_ast_members_prepend_t *RBS_NONNULL rbs_ast_members_prepend_new(rbs_allocator
998
998
  rbs_ast_members_private_t *RBS_NONNULL rbs_ast_members_private_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location);
999
999
  rbs_ast_members_public_t *RBS_NONNULL rbs_ast_members_public_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location);
1000
1000
  rbs_ast_ruby_annotations_block_param_type_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_block_param_type_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range ampersand_location, rbs_location_range name_location, rbs_location_range colon_location, rbs_location_range question_location, rbs_location_range type_location, rbs_node_t *RBS_NONNULL type_, rbs_location_range comment_location);
1001
- rbs_ast_ruby_annotations_class_alias_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_class_alias_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range keyword_location, rbs_type_name_t *RBS_NONNULL type_name, rbs_location_range type_name_location);
1001
+ rbs_ast_ruby_annotations_class_alias_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_class_alias_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range keyword_location, rbs_type_name_t *RBS_NULLABLE type_name, rbs_location_range type_name_location);
1002
1002
  rbs_ast_ruby_annotations_colon_method_type_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_colon_method_type_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_node_list_t *RBS_NONNULL annotations, rbs_node_t *RBS_NONNULL method_type);
1003
1003
  rbs_ast_ruby_annotations_double_splat_param_type_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_double_splat_param_type_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range star2_location, rbs_location_range name_location, rbs_location_range colon_location, rbs_node_t *RBS_NONNULL param_type, rbs_location_range comment_location);
1004
1004
  rbs_ast_ruby_annotations_instance_variable_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_instance_variable_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_ast_symbol_t *RBS_NONNULL ivar_name, rbs_location_range ivar_name_location, rbs_location_range colon_location, rbs_node_t *RBS_NONNULL type, rbs_location_range comment_location);
1005
1005
  rbs_ast_ruby_annotations_method_types_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_method_types_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_node_list_t *RBS_NONNULL overloads, rbs_location_range_list_t *RBS_NONNULL vertical_bar_locations, rbs_location_range dot3_location);
1006
- rbs_ast_ruby_annotations_module_alias_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_module_alias_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range keyword_location, rbs_type_name_t *RBS_NONNULL type_name, rbs_location_range type_name_location);
1006
+ rbs_ast_ruby_annotations_module_alias_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_module_alias_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range keyword_location, rbs_type_name_t *RBS_NULLABLE type_name, rbs_location_range type_name_location);
1007
1007
  rbs_ast_ruby_annotations_module_self_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_module_self_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range keyword_location, rbs_location_range colon_location, rbs_type_name_t *RBS_NONNULL name, rbs_node_list_t *RBS_NONNULL args, rbs_location_range open_bracket_location, rbs_location_range close_bracket_location, rbs_location_range_list_t *RBS_NONNULL args_comma_locations, rbs_location_range comment_location);
1008
1008
  rbs_ast_ruby_annotations_node_type_assertion_t *RBS_NONNULL rbs_ast_ruby_annotations_node_type_assertion_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_node_t *RBS_NONNULL type);
1009
1009
  rbs_ast_ruby_annotations_param_type_annotation_t *RBS_NONNULL rbs_ast_ruby_annotations_param_type_annotation_new(rbs_allocator_t *RBS_NONNULL allocator, rbs_location_range location, rbs_location_range prefix_location, rbs_location_range name_location, rbs_location_range colon_location, rbs_node_t *RBS_NONNULL param_type, rbs_location_range comment_location);
@@ -121,12 +121,14 @@ module RBS
121
121
 
122
122
  def self.parse_inline_leading_annotation(source, range, variables: [])
123
123
  buf = buffer(source)
124
- _parse_inline_leading_annotation(buf, range.begin || 0, range.end || buf.last_position, variables)
124
+ byte_range = byte_range(range, buf.content)
125
+ _parse_inline_leading_annotation(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables)
125
126
  end
126
127
 
127
128
  def self.parse_inline_trailing_annotation(source, range, variables: [])
128
129
  buf = buffer(source)
129
- _parse_inline_trailing_annotation(buf, range.begin || 0, range.end || buf.last_position, variables)
130
+ byte_range = byte_range(range, buf.content)
131
+ _parse_inline_trailing_annotation(buf, byte_range.begin || 0, byte_range.end || buf.content.bytesize, variables)
130
132
  end
131
133
 
132
134
  def self.byte_range(char_range, content)