Cooper.Resolver (Cooper v0.1.0)

Copy Markdown

Resolves everything Cooper.Merge.assemble/1 left unresolved -- Cooper.Ref.Var (@{}, eager), Cooper.Ref.Env (${}, eager), Cooper.Ref.Config (%{}, lazy against the final tree), Cooper.Ref.Resolver (!{resolver:payload}, dispatch), Cooper.Ref.Tagged (!Name(arg), dispatch), and Cooper.Merge.Layered (a for loop's lazy from base with overrides on top, see Cooper.Loop).

@{}/${} could in principle resolve before merge, "so no Ref.Var nodes remain by merge time" -- but this module does it the other way -- after merge, walking the assembled tree -- which is deliberate, not an oversight: @{}/${} never depend on the merged tree's own shape (only on the variable/env environment, independent of merge outcome), so resolving them before or after merge produces identical results. Doing it here, uniformly with %{}'s genuinely-must-be-lazy resolution, keeps one walker instead of two, and matches Cooper.Grammar.run/2's own choice to leave Cooper.Ref.* nodes unresolved until this stage runs.

${?NAME} (CASC.md §7.2's conditional statement skip) is explicitly not handled here -- it removes an entire op rather than resolving a value, so it's evaluated back in Cooper.Actions' :conditional_statement handler instead, before this module ever sees the statement. Backslash-continued strings (CASC.md §6.5) remain a genuine open gap -- see test/SPEC_COVERAGE.md.

Summary

Functions

resolve(tree, opts \\ [])

@spec resolve(
  term(),
  keyword()
) :: {:ok, term()} | {:error, Ichor.Error.t()}

opts:

  • :vars -- %{name => value}, the file's own resolved variable environment (Cooper.Grammar.run_tree/2 builds this from Cooper.Actions' ctx.vars, already public/private-filtered by Cooper.Loader across imports).
  • :env -- %{name => value}, defaults to System.get_env/0.
  • :resolvers -- %{name => (payload :: String.t() -> {:ok, term()} | {:error, term()})}, for !{resolver:payload} (CASC.md §7.4/§9.2).
  • :tags -- same shape, for !Name(arg) beyond the five built-ins (int/float/bool/duration/bytes, CASC.md §7.5/§9.1).