summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaszlo Bacsi <lackac@lackac.hu>2018-07-10 13:16:57 +0200
committerJosé Valim <jose.valim@gmail.com>2018-07-10 13:42:20 +0200
commit1aff3b1370d88212675c6d14f497a177dc415f91 (patch)
tree211d041b83d901970f7591fee9ce4c6619c637de
parentcf68b9f652ce7b3788d496dd344e6fb8efe8a470 (diff)
downloadelixir-1aff3b1370d88212675c6d14f497a177dc415f91.tar.gz
Add since, deprecated, and defaults to docs metadata
-rw-r--r--lib/elixir/lib/kernel/typespec.ex32
-rw-r--r--lib/elixir/lib/module.ex39
-rw-r--r--lib/elixir/test/elixir/kernel/docs_test.exs58
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