Socket
Socket
Sign inDemoInstall

@glimmer/syntax

Package Overview
Dependencies
5
Maintainers
13
Versions
286
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

@glimmer/syntax


Version published
Maintainers
13
Created

Readme

Source

AST v2 enhances the original AST with a number of clarifying features.

Removals

ASTv1 retains a node for Handlebars' "partial" syntax ({{> ...}}). ASTv2 does not include that node (just as neither version of the AST includes a node for Handlebars "decorator" syntax), as it is not supported by Glimmer.

Naming Changes

There are a number of small naming changes that improve the clarity and precision of the AST:

  1. hash -> named
  2. params -> positional
  3. path -> callee
  4. SubExpression -> CallExpression
  5. BlockStatement -> InvokeBlock
  6. MustacheStatement -> AppendContent

Literals

In ASTv1, there is a separate literal node for each kind of literal. In ASTv2, all literals are ASTv2.Literal.

Args

In ASTv1, nodes have params and hash next to each other. In ASTv2, those nodes are grouped into an Args node that contains the positional and named arguments.

Because ASTv2 nodes are objects, this also allows these nodes to have an isEmpty() method, which makes it easy to check if a call node's arguments are totally empty.

Blocks

All nodes that can have block parameters have a table: BlockSymbolTable property in ASTv2.

Named Blocks

Elements that begin with a : are represented as ASTv2.NamedBlock.

Components

Elements that satisfy the component heuristics are represented as ASTv2.InvokeComponent.

An element is a component if the part of its tag name before any .:

  • begins with @
  • is this
  • is a reference to an in-scope binding
  • begins with an uppercase letter

Simple Elements

Elements that are not named blocks and do not satisfy the component heuristics are represented as ASTv2.SimpleElement.

Strict vs. Loose Mode

The difference between strict and loose mode is entirely encapsulated in the FreeVarReference.

Consumers of ASTv2 don't need to know whether they're looking at a "strict" or "loose" template. They just need to know how to handle the different contexts in FreeVarReference.

Variable References

In ASTv2, every variable name is represented as a VariableReference.

The first part of a PathExpression is a VariableReference.

