943 Commits
Author SHA1 Message Date
Kevin Newton 51f2767aa0 [ruby/prism] Avoid vsnprintf when possible
When formatting error messages, first try to format into a fixed
buffer instead of formatting once to get the length then a second
time to get the actual format.

https://github.com/ruby/prism/commit/557cffe23e
2026-10-26 15:38:14 +00:00
Kevin Newton 41fc5017d6 [ruby/prism] Use xxh3 hashing for static literals
Instead of the half-baked murmur hash we were using. Also since
it now nicely spreads out the bits, keep all of the nodes in one
hash/allocation, and keep a 4-pointer buffer on the stack for the
majority case where there aren't that many keys.

https://github.com/ruby/prism/commit/cde8d1183c
2026-10-24 00:43:56 +00:00
Kevin Newton 4f6a7e0fa9 [ruby/prism] Serialize using post-order traversal
This makes it so that you do not have to recurse when serializing
and deserializing, making this safe for deep trees.

https://github.com/ruby/prism/commit/ab92f0eb4b
2026-10-20 21:02:33 +00:00
Kevin Newton 0fc3e6a8ae [ruby/prism] Avoid allocating when comparing magic comments
https://github.com/ruby/prism/commit/dd8b706c61
2026-10-20 19:07:47 +00:00
Kevin Newton ae6ef1bfb5 [ruby/prism] Add checksum
CRuby is now hashing the contents of a file and attaching that to
iseqs in order to properly determine if a file has changed since
it was compiled. This is used in a couple places, but namely it is
used for error_highlight to make sure it isn't highlighting stale
locations.

The hashing algorithm doesn't actually matter since it's just used
to compare across parses, so as long as it is consistent it's okay.
I wanted something fast and standard, so this commit implements the
XXH3_64 algorithm from the spec. Noteably it uses the default
secret and a seed of 0 to make things even simpler. With NEON and
SSE2 implementations, this thing flies quite a bit faster than the
upstream FNV-1a implementation.

I figured this could be useful for other consumers as well, in
particular for tools that generate some kind of metadata around
files (type checkers, linters, etc). Eventually a nice extension
may be to hash a minimal version of the contents (i.e., with
context-insensitive whitespace removed) so that changes to docs or
indentation do not change the hash value.

If you're using the C API, you are only charged for this function
if you actually call it since it is computed lazily. For everyone
else it is automatically called, but truthfully it is so fast that
the difference is completely negligible.

https://github.com/ruby/prism/commit/6b7c5773eb
2026-10-19 17:30:05 -04:00
Kevin Newton 5b1c373522 [ruby/prism] Attach block to correct argument inside jump value
https://github.com/ruby/prism/commit/7e8c702c33
2026-10-17 18:56:13 +00:00
Kevin Newton 58c56248c0 [ruby/prism] Keywords revisit
Introduce a perfect hash for keyword checking so we do not have to
do as many comparisons. This results in about a 1% speed up.

Also, introduce a function called by the C extension and the FFI
backend that can check if something is a keyword.

https://github.com/ruby/prism/commit/9d6a9e7d5f
2026-10-17 00:51:35 +00:00
Kevin Newton 19c0ec232e [ruby/prism] Fix up handling Foo::Bar {} with a comma
https://github.com/ruby/prism/commit/4893d3b94e
2026-10-15 20:43:54 +00:00
Kevin Newton 12c4506f46 [ruby/prism] Fix up not command inside endless def
https://github.com/ruby/prism/commit/c3bdf7c769
2026-10-15 20:43:44 +00:00
Kevin Newton 8c7656f5ba [ruby/prism] Split up command write checks
Previously checking for a command write was the same concept as
checking for a command call, but in reality (and since 4.0) they
are different things.

https://github.com/ruby/prism/commit/e9cdac6b98
2026-10-15 20:24:39 +00:00
Kevin Newton 16e5778e07 [ruby/prism] Handle command assignment with endless def
A very subtle issue, but one that came up with fuzzers.

