Skip to content

Latest commit

 

History

History
284 lines (251 loc) · 9.09 KB

es2020.md

File metadata and controls

284 lines (251 loc) · 9.09 KB

This document specifies the extensions to the core ESTree AST types to support the ES2020 grammar.

Literal

extend interface Literal <: Expression {
    type: "Literal";
    value: string | boolean | null | number | RegExp | bigint;
}
  • value property can be a BigInt value to represent BigInt literals such as 100n.

BigIntLiteral

interface BigIntLiteral <: Literal {
  bigint: string;
}
  • bigint property is the string representation of the BigInt value. It doesn't include the suffix n.
  • In environments that don't support BigInt values, value property will be null as the BigInt value can't be represented natively.

Expressions

ImportExpression

interface ImportExpression <: Expression {
  type: "ImportExpression";
  source: Expression;
}
  • ImportExpression node represents Dynamic Imports such as import(source). The source property is the importing source as similar to ImportDeclaration node, but it can be an arbitrary expression node.

LogicalExpression

extend enum LogicalOperator {
    "||" | "&&" | "??"
}
  • The operator property of the LogicalExpression node can be "??" to represent Nullish Coalescing syntax.

OptionalChainLink

interface OptionalChainLink {
  optional: boolean;
  shortCircuited: boolean;
}

extend interface MemberExpression <: OptionalChainLink {}
extend interface CallExpression <: OptionalChainLink {}
  • The OptionalChainLink interface represents Optional Chaining syntax. This is just an interface rather than a Node.
    • The optional property represents if it's optional by ?..
    • The shortCircuited property represents if it's short-circuited by preceded optional member|call expressions.
  • The existing MemberExpression and CallExpression nodes inherit the OptionalChainLink interface to represent that those are the links of optional chaining.
For examples:
// obj?.aaa?.bbb
{
  "type": "MemberExpression",
  "optional": true,     // If `obj.aaa` was nullish, this node is evaluated to undefined.
  "shortCircuited": true, // If `obj` was nullish, this node is short-circuited.
  "object": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// obj?.aaa.bbb
{
  "type": "MemberExpression",
  "optional": false,    // If `obj.aaa` was nullish, this node is evaluated to throwing TypeError.
  "shortCircuited": true, // If `obj` was nullish, this node is short-circuited.
  "object": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// (obj?.aaa)?.bbb
{
  "type": "MemberExpression",
  "optional": true,      // If `obj.aaa` was nullish, this node is evaluated to undefined.
  "shortCircuited": false, // This node isn't short-circuited.
  "object": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// (obj?.aaa).bbb
{
  "type": "MemberExpression",
  "optional": false,     // If `obj.aaa` was nullish, this node is evaluated to throwing TypeError.
  "shortCircuited": false, // This node isn't short-circuited.
  "object": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// func?.()?.bbb
{
  "type": "MemberExpression",
  "optional": true,     // If the result of `func()` was nullish, this node is evaluated to undefined.
  "shortCircuited": true, // If `func` was nullish, this node is short-circuited.
  "object": {
    "type": "CallExpression",
    "optional": true,      // If `func` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "callee": { "type": "Identifier", "name": "func" },
    "arguments": [],
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// func?.().bbb
{
  "type": "MemberExpression",
  "optional": false,    // If the result of `func()` was nullish, this node is evaluated to throwing TypeError.
  "shortCircuited": true, // If `func` was nullish, this node is short-circuited.
  "object": {
    "type": "CallExpression",
    "optional": true,      // If `func` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "callee": { "type": "Identifier", "name": "func" },
    "arguments": [],
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// (func?.())?.bbb
{
  "type": "MemberExpression",
  "optional": true,      // If the result of `func()` was nullish, this node is evaluated to undefined.
  "shortCircuited": false, // This node isn't short-circuited.
  "object": {
    "type": "CallExpression",
    "optional": true,      // If `func` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "callee": { "type": "Identifier", "name": "func" },
    "arguments": [],
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// (func?.()).bbb
{
  "type": "MemberExpression",
  "optional": false,     // If the result of `func()` was nullish, this node is evaluated to throwing TypeError.
  "shortCircuited": false, // This node isn't short-circuited.
  "object": {
    "type": "CallExpression",
    "optional": true,      // If `func` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "callee": { "type": "Identifier", "name": "func" },
    "arguments": [],
  },
  "property": { "type": "Identifier", "name": "bbb" },
}
// obj?.aaa?.()
{
  "type": "CallExpression",
  "optional": true,     // If `obj.aaa` was nullish, this node is evaluated to undefined.
  "shortCircuited": true, // If `obj` was nullish, this node is short-circuited.
  "callee": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "arguments": [],
}
// obj?.aaa()
{
  "type": "CallExpression",
  "optional": false,    // If `obj.aaa` was nullish, this node is evaluated to throwing TypeError.
  "shortCircuited": true, // If `obj` was nullish, this node is short-circuited.
  "callee": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "arguments": [],
}
// (obj?.aaa)?.()
{
  "type": "CallExpression",
  "optional": true,      // If `obj.aaa` was nullish, this node is evaluated to undefined.
  "shortCircuited": false, // This node isn't short-circuited.
  "callee": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "arguments": [],
}
// (obj?.aaa)()
{
  "type": "CallExpression",
  "optional": false,     // If `obj.aaa` was nullish, this node is evaluated to throwing TypeError.
  "shortCircuited": false, // This node isn't short-circuited.
  "callee": {
    "type": "MemberExpression",
    "optional": true,      // If `obj` was nullish, this node is evaluated to undefined.
    "shortCircuited": false, // This node isn't short-circuited.
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" },
  },
  "arguments": [],
}