Current section

Files

Jump to
credence lib rule no_redundant_enum_join_separator.ex
Raw

lib/rule/no_redundant_enum_join_separator.ex

defmodule Credence.Rule.NoRedundantEnumJoinSeparator do
@moduledoc """
Readability rule: Detects `Enum.join("")` where the empty-string separator
is passed explicitly.
`Enum.join/1` already defaults to `""`, so the argument adds visual noise
without changing behaviour.
## Bad
graphemes |> Enum.join("")
Enum.join(list, "")
## Good
graphemes |> Enum.join()
Enum.join(list)
"""
@behaviour Credence.Rule
alias Credence.Issue
@impl true
def check(ast, _opts) do
{_ast, issues} =
Macro.prewalk(ast, [], fn
# Direct call: Enum.join(list, "")
{{:., _, [{:__aliases__, _, [:Enum]}, :join]}, meta, [_list, ""]} = node, issues ->
{node, [build_issue(meta) | issues]}
# In a pipe the separator is the only explicit arg: ... |> Enum.join("")
# The piped value becomes the first arg, so the AST call has [""]
{{:., _, [{:__aliases__, _, [:Enum]}, :join]}, meta, [""]} = node, issues ->
{node, [build_issue(meta) | issues]}
node, issues ->
{node, issues}
end)
Enum.reverse(issues)
end
defp build_issue(meta) do
%Issue{
rule: :no_redundant_enum_join_separator,
severity: :info,
message:
"`Enum.join/1` already defaults to an empty string separator. " <>
"Remove the redundant `\"\"` argument.",
meta: %{line: Keyword.get(meta, :line)}
}
end
end