diff options
-rw-r--r-- | lib/elixir/lib/code/formatter.ex | 37 | ||||
-rw-r--r-- | lib/elixir/lib/macro.ex | 1 | ||||
-rw-r--r-- | lib/elixir/test/elixir/code_formatter/integration_test.exs | 34 |
3 files changed, 62 insertions, 10 deletions
diff --git a/lib/elixir/lib/code/formatter.ex b/lib/elixir/lib/code/formatter.ex index 54c2f161f..a2bfe51c5 100644 --- a/lib/elixir/lib/code/formatter.ex +++ b/lib/elixir/lib/code/formatter.ex @@ -1643,12 +1643,15 @@ defmodule Code.Formatter do ) do min_line = line(meta) {body_doc, state} = block_to_algebra(body, min_line, max_line, state) + break_or_line = clause_break_or_line(clauses, state) doc = "fn ->" - |> glue(body_doc) + |> concat(break_or_line) + |> concat(body_doc) |> nest(2) - |> glue("end") + |> concat(break_or_line) + |> concat("end") |> maybe_force_clauses(clauses, state) |> group() @@ -1677,12 +1680,16 @@ defmodule Code.Formatter do |> nest(:cursor) |> group() + break_or_line = clause_break_or_line(clauses, state) + doc = "fn " |> concat(head) - |> glue(body_doc) + |> concat(break_or_line) + |> concat(body_doc) |> nest(2) - |> glue("end") + |> concat(break_or_line) + |> concat("end") |> maybe_force_clauses(clauses, state) |> group() @@ -1724,13 +1731,14 @@ defmodule Code.Formatter 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) + break_or_line = clause_break_or_line(clauses, state) doc = args_doc |> ungroup_if_group() |> concat(" ->") |> group() - |> concat(break() |> concat(body_doc) |> nest(2)) + |> concat(break_or_line |> concat(body_doc) |> nest(2)) |> wrap_in_parens() |> maybe_force_clauses(clauses, state) |> group() @@ -1751,12 +1759,21 @@ defmodule Code.Formatter do ## Clauses + defp multi_line_clauses?(clauses, state) do + Enum.any?(clauses, fn {:->, meta, [_, block]} -> + eol?(meta, state) or multi_line_block?(block) + end) + end + + defp multi_line_block?({:__block__, _, [_, _ | _]}), do: true + defp multi_line_block?(_), do: false + + defp clause_break_or_line(clauses, state) do + if multi_line_clauses?(clauses, state), do: line(), else: break() + end + defp maybe_force_clauses(doc, clauses, state) do - if Enum.any?(clauses, fn {:->, meta, _} -> eol?(meta, state) end) do - force_unfit(doc) - else - doc - end + if multi_line_clauses?(clauses, state), do: force_unfit(doc), else: doc end defp clauses_to_algebra([{:->, _, _} | _] = clauses, min_line, max_line, state) do diff --git a/lib/elixir/lib/macro.ex b/lib/elixir/lib/macro.ex index 5f9b22f32..719169713 100644 --- a/lib/elixir/lib/macro.ex +++ b/lib/elixir/lib/macro.ex @@ -956,6 +956,7 @@ defmodule Macro do """ @spec to_string(t()) :: String.t() + # TODO: Allow line_length to be configurable on v1.17 def to_string(tree) do doc = Inspect.Algebra.format(Code.quoted_to_algebra(tree), :infinity) IO.iodata_to_binary(doc) diff --git a/lib/elixir/test/elixir/code_formatter/integration_test.exs b/lib/elixir/test/elixir/code_formatter/integration_test.exs index 69f6b4820..2b1481d71 100644 --- a/lib/elixir/test/elixir/code_formatter/integration_test.exs +++ b/lib/elixir/test/elixir/code_formatter/integration_test.exs @@ -620,4 +620,38 @@ defmodule Code.Formatter.IntegrationTest do when y """ end + + test "functions with infinity line length" do + assert_same ~S""" + x = fn -> + {:ok, pid} = Repl.start_link({self(), opts}) + assert Exception.message(error) =~ msg + end + """, + line_length: :infinity + + assert_same ~S""" + capture_log(fn x -> + {:ok, pid} = Repl.start_link({self(), opts}) + assert Exception.message(error) =~ msg + end) =~ msg + """, + line_length: :infinity + + assert_same ~S""" + capture_log(fn -> + {:ok, pid} = Repl.start_link({self(), opts}) + assert Exception.message(error) =~ msg + end) =~ msg + """, + line_length: :infinity + + assert_same ~S""" + capture_log(fn x -> + {:ok, pid} = Repl.start_link({self(), opts}) + assert Exception.message(error) =~ msg + end) =~ msg + """, + line_length: :infinity + end end |