ariya/esprima — pull request #287 by caridy (2014-09-27 19:01:30+00:00)
Title: ES6 module syntax update

## Important Notice

This is a non-backward compatible change in esprima:harmony branch since it removes some syntax from previous drafts that were specs recently and introduces the changes to align with the final draft.

## Changes

* revision of ES6 import final syntax based on specs
* revision of ES6 export final syntax based on specs
* tests for import/export syntax in a separate test file for conviniece
* introduces `Syntax.ImportGlobSpecifier` for `import * as foo from "foo"`
* introduces `Syntax.ImportDefaultSpecifier` for `import foo from "foo";`
* removes `kind=default` and `kind=named` from `ImportDeclaration` in favor of
`Syntax.ImportDefaultSpecifier` form
* eliminate `module {}` syntax
* clean up old tests from `harmonytest.js`

## Export Syntax

```javascript
// default exports
export default 42;
export default {};
export default [];
export default foo;
export default function () {}
export default class {}
export default function foo () {}
export default class foo {}

// variables exports
export var foo = 1;
export var foo = function () {};
export var bar; // lazy initialization
export let foo = 2;
export let bar; // lazy initialization
export const foo = 3;
export function foo () {}
export class foo {}

// named exports
export {foo};
export {foo, bar};
export {foo as bar};
export {foo as default};
export {foo as default, bar};

// exports from
export * from "foo";
export {foo} from "foo";
export {foo, bar} from "foo";
export {foo as bar} from "foo";
export {foo as default} from "foo";
export {foo as default, bar} from "foo";
export {default} from "foo";
export {default as foo} from "foo";
```

## Import Syntax

```javascript
// default imports
import foo from "foo";
import {default as foo} from "foo";

// named imports
import {bar} from "foo";
import {bar, baz} from "foo";
import {bar as baz} from "foo";
import {bar as baz, xyz} from "foo";

// glob imports
import * as foo from "foo";

// mixing imports
import foo, {baz as xyz} from "foo";
import * as bar, {baz as xyz} from "foo";
import foo, * as bar, {baz as xyz} from "foo";
```

## Invalid Syntax

```javascript
export const bar;
// const variables must have an initializer

export foo;
// Unexpected token identifier, invalid named export syntax

export function () {}
// Unexpected token (, use a function declaration instead

export function default () {}
// Unexpected token default

import foo;
// Missing from after import

import { foo, bar };
// Missing from after import

import foo from bar;
// Invalid module specifier

import default from "foo";
// Unexpected token default

export default from "foo";
// Unexpected token from

export {default};
// Missing from after export

export *;
// Missing from after export

import {default as foo};
// Missing from after import

// import * from "foo";
// Missing as after import *'

export default = 42;
// Unexpected token =

import {bar as default} from "foo";
// Unexpected token default
```

## TODO

* [ ] sign off from modules champions (@wycats, @dherman)
* [ ] follow up with `es6-module-transpiler`
* [ ] follow up with `recast` builders
* [ ] follow up with `recast` ast-types

/cc @ericf @domenic @guybedford @benjamn @eventualbuddha @jeffmo