From bf11bf60bfc5ad941b13cfcbe240b74854312f9e Mon Sep 17 00:00:00 2001 From: Emily Guthrie Date: Thu, 6 Feb 2025 11:45:10 -0800 Subject: [PATCH] Don't lift alias that would collide with already-aliased module --- lib/style/module_directives.ex | 15 ++++++++++----- .../module_directives/alias_lifting_test.exs | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/style/module_directives.ex b/lib/style/module_directives.ex index fd7e3b7..f8bc362 100644 --- a/lib/style/module_directives.ex +++ b/lib/style/module_directives.ex @@ -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. @@ -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 @@ -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 diff --git a/test/style/module_directives/alias_lifting_test.exs b/test/style/module_directives/alias_lifting_test.exs index 6e65039..4560380 100644 --- a/test/style/module_directives/alias_lifting_test.exs +++ b/test/style/module_directives/alias_lifting_test.exs @@ -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