Record type should be private by default, closes #1288

This commit is contained in:
José Valim
2013-06-23 20:20:47 +02:00
parent fc219e7dca
commit a8a2f86a23
3 changed files with 19 additions and 15 deletions
+4 -5
View File
@@ -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)
+12 -8
View File
@@ -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 """
+3 -2
View File
@@ -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