Skip to content

Commit a806765

Browse files
committed
Ignore lines when formatting specs, closes #2245
1 parent 4c269a6 commit a806765

3 files changed

Lines changed: 26 additions & 0 deletions

File tree

lib/ex_doc/language/elixir.ex

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ defmodule ExDoc.Language.Elixir do
378378
@impl true
379379
def format_spec(ast) do
380380
ast
381+
|> normalize_spec_metadata()
381382
|> Macro.to_string()
382383
|> safe_format_string!()
383384
|> ExDoc.Utils.h()
@@ -650,6 +651,18 @@ defmodule ExDoc.Language.Elixir do
650651
end
651652
end
652653

654+
defp normalize_spec_metadata(ast) do
655+
Macro.prewalk(ast, fn
656+
{name, metadata, args} when is_atom(name) and is_list(metadata) and is_list(args) ->
657+
# Elixir uses line metadata to decide when to break lines during stringification.
658+
# Specs come from debug info, so we do not want line numbers to affect rendering.
659+
{name, Keyword.delete(metadata, :line), args}
660+
661+
other ->
662+
other
663+
end)
664+
end
665+
653666
defp typespec_name({:"::", _, [{name, _, _}, _]}), do: Atom.to_string(name)
654667
defp typespec_name({:when, _, [left, _]}), do: typespec_name(left)
655668
defp typespec_name({name, _, _}) when is_atom(name), do: Atom.to_string(name)

test/ex_doc/formatter/html/templates_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,12 @@ defmodule ExDoc.Formatter.HTML.TemplatesTest do
481481
test "outputs the types and function specs", context do
482482
content = get_module_template([TypesAndSpecs, TypesAndSpecs.Sub], context)
483483
integer = ~s[<a href="https://elixir.hexdocs.pm/typespecs.html#basic-types">integer</a>()]
484+
atom = ~s[<a href="https://elixir.hexdocs.pm/typespecs.html#basic-types">atom</a>()]
485+
486+
keyword =
487+
~s[<a href="https://elixir.hexdocs.pm/typespecs.html#built-in-types">keyword</a>()]
488+
489+
string_t = ~s[<a href="https://elixir.hexdocs.pm/String.html#t:t/0">String.t</a>()]
484490

485491
public_html =
486492
~S[<span class="attribute">@type</span> public(t) :: {t, ] <>
@@ -495,6 +501,10 @@ defmodule ExDoc.Formatter.HTML.TemplatesTest do
495501
assert content =~ ~s[A public type]
496502
assert content =~ ~s[<span class="attribute">@spec</span> add(]
497503
assert content =~ ~s[add(#{integer}, <a href="#t:opaque/0">opaque</a>()) :: #{integer}]
504+
505+
assert content =~
506+
~s[format_filters(#{keyword}, #{atom}) :: #{string_t}]
507+
498508
refute content =~ ~s[minus(#{integer}, #{integer}) :: #{integer}]
499509

500510
assert content =~

test/fixtures/types_and_specs.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ defmodule TypesAndSpecs do
2828
@spec macro_with_spec(v) :: {:ok, v} when v: any()
2929
defmacro macro_with_spec(v), do: {:ok, v}
3030

31+
@spec format_filters(keyword(), atom()) :: String.t()
32+
def format_filters(filters, _type), do: inspect(filters)
33+
3134
@spec priv_macro_spec(any) :: {:no, any}
3235
defmacrop priv_macro_spec(v), do: {:no, v}
3336

0 commit comments

Comments
 (0)