Current section
Files
Jump to
Current section
Files
lib/credence.ex
defmodule Credence do
@moduledoc """
Credence (Semantic Linter for Elixir)
Main entry point for analyzing Elixir code.
"""
alias Credence.Issue
@doc """
Analyzes an Elixir code string and returns a deterministic pass/fail result.
"""
@spec analyze(String.t(), keyword()) :: %{valid: boolean(), issues: [Issue.t()]}
def analyze(code_string, opts \\ []) do
rules = Keyword.get(opts, :rules, default_rules())
case Code.string_to_quoted(code_string) do
{:ok, ast} ->
issues = run_rules(ast, rules, opts)
%{
valid: Enum.empty?(issues),
issues: issues
}
{:error, {line, error_msg, token}} ->
# Fails gracefully by returning the parse error as a critical issue
%{
valid: false,
issues: [
%Issue{
rule: :parse_error,
severity: :critical,
message: "Syntax error: #{error_msg} at token #{inspect(token)}",
meta: %{line: line}
}
]
}
end
end
defp run_rules(ast, rules, opts) do
Enum.flat_map(rules, fn rule ->
rule.check(ast, opts)
end)
end
defp default_rules do
Application.spec(:credence, :modules)
|> Enum.filter(fn module ->
Credence.Rule in Keyword.get(module.__info__(:attributes), :behaviour, [])
end)
end
end