From 510258aa2b01f0819acb225bd31429a817006cb9 Mon Sep 17 00:00:00 2001 From: Earlopain <14981592+Earlopain@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:18:34 +0100 Subject: [PATCH] Also handle string conversion in `Ripper.lex` In `ripper`, both go through the same converion logic. Needed for rspec, no other failures in their own tests --- lib/prism/translation/ripper.rb | 29 +++++++++++++++++------------ test/prism/ruby/ripper_test.rb | 8 ++++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb index e1dec0b47e..7e2125be09 100644 --- a/lib/prism/translation/ripper.rb +++ b/lib/prism/translation/ripper.rb @@ -69,7 +69,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, version: "current") + result = Prism.lex_compat(coerce_source(src), filepath: filename, line: lineno, version: "current") if result.failure? && raise_errors raise SyntaxError, result.errors.first.message @@ -91,6 +91,21 @@ def self.tokenize(...) lex(...).map { |token| token[2] } end + # Mirros the various lex_types that ripper supports + def self.coerce_source(source) # :nodoc: + if source.is_a?(IO) + source.read + elsif source.respond_to?(:gets) + src = +"" + while line = source.gets + src << line + end + src + else + source.to_str + end + end + # This contains a table of all of the parser events and their # corresponding arity. PARSER_EVENT_TABLE = { @@ -480,17 +495,7 @@ def self.lex_state_name(state) # Create a new Translation::Ripper object with the given source. def initialize(source, filename = "(ripper)", lineno = 1) - if source.is_a?(IO) - @source = source.read - elsif source.respond_to?(:gets) - @source = +"" - while line = source.gets - @source << line - end - else - @source = source.to_str - end - + @source = Ripper.coerce_source(source) @filename = filename @lineno = lineno @column = 0 diff --git a/test/prism/ruby/ripper_test.rb b/test/prism/ruby/ripper_test.rb index 8c80b9f886..3a0f666fff 100644 --- a/test/prism/ruby/ripper_test.rb +++ b/test/prism/ruby/ripper_test.rb @@ -243,6 +243,14 @@ def string_like.to_str end end + def test_lex_coersion + string_like = Object.new + def string_like.to_str + "a" + end + assert_equal Ripper.lex(string_like), Translation::Ripper.lex(string_like) + end + # Check that the hardcoded values don't change without us noticing. def test_internals actual = Translation::Ripper.constants.select { |name| name.start_with?("EXPR_") }.sort