Packages
styler
1.2.0
1.11.0
1.10.1
1.10.0
1.9.1
1.9.0
1.8.0
1.7.0
1.6.0
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
1.0.0-alpha.0
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.5
0.10.4
retired
0.10.3
0.10.2
0.10.1
0.10.0
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
retired
0.9.1
retired
0.9.0
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.1
0.1.0
A code-style enforcer that will just FIFY instead of complaining
Current section
Files
Jump to
Current section
Files
lib/alias_env.ex
defmodule Styler.AliasEnv do
@moduledoc """
A datastructure for maintaining something like compiler alias state when traversing AST.
Not anywhere as correct as what the compiler gives us, but close enough for open source work.
A alias env is a map from an alias's `as` to its resolution in a context.
Given the ast for
alias Foo.Bar
we'd create the env:
%{:Bar => [:Foo, :Bar]}
"""
def define(env \\ %{}, ast)
def define(env, asts) when is_list(asts), do: Enum.reduce(asts, env, &define(&2, &1))
def define(env, {:alias, _, aliases}) do
case aliases do
[{:__aliases__, _, aliases}] -> define(env, aliases, List.last(aliases))
[{:__aliases__, _, aliases}, [{_as, {:__aliases__, _, [as]}}]] -> define(env, aliases, as)
# `alias __MODULE__` or other oddities i'm not bothering to get right
_ -> env
end
end
defp define(env, modules, as), do: Map.put(env, as, do_expand(env, modules))
# no need to traverse ast if there are no aliases
def expand(env, ast) when map_size(env) == 0, do: ast
def expand(env, ast) do
Macro.prewalk(ast, fn
{:__aliases__, meta, modules} -> {:__aliases__, meta, do_expand(env, modules)}
ast -> ast
end)
end
# if the list of modules is itself already aliased, dealias it with the compound alias
# given:
# alias Foo.Bar
# Bar.Baz.Bop.baz()
#
# lifting Bar.Baz.Bop should result in:
# alias Foo.Bar
# alias Foo.Bar.Baz.Bop
# Bop.baz()
defp do_expand(env, [first | rest] = modules) do
if dealias = env[first], do: dealias ++ rest, else: modules
end
end