ExPanda.EnvManager (ExPanda v0.2.1)

View Source

Manages Macro.Env structs for macro expansion.

Handles environment construction, updates for compilation directives (alias, import, require), module/function scoping, and variable registration for :elixir_expand compatibility.

Summary

Functions

Apply an alias directive to the environment.

Apply an import directive to the environment.

Apply a require directive to the environment.

Create a child environment for a function scope.

Create a child environment for a module scope.

Extract parameter names from a function signature AST.

Create an environment from the caller's current context.

Create a fresh compilation environment using Elixir's internal env factory.

Set the file path in the environment.

Set the line number in the environment.

Register multiple variable names extracted from a pattern AST.

Register a variable name in the environment's versioned_vars.

Extract the module name from an alias AST node.

Functions

apply_alias(env, module, as_name)

@spec apply_alias(Macro.Env.t(), module(), module() | nil) :: Macro.Env.t()

Apply an alias directive to the environment.

Handles both alias Foo.Bar (aliasing Bar) and alias Foo.Bar, as: Baz.

Examples

iex> env = ExPanda.EnvManager.new_env()
iex> env = ExPanda.EnvManager.apply_alias(env, Foo.Bar, nil)
iex> {Foo.Bar, Bar} in env.aliases or Keyword.get(env.aliases, :"Elixir.Bar") == Foo.Bar
true

apply_import(env, module, opts \\ [])

@spec apply_import(Macro.Env.t(), module(), keyword()) :: Macro.Env.t()

Apply an import directive to the environment.

Loads the target module's functions and macros into the env. Returns the env unchanged if the module is not available.

apply_require(env, module)

@spec apply_require(Macro.Env.t(), module()) :: Macro.Env.t()

Apply a require directive to the environment.

Adds the module to the requires list if not already present.

enter_function(env, name, arity, param_names)

@spec enter_function(Macro.Env.t(), atom(), non_neg_integer(), list()) ::
  Macro.Env.t()

Create a child environment for a function scope.

Sets the function name/arity and registers parameters as variables.

enter_module(env, module_name)

@spec enter_module(Macro.Env.t(), module()) :: Macro.Env.t()

Create a child environment for a module scope.

Sets the module name and resets function context.

extract_param_names(params)

@spec extract_param_names(list()) :: [atom()]

Extract parameter names from a function signature AST.

Handles simple params, pattern params, default values, and guards.

Examples

iex> ExPanda.EnvManager.extract_param_names([{:x, [], nil}, {:y, [], nil}])
[:x, :y]

from_caller(caller_env)

@spec from_caller(Macro.Env.t()) :: Macro.Env.t()

Create an environment from the caller's current context.

Useful when expanding code within a running application where all dependencies are already loaded.

new_env()

@spec new_env() :: Macro.Env.t()

Create a fresh compilation environment using Elixir's internal env factory.

This produces a Macro.Env with Kernel functions and macros pre-loaded, matching what a new module compilation would start with.

Examples

iex> env = ExPanda.EnvManager.new_env()
iex> env.__struct__
Macro.Env
iex> Kernel in env.requires
true

put_file(env, path)

@spec put_file(Macro.Env.t(), String.t()) :: Macro.Env.t()

Set the file path in the environment.

put_line(env, line)

@spec put_line(Macro.Env.t(), non_neg_integer()) :: Macro.Env.t()

Set the line number in the environment.

register_pattern_vars(env, pattern)

@spec register_pattern_vars(Macro.Env.t(), Macro.t()) :: Macro.Env.t()

Register multiple variable names extracted from a pattern AST.

Walks the pattern to find all variable bindings and registers them.

register_var(env, name)

@spec register_var(Macro.Env.t(), atom()) :: Macro.Env.t()

Register a variable name in the environment's versioned_vars.

This is needed for :elixir_expand.expand/3 which raises on undefined variables.

resolve_module_name(atom, env)

@spec resolve_module_name(Macro.t(), Macro.Env.t()) :: module()

Extract the module name from an alias AST node.

Examples

iex> ExPanda.EnvManager.resolve_module_name({:__aliases__, [], [:Foo, :Bar]}, ExPanda.EnvManager.new_env())
Foo.Bar