Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lib/elixir/lib/code/typespec.ex
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ defmodule Code.Typespec do
Returns all types available from the module's BEAM code.

The result is returned as a list of tuples where the first
element is the type (`:typep`, `:type` and `:opaque`).
element is the type (`:typep`, `:type`, `:opaque` and, on Erlang/OTP 28+,
`:nominal`).

The module must have a corresponding BEAM file which can be
located by the runtime system. The types will be in the Erlang
Expand All @@ -95,9 +96,10 @@ defmodule Code.Typespec do

types =
for {:attribute, _, kind, {name, _, args} = type} <- abstract_code,
kind in [:opaque, :type] do
kind in [:opaque, :type, :nominal] do
cond do
kind == :opaque -> {:opaque, type}
kind == :nominal -> {:nominal, type}
{name, length(args)} in exported_types -> {:type, type}
true -> {:typep, type}
end
Expand Down
17 changes: 17 additions & 0 deletions lib/elixir/test/elixir/typespec_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1438,6 +1438,23 @@ defmodule TypespecTest do
assert Code.Typespec.fetch_specs(Unknown) == :error
end

if System.otp_release() >= "28" do
test "retrieval of Erlang nominal types" do
forms = [
{:attribute, 1, :module, :typespec_nominal_sample},
{:attribute, 2, :export_type, [meters: 0]},
{:attribute, 3, :nominal, {:meters, {:type, 3, :integer, []}, []}},
{:attribute, 4, :type, {:plain, {:type, 4, :atom, []}, []}}
]

{:ok, :typespec_nominal_sample, beam} = :compile.forms(forms, [:debug_info])

assert {:ok, types} = Code.Typespec.fetch_types(beam)
assert {:nominal, {:meters, {:type, 3, :integer, []}, []}} in types
assert {:typep, {:plain, {:type, 4, :atom, []}, []}} in types
end
end

# This is a test that implements all types specified in lib/elixir/pages/typespecs.md
test "documented types and their AST" do
defmodule SomeStruct do
Expand Down
Loading