Current section

Files

Jump to
credo lib credo check readability max_line_length.ex
Raw

lib/credo/check/readability/max_line_length.ex

defmodule Credo.Check.Readability.MaxLineLength do
@moduledoc """
Checks for the length of lines.
Ignores function definitions and (multi-)line strings by default.
"""
@explanation [
check: @moduledoc,
params: [
max_length: "The maximum number of characters a line may consist of.",
ignore_definitions: "Set to `true` to ignore lines including function definitions.",
]
]
@default_params [
max_length: 80,
ignore_definitions: true,
ignore_strings: true
]
@def_ops [:def, :defp, :defmacro]
use Credo.Check, base_priority: :low
def run(%SourceFile{ast: ast, lines: lines} = source_file, params \\ []) do
issue_meta = IssueMeta.for(source_file, params)
max_length = params |> Params.get(:max_length, @default_params)
ignore_definitions = params |> Params.get(:ignore_definitions, @default_params)
ignore_strings = params |> Params.get(:ignore_strings, @default_params)
definitions = Credo.Code.traverse(ast, &find_definitions/2)
Enum.reduce(lines, [], fn({line_no, line}, issues) ->
if String.length(line) > max_length do
if refute_issue?(line_no, definitions, ignore_definitions, ignore_strings) do
issues
else
[issue_for(line_no, max_length, line, issue_meta) | issues]
end
else
issues
end
end)
end
for op <- @def_ops do
defp find_definitions({unquote(op), meta, arguments} = ast, definitions) when is_list(arguments) do
{ast, [meta[:line] | definitions]}
end
end
defp find_definitions(ast, definitions) do
{ast, definitions}
end
defp refute_issue?(line_no, definitions, ignore_definitions, ignore_strings) do
refute = false
if ignore_definitions do
refute = refute || Enum.member?(definitions, line_no)
end
if ignore_strings do
refute = refute || false # TODO: implement this check
end
refute
end
defp issue_for(line_no, max_length, line, issue_meta) do
length = String.length(line)
column = max_length + 1
trigger = String.slice(line, max_length, length-max_length)
format_issue issue_meta,
message: "Line is too long (max is #{max_length}, was #{length}).",
line_no: line_no,
column: column,
trigger: trigger
end
end