From 940c9031be4c9e956d1f64ffb7e7e18acf342734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 15 Dec 2024 15:27:08 +0100 Subject: [PATCH 1/2] Fix typespec with (...) -> any(), closes #1974 --- lib/ex_doc/language/erlang.ex | 48 +++++++++++++++++----------- test/ex_doc/language/erlang_test.exs | 4 +++ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/lib/ex_doc/language/erlang.ex b/lib/ex_doc/language/erlang.ex index f28878b86..1bfe73e4b 100644 --- a/lib/ex_doc/language/erlang.ex +++ b/lib/ex_doc/language/erlang.ex @@ -546,9 +546,14 @@ defmodule ExDoc.Language.Erlang do {op, _, [int]}, acc when is_integer(int) and op in [:+, :-] -> {nil, acc} - # fun() (spec_to_quoted expands it to (... -> any()) - {:->, _, [[{name, _, _}], {:any, _, _}]}, acc when name == :... -> - {nil, acc} + # fun() (spec_to_quoted expands it to (... -> any() in Elixir v1.17 and earlier) + # TODO: Remove me when we require Elixir v1.18+ + {:->, _, [[{name, _, _}], {:any, _, _}]} = node, acc when name == :... -> + if Version.match?(System.version(), ">= 1.18.0-rc") do + {node, acc} + else + {nil, acc} + end # record{type :: remote:type/arity} {:field_type, _, [name, {{:., _, [r_mod, r_type]}, _, args}]}, acc -> @@ -588,7 +593,7 @@ defmodule ExDoc.Language.Erlang do end |> Enum.concat() - put(acc) + put_stack(acc) # Drop and re-add type name (it, the first element in acc, is dropped there too) # @@ -614,16 +619,21 @@ defmodule ExDoc.Language.Erlang do defp replace(formatted, acc, config) do String.replace(formatted, Enum.map(acc, &"#{elem(&1, 0)}("), fn string -> string = String.trim_trailing(string, "(") - {other, ref} = pop() - - if string != other do - Autolink.maybe_warn( - config, - "internal inconsistency, please submit bug: #{inspect(string)} != #{inspect(other)}", - nil, - nil - ) - end + + ref = + case get_stack() do + [{^string, ref} | tail] -> + put_stack(tail) + ref + + _ -> + Autolink.maybe_warn( + config, + "internal inconsistency when processing #{inspect(formatted)}", + nil, + nil + ) + end what = case config.current_kfa do @@ -691,16 +701,16 @@ defmodule ExDoc.Language.Erlang do end) end - defp put(items) do + defp put_stack(items) do Process.put({__MODULE__, :stack}, items) end - defp pop() do - [head | tail] = Process.get({__MODULE__, :stack}) - put(tail) - head + defp get_stack() do + Process.get({__MODULE__, :stack}) end + defp pp(:fun), do: "fun" + defp pp(name) when is_atom(name) do :io_lib.format("~p", [name]) |> IO.iodata_to_binary() end diff --git a/test/ex_doc/language/erlang_test.exs b/test/ex_doc/language/erlang_test.exs index e68a15f31..238f498f2 100644 --- a/test/ex_doc/language/erlang_test.exs +++ b/test/ex_doc/language/erlang_test.exs @@ -806,6 +806,10 @@ defmodule ExDoc.Language.ErlangTest do test "function - any arity", c do assert autolink_spec(~s"-spec foo() -> fun((...) -> t()) | erlang_bar:t().", c) == ~s[foo() -> fun((...) -> t()) | erlang_bar:t().] + + assert autolink_spec(~s"-type foo() :: fun((...) -> any()) | [any()].", c) == + "foo() :: fun((...) -> any()) | " <> + "[any()]." end test "local type", c do From cae5b3e3dc33f11e51ca4c57a47977952940f0b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 15 Dec 2024 15:28:25 +0100 Subject: [PATCH 2/2] address test --- test/ex_doc/language/erlang_test.exs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/ex_doc/language/erlang_test.exs b/test/ex_doc/language/erlang_test.exs index 238f498f2..9c5ffcd8a 100644 --- a/test/ex_doc/language/erlang_test.exs +++ b/test/ex_doc/language/erlang_test.exs @@ -807,9 +807,11 @@ defmodule ExDoc.Language.ErlangTest do assert autolink_spec(~s"-spec foo() -> fun((...) -> t()) | erlang_bar:t().", c) == ~s[foo() -> fun((...) -> t()) | erlang_bar:t().] - assert autolink_spec(~s"-type foo() :: fun((...) -> any()) | [any()].", c) == - "foo() :: fun((...) -> any()) | " <> - "[any()]." + if Version.match?(System.version(), ">= 1.18.0-rc") do + assert autolink_spec(~s"-type foo() :: fun((...) -> any()) | [any()].", c) == + "foo() :: fun((...) -> any()) | " <> + "[any()]." + end end test "local type", c do