Repository: adobe/elixir-styler (elixir)

Issue:
Delete pathless aliases (`alias Foo`)
There's no reason to use `alias` with a root-level module name. If we see that, we can just nix the node.

## Example Input

```elixir
assert_style """
alias unquote(Foo)
alias Foo
alias Bar, as: Bop
alias __MODULE__
""",
"""
alias __MODULE__
alias Bar, as: Bop
alias unquote(Foo)
"""
```


Pull request:
Delete root level alias
- [x] Please [sign Adobe's CLA](http://opensource.adobe.com/cla.html) if this is your first time contributing to an Adobe open source repo. Thanks!

Closes #87 

Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ed7b3b7..93df109 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,7 +9,7 @@ jobs:
     name: Ex${{matrix.elixir}}/OTP${{matrix.otp}}
     strategy:
       matrix:
-        elixir: ['1.14.2', '1.15.7']
+        elixir: ['1.14.2', '1.15.0']
         otp: ['25.1.2']
     steps:
       - uses: actions/checkout@v3
diff --git a/.tool-versions b/.tool-versions
index ff52406..12be720 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,2 +1,2 @@
-erlang 26.1.2
-elixir 1.15.7-otp-26
+erlang 25.1.2
+elixir 1.14.2-otp-25
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1bcb7f8..181dd05 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,17 +2,6 @@
 
 ## main
 
-## v0.10.3
-
-### Improvements
-
-* charlists: leave charlist rewriting to elixir's formatter on elixir >= 1.15
-
-### Fixes
-
-* charlists: rewrite empty charlist to use sigil (`''` => `~c""`)
-* pipes: don't blow up extracting fully-qualified macros (`Foo.bar do end |> foo()`, #91, h/t @NikitaNaumenko)
-
 ## v0.10.2
 
 ### Improvements
diff --git a/lib/style/pipes.ex b/lib/style/pipes.ex
index ad616c6..03ecf55 100644
--- a/lib/style/pipes.ex
+++ b/lib/style/pipes.ex
@@ -103,14 +103,7 @@ defmodule Styler.Style.Pipes do
       #
       # block_result
       # |> ...
-      var_name =
-        case fun do
-          fun when is_atom(fun) -> fun
-          {:., _, [{:__aliases__, _, _}, fun]} when is_atom(fun) -> fun
-          _ -> "block"
-        end
-
-      variable = {:"#{var_name}_result", [line: line], nil}
+      variable = {:"#{fun}_result", [line: line], nil}
       new_assignment = {:=, [line: line], [variable, lhs]}
       {variable, new_assignment}
     else
diff --git a/lib/style/single_node.ex b/lib/style/single_node.ex
index 75c3ba2..0c42cb1 100644
--- a/lib/style/single_node.ex
+++ b/lib/style/single_node.ex
@@ -30,15 +30,21 @@ defmodule Styler.Style.SingleNode do
   alias Styler.Style
   alias Styler.Zipper
 
+  # Delete root level alias
+  # `alias Foo` -> ``
+  def run({{:alias, _, [{:__aliases__, _, [_]}]}, _} = zipper, ctx), do: {:cont, Zipper.remove(zipper), ctx}
+
   def run({node, meta}, ctx), do: {:cont, {style(node), meta}, ctx}
 
-  # as of 1.15, elixir's formatter takes care of this for us.
-  if Version.match?(System.version(), "< 1.15.0-dev") do
-    # 'charlist' => ~c"charlist"
-    defp style({:__block__, meta, [chars]} = node) when is_list(chars) do
-      if meta[:delimiter] == "'",
-        do: {:sigil_c, Keyword.put(meta, :delimiter, "\""), [{:<<>>, [line: meta[:line]], [List.to_string(chars)]}, []]},
-        else: node
+  # Our use of the `literal_encoder` option of `Code.string_to_quoted_with_comments!/2` creates
+  # invalid charlists literal AST nodes from `'foo'`. this rewrites them to use the `~c` sigil
+  # 'foo' => ~c"foo".
+  defp style({:__block__, meta, [[int | _] = chars]} = node) when is_integer(int) do
+    if meta[:delimiter] == "'" do
+      new_meta = Keyword.put(meta, :delimiter, "\"")
+      {:sigil_c, new_meta, [{:<<>>, [line: meta[:line]], [List.to_string(chars)]}, []]}
+    else
+      node
     end
   end
 
diff --git a/mix.exs b/mix.exs
index 3fb9b44..45d4eed 100644
--- a/mix.exs
+++ b/mix.exs
@@ -12,7 +12,7 @@ defmodule Styler.MixProject do
   use Mix.Project
 
   # Don't forget to bump the README when doing non-patch version changes
-  @version "0.10.3"
+  @version "0.10.2"
   @url "https://github.com/adobe/elixir-styler"
 
   def project do


Test patch:
diff --git a/test/style/pipes_test.exs b/test/style/pipes_test.exs
index 9cfda76..3e69f62 100644
--- a/test/style/pipes_test.exs
+++ b/test/style/pipes_test.exs
@@ -125,31 +125,6 @@ defmodule Styler.Style.PipesTest do
       )
     end
 
-    test "block extraction: names aliased modules" do
-      assert_style(
-        """
-        Foo.bar do
-          :ok
-        end
-        |> case do
-          :ok -> :ok
-          _ -> :error
-        end
-        """,
-        """
-        bar_result =
-          Foo.bar do
-            :ok
-          end
-
-        case bar_result do
-          :ok -> :ok
-          _ -> :error
-        end
-        """
-      )
-    end
-
     test "macro with arg and do block" do
       assert_style("""
       "baz"
diff --git a/test/style/single_node_test.exs b/test/style/single_node_test.exs
index 6b125a2..401fd77 100644
--- a/test/style/single_node_test.exs
+++ b/test/style/single_node_test.exs
@@ -11,12 +11,9 @@
 defmodule Styler.Style.SingleNodeTest do
   use Styler.StyleCase, async: true
 
-  if Version.match?(System.version(), "< 1.15.0-dev") do
-    test "charlist literals: rewrites single quote charlists to ~c" do
-      assert_style("'foo'", ~s|~c"foo"|)
-      assert_style(~s|'"'|, ~s|~c"\\""|)
-      assert_style("''", ~s|~c""|)
-    end
+  test "charlist literals: rewrites single quote charlists to ~c" do
+    assert_style("'foo'", ~s|~c"foo"|)
+    assert_style(~s|'"'|, ~s|~c"\\""|)
   end
 
   test "Logger.warn to Logger.warning" do
@@ -293,4 +290,20 @@ defmodule Styler.Style.SingleNodeTest do
       assert_style("Enum.reverse(foo, bar) ++ bar")
     end
   end
+
+  test "Delete root level alias" do
+    assert_style(
+      """
+      alias unquote(Foo)
+      alias Foo
+      alias Bar, as: Bop
+      alias __MODULE__
+      """,
+      """
+      alias __MODULE__
+      alias Bar, as: Bop
+      alias unquote(Foo)
+      """
+    )
+  end
 end