diff --git a/lib/ruby2js/converter/send.rb b/lib/ruby2js/converter/send.rb index fec5a6d..312c655 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 471a3e7..7b83874 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