summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSihui Huang <sihuih@gmail.com>2018-06-10 08:45:02 -0700
committerJosé Valim <jose.valim@plataformatec.com.br>2018-06-19 19:38:35 +0200
commitd0694b5d5847c06d5a5c8bdf94650d915adbe17a (patch)
tree5271cfc41414b65db9b790118c35167741f2de67
parent16fe53bc10fd4360cd41139f79207bb93c167b60 (diff)
downloadelixir-d0694b5d5847c06d5a5c8bdf94650d915adbe17a.tar.gz
When fn is followed by a newline, use multi-clause formatting style (#7737)
Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
-rw-r--r--lib/elixir/lib/code/formatter.ex24
-rw-r--r--lib/elixir/src/elixir_parser.yrl4
-rw-r--r--lib/elixir/test/elixir/code_formatter/comments_test.exs17
-rw-r--r--lib/elixir/test/elixir/code_formatter/general_test.exs16
4 files changed, 47 insertions, 14 deletions
diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex
index 96e5a5753..3f10eb268 100644
--- a/lib/elixir/lib/code/formatter.ex
+++ b/lib/elixir/lib/code/formatter.ex
@@ -522,7 +522,7 @@ defmodule Code.Formatter do
end
defp quoted_to_algebra({:fn, meta, [_ | _] = clauses}, _context, state) do
- anon_fun_to_algebra(clauses, line(meta), end_line(meta), state)
+ anon_fun_to_algebra(clauses, line(meta), end_line(meta), state, eol?(meta))
end
defp quoted_to_algebra({fun, meta, args}, context, state) when is_atom(fun) and is_list(args) do
@@ -1598,7 +1598,13 @@ defmodule Code.Formatter do
## Anonymous functions
# fn -> block end
- defp anon_fun_to_algebra([{:->, meta, [[], body]}] = clauses, _min_line, max_line, state) do
+ defp anon_fun_to_algebra(
+ [{:->, meta, [[], body]}] = clauses,
+ _min_line,
+ max_line,
+ state,
+ _multi_clauses_style
+ ) do
min_line = line(meta)
{body_doc, state} = block_to_algebra(body, min_line, max_line, state)
@@ -1617,7 +1623,13 @@ defmodule Code.Formatter do
# fn x ->
# y
# end
- defp anon_fun_to_algebra([{:->, meta, [args, body]}] = clauses, _min_line, max_line, state) do
+ defp anon_fun_to_algebra(
+ [{:->, meta, [args, body]}] = clauses,
+ _min_line,
+ max_line,
+ state,
+ false = _multi_clauses_style
+ ) do
min_line = line(meta)
{args_doc, state} = clause_args_to_algebra(args, min_line, state)
{body_doc, state} = block_to_algebra(body, min_line, max_line, state)
@@ -1647,7 +1659,7 @@ defmodule Code.Formatter do
# args2 ->
# block2
# end
- defp anon_fun_to_algebra(clauses, min_line, max_line, state) do
+ defp anon_fun_to_algebra(clauses, min_line, max_line, state, _multi_clauses_style) do
{clauses_doc, state} = clauses_to_algebra(clauses, min_line, max_line, state)
{"fn" |> line(clauses_doc) |> nest(2) |> line("end") |> force_unfit(), state}
end
@@ -2139,6 +2151,10 @@ defmodule Code.Formatter do
false
end
+ defp eol?(meta) do
+ Keyword.get(meta, :eol, false)
+ end
+
defp line(meta) do
Keyword.get(meta, :line, @max_line)
end
diff --git a/lib/elixir/src/elixir_parser.yrl b/lib/elixir/src/elixir_parser.yrl
index 129f6a363..9d1a6995c 100644
--- a/lib/elixir/src/elixir_parser.yrl
+++ b/lib/elixir/src/elixir_parser.yrl
@@ -305,7 +305,7 @@ eoe -> ';' : '$1'.
eoe -> eol ';' : '$1'.
fn_eoe -> 'fn' : '$1'.
-fn_eoe -> 'fn' eoe : '$1'.
+fn_eoe -> 'fn' eoe : next_is_eol('$1').
do_eoe -> 'do' : '$1'.
do_eoe -> 'do' eoe : '$1'.
@@ -659,7 +659,7 @@ meta_from_token_with_end_line(Begin, End) ->
case ?formatter_metadata() of
true ->
[{end_line, line_from_location(?location(End))}
- | meta_from_token(Begin)];
+ | eol_op(?location(Begin)) ++ meta_from_token(Begin)];
false ->
meta_from_token(Begin)
end.
diff --git a/lib/elixir/test/elixir/code_formatter/comments_test.exs b/lib/elixir/test/elixir/code_formatter/comments_test.exs
index 32e9bd7c5..740b8e6a2 100644
--- a/lib/elixir/test/elixir/code_formatter/comments_test.exs
+++ b/lib/elixir/test/elixir/code_formatter/comments_test.exs
@@ -449,14 +449,15 @@ defmodule Code.Formatter.CommentsTest do
assert_format bad, ~S"""
# fn
- # before head
- # middle head
- # after head
- fn hello ->
- # before body
- # middle body
- world
- # after body
+ fn
+ # before head
+ # middle head
+ hello ->
+ # after head
+ # before body
+ # middle body
+ world
+ # after body
end
"""
end
diff --git a/lib/elixir/test/elixir/code_formatter/general_test.exs b/lib/elixir/test/elixir/code_formatter/general_test.exs
index 52e593f24..4950f2626 100644
--- a/lib/elixir/test/elixir/code_formatter/general_test.exs
+++ b/lib/elixir/test/elixir/code_formatter/general_test.exs
@@ -187,6 +187,22 @@ defmodule Code.Formatter.GeneralTest do
assert_same code, @short_length
end
+ test "with a single clause, followed by a newline, and can fit in one line" do
+ assert_same """
+ fn
+ hello -> world
+ end
+ """
+ end
+
+ test "with a single clause, followed by a newline, and can not fit in one line" do
+ assert_same """
+ SomeModule.long_function_name_that_approaches_max_columns(argument, acc, fn
+ %SomeStruct{key: key}, acc -> more_code(key, acc)
+ end)
+ """
+ end
+
test "with multiple clauses" do
code = """
fn