summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-04-01 13:57:38 -0400
committergit <svn-admin@ruby-lang.org>2024-04-01 18:13:45 +0000
commita9658b64094db1371550a5b8ca47308cdd60db78 (patch)
treed2584dd658fb2d8837c4dac3ac43291eacc1ae83
parentec879e7eac89dd7ef4f67eb737b3a633a96e280f (diff)
[ruby/prism] Do not track locals starting with _
https://github.com/ruby/prism/commit/0d5a6d936a
-rw-r--r--prism/prism.c7
-rw-r--r--test/prism/errors_test.rb63
2 files changed, 43 insertions, 27 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 15c7e4568d..2a288cae93 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -14605,6 +14605,9 @@ parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, bool top_pat
*/
static void
parse_pattern_capture(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_constant_id_t capture, const pm_location_t *location) {
+ // Skip this capture if it starts with an underscore.
+ if (*location->start == '_') return;
+
if (pm_constant_id_list_includes(captures, capture)) {
pm_parser_err(parser, location->start, location->end, PM_ERR_PATTERN_CAPTURE_DUPLICATE);
} else {
@@ -14828,6 +14831,10 @@ parse_pattern_hash_implicit_value(pm_parser_t *parser, pm_constant_id_list_t *ca
return (pm_node_t *) pm_implicit_node_create(parser, (pm_node_t *) target);
}
+/**
+ * Add a node to the list of keys for a hash pattern, and if it is a duplicate
+ * then add an error to the parser.
+ */
static void
parse_pattern_hash_key(pm_parser_t *parser, pm_static_literals_t *keys, pm_node_t *node) {
if (pm_static_literals_add(parser, keys, node) != NULL) {
diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb
index 856e46fb76..cfe4ea41be 100644
--- a/test/prism/errors_test.rb
+++ b/test/prism/errors_test.rb
@@ -2075,7 +2075,7 @@ module Prism
source = "proc { || it }"
errors = [["`it` is not allowed when an ordinary parameter is defined", 10..12]]
- assert_errors expression(source), source, errors
+ assert_errors expression(source), source, errors, check_valid_syntax: RUBY_VERSION >= "3.4.0"
end
def test_regular_expression_with_unknown_regexp_options
@@ -2170,47 +2170,56 @@ module Prism
def test_duplicate_pattern_capture
source = <<~RUBY
- () => [a, a]
- () => [a, *a]
- () => {a: a, b: a}
- () => {a: a, **a}
- () => [a, {a:}]
- () => [a, {a: {a: {a: [a]}}}]
- () => a => a
- () => [A => a, {a: b => a}]
+ case (); in [a, a]; end
+ case (); in [a, *a]; end
+ case (); in {a: a, b: a}; end
+ case (); in {a: a, **a}; end
+ case (); in [a, {a:}]; end
+ case (); in [a, {a: {a: {a: [a]}}}]; end
+ case (); in a => a; end
+ case (); in [A => a, {a: b => a}]; end
RUBY
assert_error_messages source, Array.new(source.lines.length, "duplicated variable name")
+ refute_error_messages "case (); in [_a, _a]; end"
end
def test_duplicate_pattern_hash_key
- assert_error_messages "() => {a:, a:}", ["duplicated key name", "duplicated variable name"]
- assert_error_messages "() => {a:1, a:2}", ["duplicated key name"]
+ assert_error_messages "case (); in {a:, a:}; end", ["duplicated key name", "duplicated variable name"]
+ assert_error_messages "case (); in {a:1, a:2}; end", ["duplicated key name"]
refute_error_messages "case (); in [{a:1}, {a:2}]; end"
end
private
- def check_syntax(source)
- $VERBOSE, previous = nil, $VERBOSE
+ if RUBY_ENGINE == "ruby"
+ def check_syntax(source)
+ $VERBOSE, previous = nil, $VERBOSE
- begin
- RubyVM::InstructionSequence.compile(source)
- ensure
- $VERBOSE = previous
+ begin
+ RubyVM::InstructionSequence.compile(source)
+ ensure
+ $VERBOSE = previous
+ end
end
- end
- def assert_valid_syntax(source)
- check_syntax(source)
- end
+ def assert_valid_syntax(source)
+ check_syntax(source)
+ end
- def refute_valid_syntax(source)
- assert_raise(SyntaxError) { check_syntax(source) }
+ def refute_valid_syntax(source)
+ assert_raise(SyntaxError) { check_syntax(source) }
+ end
+ else
+ def assert_valid_syntax(source)
+ end
+
+ def refute_valid_syntax(source)
+ end
end
- def assert_errors(expected, source, errors)
- refute_valid_syntax(source) if RUBY_ENGINE == "ruby"
+ def assert_errors(expected, source, errors, check_valid_syntax: true)
+ refute_valid_syntax(source) if check_valid_syntax
result = Prism.parse(source)
node = result.value.statements.body.last
@@ -2220,13 +2229,13 @@ module Prism
end
def assert_error_messages(source, errors)
- refute_valid_syntax(source) if RUBY_ENGINE == "ruby"
+ refute_valid_syntax(source)
result = Prism.parse(source)
assert_equal(errors, result.errors.map(&:message))
end
def refute_error_messages(source)
- assert_valid_syntax(source) if RUBY_ENGINE == "ruby"
+ assert_valid_syntax(source)
assert Prism.parse_success?(source)
end