This document specifies the extensions to the core ESTree AST types to support the ES2022 grammar.

# Classes

These language extensions cover following class features proposals:
 - [Class Fields]
 - [Static Class Features]
 - [Private Methods]
 - [Static Initialization Blocks].

## ClassBody

```js
extend interface ClassBody {
    body: [ MethodDefinition | PropertyDefinition | StaticBlock ];
}
```

## PropertyDefinition

```js
interface PropertyDefinition <: Node {
    type: "PropertyDefinition";
    key: Expression | PrivateIdentifier;
    value: Expression | null;
    computed: boolean;
    static: boolean;
}
```

- When `key` is a `PrivateIdentifier`, `computed` must be `false`.

## MethodDefinition

```js
extend interface MethodDefinition {
    key: Expression | PrivateIdentifier;
}
```

- When `key` is a `PrivateIdentifier`, `computed` must be `false` and `kind` can not be `"constructor"`.

### PrivateIdentifier

```js
interface PrivateIdentifier <: Node {
    type: "PrivateIdentifier";
    name: string;
}
```

A private identifier refers to private class elements. For a private name `#a`, its `name` is `a`.

```js
extend interface MemberExpression {
    property: Expression | PrivateIdentifier;
}
```

- When `property` is a `PrivateIdentifier`, `computed` must be `false`.
- When `object` is a `Super`, `property` can not be a `PrivateIdentifier`.

## StaticBlock

```js
interface StaticBlock <: BlockStatement {
    type: "StaticBlock";
}
```

A static block `static { }` is a block statement serving as an additional static initializer.

## Expressions

### BinaryExpression

```js
extend interface BinaryExpression <: Expression {
    left: Expression | PrivateIdentifier;
}
```

- `left` can be a private identifier (e.g. `#foo`) when `operator` is `"in"`.
- See [Ergonomic brand checks for Private Fields][proposal-private-fields-in-in] for details.

# Modules

See [Arbitrary module namespace identifier names] for more details.

## Imports

### ImportSpecifier

```js
extend interface ImportSpecifier <: ModuleSpecifier {
    imported: Identifier | Literal;
}
```

If `imported` is a `Literal`, `imported.value` must be a string without lone surrogate.

## Exports

### ExportSpecifier

```js
extend interface ExportSpecifier <: ModuleSpecifier {
    local: Identifier | Literal;
    exported: Identifier | Literal;
}
```

`local` can be `Literal` only if the `source` of the `ExportNamedDeclaration` of the parent of this node is not `null`. e.g. `export { "foo" as "foo" } from "mod"` is valid, `export { "foo" as "foo" }` is invalid.

If `exported`/`local` is `Literal`, `exported.value`/`local.value` must be a string without lone surrogate.

### ExportAllDeclaration

```js
extend interface ExportAllDeclaration {
    exported: Identifier | Literal | null;
}
```

If `exported` is `Literal`, `exported.value` must be a string without lone surrogate.

[class fields]: https://github.com/tc39/proposal-class-fields
[static class features]: https://github.com/tc39/proposal-static-class-features/
[private methods]: https://github.com/tc39/proposal-private-methods
[proposal-private-fields-in-in]: https://github.com/tc39/proposal-private-fields-in-in
[static initialization blocks]: https://github.com/tc39/proposal-class-static-block
[arbitrary module namespace identifier names]: https://github.com/tc39/ecma262/pull/2154
