Skip to content

Commit

Permalink
Rename Dealias to AliasEnv, now that elixir 1.17 gave me much better …
Browse files Browse the repository at this point in the history
…words for everything
  • Loading branch information
novaugust committed May 24, 2024
1 parent 83103ec commit 02ac4c9
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 51 deletions.
49 changes: 49 additions & 0 deletions lib/alias_env.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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 `dealias` is a map from what an alias's `as` to its resolution in a context. In other words
alias Foo.Bar
would create the dealias map
%{:Bar => [:Foo, :Bar]}
"""
def define(dealiases \\ %{}, ast)
def define(d, list) when is_list(list), do: Enum.reduce(list, d, &define(&2, &1))
def define(d, {:alias, _, [{:__aliases__, _, aliases}]}), do: do_define(d, aliases, List.last(aliases))
def define(d, {:alias, _, [{:__aliases__, _, aliases}, [{_as, {:__aliases__, _, [as]}}]]}), do: do_define(d, aliases, as)
# `alias __MODULE__` or other oddities i'm not bothering to get right
def define(dealiases, {:alias, _, _}), do: dealiases

defp do_define(dealiases, modules, as), do: Map.put(dealiases, as, do_expand(dealiases, modules))

# no need to traverse ast if there are no aliases
def expand(dealiases, ast) when map_size(dealiases) == 0, do: ast

def expand(dealiases, {:alias, m, [{:__aliases__, m_, modules} | rest]}),
do: {:alias, m, [{:__aliases__, m_, do_expand(dealiases, modules)} | rest]}

def expand(dealiases, ast) do
Macro.prewalk(ast, fn
{:__aliases__, meta, modules} -> {:__aliases__, meta, do_expand(dealiases, 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(dealiases, [first | rest] = modules) do
if dealias = dealiases[first], do: dealias ++ rest, else: modules
end
end
45 changes: 0 additions & 45 deletions lib/dealias.ex

This file was deleted.

12 changes: 6 additions & 6 deletions lib/style/module_directives.ex
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ defmodule Styler.Style.ModuleDirectives do
"""
@behaviour Styler.Style

alias Styler.Dealias
alias Styler.AliasEnv
alias Styler.Style
alias Styler.Zipper

Expand Down Expand Up @@ -235,7 +235,7 @@ defmodule Styler.Style.ModuleDirectives do
|> Enum.reduce(@acc, fn
{:@, _, [{attr_directive, _, _}]} = ast, acc when attr_directive in @attr_directives ->
# attr_directives are moved above aliases, so we need to dealias them
{ast, acc} = acc.dealiases |> Dealias.apply(ast) |> lift_module_attrs(acc)
{ast, acc} = acc.dealiases |> AliasEnv.expand(ast) |> lift_module_attrs(acc)
%{acc | attr_directive => [ast | acc[attr_directive]]}

{:@, _, [{attr, _, _}]} = ast, acc ->
Expand All @@ -245,8 +245,8 @@ defmodule Styler.Style.ModuleDirectives do
{ast, acc} = lift_module_attrs(ast, acc)
ast = expand(ast)
# import and used get hoisted above aliases, so need to dealias
ast = if directive in ~w(import use)a, do: Dealias.apply(acc.dealiases, ast), else: ast
dealiases = if directive == :alias, do: Dealias.put(acc.dealiases, ast), else: acc.dealiases
ast = if directive in ~w(import use)a, do: AliasEnv.expand(acc.dealiases, ast), else: ast
dealiases = if directive == :alias, do: AliasEnv.define(acc.dealiases, ast), else: acc.dealiases

# the reverse accounts for `expand` putting things in reading order, whereas we're accumulating in reverse
%{acc | directive => Enum.reverse(ast, acc[directive]), dealiases: dealiases}
Expand Down Expand Up @@ -327,7 +327,7 @@ defmodule Styler.Style.ModuleDirectives do
defp lift_aliases(%{alias: aliases, require: requires, nondirectives: nondirectives} = acc) do
# we can't use the dealias map built into state as that's what things look like before sorting
# now that we've sorted, it could be different!
dealiases = Dealias.new(aliases)
dealiases = AliasEnv.define(aliases)
excluded = dealiases |> Map.keys() |> Enum.into(Styler.Config.get(:lifting_excludes))
liftable = find_liftable_aliases(requires ++ nondirectives, excluded)

Expand All @@ -339,7 +339,7 @@ defmodule Styler.Style.ModuleDirectives do

aliases =
liftable
|> Enum.map(&Dealias.apply(dealiases, {:alias, m, [{:__aliases__, [{:last, m} | m], &1}]}))
|> Enum.map(&AliasEnv.expand(dealiases, {:alias, m, [{:__aliases__, [{:last, m} | m], &1}]}))
|> Enum.concat(aliases)
|> sort()

Expand Down

0 comments on commit 02ac4c9

Please sign in to comment.