diff --git a/lib/iex/lib/iex/introspection.ex b/lib/iex/lib/iex/introspection.ex index 2eaa85b954f..56622dfc30c 100644 --- a/lib/iex/lib/iex/introspection.ex +++ b/lib/iex/lib/iex/introspection.ex @@ -455,16 +455,16 @@ defmodule IEx.Introspection do end defp print_fun(mod, {{kind, fun, arity}, _line, signature, doc, metadata}, spec) do - if callback_module = doc == :none and callback_module(mod, fun, arity) do - filter = &match?({_, ^fun, ^arity}, elem(&1, 0)) - - case get_callback_docs(callback_module, filter) do - {:ok, callback_docs} -> Enum.each(callback_docs, &print_typespec/1) - _ -> nil + doc = + if callback_module = doc == :none and callback_module(mod, fun, arity) do + %{ + "en" => "Callback implementation for `c:#{inspect(callback_module)}.#{fun}/#{arity}`." + } + else + doc end - else - print_doc("#{kind_to_def(kind)} #{Enum.join(signature, " ")}", spec, doc, metadata) - end + + print_doc("#{kind_to_def(kind)} #{Enum.join(signature, " ")}", spec, doc, metadata) end defp kind_to_def(:function), do: :def diff --git a/lib/iex/test/iex/helpers_test.exs b/lib/iex/test/iex/helpers_test.exs index dc9821a80e6..8632901b0a1 100644 --- a/lib/iex/test/iex/helpers_test.exs +++ b/lib/iex/test/iex/helpers_test.exs @@ -467,20 +467,27 @@ defmodule IEx.HelpersTest do behaviour = """ defmodule MyBehaviour do @doc "Docs for MyBehaviour.first" + @callback first(integer) :: integer @callback second(integer) :: integer @callback second(integer, integer) :: integer + @macrocallback third() :: any end """ impl = """ defmodule Impl do @behaviour MyBehaviour + def first(0), do: 0 + @doc "Docs for Impl.second/1" def second(0), do: 0 + @doc "Docs for Impl.second/2" def second(0, 0), do: 0 + + defmacro third(), do: nil end """ @@ -490,7 +497,7 @@ defmodule IEx.HelpersTest do assert c(files, ".") |> Enum.sort() == [Impl, MyBehaviour] assert capture_io(fn -> h(Impl.first() / 1) end) == - "@callback first(integer()) :: integer()\n\nDocs for MyBehaviour.first\n" + "* def first(int)\n\nCallback implementation for `c:MyBehaviour.first/1`.\n" assert capture_io(fn -> h(Impl.second() / 1) end) == "* def second(int)\n\nDocs for Impl.second/1\n" @@ -499,11 +506,14 @@ defmodule IEx.HelpersTest do "* def second(int1, int2)\n\nDocs for Impl.second/2\n" assert capture_io(fn -> h(Impl.first()) end) == - "@callback first(integer()) :: integer()\n\nDocs for MyBehaviour.first\n" + "* def first(int)\n\nCallback implementation for `c:MyBehaviour.first/1`.\n" assert capture_io(fn -> h(Impl.second()) end) == "* def second(int)\n\nDocs for Impl.second/1\n* def second(int1, int2)\n\nDocs for Impl.second/2\n" + assert capture_io(fn -> h(Impl.third() / 0) end) == + "* defmacro third()\n\nCallback implementation for `c:MyBehaviour.third/0`.\n" + assert capture_io(fn -> h(MyBehaviour.first()) end) == """ No documentation for function MyBehaviour.first was found, but there is a callback with the same name. You can view callback documentation with the b/1 helper.\n @@ -516,6 +526,11 @@ defmodule IEx.HelpersTest do assert capture_io(fn -> h(MyBehaviour.second() / 3) end) == "No documentation for MyBehaviour.second/3 was found\n" + + assert capture_io(fn -> h(MyBehaviour.third() / 0) end) == """ + No documentation for function MyBehaviour.third/0 was found, but there is a callback with the same name. + You can view callback documentation with the b/1 helper.\n + """ end) after cleanup_modules([Impl, MyBehaviour])