Skip to content

Commit e1539cd

Browse files
committed
Support some incomplete expressions
This adds support for some incomplete expressions, notably case & receive without clauses or begin block without expressions.
1 parent 9287739 commit e1539cd

File tree

3 files changed

+77
-29
lines changed

3 files changed

+77
-29
lines changed

src/erlfmt_format.erl

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -201,34 +201,31 @@ do_expr_to_algebra({macro_string, _Meta, Name}) ->
201201
do_expr_to_algebra({remote, _Meta, Left, Right}) ->
202202
concat(expr_to_algebra(Left), <<":">>, expr_to_algebra(Right));
203203
do_expr_to_algebra({block, Meta, Exprs}) ->
204-
surround_block(<<"begin">>, block_to_algebra(Meta, Exprs), <<"end">>);
204+
surround_block(<<"begin">>, Exprs, fun(X) -> block_to_algebra(Meta, X) end, <<"end">>);
205205
do_expr_to_algebra({'fun', _Meta, Expr}) ->
206206
fun_to_algebra(Expr);
207207
do_expr_to_algebra({args, Meta, Values}) ->
208208
container(Meta, Values, <<"(">>, <<")">>);
209209
do_expr_to_algebra({'case', _Meta, Expr, Clauses}) ->
210210
Prefix = surround(<<"case">>, <<" ">>, expr_to_algebra(Expr), <<" ">>, <<"of">>),
211-
surround_block(Prefix, clauses_to_algebra(Clauses), <<"end">>);
211+
surround_block(Prefix, Clauses, fun clauses_to_algebra/1, <<"end">>);
212212
do_expr_to_algebra({'maybe', _Meta, MaybeExpressions}) ->
213-
surround_block(<<"maybe">>, maybe_expressions_to_algebra(MaybeExpressions), <<"end">>);
213+
surround_block(<<"maybe">>, MaybeExpressions, fun maybe_expressions_to_algebra/1, <<"end">>);
214214
do_expr_to_algebra({'maybe', _Meta, MaybeExpressions, Else}) ->
215215
ElseD = expr_to_algebra(Else),
216216
surround_block(
217-
<<"maybe">>, maybe_expressions_to_algebra(MaybeExpressions), line(ElseD, <<"end">>)
217+
<<"maybe">>, MaybeExpressions, fun maybe_expressions_to_algebra/1, line(ElseD, <<"end">>)
218218
);
219219
do_expr_to_algebra({else_clause, _Meta, Clauses}) ->
220220
concat(
221221
force_breaks(),
222222
group(concat(<<"else">>, nest(concat(line(), clauses_to_algebra(Clauses)), ?INDENT)))
223223
);
224224
do_expr_to_algebra({'receive', _Meta, Clauses}) ->
225-
surround_block(<<"receive">>, expr_to_algebra(Clauses), <<"end">>);
226-
do_expr_to_algebra({'receive', _Meta, empty, After}) ->
227-
AfterD = expr_to_algebra(After),
228-
concat(force_breaks(), (line(<<"receive">>, line(AfterD, <<"end">>))));
225+
surround_block(<<"receive">>, Clauses, fun expr_to_algebra/1, <<"end">>);
229226
do_expr_to_algebra({'receive', _Meta, Clauses, After}) ->
230227
AfterD = expr_to_algebra(After),
231-
surround_block(<<"receive">>, expr_to_algebra(Clauses), line(AfterD, <<"end">>));
228+
surround_block(<<"receive">>, Clauses, fun expr_to_algebra/1, line(AfterD, <<"end">>));
232229
do_expr_to_algebra({after_clause, _Meta, Expr, Body}) ->
233230
receive_after_to_algebra(Expr, Body);
234231
do_expr_to_algebra({'try', _Meta, Exprs, OfClauses, CatchClauses, After}) ->
@@ -237,7 +234,7 @@ do_expr_to_algebra({'catch', _Meta, Exprs}) ->
237234
ExprsD = lists:map(fun expr_to_algebra/1, Exprs),
238235
fold_doc(fun(Doc, Acc) -> concat(Doc, <<":">>, Acc) end, ExprsD);
239236
do_expr_to_algebra({'if', _Meta, Clauses}) ->
240-
surround_block(<<"if">>, clauses_to_algebra(Clauses), <<"end">>);
237+
surround_block(<<"if">>, Clauses, fun clauses_to_algebra/1, <<"end">>);
241238
do_expr_to_algebra({spec, _Meta, Name, [SingleClause]}) ->
242239
single_clause_spec_to_algebra(Name, SingleClause);
243240
do_expr_to_algebra({spec, _Meta, Name, Clauses}) ->
@@ -261,13 +258,8 @@ do_expr_to_algebra({clauses, _Meta, Clauses}) ->
261258
do_expr_to_algebra({body, _Meta, Exprs}) ->
262259
block_to_algebra(Exprs);
263260
do_expr_to_algebra({sigil, _Meta, Prefix, Content, Suffix}) ->
264-
concat(
265-
concat(
266-
concat(<<"~">>, do_expr_to_algebra(Prefix)),
267-
do_expr_to_algebra(Content)
268-
),
269-
do_expr_to_algebra(Suffix)
270-
);
261+
PrefixDoc = concat(<<"~">>, do_expr_to_algebra(Prefix)),
262+
concat(concat(PrefixDoc, do_expr_to_algebra(Content)), do_expr_to_algebra(Suffix));
271263
do_expr_to_algebra({sigil_prefix, _Meta, ''}) ->
272264
<<"">>;
273265
do_expr_to_algebra({sigil_prefix, _Meta, SigilName}) ->
@@ -288,7 +280,10 @@ surround(Left, LeftSpace, Doc, RightSpace, Right) ->
288280
)
289281
).
290282

