summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/elixir/lib/code/formatter.ex37
-rw-r--r--lib/elixir/lib/macro.ex1
-rw-r--r--lib/elixir/test/elixir/code_formatter/integration_test.exs34
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