typedescription
ThisReferencethe literal this
ArgReferencea variable reference that begins with with @
LocalVarReferencea reference to an in-scope variable binding
FreeVarReferencea reference to a variable binding that was not introduced by block params (`as

Important Note: The remainder of this README is a description of the loose mode rules for free variable resolution. Strict mode free variable references always refer to an in-scope JavaScript binding, regardless of their syntactic position.

RFC #496 (Handlebars Strict Mode) rationalized the rules for loose mode. This README describes the semantics of #496 in terms of namespaced free variable references and fallback semantics.

Free Variable References

There are two significant differences between strict and loose mode that affect the AST.

In loose mode:

  1. Certain free variable references fall back to a property lookup on this.
  2. Free variable references in "call" positions are resolved using a contextual namespace. For example, the free variable reference h in (h 123) is resolved as helper:h. The free variable reference h in <p {{h 123}}> is resolved as modifier:h.

In strict mode, all free variable references refer to bindings provided by a JavaScript scope that the template will be embedded within.

To represent this difference, all FreeVarReference nodes in ASTv2 are tagged with a FreeVarResolution.

Strict Variable Resolution

The Strict resolution applies to all free variables encountered while parsing a template in strict mode.

Runtime Error Cases

None. Strict mode templates must be embedded in a JavaScript context where all free variable references are in scope. A compile-time error should be produced if free there are variable references that do not correspond to any in-scope variables.

Fallback Semantics

When a free variable resolution is said to have "fallback semantics", it means the following algorithm:

  1. Attempt to resolve the name in the namespaces for the resolution, if any.
  2. If the name could not be resolved, resolve it as a property on this.

Note: A free variable resolution has fallback semantics if it's an append or attribute curly without arguments, or if it's a path in argument position. See the summary table below for full details.

Eval Mode Semantics

When a free variable resolution has fallback semantics, it is also said to have "eval mode semantics", which means:

  1. If the template is evaluated in eval mode (i.e. as a partial), dynamically resolve the free variable in the context of the template that invoked the partial (the "invoker"):
  2. If the variable name is in the local scope of the invoker, resolve it as a local variable in the invoker's local scope
  3. Otherwise:
  4. if the invoker is also in eval mode, repeat the process with the invoker's invoker
  5. if the invoker is not in eval mode, resolve the free variable using fallback semantics in the invoker's scope
  6. Otherwise, resolve the free variable using fallback semantics in the current scope

Namespaced Variable Resolution

Syntax PositionsSubExpression, Block, Modifier, Component
Path has dots?
Arguments?Any
Namespacesee table below
Fallback semantics?

These resolutions occur in syntaxes that are definitely calls (e.g. subexpressions, blocks, modifiers, etc.).

Applicable Situation
situationvariablenamespace
(x y)xHelper
{{#x y}}xBlock
<p {{x y}}>xModifier
X in <X />XComponent
Runtime Error Cases

If the variable reference cannot be resolved in its namespace.

Namespaced Resolution: Ambiguous Component or Helper

Syntax Positionsappend
Path has dots?
Arguments?
Namespacehelper or component
Fallback semantics?

This resolution occurs in append nodes with at least one argument, and when the path does not have dots (e.g. {{hello world}}).

Applicable Situation
situationvariablenamespace
{{x y}} as appendxComponentOrHelper

In this situation, the x may refer to:

  • a helper x
  • a component x
Runtime Error Cases

If the variable reference cannot be resolved in the helper or component namespaces.

Ambiguous Resolution: Append Ambiguity

Syntax Positionsappend
Path has dots?
Arguments?
Namespacehelper, component
Fallback semantics?

This resolution occurs in append nodes with zero arguments, and when the path does not have dots (e.g. {{hello}}).

Applicable Situations
situationvariableambiguity
{{x}} as appendxAppend

In this situation, the x may refer to:

  • a helper x
  • a component x
  • a local variable in partial scope
  • this.x.
Runtime Error Cases

None.

Ambiguous Resolution: Attribute Ambiguity

This resolution context occurs in attribute nodes with zero arguments, and when the path does not have dots.

Syntax Positionsattribute, interpolation
Path has dots?
Arguments?
Namespacehelper
Fallback semantics?
Applicable Situations
situationvariableambiguity
<p attr={{x}}>
<a href="{{x}}.html">
xAttr

In this situation, the x may refer to:

  • a helper x
  • a local variable in partial scope
  • this.x.
Runtime Error Cases

None.

Summary

These tables apply to situations where the head of the callee's path is a free variable. When the head is a local variable, it always uses strict resolution.

Syntax Errors 🙅‍♀️

Situations that meet all three of these criteria are syntax errors:

  1. Unambiguous invocations
  2. The callee contains a .
  3. The head of the callee is a FreeVarReference
Syntax PositionExampleDots?Arguments?
Component<X.y />Any
Modifier<p {{x.y}} />Any
SubExpression(x.y)Any
Block{{#x.y}}Any
Append, Attribute{{x.y z}}
Block, Component, Modifier, SubExpression
Path has dots?
Arguments?Any
Fallback semantics?
Syntax PositionExampleNamespace
Block{{#x}}block
Component<X />component
Modifier<p {{x}} />modifier
SubExpression(x)helper
Append
Syntax PositionExampleDots?Args?NamespaceFallback?
Append{{x}}helper, component
Append{{x.y}}None
Append{{x y}}helper, component
Attributes

The Attribute syntax position includes:

  • the value of an HTML attribute (href={{...}})
  • the value of an element argument (@title={{...}})
  • a part of an interpolation (href="{{...}}.html")
Syntax PositionExampleDots?Arguments?NamespaceFallback?
Attributehref={{x}}helper
Attributehref={{x.y}}None
Attributehref={{x y}}helper

FAQs

Last updated on 24 Oct 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc