Skip to content

Commit a83cb7b

Browse files
committed
Handle String-like objects for Ripper.sexp
* RSpec relies on this in https://github.com/rspec/rspec/blob/rspec-support-v3.13.6/rspec-support/lib/rspec/support/source.rb#L57 which is given an RSpec::Support::EncodedString. * CI failure caused by this on truffleruby: https://github.com/sporkmonger/addressable/actions/runs/21457707372/job/61802608154#step:7:14
1 parent e8c6b49 commit a83cb7b

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

lib/prism/translation/ripper.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,17 @@ def self.lex_state_name(state)
480480

481481
# Create a new Translation::Ripper object with the given source.
482482
def initialize(source, filename = "(ripper)", lineno = 1)
483-
@source = source
483+
if source.is_a?(IO)
484+
@source = source.read
485+
elsif source.respond_to?(:gets)
486+
@source = +""
487+
while line = source.gets
488+
@source << line
489+
end
490+
else
491+
@source = source.to_str
492+
end
493+
484494
@filename = filename
485495
@lineno = lineno
486496
@column = 0

test/prism/ruby/ripper_test.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,36 @@ def test_tokenize
145145
assert_equal(Ripper.tokenize(source), Translation::Ripper.tokenize(source))
146146
end
147147

148+
def test_sexp_coercion
149+
string_like = Object.new
150+
def string_like.to_str
151+
"a"
152+
end
153+
assert_equal Ripper.sexp(string_like), Translation::Ripper.sexp(string_like)
154+
155+
File.open(__FILE__) do |file1|
156+
File.open(__FILE__) do |file2|
157+
assert_equal Ripper.sexp(file1), Translation::Ripper.sexp(file2)
158+
end
159+
end
160+
161+
File.open(__FILE__) do |file1|
162+
File.open(__FILE__) do |file2|
163+
object1_with_gets = Object.new
164+
object1_with_gets.define_singleton_method(:gets) do
165+
file1.gets
166+
end
167+
168+
object2_with_gets = Object.new
169+
object2_with_gets.define_singleton_method(:gets) do
170+
file2.gets
171+
end
172+
173+
assert_equal Ripper.sexp(object1_with_gets), Translation::Ripper.sexp(object2_with_gets)
174+
end
175+
end
176+
end
177+
148178
# Check that the hardcoded values don't change without us noticing.
149179
def test_internals
150180
actual = Translation::Ripper.constants.select { |name| name.start_with?("EXPR_") }.sort

0 commit comments

Comments
 (0)