KogenCredo.CoreSupport.Ast (KogenCredo v0.1.0)
View SourceAST helpers shared by the KogenCredo checks.
Everything here is syntactic: no compilation, no type information.
Summary
Types
Dotted module name without Elixir. (MyApp.Repo is the string MyApp.Repo); Erlang
modules keep a colon (:ets is the string :ets).
Functions
True for any variable node, including _ and _name.
The name of an existing module atom: Enum is "Enum", :rand is ":rand". Only for atoms
that already exist (literals in this package's source, configuration, compiled metadata).
Parses a def/defp clause into {:ok, {kind, name, args, guard, body, meta}} or :error.
Rewrites a |> f(b) into f(a, b) everywhere so arities and argument positions are real.
Renders a list of module names the way inspect/1 renders the same list of module atoms
([MyApp.Shared, MyApp.Ports]), including its truncation of very long lists.
Joins alias segments ([:MyApp, :Billing], or a resolved prefix name followed by more
segments) into a module name ("MyApp.Billing"). A leading Elixir segment is dropped.
Last expression of a block.
Module name from a literal alias node or an atom, else nil. Aliases are not expanded.
Every defmodule as {name_ast, meta, body} (nested modules included).
Shape of code: variables renamed by first appearance, metadata dropped, pipes expanded.
Variable names bound at the top of a parameter pattern (x, x = %{}, x \\ 1).
True when the atom's text starts with prefix (e.g. _ignored with "_").
Node count.
Flattens a literal or interpolated string into the text of its literal parts, or nil.
Removes nested defmodule nodes so per-module counts exclude inner modules.
True when name is prefix or lies under it (A.B.C is under A.B, A.BC is not).
True for a plain variable node that is not underscore-prefixed or a __MODULE__-style form.
Depth-first accumulate over every node.
Types
@type module_name() :: String.t()
Dotted module name without Elixir. (MyApp.Repo is the string MyApp.Repo); Erlang
modules keep a colon (:ets is the string :ets).
Functions
True for any variable node, including _ and _name.
@spec atom_name(atom()) :: module_name()
The name of an existing module atom: Enum is "Enum", :rand is ":rand". Only for atoms
that already exist (literals in this package's source, configuration, compiled metadata).
Parses a def/defp clause into {:ok, {kind, name, args, guard, body, meta}} or :error.
Rewrites a |> f(b) into f(a, b) everywhere so arities and argument positions are real.
@spec inspect_names([module_name()]) :: String.t()
Renders a list of module names the way inspect/1 renders the same list of module atoms
([MyApp.Shared, MyApp.Ports]), including its truncation of very long lists.
@spec join_name([atom() | String.t()]) :: module_name()
Joins alias segments ([:MyApp, :Billing], or a resolved prefix name followed by more
segments) into a module name ("MyApp.Billing"). A leading Elixir segment is dropped.
Last expression of a block.
@spec module_name(Macro.t()) :: module_name() | nil
Module name from a literal alias node or an atom, else nil. Aliases are not expanded.
Every defmodule as {name_ast, meta, body} (nested modules included).
Shape of code: variables renamed by first appearance, metadata dropped, pipes expanded.
Variable names bound at the top of a parameter pattern (x, x = %{}, x \\ 1).
True when the atom's text starts with prefix (e.g. _ignored with "_").
@spec size(Macro.t()) :: non_neg_integer()
Node count.
Flattens a literal or interpolated string into the text of its literal parts, or nil.
Removes nested defmodule nodes so per-module counts exclude inner modules.
@spec under_name?(module_name(), module_name()) :: boolean()
True when name is prefix or lies under it (A.B.C is under A.B, A.BC is not).
True for a plain variable node that is not underscore-prefixed or a __MODULE__-style form.
Depth-first accumulate over every node.