test/pt_testcase.rb in ParseTree-2.0.2 vs test/pt_testcase.rb in ParseTree-2.1.0

- old
+ new

@@ -2,10 +2,13 @@ require 'test/unit/testcase' require 'sexp_processor' # for deep_clone require 'unique' +# key: +# wwtt = what were they thinking? + class Examples attr_reader :reader attr_writer :writer def a_method(x); x+1; end @@ -69,16 +72,30 @@ "ParseTree" => [:class, :X, nil, [:scope, [:alias, [:lit, :y], [:lit, :x]]]], "Ruby2Ruby" => "class X\n alias_method :y, :x\nend", }, + "alias_ugh" => { + "Ruby" => "class X\n alias y x\nend", + "ParseTree" => [:class, :X, nil, + [:scope, [:alias, [:lit, :y], [:lit, :x]]]], + "Ruby2Ruby" => "class X\n alias_method :y, :x\nend", + }, + "and" => { "Ruby" => "(a and b)", "ParseTree" => [:and, [:vcall, :a], [:vcall, :b]], }, - "argscat" => { + "argscat_inside" => { + "Ruby" => "a = [b, *c]", + "ParseTree" => [:lasgn, :a, + [:argscat, [:array, [:vcall, :b]], [:vcall, :c]]], + "Ruby2Ruby" => "a = b, *c", + }, + + "argscat_svalue" => { "Ruby" => "a = b, c, *d", "ParseTree" => [:lasgn, :a, [:svalue, [:argscat, [:array, [:vcall, :b], [:vcall, :c]], @@ -96,10 +113,18 @@ "array" => { "Ruby" => "[1, :b, \"c\"]", "ParseTree" => [:array, [:lit, 1], [:lit, :b], [:str, "c"]], }, + "array_pct_W" => { + "Ruby" => "%W[--remove #\{@gem_repo}]", + "ParseTree" => [:array, + [:str, "--remove"], + [:dstr, "", [:evstr, [:ivar, :@gem_repo]]]], + "Ruby2Ruby" => "[\"--remove\", \"#\{@gem_repo}\"]", + }, + "attrasgn" => { "Ruby" => "y = 0\n42.method = y\n", "ParseTree" => [:block, [:lasgn, :y, [:lit, 0]], [:attrasgn, [:lit, 42], :method=, [:array, [:lvar, :y]]]], @@ -128,30 +153,62 @@ "begin" => { "Ruby" => "begin\n (1 + 1)\nend", "ParseTree" => [:begin, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], }, + "begin_def" => { + "Ruby" => "def m\n begin\n\n end\nend", + "ParseTree" => [:defn, :m, [:scope, [:block, [:args], [:nil]]]], + "Ruby2Ruby" => "def m\n # do nothing\nend", + }, + "begin_rescue_ensure" => { - "Ruby" => "begin\n rescue\n # do nothing\n ensure\n nil\nend", + "Ruby" => "begin\nrescue\n # do nothing\nensure\n nil\nend", "ParseTree" => [:begin, [:ensure, [:rescue, [:resbody, nil]], [:nil]]] }, + "begin_rescue_twice" => { # testing block/begin processing really + "Ruby" => "begin\nrescue => mes\n # do nothing\nend\nbegin\nrescue => mes\n # do nothing\nend\n", + "ParseTree" => [:block, + [:rescue, + [:resbody, nil, + [:lasgn, :mes, [:gvar, :$!]]]], + [:begin, + [:rescue, + [:resbody, nil, + [:lasgn, :mes, [:gvar, :$!]]]]]], + }, + "block_lasgn" => { "Ruby" => "x = (y = 1\n(y + 2))", "ParseTree" => [:lasgn, :x, [:block, [:lasgn, :y, [:lit, 1]], [:call, [:lvar, :y], :+, [:array, [:lit, 2]]]]], }, - "block_pass" => { - "Ruby" => "a(&b)", - "ParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]], + "block_mystery_block" => { # FIX: I don't like that extra return + "Ruby" => "a(b) do\n if b then\n true\n else\n c = false\n d { |x| c = true }\n c\n \n end\nend", + "ParseTree" => [:iter, + [:fcall, :a, [:array, [:vcall, :b]]], + nil, + [:block, + [:dasgn_curr, :c], + [:if, + [:vcall, :b], + [:true], + [:block, + [:dasgn_curr, :c, [:false]], + [:iter, + [:fcall, :d], + [:dasgn_curr, :x], + [:dasgn, :c, [:true]]], + [:dvar, :c]]]]], }, "block_pass_args_and_splat" => { "Ruby" => "def blah(*args, &block)\n other(42, *args, &block)\nend", "ParseTree" => [:defn, :blah, @@ -163,10 +220,50 @@ [:lvar, :block], [:fcall, :other, [:argscat, [:array, [:lit, 42]], [:lvar, :args]]]]]]], }, + "block_pass_call_0" => { + "Ruby" => "a.b(&c)", + "ParseTree" => [:block_pass, [:vcall, :c], [:call, [:vcall, :a], :b]], + }, + + "block_pass_call_1" => { + "Ruby" => "a.b(4, &c)", + "ParseTree" => [:block_pass, + [:vcall, :c], + [:call, [:vcall, :a], :b, [:array, [:lit, 4]]]], + }, + + "block_pass_call_n" => { + "Ruby" => "a.b(1, 2, 3, &c)", + "ParseTree" => [:block_pass, + [:vcall, :c], + [:call, [:vcall, :a], :b, + [:array, [:lit, 1], [:lit, 2], [:lit, 3]]]], + }, + + "block_pass_fcall_0" => { + "Ruby" => "a(&b)", + "ParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]], + }, + + "block_pass_fcall_1" => { + "Ruby" => "a(4, &b)", + "ParseTree" => [:block_pass, + [:vcall, :b], + [:fcall, :a, [:array, [:lit, 4]]]], + }, + + "block_pass_fcall_n" => { + "Ruby" => "a(1, 2, 3, &b)", + "ParseTree" => [:block_pass, + [:vcall, :b], + [:fcall, :a, + [:array, [:lit, 1], [:lit, 2], [:lit, 3]]]], + }, + "block_pass_omgwtf" => { "Ruby" => "define_attr_method(:x, :sequence_name, &Proc.new { |*args| nil })", "ParseTree" => [:block_pass, [:iter, [:call, [:const, :Proc], :new], @@ -186,10 +283,56 @@ [:block_pass, [:lvar, :block], [:fcall, :other, [:splat, [:lvar, :args]]]]]]], }, + "block_pass_thingy" => { + "Ruby" => "r.read_body(dest, &block)", + "ParseTree" => [:block_pass, + [:vcall, :block], + [:call, [:vcall, :r], :read_body, + [:array, [:vcall, :dest]]]], + }, + + "block_stmt_after" => { + "Ruby" => "def f\n begin\n b\n rescue\n c\n end\n\n d\nend", + "ParseTree" => [:defn, + :f, + [:scope, + [:block, + [:args], + [:rescue, [:vcall, :b], [:resbody, nil, [:vcall, :c]]], + [:vcall, :d]]]], + "Ruby2Ruby" => "def f\n b rescue c\n d\nend", + }, + + "block_stmt_before" => { + "Ruby" => "def f\n a\n begin\n b\n rescue\n c\n end\nend", + "ParseTree" => [:defn, + :f, + [:scope, + [:block, + [:args], + [:vcall, :a], + [:begin, + [:rescue, [:vcall, :b], + [:resbody, nil, [:vcall, :c]]]]]]], + }, + + "block_stmt_both" => { + "Ruby" => "def f\n a\n begin\n b\n rescue\n c\n end\n d\nend", + "ParseTree" => [:defn, + :f, + [:scope, + [:block, + [:args], + [:vcall, :a], + [:rescue, [:vcall, :b], [:resbody, nil, [:vcall, :c]]], + [:vcall, :d]]]], + "Ruby2Ruby" => "def f\n a\n b rescue c\n d\nend", + }, + "bmethod" => { "Ruby" => [Examples, :unsplatted], "ParseTree" => [:defn, :unsplatted, [:bmethod, @@ -236,14 +379,47 @@ "Ruby" => "self.method", "ParseTree" => [:call, [:self], :method], }, "call_arglist" => { - "Ruby" => "puts(42)", - "ParseTree" => [:fcall, :puts, [:array, [:lit, 42]]], + "Ruby" => "o.puts(42)", + "ParseTree" => [:call, [:vcall, :o], :puts, [:array, [:lit, 42]]], }, + "call_arglist_hash" => { + "Ruby" => "o.m(:a => 1, :b => 2)", + "ParseTree" => [:call, + [:vcall, :o], :m, + [:array, + [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]], + }, + + "call_arglist_norm_hash" => { + "Ruby" => "o.m(42, :a => 1, :b => 2)", + "ParseTree" => [:call, + [:vcall, :o], :m, + [:array, + [:lit, 42], + [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]], + }, + + "call_arglist_norm_hash_splat" => { + "Ruby" => "o.m(42, :a => 1, :b => 2, *c)", + "ParseTree" => [:call, + [:vcall, :o], :m, + [:argscat, + [:array, + [:lit, 42], + [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]], + [:vcall, :c]]], + }, + + "call_command" => { + "Ruby" => "1.b(c)", + "ParseTree" => [:call, [:lit, 1], :b, [:array, [:vcall, :c]]], + }, + "call_expr" => { "Ruby" => "(v = (1 + 1)).zero?", "ParseTree" => [:call, [:lasgn, :v, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], @@ -253,10 +429,23 @@ "call_index" => { # see attrasgn_index_equals for opposite "Ruby" => "a[42]", "ParseTree" => [:call, [:vcall, :a], :[], [:array, [:lit, 42]]], }, + "call_index_no_args" => { + "Ruby" => "a[]", + "ParseTree" => [:call, [:vcall, :a], :[]], + }, + + "call_unary_neg" => { + "Ruby" => "-2**31", + "ParseTree" => [:call, + [:call, [:lit, 2], :**, [:array, [:lit, 31]]], + :-@], + "Ruby2Ruby" => "-(2 ** 31)", + }, + "case" => { "Ruby" => "var = 2\nresult = \"\"\ncase var\nwhen 1 then\n puts(\"something\")\n result = \"red\"\nwhen 2, 3 then\n result = \"yellow\"\nwhen 4 then\n # do nothing\nelse\n result = \"green\"\nend\ncase result\nwhen \"red\" then\n var = 1\nwhen \"yellow\" then\n var = 2\nwhen \"green\" then\n var = 3\nelse\n # do nothing\nend\n", "ParseTree" => [:block, [:lasgn, :var, [:lit, 2]], [:lasgn, :result, [:str, ""]], @@ -308,21 +497,42 @@ [:lasgn, :result, [:lit, 5]]], [:lasgn, :result, [:lit, 6]]]], [:lasgn, :result, [:lit, 7]]]] }, + "case_nested_inner_no_expr" => { + "Ruby" => "case a\nwhen b then\n case\n when (d and e) then\n f\n else\n # do nothing\n end\nelse\n # do nothing\nend", + "ParseTree" => [:case, [:vcall, :a], + [:when, [:array, [:vcall, :b]], + [:case, nil, + [:when, [:array, [:and, [:vcall, :d], [:vcall, :e]]], + [:vcall, :f]], + nil]], + nil], + }, + "case_no_expr" => { # TODO: nested - "Ruby" => "case\nwhen 1 then\n :a\nwhen 2 then\n :b\nelse\n :c\nend", + "Ruby" => "case\nwhen (a == 1) then\n :a\nwhen (a == 2) then\n :b\nelse\n :c\nend", "ParseTree" => [:case, nil, [:when, - [:array, [:lit, 1]], + [:array, [:call, [:vcall, :a], :==, [:array, [:lit, 1]]]], [:lit, :a]], [:when, - [:array, [:lit, 2]], [:lit, :b]], + [:array, [:call, [:vcall, :a], :==, [:array, [:lit, 2]]]], + [:lit, :b]], [:lit, :c]], }, + "case_splat" => { + "Ruby" => "case a\nwhen :b, *c then\n d\nelse\n e\nend", + "ParseTree" => [:case, [:vcall, :a], + [:when, + [:array, [:lit, :b], [:when, [:vcall, :c], nil]], # wtf? + [:vcall, :d]], + [:vcall, :e]], + }, + "cdecl" => { "Ruby" => "X = 42", "ParseTree" => [:cdecl, :X, [:lit, 42]], }, @@ -414,10 +624,56 @@ "conditional5" => { "Ruby" => "return if false unless true", "ParseTree" => [:if, [:true], nil, [:if, [:false], [:return], nil]], }, + "conditional_post_if" => { + "Ruby" => "a if b", + "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil], + }, + + "conditional_post_if_not" => { + "Ruby" => "a if not b", + "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]], + "Ruby2Ruby" => "a unless b" + }, + + "conditional_post_unless" => { + "Ruby" => "a unless b", + "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]], + }, + + "conditional_post_unless_not" => { + "Ruby" => "a unless not b", + "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil], + "Ruby2Ruby" => "a if b" + }, + + "conditional_pre_if" => { + "Ruby" => "if b then a end", + "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil], + "Ruby2Ruby" => "a if b" + }, + + "conditional_pre_if_not" => { + "Ruby" => "if not b then a end", + "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]], + "Ruby2Ruby" => "a unless b" + }, + + "conditional_pre_unless" => { + "Ruby" => "unless b then a end", + "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]], + "Ruby2Ruby" => "a unless b" + }, + + "conditional_pre_unless_not" => { + "Ruby" => "unless not b then a end", + "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil], + "Ruby2Ruby" => "a if b" + }, + "const" => { "Ruby" => "X", "ParseTree" => [:const, :X], }, @@ -431,28 +687,87 @@ "ParseTree" => [:defn, :x, [:scope, [:block, [:args], [:cvasgn, :@@blah, [:lit, 1]]]]] }, + "cvasgn_cls_method" => { + "Ruby" => "def self.quiet_mode=(boolean)\n @@quiet_mode = boolean\nend", + "ParseTree" => [:defs, [:self], :quiet_mode=, [:scope, [:block, [:args, :boolean], [:cvasgn, :@@quiet_mode, [:lvar, :boolean]]]]], + }, + "cvdecl" => { "Ruby" => "class X\n @@blah = 1\nend", "ParseTree" => [:class, :X, nil, [:scope, [:cvdecl, :@@blah, [:lit, 1]]]], }, - "dasgn" => { - "Ruby" => "a.each { |x| b.each { |y| x = (x + 1) } }", + "dasgn_0" => { + "Ruby" => "a.each { |x| b.each { |y| x = (x + 1) } if true }", "ParseTree" => [:iter, [:call, [:vcall, :a], :each], [:dasgn_curr, :x], - [:iter, - [:call, [:vcall, :b], :each], - [:dasgn_curr, :y], - [:dasgn, :x, - [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]], + [:if, [:true], + [:iter, + [:call, [:vcall, :b], :each], + [:dasgn_curr, :y], + [:dasgn, :x, + [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]], + nil]], }, + "dasgn_1" => { # without mystery block / dasgn_curr + "Ruby" => "a.each { |x| b.each { |y| c = (c + 1) } if true }", + "ParseTree" => [:iter, + [:call, [:vcall, :a], :each], + [:dasgn_curr, :x], + [:if, [:true], + [:iter, + [:call, [:vcall, :b], :each], + [:dasgn_curr, :y], + [:dasgn_curr, :c, + [:call, [:dvar, :c], :+, [:array, [:lit, 1]]]]], + nil]], + }, + + "dasgn_2" => { # WITH mystery block / dasgn_curr + "Ruby" => "a.each do |x|\n if true then\n c = 0\n b.each { |y| c = (c + 1) }\n \n end\nend", # FIX: hate that extra newline! + "ParseTree" => [:iter, + [:call, [:vcall, :a], :each], + [:dasgn_curr, :x], + [:block, + [:dasgn_curr, :c], + [:if, [:true], + [:block, + [:dasgn_curr, :c, [:lit, 0]], + [:iter, + [:call, [:vcall, :b], :each], + [:dasgn_curr, :y], + [:dasgn, :c, + [:call, [:dvar, :c], :+, [:array, [:lit, 1]]]]]], + nil]]], + }, + + "dasgn_icky" => { # WITH mystery block / dasgn_curr + "Ruby" => "a do\n v = nil\n assert_block(full_message) do\n begin\n yield\n rescue Exception => v\n break\n end\n end\nend", + "ParseTree" => [:iter, + [:fcall, :a], + nil, + [:block, + [:dasgn_curr, :v], + [:dasgn_curr, :v, [:nil]], + [:iter, + [:fcall, :assert_block, + [:array, [:vcall, :full_message]]], + nil, + [:begin, + [:rescue, + [:yield], + [:resbody, + [:array, [:const, :Exception]], + [:block, [:dasgn, :v, [:gvar, :$!]], [:break]]]]]]]], + }, + "dasgn_curr" => { "Ruby" => "data.each do |x, y|\n a = 1\n b = a\n b = a = x\nend", "ParseTree" => [:iter, [:call, [:vcall, :data], :each], [:masgn, [:array, [:dasgn_curr, :x], [:dasgn_curr, :y]]], @@ -460,38 +775,128 @@ [:dasgn_curr, :a, [:lit, 1]], [:dasgn_curr, :b, [:dvar, :a]], [:dasgn_curr, :b, [:dasgn_curr, :a, [:dvar, :x]]]]], }, + "dasgn_mixed" => { + "Ruby" => "t = 0\nns.each { |n| t += n }\n", + "ParseTree" => [:block, + [:lasgn, :t, [:lit, 0]], + [:iter, + [:call, [:vcall, :ns], :each], + [:dasgn_curr, :n], + [:lasgn, :t, + [:call, [:lvar, :t], :+, [:array, [:dvar, :n]]]]]], + "Ruby2Ruby" => "t = 0\nns.each { |n| t = (t + n) }\n", + }, + "defined" => { "Ruby" => "defined? $x", "ParseTree" => [:defined, [:gvar, :$x]], }, - "defn_args" => { + "defn_args_mand_opt_block" => { + "Ruby" => "def x(a, b = 42, &d)\n p(a, b, d)\nend", + "ParseTree" => [:defn, :x, + [:scope, + [:block, + [:args, :a, :b, + [:block, [:lasgn, :b, [:lit, 42]]]], + [:block_arg, :d], + [:fcall, :p, + [:array, [:lvar, :a], [:lvar, :b], [:lvar, :d]]]]]] + }, + + "defn_args_mand_opt_splat" => { + "Ruby" => "def x(a, b = 42, *c)\n p(a, b, c)\nend", + "ParseTree" => [:defn, :x, + [:scope, + [:block, + [:args, :a, :b, :"*c", + [:block, [:lasgn, :b, [:lit, 42]]]], + [:fcall, :p, + [:array, [:lvar, :a], [:lvar, :b], [:lvar, :c]]]]]] + }, + + "defn_args_mand_opt_splat_block" => { "Ruby" => "def x(a, b = 42, \*c, &d)\n p(a, b, c, d)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, [:args, :a, :b, "*c".intern, # s->e [:block, [:lasgn, :b, [:lit, 42]]]], - [:block_arg, :d], + [:block_arg, :d], [:fcall, :p, - [:array, [:lvar, :a], [:lvar, :b], + [:array, + [:lvar, :a], [:lvar, :b], [:lvar, :c], [:lvar, :d]]]]]] }, + "defn_args_mand_opt_splat_no_name" => { + "Ruby" => "def x(a, b = 42, *)\n p(a, b)\nend", + "ParseTree" => [:defn, :x, + [:scope, + [:block, + [:args, :a, :b, :"*", + [:block, [:lasgn, :b, [:lit, 42]]]], + [:fcall, :p, + [:array, [:lvar, :a], [:lvar, :b]]]]]] + }, + + "defn_args_opt_block" => { + "Ruby" => "def x(b = 42, &d)\n p(b, d)\nend", + "ParseTree" => [:defn, :x, + [:scope, + [:block, + [:args, :b, + [:block, [:lasgn, :b, [:lit, 42]]]], + [:block_arg, :d], + [:fcall, :p, + [:array, [:lvar, :b], [:lvar, :d]]]]]] + }, + + "defn_args_opt_splat_no_name" => { + "Ruby" => "def x(b = 42, *)\n p(b)\nend", + "ParseTree" => [:defn, :x, + [:scope, + [:block, + [:args, :b, :"*", + [:block, [:lasgn, :b, [:lit, 42]]]], + [:fcall, :p, + [:array, [:lvar, :b]]]]]] + }, + "defn_empty" => { "Ruby" => "def empty\n # do nothing\nend", "ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:nil]]]], }, - "defn_is_something" => { - "Ruby" => "def something?\n # do nothing\nend", - "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]], + "defn_empty_args" => { + "Ruby" => "def empty(*)\n # do nothing\nend", + "ParseTree" => [:defn, :empty, [:scope, [:block, [:args, :*], [:nil]]]], }, + "defn_lvar_boundary" => { # FIX: add do nothing comment to block + "Ruby" => "mes = 42\ndef instantiate_all\n Thread.new do\n begin\n rescue RuntimeError => mes\n puts(mes)\n end\n end\nend\n", + "ParseTree" => [:block, + [:lasgn, :mes, [:lit, 42]], + [:defn, :instantiate_all, + [:scope, + [:block, + [:args], + [:iter, + [:call, [:const, :Thread], :new], + nil, + [:begin, + [:rescue, + [:resbody, + [:array, [:const, :RuntimeError]], + [:block, + [:dasgn_curr, :mes, [:gvar, :$!]], + [:fcall, :puts, [:array, [:dvar, :mes]]]]]]]]]]]], + }, + "defn_optargs" => { "Ruby" => "def x(a, *args)\n p(a, args)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, @@ -504,23 +909,29 @@ "Ruby" => "def |(o)\n # do nothing\nend", "ParseTree" => [:defn, :|, [:scope, [:block, [:args, :o], [:nil]]]], }, "defn_rescue" => { - "Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid) rescue false\nend", + "Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid)\nrescue\n false\nend", "ParseTree" => [:defn, :eql?, [:scope, [:block, [:args, :resource], [:rescue, [:call, [:call, [:self], :uuid], :==, [:array, [:call, [:lvar, :resource], :uuid]]], [:resbody, nil, [:false]]]]]], + "Ruby2Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid) rescue false\nend", }, + "defn_something_eh" => { + "Ruby" => "def something?\n # do nothing\nend", + "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]], + }, + "defn_splat_no_name" => { "Ruby" => "def x(a, *)\n p(a)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, @@ -544,10 +955,33 @@ [:block, [:args, :y], [:call, [:lvar, :y], :+, [:array, [:lit, 1]]]]]], }, + "defs_args_mand_opt_splat_block" => { + "Ruby" => "def self.x(a, b = 42, \*c, &d)\n (a + b)\nend", + "ParseTree" => [:defs, [:self], :x, + [:scope, + [:block, + [:args, :a, :b, :"*c", + [:block, [:lasgn, :b, [:lit, 42]]]], + [:block_arg, :d], + [:call, [:lvar, :a], :+, [:array, [:lvar, :b]]]]]], + }, + + "defs_empty" => { + "Ruby" => "def self.empty\n # do nothing\nend", + "ParseTree" => [:defs, [:self], :empty, + [:scope, [:args]]], + }, + + "defs_empty_args" => { + "Ruby" => "def self.empty(*)\n # do nothing\nend", + "ParseTree" => [:defs, [:self], :empty, + [:scope, [:args, :*]]], + }, + "dmethod" => { "Ruby" => [Examples, :dmethod_added], "ParseTree" => [:defn, :dmethod_added, [:dmethod, @@ -570,51 +1004,140 @@ }, "dregx" => { "Ruby" => "/x#\{(1 + 1)}y/", "ParseTree" => [:dregx, "x", - [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]], + [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], [:str, "y"]], }, + "dregx_interp" => { + "Ruby" => "/#\{@rakefile}/", + "ParseTree" => [:dregx, '', [:evstr, [:ivar, :@rakefile]]], + }, + + "dregx_n" => { + "Ruby" => '/#{1}/n', + "ParseTree" => [:dregx, '', [:evstr, [:lit, 1]], 16], # TODO: use consts + "Ruby2Ruby" => "/#\{1}/", # HACK - need to support regexp flags + }, + "dregx_once" => { "Ruby" => "/x#\{(1 + 1)}y/o", "ParseTree" => [:dregx_once, "x", - [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]], + [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], [:str, "y"]], }, + "dregx_once_n_interp" => { + "Ruby" => "/#\{IAC}#\{SB}/no", + "ParseTree" => [:dregx_once, '', [:evstr, [:const, :IAC]], [:evstr, [:const, :SB]], 16], + "Ruby2Ruby" => "/#\{IAC}#\{SB}/o", # HACK + }, + "dstr" => { "Ruby" => "argl = 1\n\"x#\{argl}y\"\n", "ParseTree" => [:block, [:lasgn, :argl, [:lit, 1]], - [:dstr, "x", [:lvar, :argl], + [:dstr, "x", [:evstr, [:lvar, :argl]], [:str, "y"]]], }, + "dstr_2" => { + "Ruby" => "argl = 1\n\"x#\{(\"%.2f\" % 3.14159)}y\"\n", + "ParseTree" => [:block, + [:lasgn, :argl, [:lit, 1]], + [:dstr, + "x", + [:evstr, [:call, [:str, "%.2f"], :%, [:array, [:lit, 3.14159]]]], + [:str, "y"]]], + }, + + "dstr_3" => { + "Ruby" => "max = 2\nargl = 1\n\"x#\{(\"%.#\{max}f\" % 3.14159)}y\"\n", + "ParseTree" => [:block, + [:lasgn, :max, [:lit, 2]], + [:lasgn, :argl, [:lit, 1]], + [:dstr, + "x", + [:evstr, [:call, + [:dstr, "%.", [:evstr, [:lvar, :max]], [:str, "f"]], + :%, [:array, [:lit, 3.14159]]]], + [:str, "y"]]], + }, + + "dstr_concat" => { + "Ruby" => '"#{22}aa" "cd#{44}" "55" "#{66}"', + "ParseTree" => [:dstr, + "", + [:evstr, [:lit, 22]], + [:str, "aa"], + [:str, "cd"], + [:evstr, [:lit, 44]], + [:str, "55"], + [:evstr, [:lit, 66]]], + "Ruby2Ruby" => '"#{22}aacd#{44}55#{66}"', + }, + + "dstr_heredoc_yet_again" => { + "Ruby" => "<<-EOF\ns1 '#\{RUBY_PLATFORM}' s2\n#\{__FILE__}\n EOF\n", + "ParseTree" => [:dstr, "s1 '", + [:evstr, [:const, :RUBY_PLATFORM]], + [:str, "' s2\n"], + [:str, "(string)"], + [:str, "\n"]], + "Ruby2Ruby" => "\"s1 '#\{RUBY_PLATFORM}' s2\\n(string)\\n\"" + }, + + "dstr_nest" => { + "Ruby" => "%Q[before [#\{nest}] after]", + "ParseTree" => [:dstr, "before [", + [:evstr, [:vcall, :nest]], [:str, "] after"]], + "Ruby2Ruby" => "\"before [#\{nest}] after\"", + }, + + "dstr_str_lit_start" => { + "Ruby" => '"#{"blah"}#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})"', + "ParseTree" => [:dstr, + "blah(string):", + [:evstr, [:lit, 1]], + [:str, ": warning: "], + [:evstr, [:call, [:gvar, :$!], :message]], + [:str, " ("], + [:evstr, [:call, [:gvar, :$!], :class]], + [:str, ")"]], + "Ruby2Ruby" => '"blah(string):#{1}: warning: #{$!.message} (#{$!.class})"', + }, + + "dstr_the_revenge" => { + "Ruby" => '"before #{from} middle #{to} (#{__FILE__}:#{__LINE__})"', + "ParseTree" => [:dstr, + "before ", + [:evstr, [:vcall, :from]], + [:str, " middle "], + [:evstr, [:vcall, :to]], + [:str, " ("], + [:str, "(string)"], + [:str, ":"], + [:evstr, [:lit, 1]], + [:str, ")"]], + "Ruby2Ruby" => '"before #{from} middle #{to} ((string):#{1})"', + }, + "dsym" => { "Ruby" => ":\"x#\{(1 + 1)}y\"", "ParseTree" => [:dsym, "x", - [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]], + [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], [:str, "y"]], }, "dxstr" => { "Ruby" => "t = 5\n`touch #\{t}`\n", "ParseTree" => [:block, [:lasgn, :t, [:lit, 5]], - [:dxstr, 'touch ', [:lvar, :t]]], + [:dxstr, 'touch ', [:evstr, [:lvar, :t]]]], }, "ensure" => { - "Ruby" => "begin - (1 + 1) -rescue SyntaxError => e1 - 2 -rescue Exception => e2 - 3 -else - 4 -ensure - 5 + "Ruby" => "begin\n (1 + 1)\nrescue SyntaxError => e1\n 2\nrescue Exception => e2\n 3\nelse\n 4\nensure\n 5 end", "ParseTree" => [:begin, [:ensure, [:rescue, [:call, [:lit, 1], :+, [:array, [:lit, 1]]], @@ -642,15 +1165,52 @@ [:args, :x], [:call, [:lvar, :x], :+, [:array, [:lit, 1]]]]]]], "Ruby2Ruby" => "def an_alias(x)\n (x + 1)\nend" }, - "fcall" => { - "Ruby" => "p(4)", - "ParseTree" => [:fcall, :p, [:array, [:lit, 4]]], + "fcall_arglist" => { + "Ruby" => "m(42)", + "ParseTree" => [:fcall, :m, [:array, [:lit, 42]]], }, + "fcall_arglist_hash" => { + "Ruby" => "m(:a => 1, :b => 2)", + "ParseTree" => [:fcall, :m, + [:array, + [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]], + }, + + "fcall_arglist_norm_hash" => { + "Ruby" => "m(42, :a => 1, :b => 2)", + "ParseTree" => [:fcall, :m, + [:array, + [:lit, 42], + [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]], + }, + + "fcall_arglist_norm_hash_splat" => { + "Ruby" => "m(42, :a => 1, :b => 2, *c)", + "ParseTree" => [:fcall, :m, + [:argscat, + [:array, + [:lit, 42], + [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]], + [:vcall, :c]]], + }, + + "fcall_block" => { + "Ruby" => "a(:b) { :c }", + "ParseTree" => [:iter, + [:fcall, :a, [:array, [:lit, :b]]], nil, + [:lit, :c]], + }, + + "fcall_keyword" => { + "Ruby" => "42 if block_given?", + "ParseTree" => [:if, [:fcall, :block_given?], [:lit, 42], nil], + }, + "flip2" => { "Ruby" => "x = if ((i % 4) == 0)..((i % 3) == 0) then\n i\nelse\n nil\nend", "ParseTree" => [:lasgn, :x, [:if, @@ -665,10 +1225,22 @@ [:array, [:lit, 0]]]], [:vcall, :i], [:nil]]], }, + "flip2_method" => { + "Ruby" => "if 1..2.a?(b) then + nil +end", + "ParseTree" => [:if, + [:flip2, + [:lit, 1], + [:call, [:lit, 2], :a?, [:array, [:vcall, :b]]]], + [:nil], + nil], + }, + "flip3" => { "Ruby" => "x = if ((i % 4) == 0)...((i % 3) == 0) then\n i\nelse\n nil\nend", "ParseTree" => [:lasgn, :x, [:if, @@ -684,15 +1256,24 @@ [:vcall, :i], [:nil]]], }, "for" => { - "Ruby" => "for o in ary\n puts(o)\nend\n", - "ParseTree" => [:for, [:vcall, :ary], [:lasgn, :o], + "Ruby" => "for o in ary do\n puts(o)\nend", + "ParseTree" => [:for, + [:vcall, :ary], + [:lasgn, :o], [:fcall, :puts, [:array, [:lvar, :o]]]], }, + "for_no_body" => { + "Ruby" => "for i in (0..max) do\n # do nothing\nend", + "ParseTree" => [:for, + [:dot2, [:lit, 0], [:vcall, :max]], + [:lasgn, :i]], + }, + "gasgn" => { "Ruby" => "$x = 42", "ParseTree" => [:gasgn, :$x, [:lit, 42]], }, @@ -704,10 +1285,20 @@ "gvar" => { "Ruby" => "$x", "ParseTree" => [:gvar, :$x], }, + "gvar_underscore" => { + "Ruby" => "$_", + "ParseTree" => [:gvar, :$_], + }, + + "gvar_underscore_blah" => { + "Ruby" => "$__blah", + "ParseTree" => [:gvar, :$__blah], + }, + "hash" => { "Ruby" => "{ 1 => 2, 3 => 4 }", "ParseTree" => [:hash, [:lit, 1], [:lit, 2], [:lit, 3], [:lit, 4]], }, @@ -812,21 +1403,94 @@ [:array, [:call, [:dvar, :x], :to_s]]], [:fcall, :puts, [:array, [:call, [:dvar, :y], :to_s]]]]]]], }, + "iteration7" => { + "Ruby" => "a { |b, c| p(c) }", + "ParseTree" => [:iter, + [:fcall, :a], + [:masgn, + [:array, [:dasgn_curr, :b], [:dasgn_curr, :c]]], + [:fcall, :p, [:array, [:dvar, :c]]]], + }, + + "iteration8" => { + "Ruby" => "a { |b, c, *d| p(c) }", + "ParseTree" => [:iter, + [:fcall, :a], + [:masgn, + [:array, [:dasgn_curr, :b], [:dasgn_curr, :c]], + [:dasgn_curr, :d]], + [:fcall, :p, [:array, [:dvar, :c]]]], + }, + + "iteration9" => { + "Ruby" => "a { |b, c, *| p(c) }", + "ParseTree" => [:iter, + [:fcall, :a], + [:masgn, + [:array, [:dasgn_curr, :b], [:dasgn_curr, :c]], + [:splat]], + [:fcall, :p, [:array, [:dvar, :c]]]], + }, + + "iteration9" => { + "Ruby" => "a { |*| p(c) }", + "ParseTree" => [:iter, + [:fcall, :a], + [:masgn, + [:splat]], + [:fcall, :p, [:array, [:vcall, :c]]]], + }, + + "iteration_dasgn_curr_dasgn_madness" => { + "Ruby" => "as.each { |a|\n b += a.b(false) }", + "ParseTree" => [:iter, + [:call, [:vcall, :as], :each], + [:dasgn_curr, :a], + [:dasgn_curr, + :b, + [:call, + [:dvar, :b], + :+, + [:array, + [:call, [:dvar, :a], :b, [:array, [:false]]]]]]], + "Ruby2Ruby" => "as.each { |a| b = (b + a.b(false)) }", + }, + + "iteration_double_var" => { + "Ruby" => "a do |x|\n b do |x| \n puts x\n end\nend", + "ParseTree" => [:iter, + [:fcall, :a], + [:dasgn_curr, :x], + [:iter, + [:fcall, :b], + [:dasgn, :x], + [:fcall, :puts, [:array, [:dvar, :x]]]]], + "Ruby2Ruby" => "a { |x| b { |x| puts(x) } }", + }, + + "iteration_masgn" => { + "Ruby" => "define_method(method) { |*args| }", + "ParseTree" => [:iter, + [:fcall, :define_method, [:array, [:vcall, :method]]], + [:masgn, [:dasgn_curr, :args]]], + }, + "ivar" => { "Ruby" => [Examples, :reader], "ParseTree" => [:defn, :reader, [:ivar, :@reader]], "Ruby2Ruby" => "attr_reader :reader" }, "lasgn_array" => { "Ruby" => "var = [\"foo\", \"bar\"]", - "ParseTree" => [:lasgn, :var, [:array, - [:str, "foo"], - [:str, "bar"]]], + "ParseTree" => [:lasgn, :var, + [:array, + [:str, "foo"], + [:str, "bar"]]], }, "lasgn_call" => { "Ruby" => "c = (2 + 3)", "ParseTree" => [:lasgn, :c, [:call, [:lit, 2], :+, [:array, [:lit, 3]]]], @@ -850,10 +1514,15 @@ "lit_long" => { "Ruby" => "1", "ParseTree" => [:lit, 1], }, + "lit_long_negative" => { + "Ruby" => "-1", + "ParseTree" => [:lit, -1], + }, + "lit_range2" => { "Ruby" => "(1..10)", "ParseTree" => [:lit, 1..10], }, @@ -865,20 +1534,57 @@ "lit_regexp" => { "Ruby" => "/x/", "ParseTree" => [:lit, /x/], }, - "lit_str" => { - "Ruby" => "\"x\"", - "ParseTree" => [:str, "x"], + "lit_regexp_i_wwtt" => { + "Ruby" => 'str.split(//i)', + "ParseTree" => [:call, [:vcall, :str], :split, [:array, [:lit, //i]]], }, + + "lit_regexp_n" => { + "Ruby" => "/x/n", + "ParseTree" => [:lit, /x/n], + }, + "lit_regexp_once" => { + "Ruby" => "/x/o", + "ParseTree" => [:lit, /x/], + "Ruby2Ruby" => "/x/", + }, + "lit_sym" => { "Ruby" => ":x", "ParseTree" => [:lit, :x], }, + "lit_sym_splat" => { + "Ruby" => ":\"*args\"", + "ParseTree" => [:lit, :"*args"], + }, + + "lvar_def_boundary" => { # HACK: put # do nothing back under begin + "Ruby" => "b = 42\ndef a\n c do\n begin\n rescue RuntimeError => b\n puts(b)\n end\n end\nend\n", + "ParseTree" => [:block, + [:lasgn, :b, [:lit, 42]], + [:defn, + :a, + [:scope, + [:block, + [:args], + [:iter, + [:fcall, :c], + nil, + [:begin, + [:rescue, + [:resbody, + [:array, [:const, :RuntimeError]], + [:block, + [:dasgn_curr, :b, [:gvar, :$!]], + [:fcall, :puts, [:array, [:dvar, :b]]]]]]]]]]]], + }, + "masgn" => { "Ruby" => "a, b = c, d", "ParseTree" => [:masgn, [:array, [:lasgn, :a], [:lasgn, :b]], [:array, [:vcall, :c], [:vcall, :d]]], @@ -889,11 +1595,11 @@ "ParseTree" => [:masgn, [:array, [:lasgn, :a], [:lasgn, :b]], [:lasgn, :c], [:argscat, [:array, [:lit, 1], [:lit, 2]], - [:array, [:lit, 3], [:lit, 4]]]] + [:array, [:lit, 3], [:lit, 4]]]], }, "masgn_attrasgn" => { "Ruby" => "a, b.c = d, e", "ParseTree" => [:masgn, @@ -934,10 +1640,43 @@ [:array, [:vcall, :d], [:vcall, :e], [:vcall, :f], [:vcall, :g]]] }, + "masgn_splat_no_name_to_ary" => { + "Ruby" => "a, b, * = c", + "ParseTree" => [:masgn, + [:array, [:lasgn, :a], [:lasgn, :b]], + [:splat], + [:to_ary, [:vcall, :c]]], + }, + + "masgn_splat_no_name_trailing" => { + "Ruby" => "a, b, = c", + "ParseTree" => [:masgn, + [:array, [:lasgn, :a], [:lasgn, :b]], + [:to_ary, [:vcall, :c]]], + "Ruby2Ruby" => "a, b = c", # TODO: check this is right + }, + + "masgn_splat_to_ary" => { + "Ruby" => "a, b, *c = d", + "ParseTree" => [:masgn, + [:array, [:lasgn, :a], [:lasgn, :b]], + [:lasgn, :c], + [:to_ary, [:vcall, :d]]], + }, + + "masgn_splat_to_ary2" => { + "Ruby" => "a, b, *c = d.e(\"f\")", + "ParseTree" => [:masgn, + [:array, [:lasgn, :a], [:lasgn, :b]], + [:lasgn, :c], + [:to_ary, + [:call, [:vcall, :d], :e, [:array, [:str, 'f']]]]], + }, + "match" => { "Ruby" => "1 if /x/", "ParseTree" => [:if, [:match, [:lit, /x/]], [:lit, 1], nil], }, @@ -964,10 +1703,18 @@ [:fcall, :loop], nil, [:if, [:false], [:next], nil]], }, + "next_arg" => { + "Ruby" => "loop { next 42 if false }", + "ParseTree" => [:iter, + [:fcall, :loop], + nil, + [:if, [:false], [:next, [:lit, 42]], nil]], + }, + "not" => { "Ruby" => "(not true)", "ParseTree" => [:not, [:true]], }, @@ -1007,29 +1754,95 @@ [:call, [:call, [:lvar, :c], :d], :e], :f=, "||".intern, [:lit, 42]]], }, + "op_asgn2_self" => { + "Ruby" => "self.Bag ||= Bag.new", + "ParseTree" => [:op_asgn2, [:self], :"Bag=", :"||", [:call, [:const, :Bag], :new]], + }, + "op_asgn_and" => { "Ruby" => "a = 0\na &&= 2\n", "ParseTree" => [:block, [:lasgn, :a, [:lit, 0]], [:op_asgn_and, [:lvar, :a], [:lasgn, :a, [:lit, 2]]]], }, + "op_asgn_and_ivar2" => { # eww... stupid rubygems + "Ruby" => "@fetcher &&= new(Gem.configuration[:http_proxy])", + "ParseTree" => [:op_asgn_and, + [:ivar, :@fetcher], + [:iasgn, + :@fetcher, + [:fcall, + :new, + [:array, + [:call, + [:call, [:const, :Gem], :configuration], + :[], + [:array, [:lit, :http_proxy]]]]]]], + }, + "op_asgn_or" => { "Ruby" => "a = 0\na ||= 1\n", "ParseTree" => [:block, [:lasgn, :a, [:lit, 0]], [:op_asgn_or, [:lvar, :a], [:lasgn, :a, [:lit, 1]]]], }, + "op_asgn_or_block" => { + "Ruby" => "a ||= begin\n b\n rescue\n c\n end", + "ParseTree" => [:op_asgn_or, + [:lvar, :a], + [:lasgn, :a, + [:rescue, + [:vcall, :b], + [:resbody, nil, [:vcall, :c]]]]], + "Ruby2Ruby" => "a ||= b rescue c", + }, + + "op_asgn_or_ivar" => { + "Ruby" => "@v ||= { }", + "ParseTree" => [:op_asgn_or, [:ivar, :@v], [:iasgn, :@v, [:hash]]], + }, + + "op_asgn_or_ivar2" => { # eww... stupid rubygems + "Ruby" => "@fetcher ||= new(Gem.configuration[:http_proxy])", + "ParseTree" => [:op_asgn_or, + [:ivar, :@fetcher], + [:iasgn, + :@fetcher, + [:fcall, + :new, + [:array, + [:call, + [:call, [:const, :Gem], :configuration], + :[], + [:array, [:lit, :http_proxy]]]]]]], + }, + "or" => { "Ruby" => "(a or b)", "ParseTree" => [:or, [:vcall, :a], [:vcall, :b]], }, + "or_big" => { + "Ruby" => "((a or b) or (c and d))", + "ParseTree" => [:or, + [:or, [:vcall, :a], [:vcall, :b]], + [:and, [:vcall, :c], [:vcall, :d]]], + }, + + "or_big2" => { + "Ruby" => "((a || b) || (c && d))", + "ParseTree" => [:or, + [:or, [:vcall, :a], [:vcall, :b]], + [:and, [:vcall, :c], [:vcall, :d]]], + "Ruby2Ruby" => "((a or b) or (c and d))", + }, + "postexe" => { "Ruby" => "END { 1 }", "ParseTree" => [:iter, [:postexe], nil, [:lit, 1]], }, @@ -1047,10 +1860,18 @@ [:fcall, :proc], nil, [:call, [:vcall, :x], :+, [:array, [:lit, 1]]]], }, + "proc_zero_args" => { + "Ruby" => "proc { || (x + 1) }", + "ParseTree" => [:iter, + [:fcall, :proc], + 0, + [:call, [:vcall, :x], :+, [:array, [:lit, 1]]]], + }, + "redo" => { "Ruby" => "loop { redo if false }", "ParseTree" => [:iter, [:fcall, :loop], nil, [:if, [:false], [:redo], nil]], }, @@ -1059,15 +1880,19 @@ "Ruby" => "blah rescue nil", "ParseTree" => [:rescue, [:vcall, :blah], [:resbody, nil, [:nil]]], }, "rescue_block_body" => { - "Ruby" => "begin\n blah\nrescue\n 42\nend", + "Ruby" => "begin\n a\nrescue => e\n c\n d\nend", "ParseTree" => [:begin, [:rescue, - [:vcall, :blah], - [:resbody, nil, [:lit, 42]]]], + [:vcall, :a], + [:resbody, nil, + [:block, + [:lasgn, :e, [:gvar, :$!]], + [:vcall, :c], + [:vcall, :d]]]]], }, "rescue_block_nada" => { "Ruby" => "begin\n blah\nrescue\n # do nothing\nend", "ParseTree" => [:begin, [:rescue, [:vcall, :blah], [:resbody, nil]]] @@ -1086,34 +1911,192 @@ "retry" => { "Ruby" => "retry", "ParseTree" => [:retry], }, + "return_0" => { + "Ruby" => "return", + "ParseTree" => [:return], + }, + + "return_1" => { + "Ruby" => "return 1", + "ParseTree" => [:return, [:lit, 1]], + }, + + "return_n" => { + "Ruby" => "return 1, 2, 3", + "ParseTree" => [:return, [:array, [:lit, 1], [:lit, 2], [:lit, 3]]], + "Ruby2Ruby" => "return [1, 2, 3]", + }, + "sclass" => { "Ruby" => "class << self\n 42\nend", "ParseTree" => [:sclass, [:self], [:scope, [:lit, 42]]], }, + "sclass_trailing_class" => { + "Ruby" => "class A\n class << self\n a\n end\n class B\n end\nend", + "ParseTree" => [:class, :A, nil, + [:scope, + [:block, + [:sclass, [:self], [:scope, [:vcall, :a]]], + [:class, :B, nil, [:scope]]]]], + }, + "splat" => { "Ruby" => "def x(*b)\n a(*b)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, [:args, :"*b"], [:fcall, :a, [:splat, [:lvar, :b]]]]]], }, + "str" => { + "Ruby" => '"x"', + "ParseTree" => [:str, "x"], + }, + + "str_concat_newline" => { + "Ruby" => '"before" \\ + " after"', + "ParseTree" => [:str, "before after"], + "Ruby2Ruby" => '"before after"', + }, + + "str_concat_space" => { + "Ruby" => '"before" " after"', + "ParseTree" => [:str, "before after"], + "Ruby2Ruby" => '"before after"', + }, + + "str_heredoc" => { + "Ruby" => "<<'EOM'\n blah\nblah\nEOM\n", + "ParseTree" => [:str, " blah\nblah\n"], + "Ruby2Ruby" => "\" blah\\nblah\\n\"", + }, + + "str_heredoc_call" => { + "Ruby" => "<<'EOM'.strip\n blah\nblah\nEOM\n", + "ParseTree" => [:call, [:str, " blah\nblah\n"], :strip], + "Ruby2Ruby" => "\" blah\\nblah\\n\".strip", + }, + + "str_heredoc_double" => { + "Ruby" => "a += <<-BEGIN + b + <<-END\n first\nBEGIN\n second\nEND", + "ParseTree" => [:lasgn, :a, + [:call, + [:lvar, :a], + :+, + [:array, + [:call, + [:call, [:str, " first\n"], :+, + [:array, [:vcall, :b]]], + :+, + [:array, [:str, " second\n"]]]]]], + "Ruby2Ruby" => "a = (a + ((\" first\\n\" + b) + \" second\\n\"))", + }, + + "dstr_heredoc_expand" => { + "Ruby" => "<<EOM\n blah\n#\{1 + 1}blah\nEOM\n", + "ParseTree" => [:dstr, " blah\n", + [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], + [:str, "blah\n"]], + "Ruby2Ruby" => "\" blah\\n#\{(1 + 1)}blah\\n\"", + }, + + "str_heredoc_indent" => { + "Ruby" => "<<-EOM\n blah\nblah\n\n EOM\n", + "ParseTree" => [:str, " blah\nblah\n\n"], + "Ruby2Ruby" => "\" blah\\nblah\\n\\n\"", + }, + + "dstr_heredoc_windoze_sucks" => { + "Ruby" => "<<-EOF\r\ndef test_#\{action}_valid_feed\r\n EOF\r\n", + "ParseTree" => [:dstr, + 'def test_', + [:evstr, [:vcall, :action]], + [:str, "_valid_feed\n"]], + "Ruby2Ruby" => "\"def test_#\{action}_valid_feed\\n\"", + }, + + "str_interp_file" => { + "Ruby" => '"file = #{__FILE__} +"', + "ParseTree" => [:str, "file = (string)\n"], + "Ruby2Ruby" => '"file = (string)\\n"', + }, + + "structure_extra_block_for_dvar_scoping" => { + "Ruby" => "a.b do |c, d|\n unless e.f(c) then\n g = false\n d.h { |x, i| g = true }\n \n end\nend", # FIX: don't like the extra return + "ParseTree" => [:iter, + [:call, [:vcall, :a], :b], + [:masgn, [:array, [:dasgn_curr, :c], [:dasgn_curr, :d]]], + [:block, + [:dasgn_curr, :g], + [:if, + [:call, [:vcall, :e], :f, [:array, [:dvar, :c]]], + nil, + [:block, + [:dasgn_curr, :g, [:false]], + [:iter, + [:call, [:dvar, :d], :h], + [:masgn, [:array, [:dasgn_curr, :x], [:dasgn_curr, :i]]], + [:dasgn, :g, [:true]]]]]]], + }, + + "structure_remove_begin_1" => { + "Ruby" => "a << begin\n b\n rescue\n c\n end", + "ParseTree" => [:call, [:vcall, :a], :<<, + [:array, [:rescue, [:vcall, :b], + [:resbody, nil, [:vcall, :c]]]]], + "Ruby2Ruby" => "(a << b rescue c)", + }, + + "structure_remove_begin_2" => { + "Ruby" => "a = if c\n begin\n b\n rescue\n nil\n end\n end\na", + "ParseTree" => [:block, + [:lasgn, + :a, + [:if, [:vcall, :c], + [:rescue, [:vcall, :b], [:resbody, nil, [:nil]]], + nil]], + [:lvar, :a]], + "Ruby2Ruby" => "a = b rescue nil if c\na\n", # OMG that's awesome + }, + + "structure_unused_literal_wwtt" => { + "Ruby" => "\"prevent the above from infecting rdoc\"\n\nmodule Graffle\nend", + "ParseTree" => [:module, :Graffle, [:scope]], + "Ruby2Ruby" => "module Graffle\nend", + }, + # TODO: all supers need to pass args "super" => { "Ruby" => "def x\n super(4)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, [:args], [:super, [:array, [:lit, 4]]]]]], }, + "super_block_pass" => { + "Ruby" => "super(a, &b)", + "ParseTree" => [:block_pass, + [:vcall, :b], [:super, [:array, [:vcall, :a]]]], + }, + + "super_block_splat" => { + "Ruby" => "super(a, *b)", + "ParseTree" => [:super, + [:argscat, + [:array, [:vcall, :a]], + [:vcall, :b]]], + }, + "super_multi" => { "Ruby" => "def x\n super(4, 2, 1)\nend", "ParseTree" => [:defn, :x, [:scope, [:block, @@ -1141,31 +2124,119 @@ "undef" => { "Ruby" => "undef :x", "ParseTree" => [:undef, [:lit, :x]], }, - "undef_multi" => { + "undef_2" => { + "Ruby" => "undef :x, :y", + "ParseTree" => [:block, + [:undef, [:lit, :x]], + [:undef, [:lit, :y]]], + "Ruby2Ruby" => "undef :x\nundef :y\n", + }, + + "undef_3" => { "Ruby" => "undef :x, :y, :z", "ParseTree" => [:block, [:undef, [:lit, :x]], [:undef, [:lit, :y]], [:undef, [:lit, :z]]], "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\n", }, + "undef_block_1" => { + "Ruby" => "f1\nundef :x\n", # TODO: don't like the extra return + "ParseTree" => [:block, + [:vcall, :f1], + [:undef, [:lit, :x]]], + }, + + "undef_block_2" => { + "Ruby" => "f1\nundef :x, :y", + "ParseTree" => [:block, + [:vcall, :f1], + [:block, + [:undef, [:lit, :x]], + [:undef, [:lit, :y]], + ]], + "Ruby2Ruby" => "f1\n(undef :x\nundef :y)\n", + }, + + "undef_block_3" => { + "Ruby" => "f1\nundef :x, :y, :z", + "ParseTree" => [:block, + [:vcall, :f1], + [:block, + [:undef, [:lit, :x]], + [:undef, [:lit, :y]], + [:undef, [:lit, :z]], + ]], + "Ruby2Ruby" => "f1\n(undef :x\nundef :y\nundef :z)\n", + }, + + "undef_block_3_post" => { + "Ruby" => "undef :x, :y, :z\nf2", + "ParseTree" => [:block, + [:undef, [:lit, :x]], + [:undef, [:lit, :y]], + [:undef, [:lit, :z]], + [:vcall, :f2]], + "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\nf2\n", + }, + + "undef_block_wtf" => { + "Ruby" => "f1\nundef :x, :y, :z\nf2", + "ParseTree" => [:block, + [:vcall, :f1], + [:block, + [:undef, [:lit, :x]], + [:undef, [:lit, :y]], + [:undef, [:lit, :z]]], + [:vcall, :f2]], + "Ruby2Ruby" => "f1\n(undef :x\nundef :y\nundef :z)\nf2\n", + }, + "until_post" => { "Ruby" => "begin\n (1 + 1)\nend until false", "ParseTree" => [:until, [:false], [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false], }, + "until_post_not" => { + "Ruby" => "begin\n (1 + 1)\nend until not true", + "ParseTree" => [:while, [:true], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false], + "Ruby2Ruby" => "begin\n (1 + 1)\nend while true", + }, + "until_pre" => { "Ruby" => "until false do\n (1 + 1)\nend", "ParseTree" => [:until, [:false], [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], }, + "until_pre_mod" => { + "Ruby" => "(1 + 1) until false", + "ParseTree" => [:until, [:false], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], + "Ruby2Ruby" => "until false do\n (1 + 1)\nend", + }, + + "until_pre_not" => { + "Ruby" => "until not true do\n (1 + 1)\nend", + "ParseTree" => [:while, [:true], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], + "Ruby2Ruby" => "while true do\n (1 + 1)\nend", + }, + + "until_pre_not_mod" => { + "Ruby" => "(1 + 1) until not true", + "ParseTree" => [:while, [:true], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], + "Ruby2Ruby" => "while true do\n (1 + 1)\nend", + }, + "valias" => { "Ruby" => "alias $y $x", "ParseTree" => [:valias, :$y, :$x], }, @@ -1178,21 +2249,49 @@ "Ruby" => "begin\n (1 + 1)\nend while false", "ParseTree" => [:while, [:false], [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false], }, + "while_post_not" => { + "Ruby" => "begin\n (1 + 1)\nend while not true", + "ParseTree" => [:until, [:true], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false], + "Ruby2Ruby" => "begin\n (1 + 1)\nend until true", + }, + "while_pre" => { "Ruby" => "while false do\n (1 + 1)\nend", "ParseTree" => [:while, [:false], [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], }, + "while_pre_mod" => { + "Ruby" => "(1 + 1) while false", + "ParseTree" => [:while, [:false], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], + "Ruby2Ruby" => "while false do\n (1 + 1)\nend", # FIX can be one liner + }, + "while_pre_nil" => { "Ruby" => "while false do\nend", "ParseTree" => [:while, [:false], nil, true], }, + "while_pre_not" => { + "Ruby" => "while not true do\n (1 + 1)\nend", + "ParseTree" => [:until, [:true], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], + "Ruby2Ruby" => "until true do\n (1 + 1)\nend", + }, + + "while_pre_not_mod" => { + "Ruby" => "(1 + 1) while not true", + "ParseTree" => [:until, [:true], + [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true], + "Ruby2Ruby" => "until true do\n (1 + 1)\nend", # FIX + }, + "xstr" => { "Ruby" => "`touch 5`", "ParseTree" => [:xstr, 'touch 5'], }, @@ -1220,60 +2319,19 @@ "Ruby" => "def x\n super\nend", "ParseTree" => [:defn, :x, [:scope, [:block, [:args], [:zsuper]]]], }, } -# def test_audit_nodes -# # TODO: audit @@testcases.keys against node list - do two way audit, rename everything -# nodes = ParseTree::NODE_NAMES.map { |s| s.to_s }.sort -# tested = @@testcases.keys.map { |s| s.to_s }.sort -# if processor.respond_to? :unsupported then -# nodes -= processor.unsupported -# else -# SexpProcessor.new.unsupported -# # HACK -# nodes -= [:alloca, :argspush, :cfunc, :cref, :evstr, :ifunc, :last, :memo, :newline, :opt_n, :method].map { |s| s.to_s } -# end - -# untested = nodes-tested - -# puts -# p :untested_nodes => untested, :extra_nodes => tested-nodes - -# untested.each do |node| -# puts %( -# "#{node}" => { -# "Ruby" => "XXX", -# "ParseTree" => [], -# }, -# ) -# end - -# flunk -# end - def self.previous(key, extra=0) idx = @@testcase_order.index(key)-1-extra case key when "RubyToRubyC" then idx -= 1 end @@testcase_order[idx] end -# # lets us used unprocessed :self outside of tests, called when subclassed -# def self.clone_same -# @@testcases.each do |node, data| -# data.each do |key, val| -# if val == :same then -# prev_key = self.previous(key) -# data[key] = data[prev_key].deep_clone -# end -# end -# end -# end - def self.inherited(c) output_name = c.name.to_s.sub(/^Test/, '') raise "Unknown class #{c} in @@testcase_order" unless @@testcase_order.include? output_name @@ -1320,7 +2378,7 @@ end end end end - undef_method :default_test + undef_method :default_test rescue nil end