Skip to content

Commit f3960a2

Browse files
josevalimJosé Valim
authored and
José Valim
committed
Use flex_glue for bitstrings and tuples in the formatter (#7183)
Closes #7152
1 parent 824fcea commit f3960a2

File tree

14 files changed

+212
-198
lines changed

14 files changed

+212
-198
lines changed

lib/elixir/lib/calendar/iso.ex

+9-10
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,15 @@ defmodule Calendar.ISO do
7474
{2000, 1, 1, 12, 0, 0, {0, 6}}
7575
7676
"""
77-
@spec naive_datetime_from_iso_days(Calendar.iso_days()) ::
78-
{
79-
Calendar.year(),
80-
Calendar.month(),
81-
Calendar.day(),
82-
Calendar.hour(),
83-
Calendar.minute(),
84-
Calendar.second(),
85-
Calendar.microsecond()
86-
}
77+
@spec naive_datetime_from_iso_days(Calendar.iso_days()) :: {
78+
Calendar.year(),
79+
Calendar.month(),
80+
Calendar.day(),
81+
Calendar.hour(),
82+
Calendar.minute(),
83+
Calendar.second(),
84+
Calendar.microsecond()
85+
}
8786
@impl true
8887
def naive_datetime_from_iso_days({days, day_fraction}) do
8988
{year, month, day} = date_from_iso_days(days)

lib/elixir/lib/code.ex

+3-4
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,9 @@ defmodule Code do
379379
arg2,
380380
arg3
381381
382-
If the last argument is a data structure of variable length, such as
383-
maps and lists, and the beginning of the data structure fits on the
384-
same line as the function call, then no indentation happens, this
385-
allows code like this:
382+
If the last argument is a data structure, such as maps and lists, and
383+
the beginning of the data structure fits on the same line as the function
384+
call, then no indentation happens, this allows code like this:
386385
387386
Enum.reduce(some_collection, initial_value, fn element, acc ->
388387
# code

lib/elixir/lib/code/formatter.ex

+83-68
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,11 @@ defmodule Code.Formatter do
415415
# {}
416416
# {1, 2}
417417
defp quoted_to_algebra({:{}, meta, args}, _context, state) do
418-
tuple_to_algebra(meta, args, state)
418+
tuple_to_algebra(meta, args, :flex_glue, state)
419419
end
420420

421421
defp quoted_to_algebra({:__block__, meta, [{left, right}]}, _context, state) do
422-
tuple_to_algebra(meta, [left, right], state)
422+
tuple_to_algebra(meta, [left, right], :flex_glue, state)
423423
end
424424

425425
defp quoted_to_algebra({:__block__, meta, [list]}, _context, state) when is_list(list) do
@@ -558,7 +558,7 @@ defmodule Code.Formatter do
558558
end
559559

560560
doc =
561-
with_next_break_fits(next_break_fits?(right_arg), right, fn right ->
561+
with_next_break_fits(next_break_fits?(right_arg, state), right, fn right ->
562562
concat(group(left), group(nest(glue(op, group(right)), 2, :break)))
563563
end)
564564

@@ -727,7 +727,7 @@ defmodule Code.Formatter do
727727

728728
true ->
729729
next_break_fits? =
730-
op in @next_break_fits_operators and next_break_fits?(right_arg) and
730+
op in @next_break_fits_operators and next_break_fits?(right_arg, state) and
731731
not Keyword.get(meta, :eol, false)
732732

733733
with_next_break_fits(next_break_fits?, right, fn right ->
@@ -887,7 +887,7 @@ defmodule Code.Formatter do
887887
# expression.{arguments}
888888
defp remote_to_algebra({{:., _, [target, :{}]}, meta, args}, _context, state) do
889889
{target_doc, state} = remote_target_to_algebra(target, state)
890-
{call_doc, state} = tuple_to_algebra(meta, args, state)
890+
{call_doc, state} = tuple_to_algebra(meta, args, :glue, state)
891891
{concat(concat(target_doc, "."), call_doc), state}
892892
end
893893

@@ -1008,8 +1008,8 @@ defmodule Code.Formatter do
10081008
# * :required - never skip parens
10091009
#
10101010
defp call_args_to_algebra([], meta, _context, _parens, _list_to_keyword?, state) do
1011-
{args_doc, state} =
1012-
args_to_algebra_with_comments([], meta, false, false, false, state, &{&1, &2})
1011+
{args_doc, _join, state} =
1012+
args_to_algebra_with_comments([], meta, false, false, :glue, state, &{&1, &2})
10131013

10141014
{{surround("(", args_doc, ")"), state}, false}
10151015
end
@@ -1056,19 +1056,19 @@ defmodule Code.Formatter do
10561056
if left != [] and keyword? and skip_parens? and generators_count == 0 do
10571057
call_args_to_algebra_with_no_parens_keywords(meta, left, right, context, extra, state)
10581058
else
1059-
next_break_fits? = next_break_fits?(right)
1059+
next_break_fits? = next_break_fits?(right, state)
10601060
force_keyword? = keyword? and force_keyword?(right)
10611061
non_empty_eol? = left != [] and not next_break_fits? and Keyword.get(meta, :eol, false)
1062-
force_unfit? = generators_count > 1 or force_keyword? or non_empty_eol?
1062+
join = if generators_count > 1 or force_keyword? or non_empty_eol?, do: :line, else: :glue
10631063
args = if keyword?, do: left ++ right, else: left ++ [right]
10641064

1065-
{args_doc, state} =
1065+
{args_doc, _join, state} =
10661066
args_to_algebra_with_comments(
10671067
args,
10681068
meta,
10691069
skip_parens?,
10701070
next_break_fits?,
1071-
force_unfit?,
1071+
join,
10721072
state,
10731073
&quoted_to_algebra(&1, context, &2)
10741074
)
@@ -1098,11 +1098,11 @@ defmodule Code.Formatter do
10981098
defp call_args_to_algebra_with_no_parens_keywords(meta, left, right, context, extra, state) do
10991099
to_algebra_fun = &quoted_to_algebra(&1, context, &2)
11001100

1101-
{left_doc, state} =
1102-
args_to_algebra_with_comments(left, meta, true, false, false, state, to_algebra_fun)
1101+
{left_doc, _join, state} =
1102+
args_to_algebra_with_comments(left, meta, true, false, :glue, state, to_algebra_fun)
11031103

1104-
{right_doc, state} =
1105-
args_to_algebra_with_comments(right, meta, false, false, false, state, to_algebra_fun)
1104+
{right_doc, _join, state} =
1105+
args_to_algebra_with_comments(right, meta, false, false, :glue, state, to_algebra_fun)
11061106

11071107
right_doc = "," |> glue(right_doc) |> force_keyword(right) |> group(:inherit)
11081108

@@ -1241,15 +1241,19 @@ defmodule Code.Formatter do
12411241

12421242
defp bitstring_to_algebra(meta, args, state) do
12431243
last = length(args) - 1
1244+
join = if Keyword.get(meta, :eol, false), do: :line, else: :flex_glue
12441245
to_algebra_fun = &bitstring_segment_to_algebra(&1, &2, last)
1245-
force_unfit? = Keyword.get(meta, :eol, false)
12461246

1247-
{args_doc, state} =
1247+
{args_doc, join, state} =
12481248
args
12491249
|> Enum.with_index()
1250-
|> args_to_algebra_with_comments(meta, false, false, force_unfit?, state, to_algebra_fun)
1250+
|> args_to_algebra_with_comments(meta, false, false, join, state, to_algebra_fun)
12511251

1252-
{surround("<<", args_doc, ">>"), state}
1252+
if join == :flex_glue do
1253+
{"<<" |> concat(args_doc) |> nest(2) |> concat(">>") |> group(), state}
1254+
else
1255+
{surround("<<", args_doc, ">>"), state}
1256+
end
12531257
end
12541258

12551259
defp bitstring_segment_to_algebra({{:<-, meta, [left, right]}, i}, state, last) do
@@ -1298,22 +1302,22 @@ defmodule Code.Formatter do
12981302
## Literals
12991303

13001304
defp list_to_algebra(meta, args, state) do
1301-
to_algebra_fun = &quoted_to_algebra(&1, :parens_arg, &2)
1302-
force_unfit? = Keyword.get(meta, :eol, false)
1305+
join = if Keyword.get(meta, :eol, false), do: :line, else: :glue
1306+
fun = &quoted_to_algebra(&1, :parens_arg, &2)
13031307

1304-
{args_doc, state} =
1305-
args_to_algebra_with_comments(args, meta, false, false, force_unfit?, state, to_algebra_fun)
1308+
{args_doc, _join, state} =
1309+
args_to_algebra_with_comments(args, meta, false, false, join, state, fun)
13061310

13071311
{surround("[", args_doc, "]"), state}
13081312
end
13091313

13101314
defp map_to_algebra(meta, name_doc, [{:|, _, [left, right]}], state) do
1315+
join = if Keyword.get(meta, :eol, false), do: :line, else: :glue
13111316
fun = &quoted_to_algebra(&1, :parens_arg, &2)
1312-
force_unfit? = Keyword.get(meta, :eol, false)
13131317
{left_doc, state} = fun.(left, state)
13141318

1315-
{right_doc, state} =
1316-
args_to_algebra_with_comments(right, meta, false, false, force_unfit?, state, fun)
1319+
{right_doc, _join, state} =
1320+
args_to_algebra_with_comments(right, meta, false, false, join, state, fun)
13171321

13181322
args_doc =
13191323
left_doc
@@ -1325,33 +1329,27 @@ defmodule Code.Formatter do
13251329
end
13261330

13271331
defp map_to_algebra(meta, name_doc, args, state) do
1328-
force_unfit? = Keyword.get(meta, :eol, false)
1332+
join = if Keyword.get(meta, :eol, false), do: :line, else: :glue
13291333
fun = &quoted_to_algebra(&1, :parens_arg, &2)
13301334

1331-
{args_doc, state} =
1332-
args_to_algebra_with_comments(args, meta, false, false, force_unfit?, state, fun)
1335+
{args_doc, _join, state} =
1336+
args_to_algebra_with_comments(args, meta, false, false, join, state, fun)
13331337

13341338
name_doc = "%" |> concat(name_doc) |> concat("{")
13351339
{surround(name_doc, args_doc, "}"), state}
13361340
end
13371341

1338-
defp tuple_to_algebra(meta, args, state) do
1339-
force_unfit? = Keyword.get(meta, :eol, false)
1342+
defp tuple_to_algebra(meta, args, join, state) do
1343+
join = if Keyword.get(meta, :eol, false), do: :line, else: join
13401344
fun = &quoted_to_algebra(&1, :parens_arg, &2)
13411345

1342-
next_break_fits? =
1343-
args != [] and next_break_fits?(Enum.fetch!(args, -1)) and
1344-
not Keyword.get(meta, :eol, false)
1345-
1346-
{args_doc, state} =
1347-
args_to_algebra_with_comments(args, meta, false, next_break_fits?, force_unfit?, state, fun)
1348-
1349-
doc = surround("{", args_doc, "}")
1346+
{args_doc, join, state} =
1347+
args_to_algebra_with_comments(args, meta, false, false, join, state, fun)
13501348

1351-
if next_break_fits? do
1352-
{next_break_fits(doc, :disabled), state}
1349+
if join == :flex_glue do
1350+
{"{" |> concat(args_doc) |> nest(1) |> concat("}") |> group(), state}
13531351
else
1354-
{doc, state}
1352+
{surround("{", args_doc, "}"), state}
13551353
end
13561354
end
13571355

@@ -1456,15 +1454,7 @@ defmodule Code.Formatter do
14561454
defp heredoc_line(["", _ | _]), do: nest(line(), :reset)
14571455
defp heredoc_line(_), do: line()
14581456

1459-
defp args_to_algebra_with_comments(
1460-
args,
1461-
meta,
1462-
skip_parens?,
1463-
next_break_fits?,
1464-
force_unfit?,
1465-
state,
1466-
fun
1467-
) do
1457+
defp args_to_algebra_with_comments(args, meta, skip_parens?, next_break_fits?, join, state, fun) do
14681458
min_line = line(meta)
14691459
max_line = end_line(meta)
14701460

@@ -1498,13 +1488,16 @@ defmodule Code.Formatter do
14981488

14991489
cond do
15001490
args_docs == [] ->
1501-
{@empty, state}
1491+
{@empty, :empty, state}
15021492

1503-
force_unfit? or comments? ->
1504-
{args_docs |> Enum.reduce(&line(&2, &1)) |> force_unfit(), state}
1493+
join == :line or comments? ->
1494+
{args_docs |> Enum.reduce(&line(&2, &1)) |> force_unfit(), :line, state}
15051495

1506-
true ->
1507-
{args_docs |> Enum.reduce(&glue(&2, &1)), state}
1496+
join == :glue ->
1497+
{args_docs |> Enum.reduce(&glue(&2, &1)), :glue, state}
1498+
1499+
join == :flex_glue ->
1500+
{args_docs |> Enum.reduce(&flex_glue(&2, &1)), :flex_glue, state}
15081501
end
15091502
end
15101503

@@ -1674,7 +1667,11 @@ defmodule Code.Formatter do
16741667
defp clause_args_to_algebra(args, min_line, state) do
16751668
meta = [line: min_line]
16761669
fun = &clause_args_to_algebra/2
1677-
args_to_algebra_with_comments([args], meta, false, false, false, state, fun)
1670+
1671+
{args_docs, _join, state} =
1672+
args_to_algebra_with_comments([args], meta, false, false, :glue, state, fun)
1673+
1674+
{args_docs, state}
16781675
end
16791676

16801677
# fn a, b, c when d -> e end
@@ -1916,43 +1913,61 @@ defmodule Code.Formatter do
19161913
end
19171914
end
19181915

1919-
defp next_break_fits?({:<<>>, meta, [_ | _] = entries}) do
1920-
meta[:format] == :bin_heredoc or not interpolated?(entries)
1916+
defp next_break_fits?({:{}, meta, _args}, state) do
1917+
eol_or_comments?(meta, state)
1918+
end
1919+
1920+
defp next_break_fits?({:__block__, meta, [{_, _}]}, state) do
1921+
eol_or_comments?(meta, state)
19211922
end
19221923

1923-
defp next_break_fits?({{:., _, [String, :to_charlist]}, _, [{:<<>>, meta, [_ | _]}]}) do
1924+
defp next_break_fits?({:<<>>, meta, [_ | _] = entries}, state) do
1925+
meta[:format] == :bin_heredoc or
1926+
(not interpolated?(entries) and eol_or_comments?(meta, state))
1927+
end
1928+
1929+
defp next_break_fits?({{:., _, [String, :to_charlist]}, _, [{:<<>>, meta, [_ | _]}]}, _state) do
19241930
meta[:format] == :list_heredoc
19251931
end
19261932

1927-
defp next_break_fits?({{:., _, [_left, :{}]}, _, _}) do
1933+
defp next_break_fits?({{:., _, [_left, :{}]}, _, _}, _state) do
19281934
true
19291935
end
19301936

1931-
defp next_break_fits?({:__block__, meta, [string]}) when is_binary(string) do
1937+
defp next_break_fits?({:__block__, meta, [string]}, _state) when is_binary(string) do
19321938
meta[:format] == :bin_heredoc
19331939
end
19341940

1935-
defp next_break_fits?({:__block__, meta, [list]}) when is_list(list) do
1941+
defp next_break_fits?({:__block__, meta, [list]}, _state) when is_list(list) do
19361942
meta[:format] != :charlist
19371943
end
19381944

1939-
defp next_break_fits?({form, _, [_ | _]}) when form in [:fn, :%{}, :%] do
1945+
defp next_break_fits?({form, _, [_ | _]}, _state) when form in [:fn, :%{}, :%] do
19401946
true
19411947
end
19421948

1943-
defp next_break_fits?({fun, meta, args}) when is_atom(fun) and is_list(args) do
1949+
defp next_break_fits?({fun, meta, args}, _state) when is_atom(fun) and is_list(args) do
19441950
meta[:terminator] in [@double_heredoc, @single_heredoc] and
19451951
fun |> Atom.to_string() |> String.starts_with?("sigil_")
19461952
end
19471953

1948-
defp next_break_fits?({{:__block__, _, [atom]}, expr}) when is_atom(atom) do
1949-
next_break_fits?(expr)
1954+
defp next_break_fits?({{:__block__, _, [atom]}, expr}, state) when is_atom(atom) do
1955+
next_break_fits?(expr, state)
19501956
end
19511957

1952-
defp next_break_fits?(_) do
1958+
defp next_break_fits?(_, _state) do
19531959
false
19541960
end
19551961

1962+
defp eol_or_comments?(meta, %{comments: comments}) do
1963+
Keyword.get(meta, :eol, false) or
1964+
(
1965+
min_line = line(meta)
1966+
max_line = end_line(meta)
1967+
Enum.any?(comments, fn {line, _, _} -> line > min_line and line < max_line end)
1968+
)
1969+
end
1970+
19561971
defp last_arg_to_keyword([_ | _] = arg, _list_to_keyword?) do
19571972
{keyword?(arg), arg}
19581973
end

lib/elixir/lib/dynamic_supervisor.ex

+9-8
Original file line numberDiff line numberDiff line change
@@ -440,14 +440,15 @@ defmodule DynamicSupervisor do
440440
:ok <- validate_seconds(max_seconds),
441441
:ok <- validate_dynamic(max_children),
442442
:ok <- validate_extra_arguments(extra_arguments) do
443-
{:ok, %{
444-
state
445-
| extra_arguments: extra_arguments,
446-
max_children: max_children,
447-
max_restarts: max_restarts,
448-
max_seconds: max_seconds,
449-
strategy: strategy
450-
}}
443+
{:ok,
444+
%{
445+
state
446+
| extra_arguments: extra_arguments,
447+
max_children: max_children,
448+
max_restarts: max_restarts,
449+
max_seconds: max_seconds,
450+
strategy: strategy
451+
}}
451452
end
452453
end
453454

lib/elixir/lib/kernel.ex

+5-4
Original file line numberDiff line numberDiff line change
@@ -3134,10 +3134,11 @@ defmodule Kernel do
31343134
fun = fn {x, pos}, acc ->
31353135
case x do
31363136
{op, _, [_]} when op == :+ or op == :- ->
3137-
:elixir_errors.warn(__CALLER__.line, __CALLER__.file, <<
3138-
"piping into a unary operator is deprecated, please use the ",
3139-
"qualified name. For example, Kernel.+(5), instead of +5"
3140-
>>)
3137+
message =
3138+
<<"piping into a unary operator is deprecated, please use the ",
3139+
"qualified name. For example, Kernel.+(5), instead of +5">>
3140+
3141+
:elixir_errors.warn(__CALLER__.line, __CALLER__.file, message)
31413142

31423143
_ ->
31433144
:ok

0 commit comments

Comments
 (0)