Metastatic.Semantic.Callbacks
(Metastatic v0.23.0)
View Source
Registry of known behaviour/base-class callbacks per language.
Maps {language, behaviour_module, function_name, arity} tuples to
callback specs, enabling the enricher to annotate :function_def nodes
with callback_for: metadata when the enclosing container uses/inherits
a registered behaviour.
Storage uses :persistent_term (same strategy as Semantic.Patterns).
Built-in Registrations
The module ships with callbacks for common frameworks:
- Elixir: Oban.Worker, GenServer, Phoenix.LiveView, Plug, Broadway
- Ruby: ActiveJob::Base, Sidekiq::Worker, Resque
- Python: celery.Task, RQ Worker, Dramatiq
Usage
# Check if a function is a known callback
Callbacks.lookup(:elixir, "Oban.Worker", "perform", 1)
#=> {:ok, %{framework: :oban, domain: :queue}}
# Register a custom callback
Callbacks.register(:elixir, "MyBehaviour", "handle_event", 2,
%{framework: :custom, domain: nil})Integration
The enricher calls lookup/4 during tree traversal. When a :container
node declares a behaviour (via :import children or :parent metadata),
its :function_def children are checked against this registry.
Summary
Types
Registry key: {language, behaviour_module, function_name, arity_or_nil}
Callback specification describing the framework and domain
Functions
Returns all registered behaviours for a language.
Checks whether a function in a given behaviour is a known callback.
Clears all registered callbacks. Primarily for testing.
Looks up a callback by language, behaviour, function name, and arity.
Registers a callback for a behaviour in a specific language.
Registers all built-in callbacks for all supported languages.
Types
@type callback_key() :: {atom(), String.t(), String.t(), non_neg_integer() | nil}
Registry key: {language, behaviour_module, function_name, arity_or_nil}
Callback specification describing the framework and domain
Functions
Returns all registered behaviours for a language.
Examples
iex> behaviours = Callbacks.behaviours_for_language(:elixir)
iex> "Oban.Worker" in behaviours
true
@spec callback?(atom(), String.t(), String.t(), non_neg_integer() | nil) :: boolean()
Checks whether a function in a given behaviour is a known callback.
Examples
iex> Callbacks.callback?(:elixir, "Oban.Worker", "perform", 1)
true
iex> Callbacks.callback?(:elixir, "Oban.Worker", "unknown", 0)
false
@spec clear() :: :ok
Clears all registered callbacks. Primarily for testing.
@spec lookup(atom(), String.t(), String.t(), non_neg_integer() | nil) :: {:ok, callback_spec()} | :no_match
Looks up a callback by language, behaviour, function name, and arity.
Tries an exact arity match first, then falls back to a wildcard (nil arity) match.
Examples
iex> Callbacks.lookup(:elixir, "Oban.Worker", "perform", 1)
{:ok, %{framework: :oban, domain: :queue}}
iex> Callbacks.lookup(:elixir, "Oban.Worker", "unknown", 0)
:no_match
@spec register( atom(), String.t(), String.t(), non_neg_integer() | nil, callback_spec() ) :: :ok
Registers a callback for a behaviour in a specific language.
When arity is nil, the callback matches any arity for that function name.
Parameters
language- Source language atom (:elixir,:ruby,:python, etc.)behaviour- The behaviour/base-class module name (e.g.,"Oban.Worker")function_name- The callback function name (e.g.,"perform")arity- Expected arity, ornilfor any arityspec- A%{framework: atom(), domain: atom() | nil}map
Examples
iex> Callbacks.register(:elixir, "Oban.Worker", "perform", 1, %{framework: :oban, domain: :queue})
:ok
@spec register_builtins() :: :ok
Registers all built-in callbacks for all supported languages.
Called during application startup. Can also be called manually to
re-register after clear/0.
OTP and Elixir standard library behaviours are discovered automatically
via BEAM introspection (see Metastatic.Semantic.Callbacks.BeamIntrospector).
Third-party framework callbacks that may not be compiled are registered
manually.