Skip to content

Commit fef7ef7

Browse files
author
José Valim
committed
Ensure consistent use of stab operator in do/end, parens and fn/end, closes #780
1 parent da4654d commit fef7ef7

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

lib/elixir/src/elixir_parser.yrl

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ Nonterminals
33
expr paren_expr block_expr fn_expr bracket_expr call_expr bracket_at_expr max_expr
44
base_expr matched_expr matched_op_expr unmatched_expr op_expr
55
add_op mult_op unary_op two_op pipeline_op bin_concat_op
6-
match_op send_op default_op when_op pipe_op in_op inc_op stab_op range_op
6+
match_op send_op default_op when_op pipe_op in_op inc_op range_op
77
andand_op oror_op and_op or_op comp_expr_op colon_colon_op three_op at_op
88
open_paren close_paren empty_paren
99
open_bracket close_bracket
1010
open_curly close_curly
1111
open_bit close_bit
1212
base_comma_expr comma_expr optional_comma_expr matched_comma_expr
1313
call_args call_args_parens call_args_parens_not_one call_args_no_parens parens_call
14-
stab_expr stab_expr_list
14+
stab stab_op stab_expr stab_maybe_expr
1515
kw_eol kw_expr kw_comma kw_base
1616
matched_kw_expr matched_kw_comma matched_kw_base
1717
dot_op dot_ref dot_identifier dot_op_identifier dot_do_identifier
@@ -38,7 +38,7 @@ Terminals
3838
Rootsymbol grammar.
3939

4040
Left 5 do.
41-
Right 10 '->'.
41+
Right 10 stab_op.
4242
Left 20 ','. % Solve nested call_args conflicts
4343
Right 30 colon_colon_op.
4444
Right 40 when_op.
@@ -146,8 +146,7 @@ block_expr -> dot_punctuated_identifier call_args_no_parens do_block : build_ide
146146
block_expr -> dot_do_identifier do_block : build_identifier('$1', '$2').
147147
block_expr -> dot_identifier call_args_no_parens do_block : build_identifier('$1', '$2' ++ '$3').
148148

149-
fn_expr -> fn_eol stab_expr_list end_eol : build_fn('$1', build_stab(lists:reverse('$2'))).
150-
fn_expr -> fn_eol '->' grammar 'end' : build_fn('$1', { '->', [{line,?line('$2')}], [{ [], build_block('$3') }] }).
149+
fn_expr -> fn_eol stab end_eol : build_fn('$1', build_stab(lists:reverse('$2'))).
151150
fn_expr -> call_expr : '$1'.
152151

153152
call_expr -> dot_punctuated_identifier call_args_no_parens : build_identifier('$1', '$2').
@@ -163,7 +162,7 @@ max_expr -> parens_call call_args_parens : build_identifier('$1', '$2').
163162
max_expr -> parens_call call_args_parens call_args_parens : build_nested_parens('$1', '$2', '$3').
164163
max_expr -> dot_ref : '$1'.
165164
max_expr -> base_expr : '$1'.
166-
max_expr -> open_paren stab_expr_list close_paren : build_stab(lists:reverse('$2')).
165+
max_expr -> open_paren stab close_paren : build_stab(lists:reverse('$2')).
167166

168167
bracket_expr -> dot_bracket_identifier bracket_access : build_access(build_identifier('$1', nil), '$2').
169168
bracket_expr -> max_expr bracket_access : build_access('$1', '$2').
@@ -191,9 +190,9 @@ base_expr -> sigil : build_sigil('$1').
191190
%% Blocks
192191

