[ruby/prism] Accept all 3.3.x and 3.4.x Ruby versions for Prism.parse

https://github.com/ruby/prism/commit/a4fcd5339a
This commit is contained in:
Benoit Daloze 2024-09-17 22:44:07 +02:00 коммит произвёл git
Родитель b8baf3f3ee
Коммит ed4a55fc4d
4 изменённых файлов: 87 добавлений и 37 удалений

Просмотреть файл

@ -411,6 +411,20 @@ module Prism
end
end
# Return the value that should be dumped for the version option.
def dump_options_version(version)
case version
when nil, "latest"
0
when /\A3\.3\.\d+\z/
1
when /\A3\.4\.\d+\z/
0
else
raise ArgumentError, "invalid version: #{version}"
end
end
# Convert the given options into a serialized options string.
def dump_options(options)
template = +""
@ -443,7 +457,7 @@ module Prism
values << dump_options_command_line(options)
template << "C"
values << { nil => 0, "3.3.0" => 1, "3.3.1" => 1, "3.4.0" => 0, "latest" => 0 }.fetch(options[:version])
values << dump_options_version(options[:version])
template << "C"
values << (options[:encoding] == false ? 1 : 0)

Просмотреть файл

@ -770,8 +770,10 @@ parse_input(pm_string_t *input, const pm_options_t *options) {
* * `version` - the version of Ruby syntax that prism should used to parse Ruby
* code. By default prism assumes you want to parse with the latest version
* of Ruby syntax (which you can trigger with `nil` or `"latest"`). You
* may also restrict the syntax to a specific version of Ruby. The
* supported values are `"3.3.0"` and `"3.4.0"`.
* may also restrict the syntax to a specific version of Ruby, e.g., with `"3.3.0"`.
* To parse with the same syntax version that the current Ruby is running
* use `version: RUBY_VERSION`. Raises ArgumentError if the version is not
* currently supported by Prism.
*/
static VALUE
parse(int argc, VALUE *argv, VALUE self) {

Просмотреть файл

@ -1,4 +1,5 @@
#include "prism/options.h"
#include "prism/util/pm_char.h"
/**
* Set the shebang callback option on the given options struct.
@ -57,6 +58,10 @@ pm_options_command_line_set(pm_options_t *options, uint8_t command_line) {
options->command_line = command_line;
}
static bool is_number(const char *string, size_t length) {
return pm_strspn_decimal_digit((const uint8_t *) string, (ptrdiff_t) length) == length;
}
/**
* Set the version option on the given options struct by parsing the given
* string. If the string contains an invalid option, this returns false.
@ -64,40 +69,31 @@ pm_options_command_line_set(pm_options_t *options, uint8_t command_line) {
*/
PRISM_EXPORTED_FUNCTION bool
pm_options_version_set(pm_options_t *options, const char *version, size_t length) {
switch (length) {
case 0:
if (version == NULL) {
options->version = PM_OPTIONS_VERSION_LATEST;
return true;
}
return false;
case 5:
assert(version != NULL);
if ((strncmp(version, "3.3.0", length) == 0) || (strncmp(version, "3.3.1", length) == 0)) {
options->version = PM_OPTIONS_VERSION_CRUBY_3_3;
return true;
}
if (strncmp(version, "3.4.0", length) == 0) {
options->version = PM_OPTIONS_VERSION_LATEST;
return true;
}
return false;
case 6:
assert(version != NULL);
if (strncmp(version, "latest", length) == 0) {
options->version = PM_OPTIONS_VERSION_LATEST;
return true;
}
return false;
default:
return false;
if (version == NULL) {
options->version = PM_OPTIONS_VERSION_LATEST;
return true;
}
if (length >= 4) {
if (strncmp(version, "3.3.", 4) == 0 && is_number(version + 4, length - 4)) {
options->version = PM_OPTIONS_VERSION_CRUBY_3_3;
return true;
}
if (strncmp(version, "3.4.", 4) == 0 && is_number(version + 4, length - 4)) {
options->version = PM_OPTIONS_VERSION_LATEST;
return true;
}
}
if (length >= 6) {
if (strncmp(version, "latest", 7) == 0) { // 7 to compare the \0 as well
options->version = PM_OPTIONS_VERSION_LATEST;
return true;
}
}
return false;
}
/**

Просмотреть файл

@ -4,8 +4,46 @@ require_relative "test_helper"
module Prism
class VersionTest < TestCase
def test_version_is_set
def test_prism_version_is_set
refute_nil VERSION
end
def test_syntax_versions
assert Prism.parse("1 + 1", version: "3.3.0").success?
assert Prism.parse("1 + 1", version: "3.3.1").success?
assert Prism.parse("1 + 1", version: "3.3.9").success?
assert Prism.parse("1 + 1", version: "3.3.10").success?
assert Prism.parse("1 + 1", version: "3.4.0").success?
assert Prism.parse("1 + 1", version: "3.4.9").success?
assert Prism.parse("1 + 1", version: "3.4.10").success?
assert Prism.parse("1 + 1", version: "latest").success?
# Test edge case
error = assert_raise ArgumentError do
Prism.parse("1 + 1", version: "latest2")
end
assert_equal "invalid version: latest2", error.message
assert_raise ArgumentError do
Prism.parse("1 + 1", version: "3.3.a")
end
# Not supported version syntax
assert_raise ArgumentError do
Prism.parse("1 + 1", version: "3.3")
end
# Not supported version (too old)
assert_raise ArgumentError do
Prism.parse("1 + 1", version: "3.2.0")
end
# Not supported version (too new)
assert_raise ArgumentError do
Prism.parse("1 + 1", version: "3.5.0")
end
end
end
end