parse.y: f_margs parser events

* parse.y (f_margs): implemented parser events for massign
  formal arguments.  [ruby-core:81848] [Bug #13701]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59246 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-07-01 02:01:05 +00:00
Родитель 844ca35a92
Коммит f2d1848441
4 изменённых файлов: 111 добавлений и 6 удалений

Просмотреть файл

@ -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

12
parse.y
Просмотреть файл

@ -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);
%*/
}
;

Просмотреть файл

@ -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}

Просмотреть файл

@ -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|