From 411cc93f6e5a1002a8f162fbbaa53dc379241205 Mon Sep 17 00:00:00 2001 From: Matt Enlow Date: Sat, 23 Nov 2024 10:25:02 -0700 Subject: [PATCH] styler:sort - handle tuples --- lib/style.ex | 13 ++++++++++++- lib/style/comment_directives.ex | 7 +++---- lib/style/module_directives.ex | 5 +---- test/style/comment_directives_test.exs | 24 ++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/lib/style.ex b/lib/style.ex index da93416..4b3a9a9 100644 --- a/lib/style.ex +++ b/lib/style.ex @@ -59,9 +59,20 @@ defmodule Styler.Style do @doc "Traverses an ast node, updating all nodes' meta with `meta_fun`" def update_all_meta(node, meta_fun), do: Macro.prewalk(node, &Macro.update_meta(&1, meta_fun)) - # useful for comparing AST without meta (line numbers, etc) interfering + @doc "prewalks ast and sets all meta to `nil`. useful for comparing AST without meta (line numbers, etc) interfering" def without_meta(ast), do: update_all_meta(ast, fn _ -> nil end) + @doc "sorts a list of nodes according to their string representations" + def sort(ast, opts \\ []) when is_list(ast) do + format = if opts[:format] == :downcase, do: &String.downcase/1, else: &(&1) + + ast + |> Enum.map(&{&1, &1 |> Macro.to_string() |> format.()}) + |> Enum.uniq_by(&elem(&1, 1)) + |> List.keysort(1) + |> Enum.map(&elem(&1, 0)) + end + @doc """ Returns the current node (wrapped in a `__block__` if necessary) if it's a valid place to insert additional nodes """ diff --git a/lib/style/comment_directives.ex b/lib/style/comment_directives.ex index d41e088..fb78391 100644 --- a/lib/style/comment_directives.ex +++ b/lib/style/comment_directives.ex @@ -13,6 +13,7 @@ defmodule Styler.Style.CommentDirectives do @behaviour Styler.Style + alias Styler.Style alias Styler.Zipper def run(zipper, ctx) do @@ -28,6 +29,7 @@ defmodule Styler.Style.CommentDirectives do end) if found do + #@TODO fix line numbers, move comments Zipper.update(found, &sort/1) else zipper @@ -37,10 +39,7 @@ defmodule Styler.Style.CommentDirectives do {:halt, zipper, ctx} end - defp sort({:__block__, meta, [list]}) when is_list(list) do - list = Enum.sort_by(list, fn {f, _, a} -> {f, a} end) - {:__block__, meta, [list]} - end + defp sort({:__block__, meta, [list]}) when is_list(list), do: {:__block__, meta, [Style.sort(list)]} defp sort({:sigil_w, sm, [{:<<>>, bm, [string]}, modifiers]}) do # ew. gotta be a better way. diff --git a/lib/style/module_directives.ex b/lib/style/module_directives.ex index 623ce5f..f9eba85 100644 --- a/lib/style/module_directives.ex +++ b/lib/style/module_directives.ex @@ -413,10 +413,7 @@ defmodule Styler.Style.ModuleDirectives do defp sort(directives) do # sorting is done with `downcase` to match Credo directives - |> Enum.map(&{&1, &1 |> Macro.to_string() |> String.downcase()}) - |> Enum.uniq_by(&elem(&1, 1)) - |> List.keysort(1) - |> Enum.map(&elem(&1, 0)) + |> Style.sort(format: :downcase) |> Style.reset_newlines() end end diff --git a/test/style/comment_directives_test.exs b/test/style/comment_directives_test.exs index 16c8621..7c889f3 100644 --- a/test/style/comment_directives_test.exs +++ b/test/style/comment_directives_test.exs @@ -153,5 +153,29 @@ defmodule Styler.Style.CommentDirectivesTest do """ ) end + + test "list of tuples" do + # 2ples are represented as block literals while >2ples are created via `:{}` + # decided the easiest way to handle this is to just use string representation for meow + assert_style """ + # styler:sort + [ + {:styler, github: "adobe/elixir-styler"}, + {:ash, "~> 3.0"}, + {:fluxon, "~> 1.0.0", repo: :fluxon}, + {:phoenix_live_reload, "~> 1.2", only: :dev}, + {:tailwind, "~> 0.2", runtime: Mix.env() == :dev} + ] + """,""" + # styler:sort + [ + {:ash, "~> 3.0"}, + {:fluxon, "~> 1.0.0", repo: :fluxon}, + {:phoenix_live_reload, "~> 1.2", only: :dev}, + {:styler, github: "adobe/elixir-styler"}, + {:tailwind, "~> 0.2", runtime: Mix.env() == :dev} + ] + """ + end end end