291-
surround_block(Left, Doc, Right) ->
283+
surround_block(Left, Empty, _Mapper, Right) when Empty =:= []; Empty =:= empty ->
284+
line(Left, Right);
285+
surround_block(Left, Clauses, Mapper, Right) ->
286+
Doc = Mapper(Clauses),
292287
concat(
293288
force_breaks(),
294289
group(line(concat(Left, nest(concat(line(), Doc), ?INDENT)), Right))
@@ -752,8 +747,7 @@ fun_to_algebra({clauses, _Anno, [Clause]}) ->
752747
_ -> group(break(space(<<"fun">>, ClauseD), <<"end">>))
753748
end;
754749
fun_to_algebra({clauses, _Anno, Clauses}) ->
755-
ClausesD = clauses_to_algebra(Clauses),
756-
surround_block(<<"fun">>, ClausesD, <<"end">>);
750+
surround_block(<<"fun">>, Clauses, fun clauses_to_algebra/1, <<"end">>);
757751
fun_to_algebra(type) ->
758752
<<"fun()">>;
759753
fun_to_algebra({type, Meta, Args, Result}) ->

src/erlfmt_parse.yrl

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ map_comprehension
3030
binary_comprehension
3131
tuple
3232
record_expr record_name record_field_name record_tuple record_field record_fields
33-
map_expr map_tuple
33+
map_expr map_tuple begin_block
3434
if_expr if_clause if_clauses case_expr cr_clause cr_clauses receive_expr maybe_expr
3535
fun_expr fun_clause fun_clauses
3636
atom_or_var atom_or_var_or_macro integer_or_var_or_macro
@@ -250,7 +250,7 @@ expr_max -> map_comprehension : '$1'.
250250
expr_max -> binary_comprehension : '$1'.
251251
expr_max -> tuple : '$1'.
252252
expr_max -> '(' expr ')' : set_parens('$2').
253-
expr_max -> 'begin' exprs 'end' : {block,?range_anno('$1', '$3'),'$2'}.
253+
expr_max -> begin_block : '$1'.
254254
expr_max -> if_expr : '$1'.
255255
expr_max -> case_expr : '$1'.
256256
expr_max -> maybe_expr : '$1'.
@@ -406,7 +406,11 @@ record_field_name -> atom_or_var_or_macro : '$1'.
406406
function_call -> expr_max_remote argument_list :
407407
{call, ?range_anno('$1', '$2'), '$1', ?val('$2')}.
408408

409-
if_expr -> 'if' if_clauses 'end' : {'if',?range_anno('$1', '$3'),'$2'}.
409+
begin_block -> 'begin' 'end' : {block, ?range_anno('$1', '$2'), []}.
410+
begin_block -> 'begin' exprs 'end' : {block, ?range_anno('$1', '$3'), '$2'}.
411+
412+
if_expr -> 'if' 'end' : {'if', ?range_anno('$1', '$2'), []}.
413+
if_expr -> 'if' if_clauses 'end' : {'if', ?range_anno('$1', '$3'), '$2'}.
410414

411415
if_clauses -> if_clause : ['$1'].
412416
if_clauses -> if_clause ';' : ['$1'].
@@ -415,15 +419,22 @@ if_clauses -> if_clause ';' if_clauses : ['$1' | '$3'].
415419
if_clause -> guard clause_body :
416420
{clause, ?range_anno('$1', '$2'), empty, '$1', ?val('$2')}.
417421

422+
case_expr -> 'case' expr 'of' 'end' :
423+
{'case', ?range_anno('$1', '$4'), '$2', []}.
418424
case_expr -> 'case' expr 'of' cr_clauses 'end' :
419425
{'case', ?range_anno('$1', '$5'), '$2', '$4'}.
420426

421427
cr_clauses -> cr_clause : ['$1'].
422428
cr_clauses -> cr_clause ';' : ['$1'].
423429
cr_clauses -> cr_clause ';' cr_clauses : ['$1' | '$3'].
424430

431+
maybe_expr -> 'maybe' 'end' :
432+
{'maybe', ?range_anno('$1', '$2'), []}.
425433
maybe_expr -> 'maybe' exprs 'end' :
426434
{'maybe', ?range_anno('$1', '$3'), '$2'}.
435+
maybe_expr -> 'maybe' 'else' cr_clauses 'end' :
436+
Else = {else_clause, ?range_anno('$2', '$4'), '$3'},
437+
{'maybe', ?range_anno('$1', '$4'), [], Else}.
427438
maybe_expr -> 'maybe' exprs 'else' cr_clauses 'end' :
428439
Else = {else_clause, ?range_anno('$3', '$5'), '$4'},
429440
{'maybe', ?range_anno('$1', '$5'), '$2', Else}.
@@ -437,6 +448,8 @@ cr_clause -> expr clause_guard clause_body :
437448
cr_clause -> macro_call_expr :
438449
'$1'.
439450

451+
receive_expr -> 'receive' 'end' :
452+
{'receive', ?range_anno('$1', '$2'), empty}.
440453
receive_expr -> 'receive' cr_clauses 'end' :
441454
Clauses = {clauses, ?range_anno('$1', '$3'), '$2'},
442455
{'receive',?range_anno('$1', '$3'),Clauses}.
@@ -454,6 +467,9 @@ fun_expr -> 'fun' atom_or_var_or_macro '/' integer_or_var_or_macro :
454467
fun_expr -> 'fun' atom_or_var_or_macro ':' atom_or_var_or_macro '/' integer_or_var_or_macro :
455468
Anno = ?range_anno('$1', '$6'),
456469
{'fun',Anno,{function,Anno,'$2','$4','$6'}}.
470+
fun_expr -> 'fun' 'end' :
471+
Anno = ?range_anno('$1', '$2'),
472+
{'fun', Anno, {clauses, Anno, []}}.
457473
fun_expr -> 'fun' fun_clauses 'end' :
458474
Anno = ?range_anno('$1', '$3'),
459475
{'fun',Anno,{clauses,Anno,'$2'}}.
@@ -490,11 +506,11 @@ try_expr -> 'try' exprs try_catch :
490506
{'try', ?range_anno('$1', '$3'), Body, none, TryClauses, After}.
491507

492508
try_catch -> 'catch' try_clauses 'end' :
493-
{{clauses, ?range_anno('$1', '$3'), '$2'}, ?anno('$3'), '$1', []}.
509+
{{clauses, ?range_anno('$1', '$3'), '$2'}, ?anno('$3'), '$1', []}.
494510
try_catch -> 'catch' try_clauses 'after' exprs 'end' :
495-
{{clauses, ?range_anno('$1', '$3'), '$2'}, ?anno('$5'), '$1', '$4'}.
511+
{{clauses, ?range_anno('$1', '$3'), '$2'}, ?anno('$5'), '$1', '$4'}.
496512
try_catch -> 'after' exprs 'end' :
497-
{none, ?anno('$3'), '$1', '$2'}.
513+
{none, ?anno('$3'), '$1', '$2'}.
498514

499515
try_clauses -> try_clause : ['$1'].
500516
try_clauses -> try_clause ';' : ['$1'].

test/erlfmt_format_SUITE.erl

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@
7373
update_edgecase/1,
7474
sigils/1,
7575
doc_attributes/1,
76-
doc_macros/1
76+
doc_macros/1,
77+
incomplete/1,
78+
maybe_incomplete/1
7779
]).
7880

