Skip to content

Latest commit

 

History

History
238 lines (203 loc) · 5.87 KB

es2020.md

File metadata and controls

238 lines (203 loc) · 5.87 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 must contain only decimal digits and not include numeric separators (_) or 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

ChainExpression

interface ChainExpression <: Expression {
  type: "ChainExpression";
  expression: ChainElement;
}

interface ChainElement <: Node {
  optional: boolean;
}

extend interface CallExpression <: ChainElement {}

extend interface MemberExpression <: ChainElement {}
  • The ChainExpression node is the root of optional chaining.
  • The ChainExpression node contains one or more ChainElement nodes that are optional:true. On the other hand, ChainElement nodes that are optional:true belong to a ChainExpression node.
  • For backward compatibility, if all ChainElement nodes of a chain are optional:false, the ChainExpression node isn't inserted as the root of the chain.
  • Evaluation:
    • The ChainExpression node is evaluated to the result of the expression property's node.
    • If the callee|object property is evaluated to nullish and the optional property is true, then the node and ancestor nodes are skipped until the closest ChainExpression node, and the result of the ChainExpression node becomes undefined.
For Examples:
// obj.aaa.bbb
{
  "type": "MemberExpression",
  "optional": false,
  "object": {
    "type": "MemberExpression",
    "optional": false,
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" }
  },
  "property": { "type": "Identifier", "name": "bbb" }
}
// obj.aaa?.bbb
{
  "type": "ChainExpression",
  "expression": {
    "type": "MemberExpression",
    "optional": true,
    "object": {
      "type": "MemberExpression",
      "optional": false,
      "object": { "type": "Identifier", "name": "obj" },
      "property": { "type": "Identifier", "name": "aaa" }
    },
    "property": { "type": "Identifier", "name": "bbb" }
  }
}
// obj?.aaa.bbb
{
  "type": "ChainExpression",
  "expression": {
    "type": "MemberExpression",
    "optional": false,
    "object": {
      "type": "MemberExpression",
      "optional": true,
      "object": { "type": "Identifier", "name": "obj" },
      "property": { "type": "Identifier", "name": "aaa" }
    },
    "property": { "type": "Identifier", "name": "bbb" }
  }
}
// obj?.aaa?.bbb
{
  "type": "ChainExpression",
  "expression": {
    "type": "MemberExpression",
    "optional": true,
    "object": {
      "type": "MemberExpression",
      "optional": true,
      "object": { "type": "Identifier", "name": "obj" },
      "property": { "type": "Identifier", "name": "aaa" }
    },
    "property": { "type": "Identifier", "name": "bbb" }
  }
}
// (obj.aaa).bbb
{
  "type": "MemberExpression",
  "optional": false,
  "object": {
    "type": "MemberExpression",
    "optional": false,
    "object": { "type": "Identifier", "name": "obj" },
    "property": { "type": "Identifier", "name": "aaa" }
  },
  "property": { "type": "Identifier", "name": "bbb" }
}
// (obj.aaa)?.bbb
{
  "type": "ChainExpression",
  "expression": {
    "type": "MemberExpression",
    "optional": true,
    "object": {
      "type": "MemberExpression",
      "optional": false,
      "object": { "type": "Identifier", "name": "obj" },
      "property": { "type": "Identifier", "name": "aaa" }
    },
    "property": { "type": "Identifier", "name": "bbb" }
  }
}
// (obj?.aaa).bbb
{
  "type": "MemberExpression",
  "optional": false,
  "object": {
    "type": "ChainExpression",
    "expression": {
      "type": "MemberExpression",
      "optional": true,
      "object": { "type": "Identifier", "name": "obj" },
      "property": { "type": "Identifier", "name": "aaa" }
    }
  },
  "property": { "type": "Identifier", "name": "bbb" }
}
// (obj?.aaa)?.bbb
{
  "type": "ChainExpression",
  "expression": {
    "type": "MemberExpression",
    "optional": true,
    "object": {
      "type": "ChainExpression",
      "expression": {
        "type": "MemberExpression",
        "optional": true,
        "object": { "type": "Identifier", "name": "obj" },
        "property": { "type": "Identifier", "name": "aaa" }
      }
    },
    "property": { "type": "Identifier", "name": "bbb" }
  }
}

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.

MetaProperty

Existing MetaProperty node represents import.meta meta property as well.

Modules

ExportAllDeclaration

extend interface ExportAllDeclaration {
  exported: Identifier | null;
}

The exported property contains an Identifier when a different exported name is specified using as, e.g., export * as foo from "mod";.