Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions lib/prism/translation/ripper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,12 @@ def parse
bounds(location)

if comment.is_a?(InlineComment)
on_comment(comment.slice)
# Inline comments always contain a newline if the line itself contains it
if result.source.source.bytesize > comment.location.end_offset
on_comment("#{comment.slice}\n")
else
on_comment(comment.slice)
end
else
offset = location.start_offset
lines = comment.slice.lines
Expand Down Expand Up @@ -1577,7 +1582,6 @@ def visit_constant_path_write_node(node)
# ^^^^^^^^^^^^^^^
def visit_constant_path_operator_write_node(node)
target = visit_constant_path_write_node_target(node.target)
value = visit(node.value)

bounds(node.binary_operator_loc)
operator = on_op("#{node.binary_operator}=")
Expand All @@ -1591,7 +1595,6 @@ def visit_constant_path_operator_write_node(node)
# ^^^^^^^^^^^^^^^^
def visit_constant_path_and_write_node(node)
target = visit_constant_path_write_node_target(node.target)
value = visit(node.value)

bounds(node.operator_loc)
operator = on_op("&&=")
Expand All @@ -1605,7 +1608,6 @@ def visit_constant_path_and_write_node(node)
# ^^^^^^^^^^^^^^^^
def visit_constant_path_or_write_node(node)
target = visit_constant_path_write_node_target(node.target)
value = visit(node.value)

bounds(node.operator_loc)
operator = on_op("||=")
Expand Down Expand Up @@ -2357,6 +2359,8 @@ def visit_lambda_node(node)
visit(node.parameters.parameters)
end

visit_all(node.parameters.locals)

if node.parameters.opening_loc.nil?
params
else
Expand Down
63 changes: 49 additions & 14 deletions test/prism/ruby/ripper_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,41 @@ class RipperTest < TestCase
"whitequark/procarg0.txt",
]

omitted_scan = [
"dos_endings.txt",
"heredocs_with_fake_newlines.txt",
"rescue_modifier.txt",
"seattlerb/block_call_dot_op2_brace_block.txt",
"seattlerb/block_command_operation_colon.txt",
"seattlerb/block_command_operation_dot.txt",
"seattlerb/case_in.txt",
"seattlerb/heredoc__backslash_dos_format.txt",
"seattlerb/heredoc_backslash_nl.txt",
"seattlerb/heredoc_nested.txt",
"seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt",
"seattlerb/heredoc_squiggly_empty.txt",
"seattlerb/masgn_command_call.txt",
"seattlerb/messy_op_asgn_lineno.txt",
"seattlerb/op_asgn_primary_colon_const_command_call.txt",
"seattlerb/parse_pattern_076.txt",
"tilde_heredocs.txt",
"unparser/corpus/literal/assignment.txt",
"unparser/corpus/literal/pattern.txt",
"unparser/corpus/semantic/dstr.txt",
"variables.txt",
"whitequark/dedenting_heredoc.txt",
"whitequark/masgn_nested.txt",
"whitequark/numparam_ruby_bug_19025.txt",
"whitequark/op_asgn_cmd.txt",
"whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt",
"whitequark/parser_slash_slash_n_escaping_in_literals.txt",
"whitequark/pattern_matching_nil_pattern.txt",
"whitequark/ruby_bug_12402.txt",
"whitequark/ruby_bug_18878.txt",
"whitequark/send_block_chain_cmd.txt",
"whitequark/slash_newline_in_heredocs.txt",
]

Fixture.each_for_current_ruby(except: incorrect | omitted_sexp_raw) do |fixture|
define_method("#{fixture.test_name}_sexp_raw") { assert_ripper_sexp_raw(fixture.read) }
end
Expand All @@ -100,6 +135,9 @@ def test_lex_ignored_missing_heredoc_end
end
end

UNSUPPORTED_EVENTS = %i[backtick comma heredoc_beg heredoc_end ignored_nl kw label_end lbrace lbracket lparen nl op rbrace rbracket rparen semicolon sp symbeg tstring_beg tstring_end words_sep ignored_sp]
SUPPORTED_EVENTS = Translation::Ripper::EVENTS - UNSUPPORTED_EVENTS

module Events
attr_reader :events

Expand All @@ -108,9 +146,9 @@ def initialize(...)
@events = []
end

Prism::Translation::Ripper::PARSER_EVENTS.each do |event|
SUPPORTED_EVENTS.each do |event|
define_method(:"on_#{event}") do |*args|
@events << [event, *args]
@events << [event, *args.map(&:to_s)]
super(*args)
end
end
Expand All @@ -126,28 +164,25 @@ class PrismEvents < Translation::Ripper

class ObjectEvents < Translation::Ripper
OBJECT = BasicObject.new
Prism::Translation::Ripper::PARSER_EVENTS.each do |event|
SUPPORTED_EVENTS.each do |event|
define_method(:"on_#{event}") { |*args| OBJECT }
end
end

Fixture.each_for_current_ruby(except: incorrect) do |fixture|
Fixture.each_for_current_ruby(except: incorrect | omitted_scan) do |fixture|
define_method("#{fixture.test_name}_events") do
source = fixture.read
# Similar to test/ripper/assert_parse_files.rb in CRuby
object_events = ObjectEvents.new(source)
assert_nothing_raised { object_events.parse }
end
end

def test_events
source = "1 rescue 2"
ripper = RipperEvents.new(source)
prism = PrismEvents.new(source)
ripper.parse
prism.parse
# This makes sure that the content is the same. Ordering is not correct for now.
assert_equal(ripper.events.sort, prism.events.sort)
ripper = RipperEvents.new(source)
prism = PrismEvents.new(source)
ripper.parse
prism.parse
# This makes sure that the content is the same. Ordering is not correct for now.
assert_equal(ripper.events.sort, prism.events.sort)
end
end

def test_lexer
Expand Down