diff --git a/acorn.js b/acorn.js index 38a233bddd..9d11afe5ff 100644 --- a/acorn.js +++ b/acorn.js @@ -2683,7 +2683,14 @@ } else // export default ...; if (eat(_default)) { - node.declaration = parseMaybeAssign(); + var expr = parseMaybeAssign(); + if (expr.id) { + switch (expr.type) { + case "FunctionExpression": expr.type = "FunctionDeclaration"; break; + case "ClassExpression": expr.type = "ClassDeclaration"; break; + } + } + node.declaration = expr; node['default'] = true; node.specifiers = null; node.source = null; diff --git a/acorn_loose.js b/acorn_loose.js index 035f22395a..0f52fcc47a 100644 --- a/acorn_loose.js +++ b/acorn_loose.js @@ -846,6 +846,7 @@ next(); if (token.type === tt.name) node.id = parseIdent(); else if (isStatement) node.id = dummyIdent(); + else node.id = null; node.superClass = eat(tt._extends) ? parseExpression() : null; node.body = startNode(); node.body.body = []; @@ -1058,7 +1059,14 @@ node['default'] = eat(tt._default); node.specifiers = node.source = null; if (node['default']) { - node.declaration = parseExpression(); + var expr = parseMaybeAssign(); + if (expr.id) { + switch (expr.type) { + case "FunctionExpression": expr.type = "FunctionDeclaration"; break; + case "ClassExpression": expr.type = "ClassDeclaration"; break; + } + } + node.declaration = expr; semicolon(); } else if (token.type.keyword) { node.declaration = parseStatement(); diff --git a/test/tests-harmony.js b/test/tests-harmony.js index 7ccb49aab3..1b45b380cd 100644 --- a/test/tests-harmony.js +++ b/test/tests-harmony.js @@ -4826,6 +4826,110 @@ test("export default 42", { locations: true }); +test("export default function () {}", { + type: "Program", + range: [0, 29], + body: [{ + type: "ExportDeclaration", + range: [0, 29], + declaration: { + type: "FunctionExpression", + range: [15, 29], + id: null, + generator: false, + expression: false, + params: [], + body: { + type: "BlockStatement", + range: [27, 29], + body: [] + } + }, + default: true, + specifiers: null, + source: null + }] +}, {ecmaVersion: 6, ranges: true}); + +test("export default function f() {}", { + type: "Program", + range: [0, 30], + body: [{ + type: "ExportDeclaration", + range: [0, 30], + declaration: { + type: "FunctionDeclaration", + range: [15, 30], + id: { + type: "Identifier", + range: [24, 25], + name: "f" + }, + generator: false, + expression: false, + params: [], + body: { + type: "BlockStatement", + range: [28, 30], + body: [] + } + }, + default: true, + specifiers: null, + source: null + }] +}, {ecmaVersion: 6, ranges: true}); + +test("export default class {}", { + type: "Program", + range: [0, 23], + body: [{ + type: "ExportDeclaration", + range: [0, 23], + declaration: { + type: "ClassExpression", + range: [15, 23], + id: null, + superClass: null, + body: { + type: "ClassBody", + range: [21, 23], + body: [] + } + }, + default: true, + specifiers: null, + source: null + }] +}, {ecmaVersion: 6, ranges: true}); + +test("export default class A {}", { + type: "Program", + range: [0, 25], + body: [{ + type: "ExportDeclaration", + range: [0, 25], + declaration: { + type: "ClassDeclaration", + range: [15, 25], + id: { + type: "Identifier", + range: [21, 22], + name: "A" + }, + superClass: null, + body: { + type: "ClassBody", + range: [23, 25], + body: [] + } + }, + default: true, + specifiers: null, + source: null + }] +}, {ecmaVersion: 6, ranges: true}); + testFail("export *", "Unexpected token (1:8)", {ecmaVersion: 6}); test("export * from \"crypto\"", {