From 114588720c082b72306fc4b722180dd8f3e97b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Pr=C3=A9vost?= Date: Thu, 7 Mar 2019 07:01:21 -0500 Subject: [PATCH] Add UnnecessaryAliasExpansion check --- .credo.exs | 1 + .../unnecessary_alias_expansion.ex | 48 +++++++++++++++++++ .../unnecessary_alias_expansion_test.exs | 46 ++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 lib/credo/check/readability/unnecessary_alias_expansion.ex create mode 100644 test/credo/check/readability/unnecessary_alias_expansion_test.exs diff --git a/.credo.exs b/.credo.exs index 11a355469..97d790935 100644 --- a/.credo.exs +++ b/.credo.exs @@ -93,6 +93,7 @@ {Credo.Check.Readability.StringSigils, []}, {Credo.Check.Readability.TrailingBlankLine, []}, {Credo.Check.Readability.TrailingWhiteSpace, []}, + {Credo.Check.Readability.UnnecessaryAliasExpansion, []}, {Credo.Check.Readability.VariableNames, []}, # diff --git a/lib/credo/check/readability/unnecessary_alias_expansion.ex b/lib/credo/check/readability/unnecessary_alias_expansion.ex new file mode 100644 index 000000000..f08877423 --- /dev/null +++ b/lib/credo/check/readability/unnecessary_alias_expansion.ex @@ -0,0 +1,48 @@ +defmodule Credo.Check.Readability.UnnecessaryAliasExpansion do + @moduledoc false + + @checkdoc """ + Alias expansion is useful but when aliasing a single module, + it can be harder to read with unnecessary braces. + + # preferred + + alias ModuleA.Foo + alias ModuleA.{Foo, Bar} + + # NOT preferred + + alias ModuleA.{Foo} + + Like all `Readability` issues, this one is not a technical concern. + But you can improve the odds of others reading and liking your code by making + it easier to follow. + """ + @explanation [check: @checkdoc] + + use Credo.Check, base_priority: :low + + alias Credo.Code + + @doc false + def run(source_file, params \\ []) do + issue_meta = IssueMeta.for(source_file, params) + + Code.prewalk(source_file, &traverse(&1, &2, issue_meta)) + end + + defp traverse({:alias, _, [{_, _, [{:__aliases__, opts, [child]}]}]} = ast, issues, issue_meta) do + {ast, issues ++ [issue_for(issue_meta, Keyword.get(opts, :line), child)]} + end + + defp traverse(ast, issues, _issue_meta), do: {ast, issues} + + defp issue_for(issue_meta, line_no, trigger) do + format_issue( + issue_meta, + message: "Unnecessary alias expansion for #{trigger}, consider removing braces.", + trigger: trigger, + line_no: line_no + ) + end +end diff --git a/test/credo/check/readability/unnecessary_alias_expansion_test.exs b/test/credo/check/readability/unnecessary_alias_expansion_test.exs new file mode 100644 index 000000000..019dfe4a2 --- /dev/null +++ b/test/credo/check/readability/unnecessary_alias_expansion_test.exs @@ -0,0 +1,46 @@ +defmodule Credo.Check.Readability.UnnecessaryAliasExpansionTest do + use Credo.TestHelper + + @described_check Credo.Check.Readability.UnnecessaryAliasExpansion + + # + # cases NOT raising issues + # + + test "it should NOT report violation" do + """ + defmodule Test do + alias App.Module1 + alias App.{Module2, Module3} + end + """ + |> to_source_file + |> refute_issues(@described_check) + end + + # + # cases raising issues + # + + test "it should report a violation" do + """ + defmodule CredoSampleModule do + alias App.Module1 + alias App.Module2.{Module3} + end + """ + |> to_source_file + |> assert_issue(@described_check) + end + + test "it should report a violation for double expansion" do + """ + defmodule CredoSampleModule do + alias App.Module1 + alias App.{Module2}.{Module3} + end + """ + |> to_source_file + |> assert_issue(@described_check) + end +end