This document specifies the extensions to the core ESTree AST types to support the ES2020 grammar.

# Literal

```js
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

```js
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

## ChainExpression

```js
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`.

<details><summary>For Examples:</summary>

```jsonc
// 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" }
}
```

```jsonc
// 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" }
  }
}
```

```jsonc
// 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" }
  }
}
```

```jsonc
// 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" }
  }
}
```

```jsonc
// (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" }
}
```

```jsonc
// (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" }
  }
}
```

```jsonc
// (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" }
}
```

```jsonc
// (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" }
  }
}
```

</details>

## ImportExpression

```js
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

```js
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

```js
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";`.

[ImportDeclaration]: es2015.md#importdeclaration
[MetaProperty]: es2015.md#metaproperty
[Nullish Coalescing]: https://github.com/tc39/proposal-nullish-coalescing
