AbsinthePermission.Compiler (AbsinthePermission v1.0.0)

Copy Markdown View Source

Compile-time machinery for AbsinthePermission.

Two responsibilities:

  1. Condition compilationcompile_condition/2 turns a piece of Elixir AST like arg(:state) == "CLOSED" into the data form {:cmp, [:eq, {:arg, :state}, {:literal, "CLOSED"}]} defined by AbsinthePermission.Condition.

  2. Schema scope detectioncurrent_scope/1 reads Absinthe's in-progress blueprint to determine the field and type the DSL macro is being expanded inside.

This module is intended to be used by AbsinthePermission.DSL macros and by the @before_compile hook installed by use AbsinthePermission. It is not part of the public API.

Summary

Functions

Compile a condition AST into the runtime data form.

Returns {type_identifier, field_identifier} for the field/type the current macro expansion is inside. Either may be nil if the macro is used outside an expected scope.

Like current_scope/1 but raises a helpful compile error if the macro isn't being used inside a schema field or type body.

Types

scope()

@type scope() :: {type_id :: atom(), field_id :: atom() | nil}

Functions

compile_condition(ast, env)

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

Compile a condition AST into the runtime data form.

Returns AST that, when evaluated at the call site, produces a AbsinthePermission.Condition.t/0. Raises CompileError on malformed input, with file/line from the supplied env.

Examples (the AST input shape, not what users write)

iex> ast = quote do: arg(:state) == "CLOSED"
iex> {:cmp, [:eq, {:arg, :state}, {:literal, "CLOSED"}]} =
...>   AbsinthePermission.Compiler.compile_condition(ast, __ENV__)
...>   |> Code.eval_quoted([], __ENV__)
...>   |> elem(0)

current_scope(env)

@spec current_scope(Macro.Env.t()) :: scope()

Returns {type_identifier, field_identifier} for the field/type the current macro expansion is inside. Either may be nil if the macro is used outside an expected scope.

Reads Module.get_attribute(env.module, :absinthe_blueprint) — that attribute is populated by Absinthe's notation macros as the schema compiles.

current_scope!(env, macro_name)

@spec current_scope!(Macro.Env.t(), atom()) :: scope()

Like current_scope/1 but raises a helpful compile error if the macro isn't being used inside a schema field or type body.