Skip to content

Commit 62c7300

Browse files
authored
Merge pull request #3891 from eregon/ripper-sexp-coerce
Handle String-like and IO-like objects for Ripper.sexp
2 parents e8c6b49 + a83cb7b commit 62c7300

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

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)