Reflection 以编程方式访问typespec的定义

Reflection 以编程方式访问typespec的定义,reflection,types,elixir,Reflection,Types,Elixir,如何在代码中访问typespec的定义?我希望在宏中使用它来执行一些代码生成 像这样的东西会很理想 给定此模块和类型规范: defmodule MyMod do @type t :: :ok | :error end 我可以调用一个函数,比如code.get\u type(MyMod,:t),它将返回定义表达式的AST: {:::, [], [{:my_type, [], Elixir}, {:|, [], [:ok, :error]}]} 或者,也可以仅使用类型的AST: {:|, [

如何在代码中访问typespec的定义?我希望在宏中使用它来执行一些代码生成

像这样的东西会很理想

给定此模块和类型规范:

defmodule MyMod do
  @type t :: :ok | :error
end
我可以调用一个函数,比如
code.get\u type(MyMod,:t)
,它将返回定义表达式的AST:

{:::, [], [{:my_type, [], Elixir}, {:|, [], [:ok, :error]}]}
或者,也可以仅使用类型的AST:

{:|, [], [:ok, :error]}
这是一个hack(并且只在编译阶段有效),但它可以满足您的需要:

defmodule MyMod do                                      
  @type t1 :: :ok | :error
  @type t2 :: :done
  @type_defs Module.get_attribute(__MODULE__, :type, [])
  def type_defs,
    do: Enum.map(@type_defs, fn {:type, type, _} -> type end)
end

MyMod.type_defs
#⇒ [{:::, [line: 9], [{:t2, [line: 9], nil}, :done]},
#   {:::, [line: 8], [{:t1, [line: 8], nil}, {:|, [line: 8], [:ok, :error]}]}]
您可以使用
defmacro\uu\uuu\uuuu>声明一个模块,实现此功能,并在需要时
使用TypeExtractor

您希望在编译模块后或从该模块内访问此模块吗?