https://github.com/ruby/prism/commit/b57cd1f440
2026-10-15 19:37:22 +00:00
Kevin Newton da2efcbf76 [ruby/prism] Bump to v2.0.0.rc1
https://github.com/ruby/prism/commit/e06e08af29
2026-10-15 14:31:55 +00:00
Kevin Newton 67abedae69 [ruby/prism] Use File::path for FFI
https://github.com/ruby/prism/commit/bdf15c7566
2026-10-13 20:14:17 +00:00
Kevin Newton 1b19b75b9c [ruby/prism] Default to nearest instead of latest
https://github.com/ruby/prism/commit/b2cb61deb0
2026-10-13 18:13:55 +00:00
Kevin Newton 976b89be4a [ruby/prism] Do not report regexp errors twice with captures
When named captures were present we would reprocess the regexp and
accidentally report errors twice.

https://github.com/ruby/prism/commit/e2e11ad07f
2026-10-13 17:12:17 +00:00
Kevin Newton 55e03ec0cf [ruby/prism] Fix buffer length append check 0
https://github.com/ruby/prism/commit/812fd04263
2026-10-12 20:40:55 +00:00
Kevin Newton 98fd04f76c [ruby/prism] attach_comments
Revisit how we attach comments, allowing consumers to do it in C.

https://github.com/ruby/prism/commit/eb3528e580
2026-10-12 13:01:34 -04:00
Yusuke EndohandClaude Opus 5.5 9b23d39c44 [ruby/prism] Resync prism as Ruby::Prism
This is the output of

    ruby tool/sync_default_gems.rb prism
    git rm -r lib/prism.rb lib/prism

at https://github.com/ruby/prism/commit/0a5f9c9, with the new mapping:
lib/prism is now lib/ruby/prism, the namespace is rewritten to
Ruby::Prism, and lib/prism/prism.gemspec is no longer imported, so
prism is no longer installed as a default gem.

prism/srcs.mk.in (excluded from the sync) follows the template engine,
now Ruby::Prism::Template: it defines the Ruby module, which does not
exist in BASERUBY older than Ruby 4.0, before loading
templates/template.rb.

Ruby::Prism is the very parser that parsed the running code, no
matter which version of the prism gem is installed; the two can be
loaded side by side (the ruby binary is built with -fvisibility=hidden,
so the gem's pm_* and rb_cPrism* symbols do not collide with the
built-in ones).

