# `AshGrant.ArgumentAnalyzer`
[🔗](https://github.com/jhlee111/ash_grant/blob/v0.14.1/lib/ash_grant/argument_analyzer.ex#L1)

Compile-time analysis of which scopes reference which `^arg(...)` templates.

Given a resource, walks every scope's resolved (inheritance-applied) filter
expression and records the set of `{:_arg, name}` references per scope.
Inverting that mapping produces `%{arg_name => [scope_atoms]}`, which the
`AshGrant.Transformers.AddArgumentResolvers` transformer uses to wire up
`AshGrant.Changes.ResolveArgument` only where the argument is actually needed.

The walker understands the following AST shapes:

  * `%Ash.Query.BooleanExpression{}`, `%Ash.Query.Not{}`
  * `%Ash.Query.Call{args: [...]}`
  * `%Ash.Query.Exists{expr: ...}`
  * `%Ash.Query.Ref{}`
  * structs with `__function__?: true` and `:arguments`
  * structs with `__operator__?: true` / `:left` + `:right`
  * lists (for `in` operator RHS and function arg collections)
  * bare `{:_arg, name}` template tuples

# `arg_name`

```elixir
@type arg_name() :: atom()
```

# `scope_name`

```elixir
@type scope_name() :: atom()
```

# `arg_to_scopes`

```elixir
@spec arg_to_scopes(Ash.Resource.t()) :: %{required(arg_name()) =&gt; [scope_name()]}
```

Returns `%{arg_name => [scope_names]}` for all args referenced by any scope
on the given resource. Uses write-scope resolution so inheritance is applied.

# `referenced_args`

```elixir
@spec referenced_args(any()) :: [arg_name()]
```

Returns the list of `{:_arg, name}` argument names referenced anywhere in the
expression.

# `references_arg?`

```elixir
@spec references_arg?(any(), arg_name()) :: boolean()
```

True iff the expression references `{:_arg, name}` anywhere.

---

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