elixir-styler icon indicating copy to clipboard operation
elixir-styler copied to clipboard

bug: alias lifting produces broken code when aliases conflict with other existing usages

Open jsw800 opened this issue 1 year ago • 4 comments

Versions

  • Elixir: 1.17.1
  • Styler: 1.0.0

Example Input

Before running mix format:

defmodule SomeModule do
  def do_something(token) do
    # Guardian.Token.Jwt is a library module in the guardian library
    # MyApp.Guardian is a module defined inside my application
    Guardian.Token.Jwt.decode_token(MyApp.Guardian, token)
  end

  def do_something_else do
    Application.get_env(:my_app, MyApp.Guardian)
  end
end

Stacktrace / Current Behaviour

After running mix format:

defmodule SomeModule do
  alias MyApp.Guardian

  def do_something(token) do
    # elixir now can't find the Guardian.Token.Jwt module because it is
    # looking for MyApp.Guardian.Token.Jwt which is not a real module
    Guardian.Token.Jwt.decode_token(Guardian, token)
  end

  def do_something_else do
    Application.get_env(:my_app, Guardian)
  end
end

jsw800 avatar Sep 04 '24 17:09 jsw800

thanks for the report! definitely something styler's supposed to notice, sorry that it's got a bug there

novaugust avatar Sep 04 '24 18:09 novaugust

hey @jsw800 , i wasn't able to reproduce the issue with the snippet you gave me:

https://github.com/adobe/elixir-styler/compare/me/fix-193?expand=1

tests still pass. is there more context you can provide?

novaugust avatar Sep 04 '24 18:09 novaugust

Ah sorry about that - I had kinda changed it from my original code so as to not share my actual source code. It looks like the difference between my original code and the example I shared is that MyApp.Guardian was actually MyApp.Something.Guardian. When the code looks like this, the test fails as expected:

defmodule SomeModule do
  @moduledoc false

  def do_something(token) do
    # Guardian.Token.Jwt is a library module in the guardian library
    # MyApp.Something.Guardian is a module defined inside my application
    Guardian.Token.Jwt.decode_token(MyApp.Something.Guardian, token)
  end

  def do_something_else do
    Application.get_env(:my_app, MyApp.Something.Guardian)
  end
end

jsw800 avatar Sep 04 '24 18:09 jsw800

ty, got it now :)

novaugust avatar Sep 04 '24 18:09 novaugust

hey @jsw800 , was going through old issues and realized that this exact issue is why styler has the alias_lifting_exclude configuration. if you add Guardian to that list this issue will be resolved

that said, it'd be neat if styler could just detect this itself rather than relying on configuration

docs: https://hexdocs.pm/styler/module_directives.html#collisions

novaugust avatar Jan 14 '25 17:01 novaugust

Thanks @novaugust! We had started using the excludes configuration for some scenarios, or for more one offs, just manually renaming the colliding aliases with the as option for aliases. This will be super nice to have built-in to styler!

jsw800 avatar Jan 24 '25 16:01 jsw800

cheers dude, hopefully what's on main handles whatever you throw at it now :) i'll cut a release early next week

novaugust avatar Jan 24 '25 21:01 novaugust