# `Mutare.Extension`
[🔗](https://github.com/foxbenjaminfox/mutare/blob/v0.2.1/lib/mutare/extension.ex#L1)

Non-mutating extensions for call routing and `use` expansion.

An extension implements one or both of these behaviours:

  * `Mutare.CallRouting` — static or shape-aware macro-argument routing;
  * `Mutare.UseExpansion` — an override for a `use` that cannot be expanded normally.

Extensions do not produce mutations or appear in reports. Add them to `:extensions` as modules or `{module, opts}` pairs:

    [extensions: [Mutare.Gettext]]

Entries may be bare modules or `{module, opts}` pairs. Options are delivered only to `c:Mutare.UseExpansion.expand_use/3`; `c:Mutare.CallRouting.call_routes/0` declarations and `c:Mutare.CallRouting.route_arguments/2` classification are intentionally options-independent.

Mutators may implement `Mutare.CallRouting` too, but belong under `:mutators`. They are rejected from `:extensions` so their mutation producers cannot be enabled accidentally as routing-only modules.

An extension that routes a library's DSL may declare that library's modules by exporting `required_modules/0` (the same optional callback mutators declare — see `c:Mutare.Mutator.required_modules/0`); `validate!/1` checks each is loadable and aborts with a `Mutare.EnvironmentError` otherwise, so an external-source run fails loudly at startup instead of silently registering routes against nothing.

# `extension?`

```elixir
@spec extension?(term()) :: boolean()
```

Returns whether `module` is loaded and implements at least one extension
capability.

# `validate!`

```elixir
@spec validate!(term()) :: [Mutare.Extension.Spec.t()]
```

Validates and resolves an `:extensions` list.

Entries may be modules, `{module, options}` pairs, or resolved
`Mutare.Extension.Spec` structs. Raises `ArgumentError` for invalid entries.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
