diff --git a/lib/credo/check/readability/alias_as.ex b/lib/credo/check/readability/alias_as.ex index e7739f263..9ddac8442 100644 --- a/lib/credo/check/readability/alias_as.ex +++ b/lib/credo/check/readability/alias_as.ex @@ -2,6 +2,9 @@ defmodule Credo.Check.Readability.AliasAs do use Credo.Check, base_priority: :low, tags: [:experimental], + param_defaults: [ + ignore: [] + ], explanations: [ check: """ Aliases which are not completely renamed using the `:as` option are easier to follow. @@ -30,29 +33,52 @@ defmodule Credo.Check.Readability.AliasAs do 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. - """ + """, + params: [ + ignore: "List of modules to ignore and allow to `alias Module, as: ...`" + ] ] @doc false @impl true def run(%SourceFile{} = source_file, params) do + ignore = Params.get(params, :ignore, __MODULE__) + source_file - |> Credo.Code.prewalk(&traverse(&1, &2, IssueMeta.for(source_file, params))) + |> Credo.Code.prewalk(&traverse(&1, &2, IssueMeta.for(source_file, params), ignore)) |> Enum.reverse() end - defp traverse(ast, issues, issue_meta), do: {ast, add_issue(issues, issue(ast, issue_meta))} + defp traverse(ast, issues, issue_meta, ignore), + do: {ast, add_issue(issues, issue(ast, issue_meta, ignore))} defp add_issue(issues, nil), do: issues defp add_issue(issues, issue), do: [issue | issues] - defp issue({:alias, _, [{:__MODULE__, _, nil}, [as: {_, meta, _}]]}, issue_meta), - do: issue_for(issue_meta, meta[:line], inspect(:__MODULE__)) + defp issue({:alias, _, [{:__MODULE__, _, nil}, [as: {_, meta, _}]]}, issue_meta, ignore) do + line = meta[:line] + {Credo.IssueMeta, source_file, _check_params} = issue_meta + {_def, module_name} = Check.scope_for(source_file, line: line) + module = Module.concat([module_name]) + + if :__MODULE__ not in ignore and module not in ignore do + issue_for(issue_meta, line, inspect(:__MODULE__)) + else + nil + end + end - defp issue({:alias, _, [{_, _, original}, [as: {_, meta, _}]]}, issue_meta), - do: issue_for(issue_meta, meta[:line], inspect(Module.concat(original))) + defp issue({:alias, _, [{_, _, original}, [as: {_, meta, _}]]}, issue_meta, ignore) do + module = Module.concat(original) + + if module not in ignore do + issue_for(issue_meta, meta[:line], inspect(module)) + else + nil + end + end - defp issue(_ast, _issue_meta), do: nil + defp issue(_ast, _issue_meta, _ignore), do: nil defp issue_for(issue_meta, line_no, trigger) do format_issue( diff --git a/test/credo/check/readability/alias_as_test.exs b/test/credo/check/readability/alias_as_test.exs index 5732c2b33..07cb57fde 100644 --- a/test/credo/check/readability/alias_as_test.exs +++ b/test/credo/check/readability/alias_as_test.exs @@ -48,6 +48,39 @@ defmodule Credo.Check.Readability.AliasAsTest do assert issue3.trigger == "App.Module4" end + test "it should ignore violations for ignored modules" do + """ + defmodule Test do + alias App.Module1, as: M1 + end + """ + |> to_source_file + |> run_check(@described_check, ignore: [App.Module1]) + |> refute_issues() + end + + test "it should ignore violations for __MODULE__ when :__MODULE__ is in ignore list" do + """ + defmodule Test do + alias __MODULE__, as: Foo + end + """ + |> to_source_file + |> run_check(@described_check, ignore: [:__MODULE__]) + |> refute_issues() + end + + test "it should ignore violations for __MODULE__ when the module is in ignore list" do + """ + defmodule Test do + alias __MODULE__, as: Foo + end + """ + |> to_source_file + |> run_check(@described_check, ignore: [Test]) + |> refute_issues() + end + test "it should not raise on alias __MODULE__, as: Foo" do _ = """