Skip to content

Commit f4fa14c

Browse files
committed
Accept :locals_without_parens in Code.quoted_to_algebra/2
1 parent 541ce6e commit f4fa14c

File tree

4 files changed

+24
-8
lines changed

4 files changed

+24
-8
lines changed

lib/elixir/lib/code.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1333,7 +1333,7 @@ defmodule Code do
13331333
defp previous_eol_count(_), do: 0
13341334

13351335
@doc ~S"""
1336-
Converts a quoted expression to an algebra document.
1336+
Converts a quoted expression to an algebra document using Elixir's formatter rules.
13371337
13381338
The algebra document can be converted into a string by calling:
13391339
@@ -1378,6 +1378,12 @@ defmodule Code do
13781378
`\\n`. If the `:unescape` option was set to `false` when using
13791379
`string_to_quoted/2`, setting this option to `false` will prevent it from
13801380
escaping the sequences twice. Defaults to `true`.
1381+
1382+
* `:locals_without_parens` - a keyword list of name and arity
1383+
pairs that should be kept without parens whenever possible.
1384+
The arity may be the atom `:*`, which implies all arities of
1385+
that name. The formatter already includes a list of functions
1386+
and this option augments this list.
13811387
"""
13821388
@doc since: "1.13.0"
13831389
@spec quoted_to_algebra(Macro.t(), keyword) :: Inspect.Algebra.t()

lib/elixir/lib/code/formatter.ex

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,17 @@ defmodule Code.Formatter do
207207
doc
208208
end
209209

210+
@doc """
211+
Lists all default locals without parens.
212+
"""
213+
def locals_without_parens do
214+
@locals_without_parens
215+
end
216+
210217
@doc """
211218
Checks if a function is a local without parens.
212219
"""
213-
def local_without_parens?(fun, arity, locals_without_parens \\ @locals_without_parens) do
220+
def local_without_parens?(fun, arity, locals_without_parens) do
214221
arity > 0 and
215222
Enum.any?(locals_without_parens, fn {key, val} ->
216223
key == fun and (val == :* or val == arity)
@@ -219,13 +226,11 @@ defmodule Code.Formatter do
219226

220227
defp state(comments, opts) do
221228
force_do_end_blocks = Keyword.get(opts, :force_do_end_blocks, false)
222-
223-
locals_without_parens =
224-
Keyword.get(opts, :locals_without_parens, []) ++ @locals_without_parens
229+
locals_without_parens = Keyword.get(opts, :locals_without_parens, [])
225230

226231
%{
227232
force_do_end_blocks: force_do_end_blocks,
228-
locals_without_parens: locals_without_parens,
233+
locals_without_parens: locals_without_parens ++ locals_without_parens(),
229234
operand_nesting: 2,
230235
skip_eol: false,
231236
comments: comments

lib/elixir/lib/code/normalizer.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ defmodule Code.Normalizer do
1414
def normalize(quoted, opts \\ []) do
1515
line = Keyword.get(opts, :line, nil)
1616
escape = Keyword.get(opts, :escape, true)
17+
locals_without_parens = Keyword.get(opts, :locals_without_parens, [])
1718

1819
state = %{
1920
escape: escape,
20-
parent_meta: [line: line]
21+
parent_meta: [line: line],
22+
locals_without_parens: locals_without_parens ++ Code.Formatter.locals_without_parens()
2123
}
2224

2325
do_normalize(quoted, state)
@@ -283,7 +285,7 @@ defmodule Code.Normalizer do
283285

284286
meta =
285287
if is_nil(meta[:no_parens]) and is_nil(meta[:closing]) and
286-
not Code.Formatter.local_without_parens?(form, arity) do
288+
not Code.Formatter.local_without_parens?(form, arity, state.locals_without_parens) do
287289
[closing: [line: meta[:line]]] ++ meta
288290
else
289291
meta

lib/elixir/test/elixir/code_normalizer/quoted_ast_test.exs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ defmodule Code.Normalizer.QuotedASTTest do
1212
assert quoted_to_string(quote(do: foo(1, 2, 3))) == "foo(1, 2, 3)"
1313
assert quoted_to_string(quote(do: foo([1, 2, 3]))) == "foo([1, 2, 3])"
1414

15+
assert quoted_to_string(quote(do: foo(1, 2, 3)), locals_without_parens: [foo: 3]) ==
16+
"foo 1, 2, 3"
17+
1518
# Mixing literals and non-literals
1619
assert quoted_to_string(quote(do: foo(a, 2))) == "foo(a, 2)"
1720
assert quoted_to_string(quote(do: foo(1, b))) == "foo(1, b)"

0 commit comments

Comments
 (0)