7981
suite() ->
@@ -97,7 +99,7 @@ init_per_group(_GroupName, Config) ->
9799
end_per_group(_GroupName, _Config) ->
98100
ok.
99101

100-
init_per_testcase(maybe_expression, Config) ->
102+
init_per_testcase(Maybe, Config) when Maybe =:= maybe_expression; Maybe =:= maybe_incomplete ->
101103
case has_feature(maybe_expr, Config) of
102104
true -> Config;
103105
false -> {skip, "Maybe feature not present in the runtime system"}
@@ -122,11 +124,13 @@ groups() ->
122124
fun_expression,
123125
case_expression,
124126
maybe_expression,
127+
maybe_incomplete,
125128
receive_expression,
126129
try_expression,
127130
if_expression,
128131
macro,
129-
doc_macros
132+
doc_macros,
133+
incomplete
130134
]},
131135
{forms, [parallel], [
132136
function,
@@ -4422,3 +4426,37 @@ doc_macros(Config) when is_list(Config) ->
44224426
?assertSame("?MODULEDOC(\"Test\").\n?MODULEDOC(#{since => <<\"1.0.0\">>}).\n"),
44234427
?assertSame("?DOC(\"Test\").\n?DOC(#{since => <<\"1.0.0\">>}).\ntest() -> ok.\n"),
44244428
?assertSame("?DOC(\"Test\").\n?DOC(#{since => <<\"1.0.0\">>}).\n-type t() :: ok.\n").
4429+
4430+
incomplete(Config) when is_list(Config) ->
4431+
?assertSame(
4432+
"case X of\n"
4433+
"end.\n"
4434+
),
4435+
?assertSame(
4436+
"receive\n"
4437+
"end.\n"
4438+
),
4439+
?assertSame(
4440+
"if\n"
4441+
"end.\n"
4442+
),
4443+
?assertSame(
4444+
"fun\n"
4445+
"end.\n"
4446+
),
4447+
?assertSame(
4448+
"begin\n"
4449+
"end.\n"
4450+
).
4451+
4452+
maybe_incomplete(Config) when is_list(Config) ->
4453+
?assertSame(
4454+
"maybe\n"
4455+
"end.\n"
4456+
),
4457+
?assertSame(
4458+
"maybe\n"
4459+
"else\n"
4460+
" ok -> ok\n"
4461+
"end.\n"
4462+
).

0 commit comments

Comments
 (0)