[Bug #22379]

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 04:27:15 +09:00
Benoit Daloze d5ef1edef2 [ruby/prism] Use #source_range when available for Prism.find
* This is more accurate than using the line and is a portable API between Ruby implementations.
* I also tried to use #syntax_tree but that fails 2 tests as it returns the CallNode instead of BlockNode for blocks.
  Additionally, #syntax_tree emits many warnings when running the test suite:
  syntax_tree: a prism gem other than the default gem is loaded; the result may not correspond exactly to the compiled code

https://github.com/ruby/prism/commit/3c2855741e
2026-10-04 18:34:46 +00:00
Kevin Newton b74b3b45e8 [ruby/prism] Add a constant id set
There are times when we don't need explicit order in a list of
constants, namely when looking at names of captures in a pattern
match and names of captures in a regular expression. In these cases
it's better to be linear with respect to the number of names, so
using a hash makes a little more sense.

https://github.com/ruby/prism/commit/d1c23d4956
2026-09-29 19:02:58 +00:00
yuki300 42bf37a41d [ruby/prism] Only report real captures inside alternation patterns
When a variable is captured anywhere in a pattern, the operands of each
alternation are visited to report captures inside them. That visitor
treated every local variable target as a capture, including
underscore-prefixed names and targets that belong to a lambda, a string
interpolation, or a pinned expression:

    case foo
    in [bar, 1 | _baz]                         # error
    in [bar, "#{case 1; in baz; end}" | 2]     # error
    end

Without `bar` both are accepted. Skip underscore-prefixed names, like
parse_pattern_capture does, and only descend into the nodes that make up
the pattern itself. Nested alternations are skipped too, their operands
were already checked when they were parsed. Before this, a capture like
`1 => [x, (1 | y) | 2]` was reported twice.

The new fixture is excluded from the tests that compare against parse.y,
which currently rejects these forms because of the capture of `bar`:
https://bugs.ruby-lang.org/issues/22310

https://github.com/ruby/prism/commit/33ef692741
2026-09-28 16:22:39 +00:00
Hiroshi SHIBATAandClaude Opus 5.5 7058490a7f Remove unsupported platforms from prism host_os patterns
Ruby 1.9.1 dropped DJGPP and Windows CE, and Ruby 2.3 dropped Borland C.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:29:08 +09:00
Earlopain 68bc899b8d Sync prism
There were some difficulties after https://github.com/ruby/prism/pull/4223 was merged because
the excludes were out of sync.
2026-09-24 00:03:37 +02:00
Earlopain 882f4e3fd5 [ruby/prism] Allow path-like objects for Prism.parse_file and
similar
(https://github.com/ruby/prism/pull/4226)

This tries to coerce with `to_path` and then `to_str`  if it isn't a string already.
I had a `Pathname` from some other source and was sad I couldn't simply pass it along

https://github.com/ruby/prism/commit/4651adbaeb
2026-09-13 09:45:10 +00:00
Nobuyoshi Nakada 92ce852366 Revert "Win32: Add missing mklink internal command of cmd.exe"
This reverts commit a925c74bd2, which
includes commit miss.
2026-09-09 20:40:40 +09:00
Nobuyoshi Nakada a925c74bd2 Win32: Add missing mklink internal command of cmd.exe 2026-09-09 20:29:02 +09:00
Jean Boussier 9a2b620825 Fix the peephole optimizer to avoid duplicated line events
[Bug #22299]

Followup: https://github.com/ruby/ruby/pull/18538
2026-09-09 13:09:43 +02:00
Hiroya Fujinami 8587ce292b [ruby/prism] Avoid quadratic value-expression check on and/or chains
(https://github.com/ruby/prism/pull/4221)

Ref https://bugs.ruby-lang.org/issues/22294

pm_check_value_expression descended the left operand of every and/or
node it visited. Because pm_and_node_create and pm_or_node_create
already assert the value of their left operand when the node is built,
walking a left-associative chain such as `a && a && ... && a`
re-checked the whole left spine once per operator, which is quadratic
in the length of the chain: 16k operators took seconds.

The left operand of an existing and/or node was therefore already
checked, so stop at the node instead of descending. This makes the
check linear. The only observable change is that a void value on the
left spine of a chain is now reported once, at the innermost node
where it is created, rather than once per enclosing operator; the
errors fixture that pinned the duplicate is updated to match.

https://github.com/ruby/prism/commit/b19a0a5bc0
2026-09-05 09:18:25 +00:00
Kevin Newton 3643154e6d [ruby/prism] Check heredoc state for escaped newlines
When escaped newlines are encountered, they are added to the newline
list. We need to check that we aren't backing up to read the rest of
the line because of a heredoc, in which case the newline would have
already have been added to the list.

https://github.com/ruby/prism/commit/a3f8ba3d4a
2026-09-04 13:17:34 +00:00
Earlopain 45b8473fec [ruby/prism] Fix Comment#trailing for syntax invalid edgecase
When prism encounter invalid bytes and still  switches over to parsing comments,
`strip` will raise

`syntax_suggest` might run into this via `ruby/spec`

https://github.com/ruby/prism/commit/c72817c58b
2026-09-03 16:57:16 +00:00
Jean BoussierandJohn Hawthorn f4813a34c2 compile.c: statically resolve swap instructions when possible
If the two preceeding instructions are known not to be dependent
on the state of the stack, then we can eliminate the `swap` and inverse
the two previous instructions.

This mostly eliminate instruction in two cases:

```ruby
Object.new
```

```
0000 opt_getconstant_path                   <ic:0 Object>             (   1)[Li]
0002 putnil
0003 swap
0004 opt_new                                <calldata!mid:new, argc:0, ARGS_SIMPLE>, 11
```

And:

```ruby
{**@a, b: 2}
```

```
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 putspecialobject                       1
0005 swap
0006 putobject                              :b
0008 putobject                              2
0010 opt_send_without_block                 <calldata!mid:core#hash_merge_ptr, argc:3, ARGS_SIMPLE>
```

Co-Authored-By: John Hawthorn <john@hawthorn.email>
2026-08-27 21:07:46 +02:00
Kevin Newton 12e5584ddc [ruby/prism] Warn on duplicated key with **hash only
Previously we were just checking the token, which meant something
like `{ a: 1, **{a: 2}.select { false } }` would warn. As esoteric
as this is, it was possible. This also happily gets rid of the
current_hash_keys field on parser, making it just a tad bit slimmer.

https://github.com/ruby/prism/commit/3783ab0d31
2026-08-27 16:56:51 +00:00
Earlopain f3ed64d30c [ruby/prism] Return a plain Token for Prism.lex etc.
Instead of a 2-element array. Nobody should care about the state, and nobody seems to.
A code search on Github shows that it only gets discarded (like via `value.map(&:first)`, or similar things.

But because our own ripper translator still needs it for compatibility, we have to keep it around in some way.
I played around with `Prism.lex_internal` that keeps the same return value but that duplicates much
logic like serialization/deserialization.

This achieves the same thing and is much smaller in scope.

https://github.com/ruby/prism/commit/32455d191c
2026-08-18 21:05:33 +00:00
Benoit Daloze 4056015608 [ruby/prism] Remove rubyvm: keyword argument from Prism.find
(https://github.com/ruby/prism/pull/4202)

* This does not scale well with more find implementations.
* RubyVM is CRuby-specific and experimental so not something usually exposed in public APIs.
* Tests can use the specific class directly, which is more reliable.

https://github.com/ruby/prism/commit/411f741593
2026-08-16 13:50:09 +00:00
Kevin Newton dff4de9a41 [ruby/prism] Revert "Revert "Split up newline token""
This reverts commit https://github.com/ruby/prism/commit/115d58f71bdc.

https://github.com/ruby/prism/commit/9175663b7a
2026-08-11 12:18:44 +00:00
Kevin Newton 918fed9de4 [ruby/prism] Revert "Split up newline token"
This reverts commit https://github.com/ruby/prism/commit/3dbe592a76cb.

https://github.com/ruby/prism/commit/115d58f71b
2026-08-06 01:52:17 +00:00
Kevin Newton 1db6f0feee [ruby/prism] Split up newline token
There are actually 3 tokens in the Ruby grammar: the newline in a
whitespace insensitive position that is ignored, a newline that is
in a whitespace sensitive position that acts as a statement
terminator, and a newline in a whitespace sensisitive position that
acts as the terminator for an expression. The third one doesn't
exist in our grammar at the moment, but I want to add it, because
it makes working with translating the lex output easier.

https://github.com/ruby/prism/commit/3dbe592a76
2026-08-06 01:17:21 +00:00
Alan Wu 19f5b1248d Reintroduce recent PRISM changes
This reverts commit 895084e65b.
IRB failures are fixed by 6612731a4f.
2026-08-05 21:56:00 +00:00
XrXr 895084e65b Revert recent PRISM changes to fix irb bundled_gems CI
This reverts commit 0017dea395,
5e36630fc0, and
f3ec056c9f.

We are trying to bump to latest IRB, which has "Accomodate new prism
tokens", but that runs into another CI failure. While we figure out a
path forward at <https://github.com/ruby/ruby/pull/18207>, let's get
back to a green CI.
2026-08-05 13:06:40 -04:00
Kevin Newton 5e36630fc0 [ruby/prism] Split up lbrace token
This also more closely matches parse.y, and makes it easier to
delineate which brace belongs to which type.

https://github.com/ruby/prism/commit/43ed8c1f80
2026-08-05 11:02:34 +00:00
Kevin Newton f3ec056c9f [ruby/prism] Split up lparen token
This more closely matches parse.y, and simplifies a bit of the lex
state as seen from the outside.

https://github.com/ruby/prism/commit/06dff548e8
2026-08-05 11:02:33 +00:00
Kevin Newton f8d62cdbd9 [ruby/prism] Encoding leaking
Fixed encoding was leaking around elements because it wasn't being
cleared around elements that had only a single token.

https://github.com/ruby/prism/commit/03bde59c40
2026-08-01 18:20:26 +00:00
Kevin Newton aa63c4329b [ruby/prism] Fix up duplicate key warning
When there are strings that resolve to the same bytes but resolve
to different encodings, we need to not warn.

https://github.com/ruby/prism/commit/b776e364cd
2026-07-31 13:03:26 +00:00
Kevin Newton e67f02518a [ruby/prism] Pinned back references and pinned numbered references are not allowed
https://github.com/ruby/prism/commit/35c587b1c2
2026-07-29 20:59:02 +00:00
Earlopain 6a0b6ef633 [ruby/prism] Better compatibility for hash string-like symbol keys in parser translator
There's some special handling in regards to empty symbols and those containing newlines
that should apply here. Makes it produce the correct amount of sym/dsym nodes

https://github.com/ruby/prism/commit/8b567cc403
2026-07-28 10:20:18 +00:00
Kevin Newton 2526cb6154 [ruby/prism] Port diagnostics format to Prism from CRuby
https://github.com/ruby/prism/commit/46a5f19f77
2026-07-24 17:08:34 -04:00
Kevin Newtonandkai-matsudate 0f5e45d8cf [ruby/prism] Fix pattern matching trailing comma
This was previously an allow-list of the various tokens that were
considered the start of a pattern expression. Instead, use our
existing expression checking stuff and avoid having to list out
each token.

https://github.com/ruby/prism/commit/a139586ca0

Co-authored-by: kai-matsudate <kai.matsudate@techouse.jp>
2026-07-17 19:54:47 +00:00
Mike Dalessio 9def1ecf04 [ruby/prism] Add native gem precompilation support
Package precompiled native gems for Ruby 3.3, 3.4, and 4.0 across 10
platforms: aarch64-linux-gnu, aarch64-linux-musl, aarch64-mingw-ucrt,
arm-linux-gnu, arm-linux-musl, arm64-darwin, x64-mingw-ucrt,
x86_64-darwin, x86_64-linux-gnu, and x86_64-linux-musl.

- Add Ruby-version-aware extension loader in lib/prism.rb with GLIBC
  error message for musl/glibc mismatches
- Add cross-compilation support to Rakefile using rake-compiler-dock
- Add a reusable `build-gems.yml` workflow called by both the CI
  workflow (`test-gems.yml`) and the publish
  workflow (`publish-gem.yml`), building source and native gems across
  all platforms and Ruby versions
- Add scripts for building, verifying, and testing gems

Update `publish-gem.yml` to handle multi-gem publishing. Note that
`rubygems/release-gem` only supports a single gem, so this uses
`rubygems/configure-rubygems-credentials` and loops `gem push` over
each built `.gem`. Add a `workflow_dispatch` trigger alongside the
existing tag-push trigger, and create/update a GitHub release for the
tag with all gems plus a `CHECKSUMS.txt` manifest.

Move testing of the "ruby" platform gem (compile-from-source) out of
`main.yml` into `test-gems.yml` so we're testing the gem built by the
workflow tooling.

https://github.com/ruby/prism/commit/6cc5aa2d98
2026-07-17 16:24:52 +00:00
Kevin NewtonandSutou Kouhei 1790ac443c [ruby/prism] Fix up buffer treatment of stream parsing
A couple of things to fix, notably that we relied on the stream
returning strings and relied on it not lying about how much was
being written. Now we no longer trust either and we verify
instead.

https://github.com/ruby/prism/commit/70147e5b44

Co-authored-by: Sutou Kouhei <kou@clear-code.com>
2026-07-15 17:54:17 +00:00
Kevin Newton 0b2b21767b [ruby/prism] Add location slice to deconstruct_keys
It is nice to be able to slice out a location in pattern matching
without having to explicitly get the location object and call
slice manually.

Also, construct the response for deconstruct_keys lazily in order
to avoid reifying location objects if we don't have to.

https://github.com/ruby/prism/commit/3024cb55f2
2026-07-10 16:24:29 +00:00