diff options
-rw-r--r-- | ext/ripper/lib/ripper/sexp.rb | 12 | ||||
-rw-r--r-- | parse.y | 12 | ||||
-rw-r--r-- | test/ripper/test_parser_events.rb | 78 | ||||
-rw-r--r-- | test/ripper/test_sexp.rb | 15 |
4 files changed, 111 insertions, 6 deletions
diff --git a/ext/ripper/lib/ripper/sexp.rb b/ext/ripper/lib/ripper/sexp.rb index d7bf530088..b52dd30ddc 100644 --- a/ext/ripper/lib/ripper/sexp.rb +++ b/ext/ripper/lib/ripper/sexp.rb @@ -134,6 +134,18 @@ class Ripper list end + def on_mlhs_paren(list) + [:mlhs, *list] + end + + def on_mlhs_add_star(list, star) + list.push([:rest_param, star]) + end + + def on_mlhs_add_post(list, post) + list.concat(post) + end + PARSER_EVENT_TABLE.each do |event, arity| if /_new\z/ =~ event and arity == 0 alias_method "on_#{event}", :_dispatch_event_new @@ -3027,7 +3027,6 @@ f_marg : f_norm_arg $$ = assignable($1, 0); /*%%%*/ /*% - $$ = dispatch1(mlhs_paren, $$); %*/ } | tLPAREN f_margs rparen @@ -3082,6 +3081,7 @@ f_margs : f_marg_list $$ = NEW_MASGN($1, NEW_POSTARG($$, $6)); /*% $$ = mlhs_add_star($1, $$); + $$ = mlhs_add_post($$, $6); %*/ } | f_marg_list ',' tSTAR @@ -3097,7 +3097,8 @@ f_margs : f_marg_list /*%%%*/ $$ = NEW_MASGN($1, NEW_POSTARG(-1, $5)); /*% - $$ = mlhs_add_star($1, $5); + $$ = mlhs_add_star($1, Qnil); + $$ = mlhs_add_post($$, $5); %*/ } | tSTAR f_norm_arg @@ -3115,10 +3116,8 @@ f_margs : f_marg_list /*%%%*/ $$ = NEW_MASGN(0, NEW_POSTARG($$, $4)); /*% - #if 0 - TODO: Check me - #endif - $$ = mlhs_add_star($$, $4); + $$ = mlhs_add_star(mlhs_new(), $$); + $$ = mlhs_add_post($$, $4); %*/ } | tSTAR @@ -3135,6 +3134,7 @@ f_margs : f_marg_list $$ = NEW_MASGN(0, NEW_POSTARG(-1, $3)); /*% $$ = mlhs_add_star(mlhs_new(), Qnil); + $$ = mlhs_add_post($$, $3); %*/ } ; diff --git a/test/ripper/test_parser_events.rb b/test/ripper/test_parser_events.rb index c2d6a255be..c9189ee7a8 100644 --- a/test/ripper/test_parser_events.rb +++ b/test/ripper/test_parser_events.rb @@ -896,6 +896,84 @@ class TestRipper::ParserEvents < Test::Unit::TestCase assert_equal [nil, nil, nil, nil, nil, "x", nil], arg end + def test_params_mlhs + thru_mlhs = false + tree = parse("proc {|(a, b)|}", :on_mlhs_paren) {thru_mlhs = true} + assert_equal true, thru_mlhs + assert_include(tree, "[mlhs([a,b])]") + end + + def test_params_mlhs_add + thru_mlhs_add = false + tree = parse("proc {|(a, b)|}", :on_mlhs_add) {thru_mlhs_add = true} + assert_equal true, thru_mlhs_add + assert_include(tree, "[mlhs([a,b])]") + end + + def test_params_mlhs_add_star + thru_mlhs_add_star = false + tree = parse("proc {|(a, *b)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true} + assert_equal true, thru_mlhs_add_star + assert_include(tree, "[mlhs([a,*b])]") + thru_mlhs_add_star = false + tree = parse("proc {|(a, *b, c)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true} + assert_equal true, thru_mlhs_add_star + assert_include(tree, "[mlhs([a,*b,c])]") + thru_mlhs_add_star = false + tree = parse("proc {|(a, *, c)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true} + assert_equal true, thru_mlhs_add_star + assert_include(tree, "[mlhs([a,*,c])]") + thru_mlhs_add_star = false + tree = parse("proc {|(*b, c)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true} + assert_equal true, thru_mlhs_add_star + assert_include(tree, "[mlhs([*b,c])]") + thru_mlhs_add_star = false + tree = parse("proc {|(*b)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true} + assert_equal true, thru_mlhs_add_star + assert_include(tree, "[mlhs([*b])]") + end + + def test_params_mlhs_add_post + thru_mlhs_add_post = false + tree = parse("proc {|(a, *b)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true} + assert_equal false, thru_mlhs_add_post + assert_include(tree, "mlhs([a,*b])") + thru_mlhs_add_post = false + tree = parse("proc {|(a, *b, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true} + assert_equal true, thru_mlhs_add_post + assert_include(tree, "mlhs([a,*b,c])") + thru_mlhs_add_post = false + tree = parse("proc {|(a, *, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true} + assert_equal true, thru_mlhs_add_post + assert_include(tree, "mlhs([a,*,c])") + thru_mlhs_add_post = false + tree = parse("proc {|(*b, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true} + assert_equal true, thru_mlhs_add_post + assert_include(tree, "mlhs([*b,c])") + thru_mlhs_add_post = false + tree = parse("proc {|(*, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true} + assert_equal true, thru_mlhs_add_post + assert_include(tree, "mlhs([*,c])") + end + + def test_params_mlhs_new + thru_mlhs_new = false + tree = parse("proc {|(a, b)|}", :on_mlhs_new) {thru_mlhs_new = true} + assert_equal true, thru_mlhs_new + assert_include(tree, "[mlhs([a,b])]") + end + + def test_params_mlhs_paren + thru_mlhs_paren = 0 + tree = parse("proc {|(a, b)|}", :on_mlhs_paren) {thru_mlhs_paren += 1} + assert_equal 1, thru_mlhs_paren + assert_include(tree, "[mlhs([a,b])]") + thru_mlhs_paren = 0 + tree = parse("proc {|((a, b))|}", :on_mlhs_paren) {thru_mlhs_paren += 1} + assert_equal 2, thru_mlhs_paren + assert_include(tree, "[mlhs([a,b])]") + end + def test_paren thru_paren = false parse('()', :on_paren) {thru_paren = true} diff --git a/test/ripper/test_sexp.rb b/test/ripper/test_sexp.rb index 26d19b13a6..d3afbb2399 100644 --- a/test/ripper/test_sexp.rb +++ b/test/ripper/test_sexp.rb @@ -60,6 +60,21 @@ eot assert_equal clear_pos(sexp1), clear_pos(sexp2) end + def test_params_mlhs + sexp = Ripper.sexp("proc {|(w, *x, y), z|}") + _, ((mlhs, w, (rest, x), y), z) = search_sexp(:params, sexp) + assert_equal(:mlhs, mlhs) + assert_equal(:@ident, w[0]) + assert_equal("w", w[1]) + assert_equal(:rest_param, rest) + assert_equal(:@ident, x[0]) + assert_equal("x", x[1]) + assert_equal(:@ident, y[0]) + assert_equal("y", y[1]) + assert_equal(:@ident, z[0]) + assert_equal("z", z[1]) + end + def search_sexp(sym, sexp) return sexp if !sexp or sexp[0] == sym sexp.find do |e| |