<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
This document specifies the extensions to the [core ESTree AST types](es5.md) to support the ES2015 grammar.

- [Programs](#programs)
- [Functions](#functions)
- [Statements](#statements)
  - [ForOfStatement](#forofstatement)
- [Declarations](#declarations)
  - [VariableDeclaration](#variabledeclaration)
- [Expressions](#expressions)
  - [ArrowFunctionExpression](#arrowfunctionexpression)
  - [YieldExpression](#yieldexpression)
- [Template Literals](#template-literals)
  - [TemplateLiteral](#templateliteral)
  - [TaggedTemplateExpression](#taggedtemplateexpression)
  - [TemplateElement](#templateelement)
- [Patterns](#patterns)
  - [ObjectPattern](#objectpattern)
  - [ArrayPattern](#arraypattern)
  - [RestElement](#restelement)
  - [AssignmentPattern](#assignmentpattern)
- [Classes](#classes)
  - [ClassBody](#classbody)
  - [MethodDefinition](#methoddefinition)
  - [ClassDeclaration](#classdeclaration)
  - [ClassExpression](#classexpression)
  - [MetaProperty](#metaproperty)
- [Modules](#modules)
  - [ModuleDeclaration](#moduledeclaration)
  - [ModuleSpecifier](#modulespecifier)
  - [Imports](#imports)
    - [ImportDeclaration](#importdeclaration)
    - [ImportSpecifier](#importspecifier)
    - [ImportDefaultSpecifier](#importdefaultspecifier)
    - [ImportNamespaceSpecifier](#importnamespacespecifier)
  - [Exports](#exports)
    - [ExportNamedDeclaration](#exportnameddeclaration)
    - [ExportSpecifier](#exportspecifier)
    - [ExportDefaultDeclaration](#exportdefaultdeclaration)
    - [ExportAllDeclaration](#exportalldeclaration)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

# Programs

```js
extend interface Program {
    sourceType: "script" | "module";
    body: [ Statement | ModuleDeclaration ];
}
```

Parsers must specify `sourceType` as `"module"` if the source has been parsed as an ES6 module. Otherwise, `sourceType` must be `"script"`.

# Functions

```js
extend interface Function {
    generator: boolean;
}
```

# Statements

## ForOfStatement

```js
interface ForOfStatement <: ForInStatement {
    type: "ForOfStatement";
}
```

# Declarations

## VariableDeclaration

```js
extend interface VariableDeclaration {
    kind: "var" | "let" | "const";
}
```

# Expressions

```js
interface Super <: Node {
    type: "Super";
}

extend interface CallExpression {
    callee: Expression | Super;
    arguments: [ Expression | SpreadElement ];
}

extend interface MemberExpression {
    object: Expression | Super;
}
```

A `super` pseudo-expression.

```js
interface SpreadElement <: Node {
    type: "SpreadElement";
    argument: Expression;
}

extend interface ArrayExpression {
    elements: [ Expression | SpreadElement | null ];
}

extend interface NewExpression {
    arguments: [ Expression | SpreadElement ];
}
```

Spread expression, e.g., `[head, ...iter, tail]`, `f(head, ...iter, ...tail)`.

**FIXME:** This describes the Esprima and Acorn behaviors, which is not currently aligned with the SpiderMonkey behavior.

```js
extend interface AssignmentExpression {
    left: Pattern;
}
```

Note that pre-ES6 code was allowed [to pass references around](https://github.com/estree/estree/pull/20#issuecomment-74584758) and so `left` was much more liberal; an implementation might choose to continue using [old definition](https://github.com/estree/estree/blob/master/es5.md#assignmentexpression) if it needs to support such legacy code.

```js
extend interface Property {
    key: Expression;
    method: boolean;
    shorthand: boolean;
    computed: boolean;
}
```

## ArrowFunctionExpression

```js
interface ArrowFunctionExpression <: Function, Expression {
    type: "ArrowFunctionExpression";
    body: FunctionBody | Expression;
    expression: boolean;
    generator: false;
}
```

A fat arrow function expression, e.g., `let foo = (bar) => { /* body */ }`.

## YieldExpression

```js
interface YieldExpression <: Expression {
    type: "YieldExpression";
    argument: Expression | null;
    delegate: boolean;
}
```

A `yield` expression.

# Template Literals

## TemplateLiteral

```js
interface TemplateLiteral <: Expression {
    type: "TemplateLiteral";
    quasis: [ TemplateElement ];
    expressions: [ Expression ];
}
```

## TaggedTemplateExpression

```js
interface TaggedTemplateExpression <: Expression {
    type: "TaggedTemplateExpression";
    tag: Expression;
    quasi: TemplateLiteral;
}
```

## TemplateElement

```js
interface TemplateElement <: Node {
    type: "TemplateElement";
    tail: boolean;
    value: {
        cooked: string;
        raw: string;
    };
}
```

# Patterns

## ObjectPattern

```js
interface AssignmentProperty <: Property {
    type: "Property"; // inherited
    value: Pattern;
    kind: "init";
    method: false;
}

interface ObjectPattern <: Pattern {
    type: "ObjectPattern";
    properties: [ AssignmentProperty ];
}
```

## ArrayPattern

```js
interface ArrayPattern <: Pattern {
    type: "ArrayPattern";
    elements: [ Pattern | null ];
}
```

## RestElement

```js
interface RestElement <: Pattern {
    type: "RestElement";
    argument: Pattern;
}
```

## AssignmentPattern

```js
interface AssignmentPattern <: Pattern {
    type: "AssignmentPattern";
    left: Pattern;
    right: Expression;
}
```

# Classes

```js
interface Class <: Node {
    id: Identifier | null;
    superClass: Expression | null;
    body: ClassBody;
}
```

## ClassBody

```js
interface ClassBody <: Node {
    type: "ClassBody";
    body: [ MethodDefinition ];
}
```

## MethodDefinition

```js
interface MethodDefinition <: Node {
    type: "MethodDefinition";
    key: Expression;
    value: FunctionExpression;
    kind: "constructor" | "method" | "get" | "set";
    computed: boolean;
    static: boolean;
}
```

## ClassDeclaration

```js
interface ClassDeclaration <: Class, Declaration {
    type: "ClassDeclaration";
    id: Identifier;
}
```

## ClassExpression

```js
interface ClassExpression <: Class, Expression {
    type: "ClassExpression";
}
```

## MetaProperty

```js
interface MetaProperty <: Expression {
    type: "MetaProperty";
    meta: Identifier;
    property: Identifier;
}
```

- `MetaProperty` node represents `new.target` meta property in ES2015. In the future, it will represent other meta properties as well.

# Modules

## ModuleDeclaration

```js
interface ModuleDeclaration <: Node { }
```

A module `import` or `export` declaration.

## ModuleSpecifier

```js
interface ModuleSpecifier <: Node {
    local: Identifier;
}
```

A specifier in an import or export declaration.

## Imports

### ImportDeclaration

```js
interface ImportDeclaration <: ModuleDeclaration {
    type: "ImportDeclaration";
    specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
    source: Literal;
}
```

An import declaration, e.g., `import foo from "mod";`.

### ImportSpecifier

```js
interface ImportSpecifier <: ModuleSpecifier {
    type: "ImportSpecifier";
    imported: Identifier;
}
```

An imported variable binding, e.g., `{foo}` in `import {foo} from "mod"` or `{foo as bar}` in `import {foo as bar} from "mod"`. The `imported` field refers to the name of the export imported from the module. The `local` field refers to the binding imported into the local module scope. If it is a basic named import, such as in `import {foo} from "mod"`, both `imported` and `local` are equivalent `Identifier` nodes; in this case an `Identifier` node representing `foo`. If it is an aliased import, such as in `import {foo as bar} from "mod"`, the `imported` field is an `Identifier` node representing `foo`, and the `local` field is an `Identifier` node representing `bar`.

### ImportDefaultSpecifier

```js
interface ImportDefaultSpecifier <: ModuleSpecifier {
    type: "ImportDefaultSpecifier";
}
```

A default import specifier, e.g., `foo` in `import foo from "mod.js"`.

### ImportNamespaceSpecifier

```js
interface ImportNamespaceSpecifier <: ModuleSpecifier {
    type: "ImportNamespaceSpecifier";
}
```

A namespace import specifier, e.g., `* as foo` in `import * as foo from "mod.js"`.

## Exports

### ExportNamedDeclaration

```js
interface ExportNamedDeclaration <: ModuleDeclaration {
    type: "ExportNamedDeclaration";
    declaration: Declaration | null;
    specifiers: [ ExportSpecifier ];
    source: Literal | null;
}
```

An export named declaration, e.g., `export {foo, bar};`, `export {foo} from "mod";` or `export var foo = 1;`.

_Note: Having `declaration` populated with non-empty `specifiers` or non-null `source` results in an invalid state._

### ExportSpecifier

```js
interface ExportSpecifier <: ModuleSpecifier {
    type: "ExportSpecifier";
    exported: Identifier;
}
```

An exported variable binding, e.g., `{foo}` in `export {foo}` or `{bar as foo}` in `export {bar as foo}`. The `exported` field refers to the name exported in the module. The `local` field refers to the binding into the local module scope. If it is a basic named export, such as in `export {foo}`, both `exported` and `local` are equivalent `Identifier` nodes; in this case an `Identifier` node representing `foo`. If it is an aliased export, such as in `export {bar as foo}`, the `exported` field is an `Identifier` node representing `foo`, and the `local` field is an `Identifier` node representing `bar`.

### ExportDefaultDeclaration

```js
interface AnonymousDefaultExportedFunctionDeclaration <: Function {
    type: "FunctionDeclaration";
    id: null;
}

interface AnonymousDefaultExportedClassDeclaration <: Class {
    type: "ClassDeclaration";
    id: null;
}

interface ExportDefaultDeclaration <: ModuleDeclaration {
    type: "ExportDefaultDeclaration";
    declaration: AnonymousDefaultExportedFunctionDeclaration | FunctionDeclaration | AnonymousDefaultExportedClassDeclaration | ClassDeclaration | Expression;
}
```

An export default declaration, e.g., `export default function () {};` or `export default 1;`.

### ExportAllDeclaration

```js
interface ExportAllDeclaration <: ModuleDeclaration {
    type: "ExportAllDeclaration";
    source: Literal;
}
```

An export batch declaration, e.g., `export * from "mod";`.