193192
do_block -> do_eol 'end' : [[{do,nil}]].
194-
do_block -> do_eol stab_expr_list end_eol : [[{ do, build_stab(lists:reverse('$2')) }]].
193+
do_block -> do_eol stab end_eol : [[{ do, build_stab(lists:reverse('$2')) }]].
195194
do_block -> do_eol block_list 'end' : [[{ do, nil }|'$2']].
196-
do_block -> do_eol stab_expr_list eol block_list 'end' : [[{ do, build_stab(lists:reverse('$2')) }|'$4']].
195+
do_block -> do_eol stab eol block_list 'end' : [[{ do, build_stab(lists:reverse('$2')) }|'$4']].
197196

198197
fn_eol -> 'fn' : '$1'.
199198
fn_eol -> 'fn' eol : '$1'.
@@ -207,14 +206,18 @@ end_eol -> eol 'end' : '$2'.
207206
block_eol -> block_identifier : '$1'.
208207
block_eol -> block_identifier eol : '$1'.
209208

210-
stab_expr_list -> stab_expr : ['$1'].
211-
stab_expr_list -> stab_expr_list eol stab_expr : ['$3'|'$1'].
209+
stab -> stab_expr : ['$1'].
210+
stab -> stab eol stab_expr : ['$3'|'$1'].
212211

213212
stab_expr -> expr : '$1'.
214-
stab_expr -> call_args_no_parens stab_op expr : build_op('$2', '$1', '$3').
215-
stab_expr -> call_args_parens_not_one stab_op expr : build_op('$2', '$1', '$3').
213+
stab_expr -> stab_op stab_maybe_expr : build_op('$1', [], '$2').
214+
stab_expr -> call_args_no_parens stab_op stab_maybe_expr : build_op('$2', '$1', '$3').
215+
stab_expr -> call_args_parens_not_one stab_op stab_maybe_expr : build_op('$2', '$1', '$3').
216216

217-
block_item -> block_eol stab_expr_list eol : { ?exprs('$1'), build_stab(lists:reverse('$2')) }.
217+
stab_maybe_expr -> 'expr' : '$1'.
218+
stab_maybe_expr -> '$empty' : nil.
219+
220+
block_item -> block_eol stab eol : { ?exprs('$1'), build_stab(lists:reverse('$2')) }.
218221
block_item -> block_eol : { ?exprs('$1'), nil }.
219222

220223
block_list -> block_item : ['$1'].

lib/elixir/test/elixir/kernel/quote_test.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,17 @@ defmodule Kernel.QuoteTest do
7171
contents = [1, 2, 3]
7272
assert quote(do: [unquote_splicing(contents)|[1,2,3]]) == [1,2,3,1,2,3]
7373
end
74+
75+
test :stab do
76+
assert { :->, _, [{[],_}] } = (quote do -> end)
77+
assert { :->, _, [{[],_}] } = (quote do: (->))
78+
79+
assert { :->, _, [{[1],_}] } = (quote do 1 -> end)
80+
assert { :->, _, [{[1],_}] } = (quote do: (1 ->))
81+
82+
assert { :->, _, [{[],1}] } = (quote do -> 1 end)
83+
assert { :->, _, [{[],1}] } = (quote do: (-> 1))
84+
end
7485
end
7586

7687
defmodule Kernel.QuoteTest.VarHygiene do

lib/elixir/test/erlang/function_test.erl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ function_arg_do_end_test() ->
1111
{nil, _} = eval("if date do end").
1212

1313
function_stab_end_test() ->
14-
{_, [{a, Fun}]} = eval("a = fn -> 1 + 2 end"),
15-
3 = Fun().
14+
{_, [{a, Fun1}]} = eval("a = fn -> end"),
15+
nil = Fun1(),
16+
{_, [{a, Fun2}]} = eval("a = fn() -> end"),
17+
nil = Fun2(),
18+
{_, [{a, Fun3}]} = eval("a = fn -> 1 + 2 end"),
19+
3 = Fun3().
1620

1721
function_stab_many_test() ->
1822
{_, [{a, Fun}]} = eval("a = fn\n{ :foo, x } -> x\n{ :bar, x } -> x\nend"),

0 commit comments

Comments
 (0)