The binary AST is isomorphic to ECMA-262 Syntactic Grammar. That is, an instance of a production of the binary AST grammar, or a binary AST Node, corresponds to some Parse Node in the ECMA-262 syntactic grammar. This document specifies the following things.
A compliant binary AST Encoder, for a source text that matches either the
The inverse of
This section is derived from Shift AST Spec and parts are Copyright 2014-2017 Shape Security, Inc.
Unlike the Shift AST spec, interface types are not used to inherit fields to control over ordering of fields. Type hierarchies that are not used to discriminate are collapsed to make space costs simple. Nor are they used to discriminate types, for which explicitly discriminated unions types are used.
The grammar is presented in WebIDL with the [TypeIndicator] and [NonEmpty] extensions per Shift AST spec. The [Lazy] extension serves as a hint to the surface encoding that the [Lazy] attribute should be skippable in the byte stream in constant time. The typedefs of or types are to be read as recursive sum types. In text below, the "is a Foo" prose is shorthand for checking the node's type attribute being equal to "Foo".
// Type aliases and enums.
typedef FrozenArray<(SpreadElement or Expression)> Arguments;
typedef DOMString string;
// Identifier:: IdentifierName but not ReservedWord
typedef string Identifier;
typedef string IdentifierName;
typedef string Label;
enum VariableDeclarationKind {
"var",
"let",
"const"
};
enum CompoundAssignmentOperator {
"+=",
"-=",
"*=",
"/=",
"%=",
"**=",
"<<=",
">>=",
">>>=",
"|=",
"^=",
"&="
};
enum BinaryOperator {
",",
"||",
"&&",
"|",
"^",
"&",
"==",
"!=",
"===",
"!==",
"<",
"<=",
">",
">=",
"in",
"instanceof",
"<<",
">>",
">>>",
"+",
"-",
"*",
"/",
"%",
"**",
};
enum UnaryOperator {
"+",
"-",
"!",
"~",
"typeof",
"void",
"delete"
};
enum UpdateOperator {
"++",
"--"
};
enum AssertedDeclaredKind {
"var",
"non-const lexical",
"const lexical"
};
// deferred assertions
interface AssertedDeclaredName {
attribute IdentifierName name;
attribute AssertedDeclaredKind kind;
attribute boolean isCaptured;
};
interface AssertedPositionalParameterName {
attribute unsigned long index;
attribute IdentifierName name;
attribute boolean isCaptured;
};
interface AssertedRestParameterName {
attribute IdentifierName name;
attribute boolean isCaptured;
};
interface AssertedParameterName {
attribute IdentifierName name;
attribute boolean isCaptured;
};
typedef (AssertedPositionalParameterName or
AssertedRestParameterName or
AssertedParameterName)
AssertedMaybePositionalParameterName;
interface AssertedBoundName {
attribute IdentifierName name;
attribute boolean isCaptured;
};
interface AssertedBlockScope {
attribute FrozenArray<AssertedDeclaredName> declaredNames;
attribute boolean hasDirectEval;
};
interface AssertedScriptGlobalScope {
attribute FrozenArray<AssertedDeclaredName> declaredNames;
attribute boolean hasDirectEval;
};
interface AssertedVarScope {
attribute FrozenArray<AssertedDeclaredName> declaredNames;
attribute boolean hasDirectEval;
};
interface AssertedParameterScope {
attribute FrozenArray<AssertedMaybePositionalParameterName> paramNames;
attribute boolean hasDirectEval;
attribute boolean isSimpleParameterList;
};
interface AssertedBoundNamesScope {
attribute FrozenArray<AssertedBoundName> boundNames;
attribute boolean hasDirectEval;
};
// nodes
interface Node {
[TypeIndicator] readonly attribute Type type;
};
typedef (Script or Module) Program;
typedef (DoWhileStatement or
ForInStatement or
ForOfStatement or
ForStatement or
WhileStatement)
IterationStatement;
typedef (Block or
BreakStatement or
ContinueStatement or
ClassDeclaration or
DebuggerStatement or
EmptyStatement or
ExpressionStatement or
FunctionDeclaration or
IfStatement or
IterationStatement or
LabelledStatement or
ReturnStatement or
SwitchStatement or
SwitchStatementWithDefault or
ThrowStatement or
TryCatchStatement or
TryFinallyStatement or
VariableDeclaration or
WithStatement)
Statement;
typedef (LiteralBooleanExpression or
LiteralInfinityExpression or
LiteralNullExpression or
LiteralNumericExpression or
LiteralStringExpression)
Literal;
typedef (Literal or
LiteralRegExpExpression or
ArrayExpression or
ArrowExpression or
AssignmentExpression or
BinaryExpression or
CallExpression or
CompoundAssignmentExpression or
ComputedMemberExpression or
ConditionalExpression or
ClassExpression or
FunctionExpression or
IdentifierExpression or
NewExpression or
NewTargetExpression or
ObjectExpression or
UnaryExpression or
StaticMemberExpression or
TemplateExpression or
ThisExpression or
UpdateExpression or
YieldExpression or
YieldStarExpression or
AwaitExpression)
Expression;
typedef (ComputedPropertyName or
LiteralPropertyName)
PropertyName;
typedef (Method or Getter or Setter) MethodDefinition;
typedef (MethodDefinition or
DataProperty or
ShorthandProperty)
ObjectProperty;
typedef (ExportAllFrom or
ExportFrom or
ExportLocals or
ExportDefault or
Export)
ExportDeclaration;
typedef (ImportNamespace or Import) ImportDeclaration;
typedef (EagerFunctionDeclaration or
LazyFunctionDeclaration) FunctionDeclaration;
typedef (EagerFunctionExpression or
LazyFunctionExpression) FunctionExpression;
typedef (EagerMethod or LazyMethod) Method;
typedef (EagerGetter or LazyGetter) Getter;
typedef (EagerSetter or LazySetter) Setter;
typedef (EagerArrowExpressionWithFunctionBody or
LazyArrowExpressionWithFunctionBody or
EagerArrowExpressionWithExpression or
LazyArrowExpressionWithExpression) ArrowExpression;
// bindings
interface BindingIdentifier : Node {
attribute Identifier name;
};
typedef (ObjectBinding or
ArrayBinding)
BindingPattern;
typedef (BindingPattern or
BindingIdentifier)
Binding;
typedef (AssignmentTargetIdentifier or
ComputedMemberAssignmentTarget or
StaticMemberAssignmentTarget)
SimpleAssignmentTarget;
typedef (ObjectAssignmentTarget or
ArrayAssignmentTarget)
AssignmentTargetPattern;
// `DestructuringAssignmentTarget`
typedef (AssignmentTargetPattern or
SimpleAssignmentTarget)
AssignmentTarget;
// `FormalParameter`
typedef (Binding or
BindingWithInitializer)
Parameter;
interface BindingWithInitializer : Node {
attribute Binding binding;
attribute Expression init;
};
interface AssignmentTargetIdentifier : Node {
attribute Identifier name;
};
interface ComputedMemberAssignmentTarget : Node {
// The object whose property is being assigned.
attribute (Expression or Super) _object;
// The expression resolving to the name of the property to be accessed.
attribute Expression expression;
};
interface StaticMemberAssignmentTarget : Node {
// The object whose property is being assigned.
attribute (Expression or Super) _object;
// The name of the property to be accessed.
attribute IdentifierName property;
};
// `ArrayBindingPattern`
interface ArrayBinding : Node {
// The elements of the array pattern; a null value represents an elision.
attribute FrozenArray<(Binding or BindingWithInitializer)?> elements;
attribute Binding? rest;
};
// `SingleNameBinding`
interface BindingPropertyIdentifier : Node {
attribute BindingIdentifier binding;
attribute Expression? init;
};
// `BindingProperty :: PropertyName : BindingElement`
interface BindingPropertyProperty : Node {
attribute PropertyName name;
attribute (Binding or BindingWithInitializer) binding;
};
typedef (BindingPropertyIdentifier or
BindingPropertyProperty)
BindingProperty;
interface ObjectBinding : Node {
attribute FrozenArray<BindingProperty> properties;
};
// This interface represents the case where the initializer is present in
// `AssignmentElement :: DestructuringAssignmentTarget Initializer_opt`.
interface AssignmentTargetWithInitializer : Node {
attribute AssignmentTarget binding;
attribute Expression init;
};
// `ArrayAssignmentPattern`
interface ArrayAssignmentTarget : Node {
// The elements of the array pattern; a null value represents an elision.
attribute FrozenArray<(AssignmentTarget or AssignmentTargetWithInitializer?)> elements;
attribute AssignmentTarget? rest;
};
// `AssignmentProperty :: IdentifierReference Initializer_opt`
interface AssignmentTargetPropertyIdentifier : Node {
attribute AssignmentTargetIdentifier binding;
attribute Expression? init;
};
// `AssignmentProperty :: PropertyName : Node`
interface AssignmentTargetPropertyProperty : Node {
attribute PropertyName name;
attribute (AssignmentTarget or AssignmentTargetWithInitializer) binding;
};
typedef (AssignmentTargetPropertyIdentifier or
AssignmentTargetPropertyProperty)
AssignmentTargetProperty;
// `ObjectAssignmentPattern`
interface ObjectAssignmentTarget : Node {
attribute FrozenArray<AssignmentTargetProperty> properties;
};
// classes
interface ClassExpression : Node {
attribute BindingIdentifier? name;
attribute Expression? super;
attribute FrozenArray<ClassElement> elements;
};
interface ClassDeclaration : Node {
attribute BindingIdentifier name;
attribute Expression? super;
attribute FrozenArray<ClassElement> elements;
};
interface ClassElement : Node {
// True iff `IsStatic` of ClassElement is true.
attribute boolean isStatic;
attribute MethodDefinition method;
};
// modules
interface Module : Node {
attribute AssertedVarScope scope;
attribute FrozenArray<Directive> directives;
attribute FrozenArray<(ImportDeclaration or ExportDeclaration or Statement)> items;
};
// An `ImportDeclaration` not including a namespace import.
interface Import : Node {
attribute string moduleSpecifier;
// `ImportedDefaultBinding`, if present.
attribute BindingIdentifier? defaultBinding;
attribute FrozenArray<ImportSpecifier> namedImports;
};
// An `ImportDeclaration` including a namespace import.
interface ImportNamespace : Node {
attribute string moduleSpecifier;
// `ImportedDefaultBinding`, if present.
attribute BindingIdentifier? defaultBinding;
attribute BindingIdentifier namespaceBinding;
};
interface ImportSpecifier : Node {
// The `IdentifierName` in the production `ImportSpecifier :: IdentifierName as ImportedBinding`;
// absent if this specifier represents the production `ImportSpecifier :: ImportedBinding`.
attribute IdentifierName? name;
attribute BindingIdentifier binding;
};
// `export * FromClause;`
interface ExportAllFrom : Node {
attribute string moduleSpecifier;
};
// `export ExportClause FromClause;`
interface ExportFrom : Node {
attribute FrozenArray<ExportFromSpecifier> namedExports;
attribute string moduleSpecifier;
};
// `export ExportClause;`
interface ExportLocals : Node {
attribute FrozenArray<ExportLocalSpecifier> namedExports;
};
// `export VariableStatement`, `export Declaration`
interface Export : Node {
attribute (FunctionDeclaration or ClassDeclaration or VariableDeclaration) declaration;
};
// `export default HoistableDeclaration`,
// `export default ClassDeclaration`,
// `export default AssignmentExpression`
interface ExportDefault : Node {
attribute (FunctionDeclaration or ClassDeclaration or Expression) body;
};
// `ExportSpecifier`, as part of an `ExportFrom`.
interface ExportFromSpecifier : Node {
// The only `IdentifierName in `ExportSpecifier :: IdentifierName`,
// or the first in `ExportSpecifier :: IdentifierName as IdentifierName`.
attribute IdentifierName name;
// The second `IdentifierName` in `ExportSpecifier :: IdentifierName as IdentifierName`,
// if that is the production represented.
attribute IdentifierName? exportedName;
};
// `ExportSpecifier`, as part of an `ExportLocals`.
interface ExportLocalSpecifier : Node {
// The only `IdentifierName in `ExportSpecifier :: IdentifierName`,
// or the first in `ExportSpecifier :: IdentifierName as IdentifierName`.
attribute IdentifierExpression name;
// The second `IdentifierName` in `ExportSpecifier :: IdentifierName as IdentifierName`, if present.
attribute IdentifierName? exportedName;
};
// property definition
// `MethodDefinition :: PropertyName ( UniqueFormalParameters ) { FunctionBody }`,
// `GeneratorMethod :: * PropertyName ( UniqueFormalParameters ) { GeneratorBody }`,
// `AsyncMethod :: async PropertyName ( UniqueFormalParameters ) { AsyncFunctionBody }`
interface EagerMethod : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute PropertyName name;
// `length` property of this method.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute FunctionOrMethodContents contents;
};
interface LazyMethod : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute PropertyName name;
// `length` property of this method.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute FunctionOrMethodContents contents;
};
// `get PropertyName ( ) { FunctionBody }`
interface EagerGetter : Node {
attribute PropertyName name;
attribute FrozenArray<Directive> directives;
attribute GetterContents contents;
};
interface LazyGetter : Node {
attribute PropertyName name;
attribute FrozenArray<Directive> directives;
[Lazy] attribute GetterContents contents;
};
interface GetterContents : Node {
attribute boolean isThisCaptured;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
// `set PropertyName ( PropertySetParameterList ) { FunctionBody }`
interface EagerSetter : Node {
attribute PropertyName name;
// `length` property of this setter function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute SetterContents contents;
};
interface LazySetter : Node {
attribute PropertyName name;
// `length` property of this setter function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute SetterContents contents;
};
interface SetterContents : Node {
attribute boolean isThisCaptured;
attribute AssertedParameterScope parameterScope;
attribute Parameter param;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
// `PropertyDefinition :: PropertyName : AssignmentExpression`
interface DataProperty : Node {
attribute PropertyName name;
// The `AssignmentExpression`.
attribute Expression expression;
};
// `PropertyDefinition :: IdentifierReference`
interface ShorthandProperty : Node {
// The `IdentifierReference`.
attribute IdentifierExpression name;
};
interface ComputedPropertyName : Node {
attribute Expression expression;
};
// `LiteralPropertyName`
interface LiteralPropertyName : Node {
attribute string value;
};
// literals
// `BooleanLiteral`
interface LiteralBooleanExpression : Node {
attribute boolean value;
};
// A `NumericLiteral` for which the Number value of its MV is positive infinity.
interface LiteralInfinityExpression : Node { };
// `NullLiteral`
interface LiteralNullExpression : Node { };
// `NumericLiteral`
interface LiteralNumericExpression : Node {
attribute double value;
};
// `RegularExpressionLiteral`
interface LiteralRegExpExpression : Node {
attribute string pattern;
attribute string flags;
};
// `StringLiteral`
interface LiteralStringExpression : Node {
attribute string value;
};
// other expressions
// `ArrayLiteral`
interface ArrayExpression : Node {
// The elements of the array literal; a null value represents an elision.
attribute FrozenArray<(SpreadElement or Expression)?> elements;
};
// `ArrowFunction`,
// `AsyncArrowFunction`
interface EagerArrowExpressionWithFunctionBody : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute ArrowExpressionContentsWithFunctionBody contents;
};
interface LazyArrowExpressionWithFunctionBody : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute ArrowExpressionContentsWithFunctionBody contents;
};
interface EagerArrowExpressionWithExpression : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
attribute ArrowExpressionContentsWithExpression contents;
};
interface LazyArrowExpressionWithExpression : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
[Lazy] attribute ArrowExpressionContentsWithExpression contents;
};
interface ArrowExpressionContentsWithFunctionBody : Node {
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
interface ArrowExpressionContentsWithExpression : Node {
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute Expression body;
};
// `AssignmentExpression :: LeftHandSideExpression = AssignmentExpression`
interface AssignmentExpression : Node {
// The `LeftHandSideExpression`.
attribute AssignmentTarget binding;
// The `AssignmentExpression` following the `=`.
attribute Expression expression;
};
// `ExponentiationExpression`,
// `MultiplicativeExpression`,
// `AdditiveExpression`,
// `ShiftExpression`,
// `RelationalExpression`,
// `EqualityExpression`,
// `BitwiseANDExpression`,
// `BitwiseXORExpression`,
// `BitwiseORExpression`,
// `LogicalANDExpression`,
// `LogicalORExpression`
interface BinaryExpression : Node {
attribute BinaryOperator operator;
// The expression before the operator.
attribute Expression left;
// The expression after the operator.
attribute Expression right;
};
interface CallExpression : Node {
attribute (Expression or Super) callee;
attribute Arguments arguments;
};
// `AssignmentExpression :: LeftHandSideExpression AssignmentOperator AssignmentExpression`
interface CompoundAssignmentExpression : Node {
attribute CompoundAssignmentOperator operator;
// The `LeftHandSideExpression`.
attribute SimpleAssignmentTarget binding;
// The `AssignmentExpression`.
attribute Expression expression;
};
interface ComputedMemberExpression : Node {
// The object whose property is being accessed.
attribute (Expression or Super) _object;
// The expression resolving to the name of the property to be accessed.
attribute Expression expression;
};
// `ConditionalExpression :: LogicalORExpression ? AssignmentExpression : AssignmentExpression`
interface ConditionalExpression : Node {
// The `LogicalORExpression`.
attribute Expression test;
// The first `AssignmentExpression`.
attribute Expression consequent;
// The second `AssignmentExpression`.
attribute Expression alternate;
};
// `FunctionExpression`,
// `GeneratorExpression`,
// `AsyncFunctionExpression`,
interface EagerFunctionExpression : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier? name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute FunctionExpressionContents contents;
};
interface LazyFunctionExpression : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier? name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute FunctionExpressionContents contents;
};
interface FunctionExpressionContents : Node {
attribute boolean isFunctionNameCaptured;
attribute boolean isThisCaptured;
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
// `IdentifierReference`
interface IdentifierExpression : Node {
attribute Identifier name;
};
interface NewExpression : Node {
attribute Expression callee;
attribute Arguments arguments;
};
interface NewTargetExpression : Node { };
interface ObjectExpression : Node {
attribute FrozenArray<ObjectProperty> properties;
};
interface UnaryExpression : Node {
attribute UnaryOperator operator;
attribute Expression operand;
};
interface StaticMemberExpression : Node {
// The object whose property is being accessed.
attribute (Expression or Super) _object;
// The name of the property to be accessed.
attribute IdentifierName property;
};
// `TemplateLiteral`,
// `MemberExpression :: MemberExpression TemplateLiteral`,
// `CallExpression : CallExpression TemplateLiteral`
interface TemplateExpression : Node {
// The second `MemberExpression` or `CallExpression`, if present.
attribute Expression? tag;
// The contents of the template. This list must be alternating
// TemplateElements and Expressions, beginning and ending with
// TemplateElement.
attribute FrozenArray<(Expression or TemplateElement)> elements;
};
// `PrimaryExpression :: this`
interface ThisExpression : Node { };
// `UpdateExpression :: LeftHandSideExpression ++`,
// `UpdateExpression :: LeftHandSideExpression --`,
// `UpdateExpression :: ++ LeftHandSideExpression`,
// `UpdateExpression :: -- LeftHandSideExpression`
interface UpdateExpression : Node {
// True for `UpdateExpression :: ++ LeftHandSideExpression` and
// `UpdateExpression :: -- LeftHandSideExpression`, false otherwise.
attribute boolean isPrefix;
attribute UpdateOperator operator;
attribute SimpleAssignmentTarget operand;
};
// `YieldExpression :: yield`,
// `YieldExpression :: yield AssignmentExpression`
interface YieldExpression : Node {
// The `AssignmentExpression`, if present.
attribute Expression? expression;
};
// `YieldExpression :: yield * AssignmentExpression`
interface YieldStarExpression : Node {
attribute Expression expression;
};
interface AwaitExpression : Node {
attribute Expression expression;
};
// other statements
interface BreakStatement : Node {
attribute Label? label;
};
interface ContinueStatement : Node {
attribute Label? label;
};
interface DebuggerStatement : Node { };
interface DoWhileStatement : Node {
attribute Expression test;
attribute Statement body;
};
interface EmptyStatement : Node { };
interface ExpressionStatement : Node {
attribute Expression expression;
};
interface ForInOfBinding : Node {
attribute VariableDeclarationKind kind;
attribute Binding binding;
};
// `for ( LeftHandSideExpression in Expression ) Statement`,
// `for ( var ForBinding in Expression ) Statement`,
// `for ( ForDeclaration in Expression ) Statement`,
// `for ( var BindingIdentifier Initializer in Expression ) Statement`
interface ForInStatement : Node {
// The expression or declaration before `in`.
attribute (ForInOfBinding or AssignmentTarget) left;
// The expression after `in`.
attribute Expression right;
attribute Statement body;
};
// `for ( LeftHandSideExpression of Expression ) Statement`,
// `for ( var ForBinding of Expression ) Statement`,
// `for ( ForDeclaration of Expression ) Statement`
interface ForOfStatement : Node {
// The expression or declaration before `of`.
attribute (ForInOfBinding or AssignmentTarget) left;
// The expression after `of`.
attribute Expression right;
attribute Statement body;
};
// `for ( Expression ; Expression ; Expression ) Statement`,
// `for ( var VariableDeclarationList ; Expression ; Expression ) Statement`
interface ForStatement : Node {
// The expression or declaration before the first `;`, if present.
attribute (VariableDeclaration or Expression)? init;
// The expression before the second `;`, if present
attribute Expression? test;
// The expression after the second `;`, if present
attribute Expression? update;
attribute Statement body;
};
// `if ( Expression ) Statement`,
// `if ( Expression ) Statement else Statement`,
interface IfStatement : Node {
attribute Expression test;
// The first `Statement`.
attribute Statement consequent;
// The second `Statement`, if present.
attribute Statement? alternate;
};
interface LabelledStatement : Node {
attribute Label label;
attribute Statement body;
};
interface ReturnStatement : Node {
attribute Expression? expression;
};
// A `SwitchStatement` whose `CaseBlock` is
// `CaseBlock :: { CaseClauses }`.
interface SwitchStatement : Node {
attribute Expression discriminant;
attribute FrozenArray<SwitchCase> cases;
};
// A `SwitchStatement` whose `CaseBlock` is
// `CaseBlock :: { CaseClauses DefaultClause CaseClauses }`.
interface SwitchStatementWithDefault : Node {
attribute Expression discriminant;
// The `CaseClauses` before the `DefaultClause`.
attribute FrozenArray<SwitchCase> preDefaultCases;
// The `DefaultClause`.
attribute SwitchDefault defaultCase;
// The `CaseClauses` after the `DefaultClause`.
attribute FrozenArray<SwitchCase> postDefaultCases;
};
interface ThrowStatement : Node {
attribute Expression expression;
};
// `TryStatement :: try Block Catch`
interface TryCatchStatement : Node {
attribute Block body;
attribute CatchClause catchClause;
};
// `TryStatement :: try Block Finally`,
// `TryStatement :: try Block Catch Finally`
interface TryFinallyStatement : Node {
// The `Block`.
attribute Block body;
// The `Catch`, if present.
attribute CatchClause? catchClause;
// The `Finally`.
attribute Block finalizer;
};
interface WhileStatement : Node {
attribute Expression test;
attribute Statement body;
};
interface WithStatement : Node {
attribute Expression _object;
attribute Statement body;
};
// other nodes
interface Block : Node {
attribute AssertedBlockScope scope;
attribute FrozenArray<Statement> statements;
};
// `Catch`
interface CatchClause : Node {
attribute AssertedBoundNamesScope bindingScope;
attribute Binding binding;
attribute Block body;
};
// An item in a `DirectivePrologue`
interface Directive : Node {
attribute string rawValue;
};
interface FormalParameters : Node {
attribute FrozenArray<Parameter> items;
attribute Binding? rest;
};
typedef FrozenArray<Statement> FunctionBody;
// `FunctionDeclaration`,
// `GeneratorDeclaration`,
// `AsyncFunctionDeclaration`
interface EagerFunctionDeclaration : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute FunctionOrMethodContents contents;
};
interface LazyFunctionDeclaration : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute FunctionOrMethodContents contents;
};
interface FunctionOrMethodContents : Node {
attribute boolean isThisCaptured;
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
interface Script : Node {
attribute AssertedScriptGlobalScope scope;
attribute FrozenArray<Directive> directives;
attribute FrozenArray<Statement> statements;
};
interface SpreadElement : Node {
attribute Expression expression;
};
// `super`
interface Super : Node { };
// `CaseClause`
interface SwitchCase : Node {
attribute Expression test;
attribute FrozenArray<Statement> consequent;
};
// `DefaultClause`
interface SwitchDefault : Node {
attribute FrozenArray<Statement> consequent;
};
// `TemplateCharacters`
interface TemplateElement : Node {
attribute string rawValue;
};
interface VariableDeclaration : Node {
attribute VariableDeclarationKind kind;
[NonEmpty] attribute FrozenArray<VariableDeclarator> declarators;
};
interface VariableDeclarator : Node {
attribute Binding binding;
attribute Expression? init;
};
The
A Parse Node may be tagged as being transformed by a
The current asserted scope is used to track asserted scopes during transformation of binary AST Nodes.
The naming convention of the
Bar and returns Parse Nodes of varying ECMAScript grammar productions.Statement.Block, thenIterationStatement, thenFrozenArray<Statement>.FunctionDeclaration, thenExpressionStatement and stmt.expression is a LiteralStringExpression:.expression).FrozenArray<VariableDeclarator>..binding)..init is .binding is not a BindingIdentifier, throw a .init).FrozenArray<VariableDeclarator>..binding)..init is .binding is not a BindingIdentifier, throw a .init).FrozenArray<SpreadElement or Expression>..expression).FrozenArray<Parameter>.Arguments.SpreadElement, then.expression).FrozenArray<ObjectProperty> or a `FrozenArray<AssignmentTargetProperty>.MethodDefinition, then let n be SwitchCase..consequent has length 0, then.consequent).SwitchDefault..consequent has length 0, thenFrozenArray<SwitchCase>.Arguments..arguments).Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.ThisExpression, then return ? IdentifierExpression, a Literal, an ArrayExpression, an ObjectExpression, a FunctionExpression, a ClassExpression, a LiteralRegExpExpression, a TemplateExpression, an AssignmentTargetIdentifier, an ArrayAssignmentExpression, or an ObjectAssignmentExpression, then return Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.ComputedMemberExpression, a StaticMemberExpression, a NewTargetExpression, a NewExpression, a ComputedMemberAssignmentTarget, or a StaticMemberAssignmentTarget, then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.NewExpression, thenCallExpression, then return Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.UpdateExpression, then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.UnaryExpression, then return ? AwaitExpression, thenExpression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "||", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "|", "/", or "%", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "+" or "-", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "<<", ">>", or ">>>", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "<", ">", "<=", ">=", "instanceof", or "in", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "==", "!=", "===", or "!==", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "&", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "^", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "|", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "&&", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is "||", then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.ConditionalExpression, then return ? Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.AssignmentExpression, a CompoundAssignmentExpression, or an AssignmentTargetWithInitializer, then return ? YieldExpression or an ArrowExpression, then return Expression, an AssignmentTarget, or an AssignmentTargetWithInitializer.BinaryExpression and e.operator is ",", then return ? LazyFunctionDeclaration, a LazyFunctionExpression, a LazyMethod, a LazyGetter, a LazySetter, or a LazyArrowExpression, then return.LazyFunctionExpression, then return..contents.isFunctionNameCaptured is FormalParameters is evaluated at runtime, LazyFunctionDeclaration, a LazyFunctionExpression, or a LazyMethod, then.contents.params..contents.parameterScope.FormalParameters.FormalParameters is evaluated at runtime, LazyArrowExpression, then.content.params..content.parameterScope.FormalParameters.Parameter is evaluated at runtime, LazySetter, then.contents.param..contents.parameterScope.Parameter.LazyFunctionDeclaration, a LazyFunctionExpression, a LazyMethod, a LazyGetter, a LazySetter, or a LazyArrowExpression, then.contents..bodyScope.ArrowExpressionContents, then perform ? Identifier or an IdentifierName.Label."yield", then return "await", then return Expression.FrozenArray<BindingProperty>.FrozenArray<(Binding or BindingWithInitializer)>.Binding or BindingWithInitializer.BindingWithInitializer, then return elem0.BindingIdentifier, thenBinding.BindingPattern, then let restElem0 be Script..scope..scope, enclosingScope)..directives prepended to s.statements..directives has length 0 and s.statements has length 0, then.directives concatenated with s.statements..scope, script).Module.FormalParameters is evaluated.FormalParameters..items has length 0, then.rest is null, then return .rest)..items)..rest is null, then return .rest).FormalParameters is evaluated.FormalParameters.Parameter.FunctionBody is evaluated.FunctionDeclaration, a FunctionExpression, a Method, a Getter, a Setter, or a ArrowExpression..contents.body is a FunctionBody, thenArrowExpression and f.directives is .directives concatenated with f.contents.body..contents.body is an Expression..directives is not .contents.body) Block..scope..scope, enclosingScope)..statements)..scope, block).Directive..rawValue escaped for double quotes.BreakStatement..label is .label) ContinueStatement..label is .label) ClassDeclaration.DebuggerStatement.EmptyStatement.ExpressionStatement..expression) EagerFunctionDeclaration or a LazyFunctionDeclaration..name)..isAsync is .isGenerator is *IfStatement..test)..consequent)..alternate is .alternate).
DoWhileStatement..test)..body).ForInStatement..right)..body)..left is a ForInOfBinding, then.left.kind is "var", then.left.binding)..left)..left).ForOfStatement..right)..body)..left is a ForInOfBinding, then.left.kind is "var", then.left.binding)..left)..left).ForStatement..test is not null, then set test to ? .test)..update is not null, then set update to ? ExperssionEcmaify(for.test)..body)..init is not .init is a VariableDeclaration, then.init.kind is "var", then.init.declarators)..init.kind) ? .init.declarators)..init).WhileStatement..test)..body).LabelledStatement..body is a FunctionDeclaration, then.body.isAsync is true or labelled.body.isGenerator is .body)..body)..label) ReturnStatement..expression is .expression).
SwitchStatement..discriminant)..cases has length 0, then set block to .cases).SwitchStatementWithDefault..discriminant)..defaultCase)..preDefaultCases has length 0, then.postDefaultCases has length 0, then.postDefaultCases)..postDefaultCases has length 0, then.preDefaultCases)..preDefaultCases)..postDefaultCases).ThrowStatement..expression).
TryCatchStatement..body)..catchClause).TryFinallyStatement..body)..finalizer)..catch is .catchClause).VariableDeclaration..kind is "var", then.declarators)..kind)..declarators).WithStatement.._object)..body).LiteralBooleanExpression..value is Infinity identifier, but for literal decimals whose mathematical values exceed the bounds of IEEE doubles.LiteralInfinityExpresion.LiteralNullExpression.LiteralNumericExpression..value.LiteralRegExpExpression..pattern..flags.LiteralStringExpression..value escaped for double quotes.ArrayExpression or an ArrayAssignmentTarget.ArrayAssignmentTarget directly to .elements has length 0, then.elements).EagerArrowExpression or a LazyArrowExpression..isAsync is AssignmentExpression..binding)..expression).BinaryExpression..operator is ",", then.left)..right)..operator is "||", then.left)..right)..operator is "&&", then.left)..right)..operator is "|", then.left)..right).|.operator is "^", then.left)..right)..operator is "&", then.left)..right)..operator is "==", "!=", "===", or "!==", then.left)..right)..operator is "==", then return .operator is "!=", then return .operator is "===", then return .operator is "<", ">", "<=", ">=", "instanceof", or "in", then.left)..right)..operator is "<" return .operator is ">", then return .operator is "<=" return .operator is ">=", then return .operator is "instanceof", then return .operator is "<<", ">>", or ">>>", then.left)..right)..operator is "<<", then return .operator is ">>", then return .operator is "+" or "-", then.left)..right)..operator is "+", then return .operator is "*", "/", or "%", then.left)..right)..operator is "*", then set op to *.operator is "/", then set op to .operator is "%", then set op to .left)..right).**CallExpression..arguments).Super, then.callee).CompoundAssignmentExpression..binding).expression)..operator is "|=" then set op to .operator is "/=" then set op to .operator is "%=" then set op to .operator is "+=" then set op to .operator is "-=" then set op to .operator is "<<=" then set op to .operator is ">>=" then set op to .operator is ">>>=" then set op to .operator is "&=" then set op to .operator is "^=" then set op to .operator is "|=" then set op to ComputedMemberExpression or a ComputedMemberAssignmentTarget..expression).._object is a Super, then._object).ConditionalExpression..test)..consequent)..alternate).ClassExpression.EagerFunctionExpression or a LazyFunctionExpression..name not .name)..isAsync is .isGenerator is *IdentifierExpression..name is "yield", then return .name is "await", then return .name).
NewExpression..callee)..arguments).NewTargetExpression.ObjectExpression or an ObjectAssignmentTarget.ObjectAssignmentTarget directly to .properties has length 0, then return .properties).UnaryExpression..operand)..operator is "delete", then return .operator is "void", then return .operator is "typeof", then return .operator is "+", then return .operator is "-", then return .operator is "StaticMemberExpression or a StaticMemberAssignmentTarget.._object is a Super, then.property.._object)..property.
TemplateExpression.ThisExpression.UpdateExpression..isPrefix is .operand)..operator is "++", then return .operand)..operator is "++", then return YieldExpression..expression is null, then.expression).YieldStarExpression..expression).*AwaitExpression..expression).ComputedPropertyName..expression).LiteralPropertyName..value is the empty string, then throw a .value escaped for double quotes.EagerMethod or a LazyMethod..name)..isAsync is .isGenerator is *EagerGetter or a LazyGetter..name).EagerSetter or a LazySetter..name)..param).DataProperty..name)..expression).ShorthandProperty..name).BindingIdentifier..name is "yield", then return .name is "await", then return .name).
ObjectBinding..properties has length 0, then return .properties) BindingPropertyIdentifier..binding)..init is not .init).BindingPropertyProperty..name).ArrayBinding..elements has length 0, then.rest is .rest)..elements)..rest is .rest)..rest is .rest).BindingWithInitializer..binding)..init)..binding is a BindingIdentifier, thenAssignmentTargetWithInitializer..binding)..init).AssignmentTargetPropertyIdentifier..binding.name)..init is not .init).AssignmentTargetPropertyProperty..name)..binding).ForInOfBinding..kind is not "var"..binding)..kind) binding.
Parameter.CatchClause..bindingScope..bindingScope, enclosingScope)..binding)..body)..bindingScope, catch)."let" or "const"."let", then return Node.Block, then return ? BreakStatement, then return ? ContinueStatement, then return ? ClassDeclaration, then return ? DebuggerStatement, then return ? EmptyStatement, then return ? ExpressionStatement, then return ? FunctionDeclaration, then return ? IfStatement, then return ? DoWhileStatement, then return ? ForInStatement, then return ? ForOfStatement, then return ? ForStatement, then return ? WhileStatement, then return ? LabelledStatement, then return ? ReturnStatement, then return ? SwitchStatement, then return ? SwitchStatementWithDefault, then return ? ThrowStatement, then return ? TryCatchStatement, then return ? TryFinallyStatement, then return ? VariableDeclaration, then return ? WithStatement, then return ? LiteralBooleanExpression, then return ? LiteralInfinityExpression, then return ? LiteralNullExpression, then return ? LiteralNumericExpression, then return ? LiteralStringExpression, then return ? LiteralRegExpExpression, then return ? ArrayExpression, then return ? ArrowExpression, then return ? AssignmentExpression, then return ? BinaryExpression, then return ? CallExpression, then return ? CompoundAssignmentExpression, then return ? ComputedMemberExpression, then return ? ConditionalExpression, then return ? ClassExpression, then return ? FunctionExpression, then return ? IdentifierExpression, then return ? NewExpression, then return ? NewTargetExpression, then return ? ObjectExpression, then return ? UnaryExpression, then return ? StaticMemberExpression, then return ? TemplateExpression, then return ? ThisExpression, then return ? UpdateExpression, then return ? YieldExpression, then return ? YieldStarExpression, then return ? AwaitExpression, then return ? ComputedPropertyName, then return ? LiteralPropertyName, then return ? LiteralPropertyName, then return ? Method, then return ? Getter, then return ? Setter, then return ? DataProperty, then return ? ShorthandProperty, then return ? ExportAllFrom, then return ? EcmaifyExportAllFrom(node).ExportFrom, then return ? EcmaifyExportFrom(node).ExportLocals, then return ? EcmaifyExportLocals(node).ExportDefault, then return ? EcmaifyExportDefault(node).ExportFromSpecifier, then return ? EcmaifyExportFromSpecifier(node).ExportLocalSpecifier, then return ? EcmaifyExportLocalSpecifier(node).Export, then return ? EcmaifyExport(node).ImportSpecifier, then return ? EcmaifyImportSpecifier(node).ImportNamespace, then return ? EcmaifyImportNamespace(node).Import, then return ? EcmaifyImport(node).BindingIdentifier, then return ? ObjectBinding, then return ? BindingPropertyIdentifier, then return ? BindingPropertyProperty, then return ? ArrayBinding, then return ? BindingWithInitializer, then return ? AssignmentTarget nodes are transformed as expressions instead of the cover grammar variant as the ECMAScript spec does reparsing.AssignmentTargetIdentifier, then return ? EcmaifyAssignmentTargetIdentifierExpression(node).AssignmentTargetWithInitializer, then return ? ComputedMemberAssignmentTarget, then return ? StaticMemberAssignmentTarget, then return ? ObjectAssignmentTarget, then return ? AssignmentTargetPropertyIdentifier, then return ? AssignmentTargetPropertyProperty, then return ? ArrayAssignmentTarget, then return ? ClassElement, then return ? EcmaifyClassElement(node).ForInOfBinding, then return ? Binary AST is evaluated via the modified
Evaluation of binary AST is possibly lazy at function boundaries. Together with AssertedScope, the intent is to allow implementations to start to start code generation without parsing the entire tree. AssertedScope represent assertions that must be checked. A failing assertion throws a
Asserted declared names must match exactly the set of actual declared names exactly in the scope. The asserted captured names in the scope must be a superset of observed captured names. If the presence of
The GlobalAssertedScopeTree is a
| Field Name | Value | Meaning |
|---|---|---|
| [[AssertedScope]] |
An AssertedBlockScope, AssertedScriptGlobalScope, AssertedVarScope, AssertedParameterScope, or AssertedBoundNamesScope
|
The payload. |
| [[Enclosing]] |
An AssertedScopeTreeNode |
The directly enclosing scope. |
.kind is kind, then add d.name as the last element of unseen..name as the last element of expectedParams.[idx] is not pn, then throw a AssertedPositionalParameterName, then.name and item.[[Index]] is p.index, thenAssertedRestParameterName, then.name, then.name as the last element of unseen.AssertedBlockScope or an AssertedScriptGlobalScope or an AssertedVarScope or an AssertedParameterScope or an AssertedBoundNamesScope.AssertedBlockScope or an AssertedScriptGlobalScope or an AssertedVarScope, then.declaredNames, "var", varDeclaredNames)..declaredNames, "const lexical", constLexicallyDeclaredNames)..declaredNames, "non-const lexical", nonConstLexicallyDeclaredNames).AssertedParameterScope, then.paramNames, paramNames)..paramNames, positionalParamNames)..paramNames, restParameterName)..isSimpleParameterList is not the same value as IsSimpleParameterList of parseTree, then throw a .boundNames, boundNames).AssertedBlockScope or an AssertedScriptGlobalScope or an AssertedVarScope, then.declaredNames.AssertedParameterScope, then,.paramNames..boundNames..name, then.isCaptured is AssertedScriptGlobalScope, then throw a .hasDirectEval is AssertedVarScope or an AssertedParameterScope.AssertedBlockScope, then.declaredNames has a single item d and d.name is "this", then.isCaptured is this binding captured by a nested arrow. Synthesize a scope that encloses the parameter and body scopes of the function body that contains the sole binding this. It is checked by EagerArrowExpression nor a LazyArrowExpression.AssertedBlockScope.AssertedDeclaredName..name to "this"..kind to "non-const lexical"..contents.isThisCaptured is .isCaptured to .declaredNames to be a new FrozenArray<AssertedDeclaredName> of length 1 containing thisDecl..hasDirectEval to enclosingScope.hasDirectEval.AssertedBlockScope.AssertedDeclaredName..name to funcExprNode.name.const, but it does not matter for the semantics of asserted scopes..kind to "const lexical"..isCaptured to .declaredNames to be a new FrozenArray<AssertedDeclaredName> of length 1 containing namedLambdaDecl..hasDirectEval to enclosingScope.hasDirectEval.FunctionDeclaration, a FunctionExpression, a Method, a Getter, a Setter, or an ArrowExpression.Getter, then.length.FreeNames is a new Static Semantics that collects uses of unbound variables.
Unless overridden, Parse Nodes have the following default definition.
"yield" ».
"await" ».
HasFreeThis is a new Static Semantics that returns this is free in the Parse Node (i.e. either used directly or in a nested arrow expression).
Unless overridden, Parse Nodes have the following default definition.
Collect the positional formal parameter names.
With parameters formalParameters.
"yield".
"await".
Return the rest parameter name.
With parameters formalParameters.
"yield".
"await".
When FormalParameters is tagged as being produced by lazyNode.
.length.
The abstract operation RunJobs is modified as follows.
Script ASTs, and/or ECMAScript Module ASTs. For each such Script, then"ScriptJobs", Module,"ScriptJobs", The abstract operation ScriptEvaluationJob is modified as follows.
Script (see TransformASTScript is a new abstract operation.
FunctionDeclaration, then.name)..isAsync is .isGenerator is *ArrowExpression, then.isAsync is FunctionExpression, then.name not .name)..isAsync is .isGenerator is *Method, then.name)..isAsync is .isGenerator is *Getter, then.name).Setter..name).Delazify is a new Runtime Semantics.
With parameter functionObject.
LazyFunctionDeclaration, a LazyFunctionExpression, a LazyMethod, a LazyGetter, a LazySetter, or a LazyArrowExpression..contents.LazyFunctionExpression, funcNode.name is not .isFunctionNameCaptured is LazyArrowExpression, thenLazyGetter, then.parameterScope, scope)..parameterScope..bodyScope, scope)..bodyScope.LazyGetter, then perform ? .parameterScope, delazifiedParams)..bodyScope, delazifiedBody).LazyArrowExpression, then.parameterScope, delazifiedParams)..bodyScope, delazifiedBody)..contents.parameterScope..contents.params)..contents.parameterScope..contents.params)..contents.parameterScope..contents.param).The runtime semantics of
With parameters functionObject and
"%GeneratorPrototype%", « [[GeneratorState]], [[GeneratorContext]] »).© 2018 Shu-yu Guo, David Teller, Ecma International
All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.