diff options
author | Laszlo Bacsi <lackac@lackac.hu> | 2018-07-10 13:16:57 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2018-07-10 13:42:20 +0200 |
commit | 1aff3b1370d88212675c6d14f497a177dc415f91 (patch) | |
tree | 211d041b83d901970f7591fee9ce4c6619c637de | |
parent | cf68b9f652ce7b3788d496dd344e6fb8efe8a470 (diff) | |
download | elixir-1aff3b1370d88212675c6d14f497a177dc415f91.tar.gz |
Add since, deprecated, and defaults to docs metadata
-rw-r--r-- | lib/elixir/lib/kernel/typespec.ex | 32 | ||||
-rw-r--r-- | lib/elixir/lib/module.ex | 39 | ||||
-rw-r--r-- | lib/elixir/test/elixir/kernel/docs_test.exs | 58 |
3 files changed, 86 insertions, 43 deletions
diff --git a/lib/elixir/lib/kernel/typespec.ex b/lib/elixir/lib/kernel/typespec.ex index c457ba5ef..33d8c5d92 100644 --- a/lib/elixir/lib/kernel/typespec.ex +++ b/lib/elixir/lib/kernel/typespec.ex @@ -136,8 +136,8 @@ defmodule Kernel.Typespec do {name, arity} -> {line, doc} = get_doc_info(set, :typedoc, line) - meta = if kind == :opaque, do: %{opaque: true}, else: %{} - store_doc(set, :type, name, arity, line, doc, meta) + doc_meta = if kind == :opaque, do: %{opaque: true}, else: %{} + store_doc(set, :type, name, arity, line, doc, doc_meta) :error -> :error @@ -157,11 +157,9 @@ defmodule Kernel.Typespec do :ok end - defp store_doc(set, kind, name, arity, line, doc, meta) do - # TODO: Add and merge this information to doc metadata - _ = get_since_info(set) - _ = get_deprecated_info(set) - :ets.insert(set, {{kind, name, arity}, line, doc, meta}) + defp store_doc(set, kind, name, arity, line, doc, doc_meta) do + doc_meta = get_doc_meta(doc_meta, set) + :ets.insert(set, {{kind, name, arity}, line, doc, doc_meta}) end defp get_doc_info(set, attr, line) do @@ -171,12 +169,24 @@ defmodule Kernel.Typespec do end end - defp get_since_info(set) do - :ets.take(set, :since) + defp get_doc_meta(doc_meta, set) do + doc_meta + |> get_since_info(set) + |> get_deprecated_info(set) end - defp get_deprecated_info(set) do - :ets.take(set, :deprecated) + defp get_since_info(doc_meta, set) do + case :ets.take(set, :since) do + [{:since, since, _}] when is_binary(since) -> Map.put(doc_meta, :since, since) + _ -> doc_meta + end + end + + defp get_deprecated_info(doc_meta, set) do + case :ets.take(set, :deprecated) do + [{:deprecated, reason, _}] when is_binary(reason) -> Map.put(doc_meta, :deprecated, reason) + _ -> doc_meta + end end defp spec_to_signature({:when, _, [spec, _]}), do: type_to_signature(spec) diff --git a/lib/elixir/lib/module.ex b/lib/elixir/lib/module.ex index be87caa26..490b35d4c 100644 --- a/lib/elixir/lib/module.ex +++ b/lib/elixir/lib/module.ex @@ -1256,17 +1256,15 @@ defmodule Module do {arity, defaults} = args_count(args, 0, 0) impl = compile_impl(set, bag, name, env, kind, arity, defaults) - _deprecated = compile_deprecated(set, bag, name, arity, defaults) - _since = compile_since(set) + doc_meta = compile_doc_meta(set, bag, name, arity, defaults) - # TODO: Store @since and @deprecated alongside the docs {line, doc} = get_doc_info(set, env) - compile_doc(set, line, kind, name, arity, args, body, doc, %{}, env, impl) + compile_doc(set, line, kind, name, arity, args, body, doc, doc_meta, env, impl) :ok end - defp compile_doc(_table, line, kind, name, arity, _args, _body, doc, _meta, env, _impl) + defp compile_doc(_table, line, kind, name, arity, _args, _body, doc, _doc_meta, env, _impl) when kind in [:defp, :defmacrop] do if doc do message = @@ -1277,16 +1275,16 @@ defmodule Module do end end - defp compile_doc(table, line, kind, name, arity, args, body, doc, meta, env, impl) do + defp compile_doc(table, line, kind, name, arity, args, body, doc, doc_meta, env, impl) do key = {doc_key(kind), name, arity} signature = build_signature(args, env) case :ets.lookup(table, key) do [] -> doc = if is_nil(doc) && impl, do: false, else: doc - :ets.insert(table, {key, line, signature, doc, meta}) + :ets.insert(table, {key, line, signature, doc, doc_meta}) - [{_, current_line, current_sign, current_doc, current_meta}] -> + [{_, current_line, current_sign, current_doc, current_doc_meta}] -> signature = merge_signatures(current_sign, signature, 1) if is_binary(doc) and is_binary(current_doc) and not is_nil(body) do @@ -1300,32 +1298,41 @@ defmodule Module do doc = if is_nil(doc), do: current_doc, else: doc doc = if is_nil(doc) && impl, do: false, else: doc - meta = Map.merge(current_meta, meta) - :ets.insert(table, {key, current_line, signature, doc, meta}) + doc_meta = Map.merge(current_doc_meta, doc_meta) + :ets.insert(table, {key, current_line, signature, doc, doc_meta}) end end defp doc_key(:def), do: :function defp doc_key(:defmacro), do: :macro - defp compile_since(table) do + defp compile_doc_meta(set, bag, name, arity, defaults) do + doc_meta = compile_since(%{}, set) + doc_meta = compile_deprecated(doc_meta, set, bag, name, arity, defaults) + add_defaults_count(doc_meta, defaults) + end + + defp compile_since(doc_meta, table) do case :ets.take(table, :since) do - [{:since, since, _}] when is_binary(since) -> since - _ -> nil + [{:since, since, _}] when is_binary(since) -> Map.put(doc_meta, :since, since) + _ -> doc_meta end end - defp compile_deprecated(set, bag, name, arity, defaults) do + defp compile_deprecated(doc_meta, set, bag, name, arity, defaults) do case :ets.take(set, :deprecated) do [{:deprecated, reason, _}] when is_binary(reason) -> :ets.insert(bag, deprecated_reasons(defaults, name, arity, reason)) - reason + Map.put(doc_meta, :deprecated, reason) _ -> - nil + doc_meta end end + defp add_defaults_count(doc_meta, 0), do: doc_meta + defp add_defaults_count(doc_meta, n), do: Map.put(doc_meta, :defaults, n) + defp deprecated_reasons(0, name, arity, reason) do [deprecated_reason(name, arity, reason)] end diff --git a/lib/elixir/test/elixir/kernel/docs_test.exs b/lib/elixir/test/elixir/kernel/docs_test.exs index c57a9e56e..1618097a2 100644 --- a/lib/elixir/test/elixir/kernel/docs_test.exs +++ b/lib/elixir/test/elixir/kernel/docs_test.exs @@ -152,6 +152,7 @@ defmodule Kernel.DocsTest do @doc "Callback doc" @since "1.2.3" + @deprecated "use baz/2 instead" @callback foo(any) :: any @doc false @@ -163,7 +164,8 @@ defmodule Kernel.DocsTest do @doc "Function doc" @since "1.2.3" - def foo(arg), do: arg + 1 + @deprecated "use baz/2 instead" + def foo(arg \\ 0), do: arg + 1 @doc "Multiple bodiless clause doc" @since "1.2.3" @@ -194,21 +196,45 @@ defmodule Kernel.DocsTest do assert module_doc == "Module doc" - assert [ - {{:callback, :bar, 0}, _, [], :hidden, %{}}, - {{:callback, :baz, 2}, _, [], :none, %{}}, - {{:callback, :foo, 1}, _, [], %{"en" => "Callback doc"}, %{}}, - {{:function, :bar, 1}, _, ["bar(arg)"], %{"en" => "Multiple bodiless clause doc"}, - %{}}, - {{:function, :baz, 1}, _, ["baz(arg)"], - %{"en" => "Multiple bodiless clause and docs"}, %{}}, - {{:function, :foo, 1}, _, ["foo(arg)"], %{"en" => "Function doc"}, %{}}, - {{:function, :nullary, 0}, _, ["nullary()"], %{"en" => "add_doc"}, %{}}, - {{:function, :qux, 1}, _, ["qux(bool)"], :hidden, %{}}, - {{:macrocallback, :qux, 1}, _, [], %{"en" => "Macrocallback doc"}, %{}}, - {{:type, :bar, 1}, _, [], %{"en" => "Opaque type doc"}, %{opaque: true}}, - {{:type, :foo, 1}, _, [], %{"en" => "Type doc"}, %{}} - ] = Enum.sort(docs) + [ + callback_bar, + callback_baz, + callback_foo, + function_bar, + function_baz, + function_foo, + function_nullary, + function_qux, + macrocallback_qux, + type_bar, + type_foo + ] = Enum.sort(docs) + + assert {{:callback, :bar, 0}, _, [], :hidden, %{}} = callback_bar + assert {{:callback, :baz, 2}, _, [], :none, %{}} = callback_baz + + assert {{:callback, :foo, 1}, _, [], %{"en" => "Callback doc"}, + %{since: "1.2.3", deprecated: "use baz/2 instead"}} = callback_foo + + assert {{:function, :bar, 1}, _, ["bar(arg)"], %{"en" => "Multiple bodiless clause doc"}, + %{since: "1.2.3"}} = function_bar + + assert {{:function, :baz, 1}, _, ["baz(arg)"], + %{"en" => "Multiple bodiless clause and docs"}, %{since: "1.2.3"}} = function_baz + + assert {{:function, :foo, 1}, _, ["foo(arg \\\\ 0)"], %{"en" => "Function doc"}, + %{since: "1.2.3", deprecated: "use baz/2 instead", defaults: 1}} = function_foo + + assert {{:function, :nullary, 0}, _, ["nullary()"], %{"en" => "add_doc"}, %{}} = + function_nullary + + assert {{:function, :qux, 1}, _, ["qux(bool)"], :hidden, %{}} = function_qux + + assert {{:macrocallback, :qux, 1}, _, [], %{"en" => "Macrocallback doc"}, %{}} = + macrocallback_qux + + assert {{:type, :bar, 1}, _, [], %{"en" => "Opaque type doc"}, %{opaque: true}} = type_bar + assert {{:type, :foo, 1}, _, [], %{"en" => "Type doc"}, %{since: "1.2.3"}} = type_foo end end |