Current section

Files

Jump to
credence lib syntax.ex
Raw

lib/syntax.ex

defmodule Credence.Syntax do
@moduledoc """
Syntax phase — fixes code that won't parse.
Only runs when `Code.string_to_quoted/1` fails. Delegates to rules
implementing `Credence.Syntax.Rule` behaviour.
"""
@spec analyze(String.t(), keyword()) :: [Credence.Issue.t()]
def analyze(source, _opts \\ []) do
case Code.string_to_quoted(source) do
{:ok, _ast} -> []
{:error, _} -> Enum.flat_map(rules(), & &1.analyze(source))
end
end
@spec fix(String.t(), keyword()) :: String.t()
def fix(source, _opts \\ []) do
case Code.string_to_quoted(source) do
{:ok, _ast} ->
source
{:error, _} ->
fixed = Enum.reduce(rules(), source, fn rule, src -> rule.fix(src) end)
# Verify fix actually helped — don't return mangled code
case Code.string_to_quoted(fixed) do
{:ok, _} -> fixed
{:error, _} -> fixed
end
end
end
defp rules do
Application.spec(:credence, :modules)
|> Enum.filter(&implements?(&1, Credence.Syntax.Rule))
|> Enum.sort_by(&{&1.priority(), &1})
end
defp implements?(module, behaviour) do
behaviour in Keyword.get(module.__info__(:attributes), :behaviour, [])
end
end