Skip to content

Instantly share code, notes, and snippets.

@pragdave
Created March 18, 2014 20:34
Show Gist options
  • Save pragdave/9628965 to your computer and use it in GitHub Desktop.
Save pragdave/9628965 to your computer and use it in GitHub Desktop.
defmodule Reflect do
use Application.Behaviour
def run do
path = :code.lib_dir(:elixir, :ebin)
load_modules_in(path)
modules = for {name,_} <- :code.all_loaded,
Regex.match?(~r/^[A-Z]/, atom_to_binary(name)),
do: name
behaviour_map = Enum.reduce modules, %{}, fn module, map ->
behaviours = module.__info__(:attributes)[:behaviour]
if behaviours do
module = normalize_module(module)
existing = Dict.get(map, module, [])
Dict.put(map, module, behaviours ++ existing)
else
map
end
end
protocol_modules = Protocol.Consolidation.extract_protocols([path])
protocol_map = Enum.reduce(protocol_modules, %{}, fn pm, map ->
Enum.reduce(Protocol.Consolidation.extract_impls(pm, [path]), map, fn client, map ->
client = normalize_module(client)
existing = Dict.get map, client, []
existing = [ inspect(pm) | existing ]
Dict.put map, client, existing
end)
end)
keys = Dict.keys(behaviour_map) || Dict.keys(protocol_map)
Enum.each keys, fn client ->
IO.puts "\n#{client}:"
p = protocol_map[client]
b = behaviour_map[client]
if p do
IO.puts ~s{ implements: #{p |> Enum.join(", ")}}
end
if b do
IO.puts ~s{ includes: #{b |> Enum.map(&inspect/1) |> Enum.join(", ")}}
end
end
end
def load_modules_in(dir) do
{ :ok, files } = :erl_prim_loader.list_dir(dir |> to_char_list)
Enum.each(files, fn name -> :code.load_abs(name) end)
end
def normalize_module(module),
do: Regex.replace(~r/^(Access|Enumerable|Inspect|String\.Chars)\./, inspect(module), "")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment