The template intermediate representation, and the vocabulary the front and back halves of the compiler agree on.
Why an IR exists
Avenx used to compile a template by rewriting it into different markup.
<@for item in items> became <template data-ax-for="items" data-ax-as="item">, <@suspense> became <div data-ax-suspense>, and the
runtime rediscovered what each of them meant by reading those attributes back
off the live DOM with querySelectorAll.
That is a compiler that throws its own analysis away. Every consequence
followed from it: the render-program backend could not compile a list,
because by the time it ran the list was an anonymous <template> element
carrying strings; the runtime had to ship a second renderer to interpret
those attributes; and a > inside a header expression broke the rewrite
because a regex was the only thing left that could read it.
The IR is where a construct's meaning is written down instead. A <@for>
becomes a ForNode with a list expression, a binding name, an optional
key and two child fragments. Nothing downstream has to guess, and nothing has
to parse markup a second time.
The shape, and why fragments are explicit
A FragmentNode is a compile boundary: each one becomes its own skeleton and its own op list in the emitted program, and its own DOM range at run time. Control flow owns fragments rather than containing raw children, because "the body of this loop" is exactly the unit that gets cloned per item and torn down per removal. Making that unit implicit is how a list renderer ends up re-deriving its own boundaries.
Extension
Adding a construct means adding a kind here, a builder case in module:lib/compiler/ir/build, and a lowering case in module:lib/compiler/ir/lower. A construct with no lowering case is refused with its own reason rather than silently mis-emitted, which is the same compile-or-refuse rule the render program has always followed -- moved one layer earlier, where the reason is still specific enough to be useful.
- Source:
Classes
Members
(static, constant) BindingKind :string
Kinds of value binding an element can carry.
Type:
- string
- Source:
(static, constant) IRKind :string
IR node kinds.
Type:
- string
- Source:
(static, constant) RefusalReason :string
Why a template, or part of one, could not be represented in the IR.
These are the constructs the IR does not model yet. They are enumerated rather than free text so a build can group them, and so a reader can tell "not implemented" from "gave up".
Type:
- string
- Source:
Methods
(static) comment(value) → {object}
Creates a comment node.
Parameters:
| Name | Type | Description |
|---|---|---|
value |
string | The comment body. |
- Source:
Returns:
The comment node.
- Type
- object
(static) component(name, optionsopt) → {object}
Creates a child-component node.
Parameters:
- Source:
Returns:
The component node.
- Type
- object
(static) conditional(branches) → {object}
Creates a conditional node.
Branches are ordered and the first whose test is truthy renders. A branch
with a null test is the <@else> and may only appear last; the builder
enforces that, so nothing downstream has to re-check it.
Parameters:
| Name | Type | Description |
|---|---|---|
branches |
Array:.<{test:: (string:|null:), body:: object:}> | Ordered branches. |
- Source:
Returns:
The conditional node.
- Type
- object
(static) deferred(when, body, placeholderopt) → {object}
Creates a deferred block.
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
when |
string | The trigger: |
|
body |
object | The fragment rendered once the trigger fires. |
|
placeholder |
object | null |
<optional> |
The fragment rendered until it does. |
- Source:
Returns:
The defer node.
- Type
- object
(static) element(tag, optionsopt) → {object}
Creates an element node.
Parameters:
| Name | Type | Attributes | Description | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
tag |
string | The tag name. |
|||||||||||||||||||||||||||||
options |
object |
<optional> |
Element parts. Properties
|
- Source:
Returns:
The element node.
- Type
- object
(static) fragment(childrenopt) → {object}
Creates a fragment.
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
children |
Array:.<object:> |
<optional> |
Child IR nodes. |
- Source:
Returns:
The fragment node.
- Type
- object
(static) interpolation(expr, rawopt) → {object}
Creates an interpolation node.
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
expr |
string | The expression source. |
|
raw |
boolean |
<optional> |
True for |
- Source:
Returns:
The interpolation node.
- Type
- object
(static) isBlockNode(node) → {boolean}
Whether a node introduces its own compile and DOM boundary.
Control flow does; an element does not. Used by the lowering pass to decide where one skeleton ends and the next begins.
Parameters:
| Name | Type | Description |
|---|---|---|
node |
object | An IR node. |
- Source:
Returns:
True when the node owns fragments.
- Type
- boolean
(static) iteration(parts) → {object}
Creates an iteration node.
Exactly one of item and destructure is set: the first for x in xs, the
second for [a, b] in pairs, which destructures each element rather than
binding an index. The index is bound implicitly under the name index by
the runtime and is therefore not part of the node.
Parameters:
| Name | Type | Description | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
parts |
object | Loop parts. Properties
|
- Source:
Returns:
The iteration node.
- Type
- object
(static) slot(name, fallbackFragmentopt) → {object}
Creates a slot outlet.
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
name |
string | The slot name; |
|
fallbackFragment |
object |
<optional> |
Content rendered when nothing is transcluded. |
- Source:
Returns:
The slot node.
- Type
- object
(static) text(value) → {object}
Creates a literal text node.
Parameters:
| Name | Type | Description |
|---|---|---|
value |
string | The character data. |
- Source:
Returns:
The text node.
- Type
- object
(static) walkIR(node, visit, parentopt)
Walks every node in an IR tree, depth first, including fragment bodies.
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
node |
object | The root node. |
|
visit |
function | Called with each node and its parent. |
|
parent |
object | null |
<optional> |
The parent, for recursive calls. |
- Source: