Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 8 additions & 12 deletions ext/prism/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,14 @@ build_options_i(VALUE key, VALUE value, VALUE argument) {
rb_exc_raise(rb_exc_new_cstr(rb_cPrismCurrentVersionError, ruby_version));
}
} else if (RSTRING_LEN(value) == 7 && strncmp(version, "nearest", 7) == 0) {
const char *nearest_version;

if (ruby_version[0] < '3' || (ruby_version[0] == '3' && ruby_version[2] < '3')) {
nearest_version = "3.3";
} else if (ruby_version[0] > '4' || (ruby_version[0] == '4' && ruby_version[2] > '1')) {
nearest_version = "4.1";
} else {
nearest_version = ruby_version;
}

if (!pm_options_version_set(options, nearest_version, 3)) {
rb_raise(rb_eArgError, "invalid nearest version: %s", nearest_version);
if (!pm_options_version_set(options, ruby_version, 3)) {
// Prism doesn't know this specific version. Is it lower?
if (ruby_version[0] < '3' || (ruby_version[0] == '3' && ruby_version[2] < '3')) {
options->version == PM_OPTIONS_VERSION_CRUBY_3_3;
} else {
// Must be higher.
options->version == PM_OPTIONS_VERSION_LATEST;
}
}
} else if (!pm_options_version_set(options, version, RSTRING_LEN(value))) {
rb_raise(rb_eArgError, "invalid version: %" PRIsVALUE, value);
Expand Down
43 changes: 19 additions & 24 deletions lib/prism/ffi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -423,27 +423,28 @@ def dump_options_command_line(options)

# Return the value that should be dumped for the version option.
def dump_options_version(version)
checking =
case version
when "current"
RUBY_VERSION
when "latest"
nil
when "nearest"
if RUBY_VERSION <= "3.3"
"3.3"
elsif RUBY_VERSION >= "4.1"
"4.1"
else
RUBY_VERSION
end
case version
when "current"
version_string_to_number(RUBY_VERSION) || raise(CurrentVersionError, RUBY_VERSION)
when "latest", nil
0 # Handled in pm_parser_init
when "nearest"
dump = version_string_to_number(RUBY_VERSION)
return dump if dump
if RUBY_VERSION < "3.3"
version_string_to_number("3.3")
else
version
0 # Handled in pm_parser_init
end
else
version_string_to_number(version) || raise(ArgumentError, "invalid version: #{version}")
end
end

case checking
when nil
0 # Handled in pm_parser_init
# Converts a version string like "4.0.0" or "4.0" into a number.
# Returns nil if the version is unknown.
def version_string_to_number(version)
case version
when /\A3\.3(\.\d+)?\z/
1
when /\A3\.4(\.\d+)?\z/
Expand All @@ -452,12 +453,6 @@ def dump_options_version(version)
3
when /\A4\.1(\.\d+)?\z/
4
else
if version == "current"
raise CurrentVersionError, RUBY_VERSION
else
raise ArgumentError, "invalid version: #{version}"
end
end
end

Expand Down
4 changes: 4 additions & 0 deletions test/prism/api/parse_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ def test_version_current
end
end

def test_nearest
assert Prism.parse_success?("1 + 1", version: "nearest")
end

def test_scopes
assert_kind_of Prism::CallNode, Prism.parse_statement("foo")
assert_kind_of Prism::LocalVariableReadNode, Prism.parse_statement("foo", scopes: [[:foo]])
Expand Down