From 6cd4371034bd08f67d05cd89d9c4523a1075ad77 Mon Sep 17 00:00:00 2001 From: Ostap Brehin Date: Tue, 30 Jul 2024 06:27:19 +0100 Subject: [PATCH] Fix conversion of multiple `<<` to multiple `.push` calls --- lib/ruby2js/converter/send.rb | 24 ++++++++++++++++++++++-- spec/transliteration_spec.rb | 8 ++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/ruby2js/converter/send.rb b/lib/ruby2js/converter/send.rb index fec5a6de..312c6555 100644 --- a/lib/ruby2js/converter/send.rb +++ b/lib/ruby2js/converter/send.rb @@ -233,8 +233,28 @@ class Converter elsif method == :!~ put '!'; parse args.first; put '.test('; parse receiver; put ')' - elsif method == :<< and args.length == 1 and @state == :statement - parse receiver; put '.push('; parse args.first; put ')' + elsif method == :<< + if @state == :statement + # Handle chained << operations by converting them to push() method calls + current = receiver + operations = [args.first] + + # Traverse the AST to collect all chained << operations + while current.type == :send && current.children[1] == :<< + operations.unshift(current.children[2]) + current = current.children[0] + end + + # Generate a series of push() calls for each operation in the chain + operations.each do |arg| + parse current ; put '.push(' ; parse arg ; put ')' + put '; ' unless arg == operations.last + end + else + # If not in statement context, fall back to original behavior + group_receiver ? group(receiver) : parse(receiver) + put " << " ; group_target ? group(args.first) : parse(args.first) + end elsif method == :<=> parse receiver; put ' < '; parse args.first; put ' ? -1 : ' diff --git a/spec/transliteration_spec.rb b/spec/transliteration_spec.rb index 471a3e76..7b838744 100644 --- a/spec/transliteration_spec.rb +++ b/spec/transliteration_spec.rb @@ -364,12 +364,16 @@ def to_js( string, opts={} ) to_js('x = ()').must_equal 'var x = null' end end - + describe 'array push' do it "should convert << statements to .push calls" do to_js( 'a << b' ).must_equal 'a.push(b)' end - + + it "should convert multiple << statements to multiple .push calls" do + to_js( 'a << b << c << d << e' ).must_equal 'a.push(b); a.push(c); a.push(d); a.push(e)' + end + it "should leave << expressions alone" do to_js( 'y = a << b' ).must_equal 'var y = a << b' end