diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex index 366a8d8b275..36670f029b2 100644 --- a/lib/elixir/lib/code/formatter.ex +++ b/lib/elixir/lib/code/formatter.ex @@ -637,8 +637,8 @@ defmodule Code.Formatter do end defp block_args_to_algebra(args, min_line, max_line, state) do - quoted_to_algebra = fn {kind, meta, _} = arg, _args, state -> - newlines = meta[:end_of_expression][:newlines] || 1 + quoted_to_algebra = fn {kind, meta, _} = arg, args, state -> + newlines = handle_newlines(arg, args, meta[:end_of_expression][:newlines] || 1) {doc, state} = quoted_to_algebra(arg, :block, state) {{doc, block_next_line(kind), newlines}, state} end @@ -656,6 +656,14 @@ defmodule Code.Formatter do defp block_next_line(:@), do: @empty defp block_next_line(_), do: break("") + defp handle_newlines({current, _, _}, [{:@, _, _} = _next | _], newlines) when current != :@ do + max(newlines, 2) + end + + defp handle_newlines(_, _, newlines) do + newlines + end + ## Operators defp maybe_unary_op_to_algebra(fun, meta, args, context, state) do diff --git a/lib/elixir/test/elixir/code_formatter/general_test.exs b/lib/elixir/test/elixir/code_formatter/general_test.exs index bc3b58ab8db..91b7c785b84 100644 --- a/lib/elixir/test/elixir/code_formatter/general_test.exs +++ b/lib/elixir/test/elixir/code_formatter/general_test.exs @@ -869,6 +869,56 @@ defmodule Code.Formatter.GeneralTest do assert_format bad, good end + test "with def followed by module attribute" do + bad = """ + defmodule Example do + @impl FooA + def a(), do: :something + @impl FooB + def b() do + :something_else + end + end + """ + + good = """ + defmodule Example do + @impl FooA + def a(), do: :something + + @impl FooB + def b() do + :something_else + end + end + """ + + assert_format bad, good + end + + test "with def followed by def" do + bad = """ + defmodule Example do + def a(), do: :something + def b() do + :something_else + end + end + """ + + good = """ + defmodule Example do + def a(), do: :something + + def b() do + :something_else + end + end + """ + + assert_format bad, good + end + test "with multiple defs" do assert_same """ def foo(:one), do: 1