Created
October 19, 2016 20:11
-
-
Save JEG2/1685a9df2274ca5cf866122fa2dbc42d to your computer and use it in GitHub Desktop.
How to get typespec information from Elixir at runtime.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule TypeSpecs do | |
def for_module(module) do | |
{:ok, {^module, [{:abstract_code, {:raw_abstract_v1, attributes}}]}} = | |
module |> :code.which |> :beam_lib.chunks([:abstract_code]) | |
attributes | |
|> Enum.filter_map(fn | |
{:attribute, _, :spec, _function_and_types} -> true | |
_attribute -> false | |
end, fn {:attribute, _, :spec, function_and_types} -> | |
function_and_types | |
end) | |
end | |
end | |
TypeSpecs.for_module(String) | |
|> IO.inspect | |
# [{{:split, 3}, | |
# [{:type, 330, :fun, | |
# [{:type, 330, :product, | |
# [{:user_type, 330, :t, []}, | |
# {:type, 330, :union, | |
# [{:user_type, 330, :pattern, []}, | |
# {:remote_type, 330, [{:atom, 0, Regex}, {:atom, 0, :t}, []]}]}, | |
# {:remote_type, 330, [{:atom, 0, Keyword}, {:atom, 0, :t}, []]}]}, | |
# {:type, 0, :list, [{:user_type, 330, :t, []}]}]}]}, | |
# {{:trim, 2}, | |
# [{:type, 847, :fun, | |
# [{:type, 847, :product, | |
# [{:user_type, 847, :t, []}, {:user_type, 847, :t, []}]}, | |
# {:user_type, 847, :t, []}]}]}, | |
# {{:pad_leading, 3}, | |
# [{:type, 884, :fun, | |
# [{:type, 884, :product, | |
# [{:user_type, 884, :t, []}, {:type, 884, :non_neg_integer, []}, | |
# {:type, 884, :union, | |
# [{:user_type, 884, :t, []}, | |
# {:type, 0, :list, [{:user_type, 884, :t, []}]}]}]}, | |
# {:user_type, 884, :t, []}]}]}, | |
# {{:pad_trailing, 3}, | |
# [{:type, 926, :fun, | |
# [{:type, 926, :product, | |
# [{:user_type, 926, :t, []}, {:type, 926, :non_neg_integer, []}, | |
# {:type, 926, :union, | |
# [{:user_type, 926, :t, []}, | |
# {:type, 0, :list, [{:user_type, 926, :t, []}]}]}]}, | |
# {:user_type, 926, :t, []}]}]}, | |
# {{:printable?, 1}, | |
# [{:type, 217, :fun, | |
# [{:type, 217, :product, [{:user_type, 217, :t, []}]}, | |
# {:type, 217, :boolean, []}]}]}, | |
# {{:valid?, 1}, | |
# [{:type, 1181, :fun, | |
# [{:type, 1181, :product, [{:user_type, 1181, :t, []}]}, | |
# {:type, 1181, :boolean, []}]}]}, | |
# {{:to_integer, 1}, | |
# [{:type, 1808, :fun, | |
# [{:type, 1808, :product, | |
# [{:remote_type, 1808, [{:atom, 0, String}, {:atom, 0, :t}, []]}]}, | |
# {:type, 1808, :integer, []}]}]}, | |
# {{:upcase, 1}, | |
# [{:type, 534, :fun, | |
# [{:type, 534, :product, [{:user_type, 534, :t, []}]}, | |
# {:user_type, 534, :t, []}]}]}, | |
# {{:downcase, 1}, | |
# [{:type, 552, :fun, | |
# [{:type, 552, :product, [{:user_type, 552, :t, []}]}, | |
# {:user_type, 552, :t, []}]}]}, | |
# {{:capitalize, 1}, | |
# [{:type, 576, :fun, | |
# [{:type, 576, :product, [{:user_type, 576, :t, []}]}, | |
# {:user_type, 576, :t, []}]}]}, | |
# {{:reverse, 1}, | |
# [{:type, 1084, :fun, | |
# [{:type, 1084, :product, [{:user_type, 1084, :t, []}]}, | |
# {:user_type, 1084, :t, []}]}]}, | |
# {{:next_grapheme, 1}, | |
# [{:type, 1305, :fun, | |
# [{:type, 1305, :product, [{:user_type, 1305, :t, []}]}, | |
# {:type, 1305, :union, | |
# [{:type, 0, :tuple, | |
# [{:user_type, 1305, :grapheme, []}, {:user_type, 1305, :t, []}]}, | |
# {:atom, 0, nil}]}]}]}, | |
# {{:next_grapheme_size, 1}, | |
# [{:type, 1326, :fun, | |
# [{:type, 1326, :product, [{:user_type, 1326, :t, []}]}, | |
# {:type, 1326, :union, | |
# [{:type, 0, :tuple, | |
# [{:type, 1326, :pos_integer, []}, {:user_type, 1326, :t, []}]}, | |
# {:atom, 0, nil}]}]}]}, | |
# {{:equivalent?, 2}, | |
# [{:type, 486, :fun, | |
# [{:type, 486, :product, | |
# [{:user_type, 486, :t, []}, {:user_type, 486, :t, []}]}, | |
# {:type, 486, :boolean, []}]}]}, | |
# {{:length, 1}, | |
# [{:type, 1386, :fun, | |
# [{:type, 1386, :product, [{:user_type, 1386, :t, []}]}, | |
# {:type, 1386, :non_neg_integer, []}]}]}, | |
# {{:starts_with?, 2}, | |
# [{:type, 1613, :fun, | |
# [{:type, 1613, :product, | |
# [{:user_type, 1613, :t, []}, | |
# {:type, 1613, :union, | |
# [{:user_type, 1613, :t, []}, | |
# {:type, 0, :list, [{:user_type, 1613, :t, []}]}]}]}, | |
# {:type, 1613, :boolean, []}]}]}, | |
# {{:ends_with?, 2}, | |
# [{:type, 1648, :fun, | |
# [{:type, 1648, :product, | |
# [{:user_type, 1648, :t, []}, | |
# {:type, 1648, :union, | |
# [{:user_type, 1648, :t, []}, | |
# {:type, 0, :list, [{:user_type, 1648, :t, []}]}]}]}, | |
# {:type, 1648, :boolean, []}]}]}, | |
# {{:match?, 2}, | |
# [{:type, 1680, :fun, | |
# [{:type, 1680, :product, | |
# [{:user_type, 1680, :t, []}, | |
# {:remote_type, 1680, [{:atom, 0, Regex}, {:atom, 0, :t}, []]}]}, | |
# {:type, 1680, :boolean, []}]}]}, | |
# {{:contains?, 2}, | |
# [{:type, 1713, :fun, | |
# [{:type, 1713, :product, | |
# [{:user_type, 1713, :t, []}, {:user_type, 1713, :pattern, []}]}, | |
# {:type, 1713, :boolean, []}]}]}, | |
# {{:to_integer, 2}, | |
# [{:type, 1824, :fun, | |
# [{:type, 1824, :product, | |
# [{:remote_type, 1824, [{:atom, 0, String}, {:atom, 0, :t}, []]}, | |
# {:type, 1824, :range, [{:integer, 0, 2}, {:integer, 0, 36}]}]}, | |
# {:type, 1824, :integer, []}]}]}, | |
# {{:normalize, 2}, | |
# [{:type, 516, :fun, | |
# [{:type, 516, :product, | |
# [{:user_type, 516, :t, []}, {:type, 516, :atom, []}]}, | |
# {:user_type, 516, :t, []}]}]}, | |
# {{:duplicate, 2}, | |
# [{:type, 1110, :fun, | |
# [{:type, 1110, :product, | |
# [{:user_type, 1110, :t, []}, {:type, 1110, :non_neg_integer, []}]}, | |
# {:user_type, 1110, :t, []}]}]}, | |
# {{:slice, 2}, | |
# [{:type, 1540, :fun, | |
# [{:type, 1540, :product, | |
# [{:user_type, 1540, :t, []}, | |
# {:remote_type, 1540, [{:atom, 0, Range}, {:atom, 0, :t}, []]}]}, | |
# {:user_type, 1540, :t, []}]}]}, | |
# {{:jaro_distance, 2}, | |
# [{:type, 1868, :fun, | |
# [{:type, 1868, :product, | |
# [{:user_type, 1868, :t, []}, {:user_type, 1868, :t, []}]}, | |
# {:type, 1868, :float, []}]}]}, | |
# {{:myers_difference, 2}, | |
# [{:type, 1960, :fun, | |
# [{:type, 1960, :product, | |
# [{:user_type, 1960, :t, []}, {:user_type, 1960, :t, []}]}, | |
# {:type, 1960, :union, | |
# [{:type, 0, :list, | |
# [{:type, 0, :tuple, | |
# [{:type, 1960, :union, | |
# [{:atom, 0, :eq}, {:atom, 0, :ins}, {:atom, 0, :del}]}, | |
# {:user_type, 1960, :t, []}]}]}, {:atom, 0, nil}]}]}]}, | |
# {{:split, 1}, | |
# [{:type, 262, :fun, | |
# [{:type, 262, :product, [{:user_type, 262, :t, []}]}, | |
# {:type, 0, :list, [{:user_type, 262, :t, []}]}]}]}, | |
# {{:splitter, 3}, | |
# [{:type, 377, :fun, | |
# [{:type, 377, :product, | |
# [{:user_type, 377, :t, []}, {:user_type, 377, :pattern, []}, | |
# {:remote_type, 377, [{:atom, 0, Keyword}, {:atom, 0, :t}, []]}]}, | |
# {:remote_type, 377, [{:atom, 0, Enumerable}, {:atom, 0, :t}, []]}]}]}, | |
# {{:next_codepoint, 1}, | |
# [{:type, 1160, :fun, | |
# [{:type, 1160, :product, [{:user_type, 1160, :t, []}]}, | |
# {:type, 1160, :union, | |
# [{:type, 0, :tuple, | |
# [{:user_type, 1160, :codepoint, []}, {:user_type, 1160, :t, []}]}, | |
# {:atom, 0, nil}]}]}]}, | |
# {{:chunk, 2}, | |
# [{:type, 1236, :fun, | |
# [{:type, 1236, :product, | |
# [{:user_type, 1236, :t, []}, | |
# {:type, 1236, :union, [{:atom, 0, :valid}, {:atom, 0, :printable}]}]}, | |
# {:type, 0, :list, [{:user_type, 1236, :t, []}]}]}]}, | |
# {{:first, 1}, | |
# [{:type, 1342, :fun, | |
# [{:type, 1342, :product, [{:user_type, 1342, :t, []}]}, | |
# {:type, 1342, :union, | |
# [{:user_type, 1342, :grapheme, []}, {:atom, 0, nil}]}]}]}, | |
# {{:last, 1}, | |
# [{:type, 1363, :fun, | |
# [{:type, 1363, :product, [{:user_type, 1363, :t, []}]}, | |
# {:type, 1363, :union, | |
# [{:user_type, 1363, :grapheme, []}, {:atom, 0, nil}]}]}]}, | |
# {{:to_charlist, 1}, | |
# [{:type, 1741, :fun, | |
# [{:type, 1741, :product, [{:user_type, 1741, :t, []}]}, | |
# {:remote_type, 0, [{:atom, 0, :elixir}, {:atom, 0, :charlist}, []]}]}]}, | |
# {{:to_float, 1}, | |
# [{:type, 1848, :fun, | |
# [{:type, 1848, :product, | |
# [{:remote_type, 1848, [{:atom, 0, String}, {:atom, 0, :t}, []]}]}, | |
# {:type, 1848, :float, []}]}]}, | |
# {{:to_char_list, 1}, | |
# [{:type, 2049, :fun, | |
# [{:type, 2049, :product, [{:user_type, 2049, :t, []}]}, | |
# {:remote_type, 0, [{:atom, 0, :elixir}, {:atom, 0, :charlist}, []]}]}]}, | |
# {{:trim_leading, 1}, | |
# [{:type, 770, :fun, | |
# [{:type, 770, :product, [{:user_type, 770, :t, []}]}, | |
# {:user_type, 770, :t, []}]}]}, | |
# {{:trim_trailing, 1}, | |
# [{:type, 800, :fun, | |
# [{:type, 800, :product, [{:user_type, 800, :t, []}]}, | |
# {:user_type, 800, :t, []}]}]}, | |
# {{:slice, 3}, | |
# [{:type, 1469, :fun, | |
# [{:type, 1469, :product, | |
# [{:user_type, 1469, :t, []}, {:type, 1469, :integer, ...}, | |
# {:type, 1469, :integer, ...}]}, {:user_type, 1469, :grapheme, []}]}]}, | |
# {{:split, 2}, | |
# [{:type, 329, :fun, | |
# [{:type, 329, :product, | |
# [{:user_type, 329, :t, ...}, {:type, 329, :union, ...}]}, | |
# {:type, 0, :list, [{:user_type, 329, :t, []}]}]}]}, | |
# {{:split_at, 2}, | |
# [{:type, 439, :fun, | |
# [{:type, 439, :product, [{:user_type, 439, ...}, {:type, 439, ...}]}, | |
# {:type, 0, :tuple, [{:user_type, 439, ...}, {:user_type, 439, ...}]}]}]}, | |
# {{:trim, 1}, | |
# [{:type, 830, :fun, | |
# [{:type, 830, :product, [{:user_type, 830, ...}]}, | |
# {:user_type, 830, :t, []}]}]}, | |
# {{:at, 2}, | |
# [{:type, 1411, :fun, | |
# [{:type, 1411, :product, [{...}, ...]}, | |
# {:type, 1411, :union, [{...}, ...]}]}]}, | |
# {{:to_atom, 1}, | |
# [{:type, 1769, :fun, | |
# [{:type, 1769, :product, ...}, {:type, 1769, :atom, ...}]}]}, | |
# {{:to_existing_atom, 1}, | |
# [{:type, 1792, :fun, [{:type, 1792, ...}, {:type, 1792, ...}]}]}, | |
# {{:trim_leading, 2}, [{:type, 785, :fun, [{:type, ...}, {:user_type, ...}]}]}, | |
# {{:trim_trailing, 2}, [{:type, 815, :fun, [{...}, ...]}]}, | |
# {{:replace, 4}, [{:type, 1030, :fun, ...}]}, | |
# {{:codepoints, 1}, [{:type, 1138, ...}]}, {{:graphemes, ...}, [{:type, ...}]}, | |
# {{:__info__, ...}, [{:type, ...}]}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment