summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Jackson <gj@mail.co.de>2018-09-28 02:41:23 -0400
committerJosé Valim <jose.valim@gmail.com>2018-09-28 08:41:23 +0200
commit97ac0e6a9f1b8dd4fd56fec4427bb8839b396f97 (patch)
treecd7a9b40d26fd1ac499fe2a58cb9617bab8f81d5
parent3fcc9241db7b022a503851056f7bbac4f06c3ab7 (diff)
downloadelixir-97ac0e6a9f1b8dd4fd56fec4427bb8839b396f97.tar.gz
Link docs for defdelegate functions (#8228)
Add :delegate_to @doc metadata tag to enable linking to delegatee's docs from delegator's docs Associated issue: elixir-lang/ex_doc#902
-rw-r--r--lib/elixir/lib/io/ansi/docs.ex6
-rw-r--r--lib/elixir/lib/kernel.ex2
-rw-r--r--lib/elixir/lib/module.ex12
-rw-r--r--lib/elixir/test/elixir/io/ansi/docs_test.exs17
-rw-r--r--lib/iex/test/iex/helpers_test.exs28
5 files changed, 62 insertions, 3 deletions
diff --git a/lib/elixir/lib/io/ansi/docs.ex b/lib/elixir/lib/io/ansi/docs.ex
index 230b86e59..69f287289 100644
--- a/lib/elixir/lib/io/ansi/docs.ex
+++ b/lib/elixir/lib/io/ansi/docs.ex
@@ -56,7 +56,7 @@ defmodule IO.ANSI.Docs do
end
@doc """
- Prints documentation metadata (only `since` and `deprecated` for now).
+ Prints documentation metadata (only `delegate_to`, `deprecated`, `guard`, and `since` for now).
See `default_options/0` for docs on the supported options.
"""
@@ -78,6 +78,10 @@ defmodule IO.ANSI.Docs do
{key, value}, _printed when is_boolean(value) and key in @metadata_filter ->
IO.puts([metadata_label(key, options), ' ', to_string(value)])
+ {:delegate_to, {m, f, a}}, _printed ->
+ label = metadata_label(:delegate_to, options)
+ IO.puts([label, ' ', Exception.format_mfa(m, f, a)])
+
_metadata, printed ->
printed
end)
diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex
index d3207dd73..e063bda79 100644
--- a/lib/elixir/lib/kernel.ex
+++ b/lib/elixir/lib/kernel.ex
@@ -5031,6 +5031,8 @@ defmodule Kernel do
for fun <- List.wrap(funs) do
{name, args, as, as_args} = Kernel.Utils.defdelegate(fun, opts)
+ @doc delegate_to: {target, as, :erlang.length(as_args)}
+
def unquote(name)(unquote_splicing(args)) do
unquote(target).unquote(as)(unquote_splicing(as_args))
end
diff --git a/lib/elixir/lib/module.ex b/lib/elixir/lib/module.ex
index b8de65e0f..8c4a7636c 100644
--- a/lib/elixir/lib/module.ex
+++ b/lib/elixir/lib/module.ex
@@ -1950,6 +1950,18 @@ defmodule Module do
"representing the replacement for the deprecated entity, got: #{inspect(value)}"
end
+ defp validate_doc_meta(:delegate_to, value) do
+ case value do
+ {m, f, a} when is_atom(m) and is_atom(f) and is_integer(a) and a >= 0 ->
+ :ok
+
+ _ ->
+ raise ArgumentError,
+ ":delegate_to is a built-in documentation metadata key. It should be a three-element " <>
+ "tuple in the form of {module, function, arity}, got: #{inspect(value)}"
+ end
+ end
+
defp validate_doc_meta(_, _), do: :ok
defp get_doc_info(table, env) do
diff --git a/lib/elixir/test/elixir/io/ansi/docs_test.exs b/lib/elixir/test/elixir/io/ansi/docs_test.exs
index e4bf1a076..642370cf5 100644
--- a/lib/elixir/test/elixir/io/ansi/docs_test.exs
+++ b/lib/elixir/test/elixir/io/ansi/docs_test.exs
@@ -24,8 +24,21 @@ defmodule IO.ANSI.DocsTest do
end
test "metadata is formatted" do
- result = format_metadata(%{since: "1.2.3", deprecated: "Use that other one", author: "Alice"})
- assert result == "\e[33mdeprecated:\e[0m Use that other one\n\e[33msince:\e[0m 1.2.3\n\n"
+ result =
+ format_metadata(%{
+ since: "1.2.3",
+ deprecated: "Use that other one",
+ author: "Alice",
+ delegate_to: {Foo, :bar, 3}
+ })
+
+ assert result == """
+ \e[33mdelegate_to:\e[0m Foo.bar/3
+ \e[33mdeprecated:\e[0m Use that other one
+ \e[33msince:\e[0m 1.2.3
+
+ """
+
assert format_metadata(%{author: "Alice"}) == ""
end
diff --git a/lib/iex/test/iex/helpers_test.exs b/lib/iex/test/iex/helpers_test.exs
index 8c8bcc56f..28844a69b 100644
--- a/lib/iex/test/iex/helpers_test.exs
+++ b/lib/iex/test/iex/helpers_test.exs
@@ -519,6 +519,34 @@ defmodule IEx.HelpersTest do
cleanup_modules([Impl, MyBehaviour])
end
+ test "prints documentation for delegates" do
+ filename = "delegate.ex"
+
+ content = """
+ defmodule Delegator do
+ defdelegate func1, to: Delegated
+ @doc "Delegator func2 doc"
+ defdelegate func2, to: Delegated
+ end
+ defmodule Delegated do
+ def func1, do: 1
+ def func2, do: 2
+ end
+ """
+
+ with_file(filename, content, fn ->
+ assert c(filename, ".") |> Enum.sort() == [Delegated, Delegator]
+
+ assert capture_io(fn -> h(Delegator.func1()) end) ==
+ "* def func1()\n\ndelegate_to: Delegated.func1/0\n\n\n"
+
+ assert capture_io(fn -> h(Delegator.func2()) end) ==
+ "* def func2()\n\ndelegate_to: Delegated.func2/0\n\nDelegator func2 doc\n"
+ end)
+ after
+ cleanup_modules([Delegated, Delegator])
+ end
+
test "prints type documentation when function docs are not available" do
content = """
defmodule MyTypes do