Skip to content

Commit a8a2f86

Browse files
author
José Valim
committed
Record type should be private by default, closes #1288
1 parent fc219e7 commit a8a2f86

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,19 +1491,18 @@ defmodule Kernel do
14911491
14921492
## Types
14931493
1494-
`defrecordp` automatically generates an opaque type based
1495-
on the record name and the types can be modified too. The
1496-
following definition:
1494+
`defrecordp` allows a developer to generate a type
1495+
automatically by simply providing a type to its fields.
1496+
The following definition:
14971497
14981498
defrecordp :user,
14991499
name: "José" :: binary,
15001500
age: 25 :: integer
15011501
15021502
Will generate the following type:
15031503
1504-
@opaque user :: { :user, binary, integer }
1504+
@typep user_t :: { :user, binary, integer }
15051505
1506-
All the fields without a specified type are assumed to have type `term`.
15071506
"""
15081507
defmacro defrecordp(name, fields) when is_atom(name) do
15091508
Record.defrecordp(name, fields)

lib/elixir/lib/record.ex

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,24 +253,28 @@ defmodule Record do
253253
so check it for more information and documentation.
254254
"""
255255
def defrecordp(name, fields) when is_atom(name) and is_list(fields) do
256-
{ fields, types } = recordp_split(fields, [], [])
256+
{ fields, types, def_type } = recordp_split(fields, [], [], false)
257+
type = :"#{name}_t"
257258

258259
quote do
259260
Record.defmacros(unquote(name), unquote(fields), __ENV__)
260-
@opaque unquote(name)() :: { unquote(name), unquote_splicing(types) }
261+
262+
if unquote(def_type) do
263+
@typep unquote(type)() :: { unquote(name), unquote_splicing(types) }
264+
end
261265
end
262266
end
263267

264-
defp recordp_split([{ field, { :::, _, [default, type] }}|t], defaults, types) do
265-
recordp_split t, [{ field, default }|defaults], [type|types]
268+
defp recordp_split([{ field, { :::, _, [default, type] }}|t], defaults, types, _) do
269+
recordp_split t, [{ field, default }|defaults], [type|types], true
266270
end
267271

268-
defp recordp_split([other|t], defaults, types) do
269-
recordp_split t, [other|defaults], [quote(do: term)|types]
272+
defp recordp_split([other|t], defaults, types, def_type) do
273+
recordp_split t, [other|defaults], [quote(do: term)|types], def_type
270274
end
271275

272-
defp recordp_split([], defaults, types) do
273-
{ :lists.reverse(defaults), :lists.reverse(types) }
276+
defp recordp_split([], defaults, types, def_type) do
277+
{ :lists.reverse(defaults), :lists.reverse(types), def_type }
274278
end
275279

276280
@doc """

lib/elixir/test/elixir/typespec_test.exs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,11 @@ defmodule Typespec.TypeTest do
262262
test "@type from defrecordp" do
263263
types = test_module do
264264
defrecordp :user, name: nil, age: 0 :: integer
265-
@opaque
265+
@opaque user :: user_t
266+
@type
266267
end
267268

268-
assert [{:user, {:type, _, :tuple,
269+
assert [{:user_t, {:type, _, :tuple,
269270
[{:atom, _, :user}, {:type, _, :term, []}, {:type, _, :integer, []}]}, []}] = types
270271
end
271272

0 commit comments

Comments
 (0)