Skip to content

Commit

Permalink
Don't lift alias that would collide with already-aliased module
Browse files Browse the repository at this point in the history
  • Loading branch information
emkguts committed Feb 6, 2025
1 parent ee339b9 commit bf11bf6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
15 changes: 10 additions & 5 deletions lib/style/module_directives.ex
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,9 @@ defmodule Quokka.Style.ModuleDirectives 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 = AliasEnv.define(aliases)
already_lifted = Map.values(dealiases)
excluded = dealiases |> Map.keys() |> Enum.into(Quokka.Config.lift_alias_excluded_lastnames())
liftable = if Quokka.Config.lift_alias?(), do: find_liftable_aliases(requires ++ nondirectives, excluded), else: []
liftable = if Quokka.Config.lift_alias?(), do: find_liftable_aliases(requires ++ nondirectives, excluded, already_lifted), else: []

if Enum.any?(liftable) do
# This is a silly hack that helps comments stay put.
Expand All @@ -337,10 +338,15 @@ defmodule Quokka.Style.ModuleDirectives do
end
end

defp find_liftable_aliases(ast, excluded) do
defp find_liftable_aliases(ast, excluded, already_lifted) do
lifts =
already_lifted
|> Enum.map(&List.first/1)
|> Map.new(&{&1, :collision_with_first})

ast
|> Zipper.zip()
|> Zipper.reduce_while(%{}, fn
|> Zipper.reduce_while(lifts, fn
# we don't want to rewrite alias name `defx Aliases ... do` of these three keywords
{{defx, _, args}, _} = zipper, lifts when defx in ~w(defmodule defimpl defprotocol)a ->
# don't conflict with submodules, which elixir automatically aliases
Expand Down Expand Up @@ -374,8 +380,7 @@ defmodule Quokka.Style.ModuleDirectives do
last = List.last(aliases)

lifts =
if excluded_namespace_match or last in excluded or not Enum.all?(aliases, &is_atom/1) or
length(aliases) <= Quokka.Config.lift_alias_depth() do
if excluded_namespace_match or last in excluded or length(aliases) <= Quokka.Config.lift_alias_depth() do
lifts
else
Map.update(lifts, last, {aliases, 1}, fn
Expand Down
18 changes: 18 additions & 0 deletions test/style/module_directives/alias_lifting_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,24 @@ defmodule Quokka.Style.ModuleDirectives.AliasLiftingTest do
end
"""
end

test "does not lift aliases that are already lifted" do
# if the last module of a list in an alias is the first of an already lifted alias,
# do not lift the alias
assert_style """
defmodule A do
@moduledoc false
alias C.D.E
E.f()
E.f()
A.B.C.f()
A.B.C.f()
end
"""
end
end

test "lifts all aliases when lift_alias_depth is 0" do
Expand Down

0 comments on commit bf11bf6

Please sign in to comment.