diff --git a/acorn.js b/acorn.js index 01d54b4870..d50d0cf428 100644 --- a/acorn.js +++ b/acorn.js @@ -2694,15 +2694,13 @@ pp.parseExport = function(node) { this.next(); - // export var|const|let|function|class ...; - if (this.type === tt._var || this.type === tt._const || this.type === tt._let || this.type === tt._function || this.type === tt._class) { - node.declaration = this.parseStatement(true); - node['default'] = false; - node.specifiers = null; - node.source = null; - } else - // export default ...; - if (this.eat(tt._default)) { + // export * from '...'; + if (this.eat(tt.star)) { + this.expectContextual("from"); + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected(); + return this.finishNode(node, "ExportAllDeclaration"); + } + if (this.eat(tt._default)) { // export default ...; var expr = this.parseMaybeAssign(); if (expr.id) { switch (expr.type) { @@ -2711,51 +2709,43 @@ } } node.declaration = expr; - node['default'] = true; - node.specifiers = null; - node.source = null; this.semicolon(); - } else { - // export * from '...'; - // export { x, y as z } [from '...']; - var isBatch = this.type === tt.star; + return this.finishNode(node, "ExportDefaultDeclaration"); + } + // export var|const|let|function|class ...; + if (this.type.keyword) { + node.declaration = this.parseStatement(true); + node.specifiers = []; + node.source = null; + } else { // export { x, y as z } [from '...']; node.declaration = null; - node['default'] = false; node.specifiers = this.parseExportSpecifiers(); if (this.eatContextual("from")) { node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected(); } else { - if (isBatch) this.unexpected(); node.source = null; } this.semicolon(); } - return this.finishNode(node, "ExportDeclaration"); + return this.finishNode(node, "ExportNamedDeclaration"); }; // Parses a comma-separated list of module exports. pp.parseExportSpecifiers = function() { var nodes = [], first = true; - if (this.type === tt.star) { - // export * from '...' - var node = this.startNode(); - this.next(); - nodes.push(this.finishNode(node, "ExportBatchSpecifier")); - } else { - // export { x, y as z } [from '...'] - this.expect(tt.braceL); - while (!this.eat(tt.braceR)) { - if (!first) { - this.expect(tt.comma); - if (this.options.allowTrailingCommas && this.eat(tt.braceR)) break; - } else first = false; + // export { x, y as z } [from '...'] + this.expect(tt.braceL); + while (!this.eat(tt.braceR)) { + if (!first) { + this.expect(tt.comma); + if (this.options.allowTrailingCommas && this.eat(tt.braceR)) break; + } else first = false; - var node = this.startNode(); - node.id = this.parseIdent(this.type === tt._default); - node.name = this.eatContextual("as") ? this.parseIdent(true) : null; - nodes.push(this.finishNode(node, "ExportSpecifier")); - } + var node = this.startNode(); + node.local = this.parseIdent(this.type === tt._default); + node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local; + nodes.push(this.finishNode(node, "ExportSpecifier")); } return nodes; }; diff --git a/acorn_loose.js b/acorn_loose.js index 6edf3b1f0c..7d6cd8be84 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -1042,9 +1042,11 @@ lp.parseExport = function() { var node = this.startNode(); this.next(); - node['default'] = this.eat(tt._default); - node.specifiers = node.source = null; - if (node['default']) { + if (this.eat(tt.star)) { + node.source = this.eatContextual("from") ? this.parseExprAtom() : null; + return this.finishNode(node, "ExportAllDeclaration"); + } + if (this.eat(tt._default)) { var expr = this.parseMaybeAssign(); if (expr.id) { switch (expr.type) { @@ -1054,14 +1056,19 @@ } node.declaration = expr; this.semicolon(); - } else if (this.tok.type.keyword) { + return this.finishNode(node, "ExportDefaultDeclaration"); + } + if (this.tok.type.keyword) { node.declaration = this.parseStatement(); + node.specifiers = []; + node.source = null; } else { node.declaration = null; - this.parseExportSpecifierList(node); + node.specifiers = this.parseExportSpecifierList(); + node.source = this.eatContextual("from") ? this.parseExprAtom() : null; + this.semicolon(); } - this.semicolon(); - return this.finishNode(node, "ExportDeclaration"); + return this.finishNode(node, "ExportNamedDeclaration"); }; lp.parseImport = function() { @@ -1078,15 +1085,16 @@ this.finishNode(elt, "ImportDefaultSpecifier"); this.eat(tt.comma); } - this.parseImportSpecifierList(node); + node.specifiers = this.parseImportSpecifierList(); + node.source = this.eatContextual("from") ? this.parseExprAtom() : null; if (elt) node.specifiers.unshift(elt); } this.semicolon(); return this.finishNode(node, "ImportDeclaration"); }; - lp.parseImportSpecifierList = function(node) { - var elts = node.specifiers = []; + lp.parseImportSpecifierList = function() { + var elts = []; if (this.tok.type === tt.star) { var elt = this.startNode(); this.next(); @@ -1114,39 +1122,27 @@ this.eat(tt.braceR); this.popCx(); } - node.source = this.eatContextual("from") ? this.parseExprAtom() : null; + return elts; }; - lp.parseExportSpecifierList = function(node) { - var elts = node.specifiers = []; - if (this.tok.type === tt.star) { + lp.parseExportSpecifierList = function() { + var elts = []; + var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; + this.pushCx(); + this.eat(tt.braceL); + if (this.curLineStart > continuedLine) continuedLine = this.curLineStart; + while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { + if (this.isContextual("from")) break; var elt = this.startNode(); - this.next(); - if (this.eatContextual("as")) elt.name = this.parseIdent(); - elts.push(this.finishNode(elt, "ExportBatchSpecifier")); - } else { - var indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart; - this.pushCx(); - this.eat(tt.braceL); - if (this.curLineStart > continuedLine) continuedLine = this.curLineStart; - while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) { - var elt = this.startNode(); - if (this.eat(tt.star)) { - if (this.eatContextual("as")) elt.name = this.parseIdent(); - this.finishNode(elt, "ExportBatchSpecifier"); - } else { - if (this.isContextual("from")) break; - elt.id = this.parseIdent(); - elt.name = this.eatContextual("as") ? this.parseIdent() : null; - this.finishNode(elt, "ExportSpecifier"); - } - elts.push(elt); - this.eat(tt.comma); - } - this.eat(tt.braceR); - this.popCx(); + elt.local = this.parseIdent(); + elt.exported = this.eatContextual("as") ? this.parseIdent() : elt.local; + this.finishNode(elt, "ExportSpecifier"); + elts.push(elt); + this.eat(tt.comma); } - node.source = this.eatContextual("from") ? this.parseExprAtom() : null; + this.eat(tt.braceR); + this.popCx(); + return elts; }; lp.parseExprList = function(close, allowEmpty) { diff --git a/test/tests-harmony.js b/test/tests-harmony.js index 48a613207e..c155978041 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -4453,7 +4453,7 @@ test("var {a:b} = {}", { test("export var document", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "VariableDeclaration", declarations: [{ @@ -4478,8 +4478,7 @@ test("export var document", { end: {line: 1, column: 19} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4499,7 +4498,7 @@ test("export var document", { test("export var document = { }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "VariableDeclaration", declarations: [{ @@ -4531,8 +4530,7 @@ test("export var document = { }", { end: {line: 1, column: 25} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4552,7 +4550,7 @@ test("export var document = { }", { test("export let document", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "VariableDeclaration", declarations: [{ @@ -4577,8 +4575,7 @@ test("export let document", { end: {line: 1, column: 19} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4598,7 +4595,7 @@ test("export let document", { test("export let document = { }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "VariableDeclaration", declarations: [{ @@ -4630,8 +4627,7 @@ test("export let document = { }", { end: {line: 1, column: 25} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4651,7 +4647,7 @@ test("export let document = { }", { test("export const document = { }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "VariableDeclaration", declarations: [{ @@ -4683,8 +4679,7 @@ test("export const document = { }", { end: {line: 1, column: 27} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4704,7 +4699,7 @@ test("export const document = { }", { test("export function parse() { }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "FunctionDeclaration", id: { @@ -4731,8 +4726,7 @@ test("export function parse() { }", { end: {line: 1, column: 27} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4752,7 +4746,7 @@ test("export function parse() { }", { test("export class Class {}", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: { type: "ClassDeclaration", id: { @@ -4777,8 +4771,7 @@ test("export class Class {}", { end: {line: 1, column: 21} } }, - default: false, - specifiers: null, + specifiers: [], source: null, loc: { start: {line: 1, column: 0}, @@ -4798,7 +4791,7 @@ test("export class Class {}", { test("export default 42", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportDefaultDeclaration", declaration: { type: "Literal", value: 42, @@ -4808,9 +4801,6 @@ test("export default 42", { end: {line: 1, column: 17} } }, - default: true, - specifiers: null, - source: null, loc: { start: {line: 1, column: 0}, end: {line: 1, column: 17} @@ -4830,7 +4820,7 @@ test("export default function () {}", { type: "Program", range: [0, 29], body: [{ - type: "ExportDeclaration", + type: "ExportDefaultDeclaration", range: [0, 29], declaration: { type: "FunctionExpression", @@ -4844,10 +4834,7 @@ test("export default function () {}", { range: [27, 29], body: [] } - }, - default: true, - specifiers: null, - source: null + } }] }, {ecmaVersion: 6, ranges: true}); @@ -4855,7 +4842,7 @@ test("export default function f() {}", { type: "Program", range: [0, 30], body: [{ - type: "ExportDeclaration", + type: "ExportDefaultDeclaration", range: [0, 30], declaration: { type: "FunctionDeclaration", @@ -4873,10 +4860,7 @@ test("export default function f() {}", { range: [28, 30], body: [] } - }, - default: true, - specifiers: null, - source: null + } }] }, {ecmaVersion: 6, ranges: true}); @@ -4884,7 +4868,7 @@ test("export default class {}", { type: "Program", range: [0, 23], body: [{ - type: "ExportDeclaration", + type: "ExportDefaultDeclaration", range: [0, 23], declaration: { type: "ClassExpression", @@ -4896,10 +4880,7 @@ test("export default class {}", { range: [21, 23], body: [] } - }, - default: true, - specifiers: null, - source: null + } }] }, {ecmaVersion: 6, ranges: true}); @@ -4907,7 +4888,7 @@ test("export default class A {}", { type: "Program", range: [0, 25], body: [{ - type: "ExportDeclaration", + type: "ExportDefaultDeclaration", range: [0, 25], declaration: { type: "ClassDeclaration", @@ -4923,10 +4904,7 @@ test("export default class A {}", { range: [23, 25], body: [] } - }, - default: true, - specifiers: null, - source: null + } }] }, {ecmaVersion: 6, ranges: true}); @@ -4935,15 +4913,7 @@ testFail("export *", "Unexpected token (1:8)", {ecmaVersion: 6}); test("export * from \"crypto\"", { type: "Program", body: [{ - type: "ExportDeclaration", - declaration: null, - specifiers: [{ - type: "ExportBatchSpecifier", - loc: { - start: {line: 1, column: 7}, - end: {line: 1, column: 8} - } - }], + type: "ExportAllDeclaration", source: { type: "Literal", value: "crypto", @@ -4971,11 +4941,19 @@ test("export * from \"crypto\"", { test("export { encrypt }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: null, specifiers: [{ type: "ExportSpecifier", - id: { + exported: { + type: "Identifier", + name: "encrypt", + loc: { + start: {line: 1, column: 9}, + end: {line: 1, column: 16} + } + }, + local: { type: "Identifier", name: "encrypt", loc: { @@ -4983,7 +4961,6 @@ test("export { encrypt }", { end: {line: 1, column: 16} } }, - name: null, loc: { start: {line: 1, column: 9}, end: {line: 1, column: 16} @@ -5008,12 +4985,20 @@ test("export { encrypt }", { test("export { encrypt, decrypt }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: null, specifiers: [ { type: "ExportSpecifier", - id: { + exported: { + type: "Identifier", + name: "encrypt", + loc: { + start: {line: 1, column: 9}, + end: {line: 1, column: 16} + } + }, + local: { type: "Identifier", name: "encrypt", loc: { @@ -5021,7 +5006,6 @@ test("export { encrypt, decrypt }", { end: {line: 1, column: 16} } }, - name: null, loc: { start: {line: 1, column: 9}, end: {line: 1, column: 16} @@ -5029,7 +5013,15 @@ test("export { encrypt, decrypt }", { }, { type: "ExportSpecifier", - id: { + exported: { + type: "Identifier", + name: "decrypt", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 25} + } + }, + local: { type: "Identifier", name: "decrypt", loc: { @@ -5037,7 +5029,6 @@ test("export { encrypt, decrypt }", { end: {line: 1, column: 25} } }, - name: null, loc: { start: {line: 1, column: 18}, end: {line: 1, column: 25} @@ -5063,19 +5054,11 @@ test("export { encrypt, decrypt }", { test("export { encrypt as default }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: null, specifiers: [{ type: "ExportSpecifier", - id: { - type: "Identifier", - name: "encrypt", - loc: { - start: {line: 1, column: 9}, - end: {line: 1, column: 16} - } - }, - name: { + exported: { type: "Identifier", name: "default", loc: { @@ -5083,6 +5066,14 @@ test("export { encrypt as default }", { end: {line: 1, column: 27} } }, + local: { + type: "Identifier", + name: "encrypt", + loc: { + start: {line: 1, column: 9}, + end: {line: 1, column: 16} + } + }, loc: { start: {line: 1, column: 9}, end: {line: 1, column: 27} @@ -5107,12 +5098,20 @@ test("export { encrypt as default }", { test("export { encrypt, decrypt as dec }", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: null, specifiers: [ { type: "ExportSpecifier", - id: { + exported: { + type: "Identifier", + name: "encrypt", + loc: { + start: {line: 1, column: 9}, + end: {line: 1, column: 16} + } + }, + local: { type: "Identifier", name: "encrypt", loc: { @@ -5120,7 +5119,6 @@ test("export { encrypt, decrypt as dec }", { end: {line: 1, column: 16} } }, - name: null, loc: { start: {line: 1, column: 9}, end: {line: 1, column: 16} @@ -5128,15 +5126,7 @@ test("export { encrypt, decrypt as dec }", { }, { type: "ExportSpecifier", - id: { - type: "Identifier", - name: "decrypt", - loc: { - start: {line: 1, column: 18}, - end: {line: 1, column: 25} - } - }, - name: { + exported: { type: "Identifier", name: "dec", loc: { @@ -5144,6 +5134,14 @@ test("export { encrypt, decrypt as dec }", { end: {line: 1, column: 32} } }, + local: { + type: "Identifier", + name: "decrypt", + loc: { + start: {line: 1, column: 18}, + end: {line: 1, column: 25} + } + }, loc: { start: {line: 1, column: 18}, end: {line: 1, column: 32} @@ -5169,12 +5167,20 @@ test("export { encrypt, decrypt as dec }", { test("export { default } from \"other\"", { type: "Program", body: [{ - type: "ExportDeclaration", + type: "ExportNamedDeclaration", declaration: null, specifiers: [ { type: "ExportSpecifier", - id: { + exported: { + type: "Identifier", + name: "default", + loc: { + start: {line: 1, column: 9}, + end: {line: 1, column: 16} + } + }, + local: { type: "Identifier", name: "default", loc: { @@ -5182,7 +5188,6 @@ test("export { default } from \"other\"", { end: {line: 1, column: 16} } }, - name: null, loc: { start: {line: 1, column: 9}, end: {line: 1, column: 16}