diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb index 6ea98fc1ea..e488b7c5cf 100644 --- a/lib/prism/translation/ripper.rb +++ b/lib/prism/translation/ripper.rb @@ -71,7 +71,7 @@ def self.parse(src, filename = "(ripper)", lineno = 1) # [[1, 13], :on_kw, "end", END ]] # def self.lex(src, filename = "-", lineno = 1, raise_errors: false) - result = Prism.lex_compat(src, filepath: filename, line: lineno) + result = Prism.lex_compat(src, filepath: filename, line: lineno, version: "current") if result.failure? && raise_errors raise SyntaxError, result.errors.first.message @@ -3295,7 +3295,7 @@ def visit_yield_node(node) # Lazily initialize the parse result. def result - @result ||= Prism.parse(source, partial_script: true) + @result ||= Prism.parse(source, partial_script: true, version: "current") end ########################################################################## diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index bd7a8a6381..706b739557 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -88,7 +88,7 @@ def assert_errors(filepath, version) expected = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8) source = expected.lines.grep_v(/^\s*\^/).join.gsub(/\n*\z/, "") - refute_valid_syntax(source) if current_major_minor == version + refute_valid_syntax(source) if CURRENT_MAJOR_MINOR == version result = Prism.parse(source, version: version) errors = result.errors diff --git a/test/prism/fixtures_test.rb b/test/prism/fixtures_test.rb index 2aebb18477..7df97029d3 100644 --- a/test/prism/fixtures_test.rb +++ b/test/prism/fixtures_test.rb @@ -24,23 +24,9 @@ class FixturesTest < TestCase except << "whitequark/ruby_bug_19281.txt" end - if RUBY_VERSION < "3.4.0" - except << "3.4/circular_parameters.txt" - end - - # Valid only on Ruby 3.3 - except << "3.3-3.3/block_args_in_array_assignment.txt" - except << "3.3-3.3/it_with_ordinary_parameter.txt" - except << "3.3-3.3/keyword_args_in_array_assignment.txt" - except << "3.3-3.3/return_in_sclass.txt" - - # Leaving these out until they are supported by parse.y. - except << "4.0/leading_logical.txt" - except << "4.0/endless_methods_command_call.txt" - # https://bugs.ruby-lang.org/issues/21168#note-5 except << "command_method_call_2.txt" - Fixture.each(except: except) do |fixture| + Fixture.each_for_current_ruby(except: except) do |fixture| define_method(fixture.test_name) { assert_valid_syntax(fixture.read) } end end diff --git a/test/prism/lex_test.rb b/test/prism/lex_test.rb index 19dd845d75..68e47a0964 100644 --- a/test/prism/lex_test.rb +++ b/test/prism/lex_test.rb @@ -7,19 +7,13 @@ module Prism class LexTest < TestCase except = [ - # It seems like there are some oddities with nested heredocs and ripper. - # Waiting for feedback on https://bugs.ruby-lang.org/issues/19838. - "seattlerb/heredoc_nested.txt", - "whitequark/dedenting_heredoc.txt", - # Ripper seems to have a bug that the regex portions before and after - # the heredoc are combined into a single token. See - # https://bugs.ruby-lang.org/issues/19838. + # https://bugs.ruby-lang.org/issues/21756 "spanning_heredoc.txt", - "spanning_heredoc_newlines.txt", - # Prism emits a single :on_tstring_content in <<- style heredocs when there - # is a line continuation preceded by escaped backslashes. It should emit two, same - # as if the backslashes are not present. + # Prism emits a single string in some cases when ripper splits them up + "whitequark/dedenting_heredoc.txt", "heredocs_with_fake_newlines.txt", + # Prism emits BEG for `on_regexp_end` + "spanning_heredoc_newlines.txt", ] if RUBY_VERSION < "3.3.0" @@ -42,17 +36,11 @@ class LexTest < TestCase except << "whitequark/ruby_bug_19281.txt" end - # https://bugs.ruby-lang.org/issues/20925 - except << "4.0/leading_logical.txt" - - # https://bugs.ruby-lang.org/issues/17398#note-12 - except << "4.0/endless_methods_command_call.txt" - # https://bugs.ruby-lang.org/issues/21168#note-5 except << "command_method_call_2.txt" - Fixture.each_with_version(except: except) do |fixture, version| - define_method(fixture.test_name(version)) { assert_lex(fixture, version) } + Fixture.each_for_current_ruby(except: except) do |fixture| + define_method(fixture.test_name) { assert_lex(fixture) } end def test_lex_file @@ -97,12 +85,10 @@ def test_parse_lex_file private - def assert_lex(fixture, version) - return unless current_major_minor == version - + def assert_lex(fixture) source = fixture.read - result = Prism.lex_compat(source, version: version) + result = Prism.lex_compat(source, version: "current") assert_equal [], result.errors Prism.lex_ripper(source).zip(result.value).each do |(ripper, prism)| diff --git a/test/prism/locals_test.rb b/test/prism/locals_test.rb index 814c9a9978..4f8d6080e8 100644 --- a/test/prism/locals_test.rb +++ b/test/prism/locals_test.rb @@ -13,11 +13,6 @@ # in comparing the locals because they will be the same. return if RubyVM::InstructionSequence.compile("").to_a[4][:parser] == :prism -# In Ruby 3.4.0, the local table for method forwarding changed. But 3.4.0 can -# refer to the dev version, so while 3.4.0 still isn't released, we need to -# check if we have a high enough revision. -return if RubyVM::InstructionSequence.compile("def foo(...); end").to_a[13][2][2][10].length != 1 - # Omit tests if running on a 32-bit machine because there is a bug with how # Ruby is handling large ISeqs on 32-bit machines return if RUBY_PLATFORM =~ /i686/ @@ -31,19 +26,11 @@ class LocalsTest < TestCase # CRuby is eliminating dead code. "whitequark/ruby_bug_10653.txt", - # Valid only on Ruby 3.3 - "3.3-3.3/block_args_in_array_assignment.txt", - "3.3-3.3/it_with_ordinary_parameter.txt", - "3.3-3.3/keyword_args_in_array_assignment.txt", - "3.3-3.3/return_in_sclass.txt", - - # Leaving these out until they are supported by parse.y. - "4.0/leading_logical.txt", - "4.0/endless_methods_command_call.txt", - "command_method_call_2.txt" + # https://bugs.ruby-lang.org/issues/21168#note-5 + "command_method_call_2.txt", ] - Fixture.each(except: except) do |fixture| + Fixture.each_for_current_ruby(except: except) do |fixture| define_method(fixture.test_name) { assert_locals(fixture) } end diff --git a/test/prism/ruby/parser_test.rb b/test/prism/ruby/parser_test.rb index 648c44e77a..c972f0962b 100644 --- a/test/prism/ruby/parser_test.rb +++ b/test/prism/ruby/parser_test.rb @@ -65,15 +65,6 @@ class ParserTest < TestCase # 1.. && 2 "ranges.txt", - # https://bugs.ruby-lang.org/issues/20478 - "3.4/circular_parameters.txt", - - # Cannot yet handling leading logical operators. - "4.0/leading_logical.txt", - - # Ruby >= 4.0 specific syntax - "4.0/endless_methods_command_call.txt", - # https://bugs.ruby-lang.org/issues/21168#note-5 "command_method_call_2.txt", ] @@ -148,7 +139,7 @@ class ParserTest < TestCase "whitequark/space_args_block.txt" ] - Fixture.each(except: skip_syntax_error) do |fixture| + Fixture.each_for_version(except: skip_syntax_error, version: "3.3") do |fixture| define_method(fixture.test_name) do assert_equal_parses( fixture, @@ -171,7 +162,7 @@ def test_non_prism_builder_class_deprecated if RUBY_VERSION >= "3.3" def test_current_parser_for_current_ruby - major, minor = current_major_minor.split(".") + major, minor = CURRENT_MAJOR_MINOR.split(".") # Let's just hope there never is a Ruby 3.10 or similar expected = major.to_i * 10 + minor.to_i assert_equal(expected, Translation::ParserCurrent.new.version) diff --git a/test/prism/ruby/ripper_test.rb b/test/prism/ruby/ripper_test.rb index 400139acc0..bd63302efc 100644 --- a/test/prism/ruby/ripper_test.rb +++ b/test/prism/ruby/ripper_test.rb @@ -8,44 +8,34 @@ module Prism class RipperTest < TestCase # Skip these tests that Ripper is reporting the wrong results for. incorrect = [ - # Not yet supported. - "4.0/leading_logical.txt", - # Ripper incorrectly attributes the block to the keyword. - "seattlerb/block_break.txt", - "seattlerb/block_next.txt", "seattlerb/block_return.txt", - "whitequark/break_block.txt", - "whitequark/next_block.txt", "whitequark/return_block.txt", - # Ripper is not accounting for locals created by patterns using the ** - # operator within an `in` clause. - "seattlerb/parse_pattern_058.txt", - # Ripper cannot handle named capture groups in regular expressions. "regex.txt", - "regex_char_width.txt", - "whitequark/lvar_injecting_match.txt", # Ripper fails to understand some structures that span across heredocs. "spanning_heredoc.txt", - "3.3-3.3/block_args_in_array_assignment.txt", - "3.3-3.3/it_with_ordinary_parameter.txt", - "3.3-3.3/keyword_args_in_array_assignment.txt", - "3.3-3.3/return_in_sclass.txt", - - # https://bugs.ruby-lang.org/issues/20478 + # Ripper interprets circular keyword arguments as method calls. "3.4/circular_parameters.txt", - # https://bugs.ruby-lang.org/issues/17398#note-12 + # Ripper doesn't emit `args_add_block` when endless method is prefixed by modifier. "4.0/endless_methods_command_call.txt", # https://bugs.ruby-lang.org/issues/21168#note-5 "command_method_call_2.txt", ] + if RUBY_VERSION.start_with?("3.3.") + incorrect += [ + "whitequark/lvar_injecting_match.txt", + "seattlerb/parse_pattern_058.txt", + "regex_char_width.txt", + ] + end + # Skip these tests that we haven't implemented yet. omitted = [ "dos_endings.txt", @@ -68,7 +58,7 @@ class RipperTest < TestCase "whitequark/slash_newline_in_heredocs.txt" ] - Fixture.each(except: incorrect | omitted) do |fixture| + Fixture.each_for_current_ruby(except: incorrect | omitted) do |fixture| define_method(fixture.test_name) { assert_ripper(fixture.read) } end diff --git a/test/prism/snapshots_test.rb b/test/prism/snapshots_test.rb index 58627e3668..23e5c9c087 100644 --- a/test/prism/snapshots_test.rb +++ b/test/prism/snapshots_test.rb @@ -36,7 +36,7 @@ def teardown ) end - Fixture.each_with_version(except: except) do |fixture, version| + Fixture.each_with_all_versions(except: except) do |fixture, version| define_method(fixture.test_name(version)) { assert_snapshot(fixture, version) } end diff --git a/test/prism/snippets_test.rb b/test/prism/snippets_test.rb index 3160442cc0..3c28d27a25 100644 --- a/test/prism/snippets_test.rb +++ b/test/prism/snippets_test.rb @@ -18,7 +18,7 @@ class SnippetsTest < TestCase "whitequark/multiple_pattern_matches.txt" ] - Fixture.each_with_version(except: except) do |fixture, version| + Fixture.each_with_all_versions(except: except) do |fixture, version| define_method(fixture.test_name(version)) { assert_snippets(fixture, version) } end diff --git a/test/prism/test_helper.rb b/test/prism/test_helper.rb index 42555738cf..f78e68e87c 100644 --- a/test/prism/test_helper.rb +++ b/test/prism/test_helper.rb @@ -72,7 +72,18 @@ def self.each(except: [], &block) paths.each { |path| yield Fixture.new(path) } end - def self.each_with_version(except: [], &block) + def self.each_for_version(except: [], version:, &block) + each(except: except) do |fixture| + next unless TestCase.ruby_versions_for(fixture.path).include?(version) + yield fixture + end + end + + def self.each_for_current_ruby(except: [], &block) + each_for_version(except: except, version: CURRENT_MAJOR_MINOR, &block) + end + + def self.each_with_all_versions(except: [], &block) each(except: except) do |fixture| TestCase.ruby_versions_for(fixture.path).each do |version| yield fixture, version @@ -232,6 +243,9 @@ def self.windows? # All versions that prism can parse SYNTAX_VERSIONS = %w[3.3 3.4 4.0] + # `RUBY_VERSION` with the patch version excluded + CURRENT_MAJOR_MINOR = RUBY_VERSION.split(".")[0, 2].join(".") + # Returns an array of ruby versions that a given filepath should test against: # test.txt # => all available versions # 3.4/test.txt # => versions since 3.4 (inclusive) @@ -250,13 +264,9 @@ def self.ruby_versions_for(filepath) end end - def current_major_minor - RUBY_VERSION.split(".")[0, 2].join(".") - end - if RUBY_VERSION >= "3.3.0" def test_all_syntax_versions_present - assert_include(SYNTAX_VERSIONS, current_major_minor) + assert_include(SYNTAX_VERSIONS, CURRENT_MAJOR_MINOR) end end