From 1414406c7daa3598fb373b7f2dabc84b1e011337 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Thu, 19 Feb 2026 10:31:26 +0100 Subject: [PATCH] Implement noblock for the ripper/ruby_parser translator In ripper, compared to `**nil` it is not a new event --- lib/prism/translation/ripper.rb | 7 ++++++ lib/prism/translation/ruby_parser.rb | 6 +++++ test/prism/ruby/parser_test.rb | 33 ++++++++++++++++++++-------- test/prism/ruby/ripper_test.rb | 3 --- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb index 2a3eaa4001..d1c28a2401 100644 --- a/lib/prism/translation/ripper.rb +++ b/lib/prism/translation/ripper.rb @@ -2623,6 +2623,13 @@ def visit_nil_node(node) on_var_ref(on_kw("nil")) end + # def foo(&nil); end + # ^^^^ + def visit_no_block_parameter_node(node) + bounds(node.location) + on_blockarg(:nil) + end + # def foo(**nil); end # ^^^^^ def visit_no_keywords_parameter_node(node) diff --git a/lib/prism/translation/ruby_parser.rb b/lib/prism/translation/ruby_parser.rb index 3ba892634f..c1fb8adfc1 100644 --- a/lib/prism/translation/ruby_parser.rb +++ b/lib/prism/translation/ruby_parser.rb @@ -1152,6 +1152,12 @@ def visit_nil_node(node) s(node, :nil) end + # def foo(&nil); end + # ^^^^ + def visit_no_block_parameter_node(node) + :"&nil" + end + # def foo(**nil); end # ^^^^^ def visit_no_keywords_parameter_node(node) diff --git a/test/prism/ruby/parser_test.rb b/test/prism/ruby/parser_test.rb index 55c12cab6f..ad9fa0c92c 100644 --- a/test/prism/ruby/parser_test.rb +++ b/test/prism/ruby/parser_test.rb @@ -187,13 +187,7 @@ def test_invalid_syntax end def test_it_block_parameter_syntax - it_fixture_path = Pathname(__dir__).join("../../../test/prism/fixtures/3.4/it.txt") - - buffer = Parser::Source::Buffer.new(it_fixture_path) - buffer.source = it_fixture_path.read - actual_ast = Prism::Translation::Parser34.new.tokenize(buffer)[0] - - it_block_parameter_sexp = parse_sexp { + assert_new_syntax("3.4/it.txt", Prism::Translation::Parser34) do s(:begin, s(:itblock, s(:send, nil, :x), :it, @@ -201,9 +195,20 @@ def test_it_block_parameter_syntax s(:itblock, s(:lambda), :it, s(:lvar, :it))) - } + end + end - assert_equal(it_block_parameter_sexp, actual_ast.to_sexp) + def test_nil_block_parameter_syntax + assert_new_syntax("4.1/noblock.txt", Prism::Translation::Parser41) do + s(:begin, + s(:def, :foo, + s(:args, + s(:blocknilarg)), nil), + s(:block, + s(:lambda), + s(:args, + s(:blocknilarg)), nil)) + end end private @@ -301,6 +306,16 @@ def assert_equal_comments(expected_comments, actual_comments) } end + def assert_new_syntax(path, parser, &sexp) + fixture_path = Pathname(__dir__).join("../../../test/prism/fixtures", path) + + buffer = Parser::Source::Buffer.new(fixture_path) + buffer.source = fixture_path.read + actual_ast = parser.new.tokenize(buffer)[0] + + assert_equal(parse_sexp(&sexp), actual_ast.to_sexp) + end + def parse_sexp(&block) Class.new { extend AST::Sexp }.instance_eval(&block).to_sexp end diff --git a/test/prism/ruby/ripper_test.rb b/test/prism/ruby/ripper_test.rb index 00cf470e0e..39cb9395ab 100644 --- a/test/prism/ruby/ripper_test.rb +++ b/test/prism/ruby/ripper_test.rb @@ -40,9 +40,6 @@ class RipperTest < TestCase # https://bugs.ruby-lang.org/issues/21669 incorrect << "4.1/void_value.txt" - # https://bugs.ruby-lang.org/issues/19979 - incorrect << "4.1/noblock.txt" - # Skip these tests that we haven't implemented yet. omitted_sexp_raw = [ "bom_leading_space.txt",