Record type should be private by default, closes #1288
This commit is contained in:
@@ -1491,9 +1491,9 @@ defmodule Kernel do
|
||||
|
||||
## Types
|
||||
|
||||
`defrecordp` automatically generates an opaque type based
|
||||
on the record name and the types can be modified too. The
|
||||
following definition:
|
||||
`defrecordp` allows a developer to generate a type
|
||||
automatically by simply providing a type to its fields.
|
||||
The following definition:
|
||||
|
||||
defrecordp :user,
|
||||
name: "José" :: binary,
|
||||
@@ -1501,9 +1501,8 @@ defmodule Kernel do
|
||||
|
||||
Will generate the following type:
|
||||
|
||||
@opaque user :: { :user, binary, integer }
|
||||
@typep user_t :: { :user, binary, integer }
|
||||
|
||||
All the fields without a specified type are assumed to have type `term`.
|
||||
"""
|
||||
defmacro defrecordp(name, fields) when is_atom(name) do
|
||||
Record.defrecordp(name, fields)
|
||||
|
||||
@@ -253,24 +253,28 @@ defmodule Record do
|
||||
so check it for more information and documentation.
|
||||
"""
|
||||
def defrecordp(name, fields) when is_atom(name) and is_list(fields) do
|
||||
{ fields, types } = recordp_split(fields, [], [])
|
||||
{ fields, types, def_type } = recordp_split(fields, [], [], false)
|
||||
type = :"#{name}_t"
|
||||
|
||||
quote do
|
||||
Record.defmacros(unquote(name), unquote(fields), __ENV__)
|
||||
@opaque unquote(name)() :: { unquote(name), unquote_splicing(types) }
|
||||
|
||||
if unquote(def_type) do
|
||||
@typep unquote(type)() :: { unquote(name), unquote_splicing(types) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp recordp_split([{ field, { :::, _, [default, type] }}|t], defaults, types) do
|
||||
recordp_split t, [{ field, default }|defaults], [type|types]
|
||||
defp recordp_split([{ field, { :::, _, [default, type] }}|t], defaults, types, _) do
|
||||
recordp_split t, [{ field, default }|defaults], [type|types], true
|
||||
end
|
||||
|
||||
defp recordp_split([other|t], defaults, types) do
|
||||
recordp_split t, [other|defaults], [quote(do: term)|types]
|
||||
defp recordp_split([other|t], defaults, types, def_type) do
|
||||
recordp_split t, [other|defaults], [quote(do: term)|types], def_type
|
||||
end
|
||||
|
||||
defp recordp_split([], defaults, types) do
|
||||
{ :lists.reverse(defaults), :lists.reverse(types) }
|
||||
defp recordp_split([], defaults, types, def_type) do
|
||||
{ :lists.reverse(defaults), :lists.reverse(types), def_type }
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
||||
@@ -262,10 +262,11 @@ defmodule Typespec.TypeTest do
|
||||
test "@type from defrecordp" do
|
||||
types = test_module do
|
||||
defrecordp :user, name: nil, age: 0 :: integer
|
||||
@opaque
|
||||
@opaque user :: user_t
|
||||
@type
|
||||
end
|
||||
|
||||
assert [{:user, {:type, _, :tuple,
|
||||
assert [{:user_t, {:type, _, :tuple,
|
||||
[{:atom, _, :user}, {:type, _, :term, []}, {:type, _, :integer, []}]}, []}] = types
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user