-
Notifications
You must be signed in to change notification settings - Fork 176
Add support for Prism.parse(foo, version: "current")
#3679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
b506238 to
281a687
Compare
|
Unsure about the ffi backend. My understanding is that alternate ruby versions will use it, basically the interface to the version of prism shipped with their runtime itself. So it should also be supported there. Is that right? |
eregon
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me 👍
Not quite, you can think of it as Prism gem having 2 backends: a C extension, only used on CRuby, and the FFI backend used on JRuby and TruffleRuby.
Yes. |
|
I wonder if |
281a687 to
8d8dc9b
Compare
|
Thanks for the the review!
Ah, right. I thought that at least on truffleruby it would use the c extension when part of the gemfile (i.e. explicitly installed)
Probably, just convert it to a string somewhere. There is already |
kddnewton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general I'm totally fine with this approach, but we're doing a lot of string parsing here that I think we should do away with, as this is not going to be a common path. Instead, I would prefer something like:
if 3.3, 3.4, 3.5 -> use version
else -> raise SomeError, given
and then declare SomeError in Ruby and have it shared between the native API and the serialization API.
|
I guess you're saying to move the C extension code for version handling into ruby as well, and then share that between ffi? Something like |
|
Not quite. What I mean is that instead of: if (RSTRING_LEN(value) == 7 && strncmp(version, "current", 7) == 0) {
if (strncmp || strncmp || strncmp || strncmp) { rb_raise }
if (!pm_options_version_set(options, current_version, 3)) { rb_raise(ArgumentError, "...") }
}and: if current
case RUBY_VERSION
when ...
raise ArgumentError, "..."
end
endand in the tests: error = assert_raise(ArgumentError) { Prism.parse(...) }
assert_equal error.message, "..."you somewhat simplify to: # prism.rb
class CurrentVersionError < ArgumentError
def initialize(version)
super("Prism does not support #{version}. Please specify a supported version instead of 'current'.")
end
endand: if (RSTRING_LEN(value) == 7 && strncmp(version, "current", 7) == 0) {
if (!pm_options_version_set(options, current_version, 3)) { rb_raise(rb_cCurrentVersionError, "...") }
}and: if current && RUBY_VERSION !~ /supported-versions-pattern/
raise CurrentVersionError, "..."
endand in the tests: error = assert_raise(CurrentVersionError) { Prism.parse(...) } |
175205b to
39b0ccf
Compare
|
Ah, gotcha. That is nicer. Thanks for the explanation |
39b0ccf to
f1d3a6d
Compare
The docs currently say to use `Prism.parse(foo, version: RUBY_VERSION)` for this. By specifying "current" instead, we can have prism raise a more specifc error. Note: Does not use `ruby_version` from `ruby/version.h` because writing a test for that is not really possible. `RUBY_VERSION` is nicely stubbable for both the c-ext and FFI backend.
f1d3a6d to
9c5cd20
Compare
| message = +"invalid version: Requested to parse as `version: 'current'`; " | ||
| gem_version = | ||
| begin | ||
| Gem::Version.new(version) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ruby/ruby CI is failing here because Gem is not loaded: https://github.com/ruby/ruby/actions/runs/18561653353/job/52911907413
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh of course. I'll fix it. Shouldn't have cowboy'd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I seem to have messed something up as well https://github.com/ruby/ruby/actions/runs/18562695205/job/52915425235
Can't look into that right now though
(This one doesn't crash: https://github.com/ruby/ruby/actions/runs/18562695142/job/52915424818)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's weird. I think RUBY_VERSION is just not consistent inside hte CRuby test suite. I reduced a lot of the tests and just ended up with some bare minimum stuff, and it appears to have resolved.
The docs currently say to use
Prism.parse(foo, version: RUBY_VERSION)for this. By specifying "current" instead, we can have prism raise a more specifc error. It doesn't add much code so I think being more explicit is worth it. It's similar toPrism::Translation::ParserCurrentbut instead of warning it raises.For a smooth experience, it requires a prism release right around when a new ruby version is released. But that is also already true for using
RUBY_VERSION.Note: Does not use
ruby_versionfromruby/version.hbecause writing a test for that is not really possible. I instead pull it fromRUBY_VERSIONconstant at runtime so it can be stubbed.Ref https://bugs.ruby-lang.org/issues/21618