correctly parse export of function & class (#2135)

This commit is contained in:
Alex Lam S.L
2017-06-21 23:15:39 +08:00
committed by GitHub
parent 8709753bfb
commit 71556d00b5
6 changed files with 89 additions and 56 deletions

View File

@@ -2413,72 +2413,60 @@ function parse($TEXT, options) {
function export_() { function export_() {
var start = S.token; var start = S.token;
var is_default; var is_default;
var exported_value;
var exported_definition;
var exported_names; var exported_names;
if (is("keyword", "default")) { if (is("keyword", "default")) {
is_default = true; is_default = true;
next(); next();
} else { } else if (exported_names = map_names(false)) {
exported_names = map_names(false); if (is("name", "from")) {
next();
if (exported_names) { var mod_str = S.token;
if (is("name", "from")) { if (mod_str.type !== 'string') {
next(); unexpected();
var mod_str = S.token;
if (mod_str.type !== 'string') {
unexpected();
}
next();
return new AST_Export({
start: start,
is_default: is_default,
exported_names: exported_names,
module_name: new AST_String({
start: mod_str,
value: mod_str.value,
quote: mod_str.quote,
end: mod_str,
}),
end: prev(),
});
} else {
return new AST_Export({
start: start,
is_default: is_default,
exported_names: exported_names,
end: prev(),
});
} }
next();
return new AST_Export({
start: start,
is_default: is_default,
exported_names: exported_names,
module_name: new AST_String({
start: mod_str,
value: mod_str.value,
quote: mod_str.quote,
end: mod_str,
}),
end: prev(),
});
} else {
return new AST_Export({
start: start,
is_default: is_default,
exported_names: exported_names,
end: prev(),
});
} }
} }
var is_definition = is("keyword", "var") || is("keyword", "let") || is("keyword", "const"); var node;
if (is_definition) { var exported_value;
if (is_default) unexpected(); var exported_definition;
exported_definition = statement(); if (is("punc", "{")
} else if (is("keyword", "class")) { || is_default
var cls = expr_atom(false); && (is("keyword", "class") || is("keyword", "function"))
if (cls.name) { && is_token(peek(), "punc")) {
cls.name = new AST_SymbolDefClass(cls.name);
exported_definition = new AST_DefClass(cls);
} else {
exported_value = cls;
}
} else if (is("keyword", "function")) {
var func = expr_atom(false);
if (func.name) {
func.name = new AST_SymbolDefun(func.name);
exported_definition = new AST_Defun(func);
} else {
exported_value = func;
}
} else {
exported_value = expression(false); exported_value = expression(false);
semicolon(); semicolon();
} else if ((node = statement()) instanceof AST_Definitions && is_default) {
unexpected(node.start);
} else if (node instanceof AST_Definitions || node instanceof AST_Defun || node instanceof AST_DefClass) {
exported_definition = node;
} else if (node instanceof AST_SimpleStatement) {
exported_value = node.body;
} else {
unexpected(node.start);
} }
return new AST_Export({ return new AST_Export({

View File

@@ -107,3 +107,16 @@ issue_2129: {
export const { keys } = Object; export const { keys } = Object;
} }
} }
async_func: {
options = {
keep_fargs: false,
unused: true,
}
input: {
export async function Foo(x){};
}
expect: {
export async function Foo(){};
}
}

View File

@@ -0,0 +1 @@
export class{};

View File

@@ -0,0 +1 @@
export function(){};

View File

@@ -534,13 +534,13 @@ describe("bin/uglifyjs", function () {
}); });
}); });
it("Should throw syntax error (block-level export)", function(done) { it("Should throw syntax error (block-level export)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/export.js -m'; var command = uglifyjscmd + ' test/input/invalid/export_1.js -m';
exec(command, function (err, stdout, stderr) { exec(command, function (err, stdout, stderr) {
assert.ok(err); assert.ok(err);
assert.strictEqual(stdout, ""); assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [ assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
"Parse error at test/input/invalid/export.js:2,4", "Parse error at test/input/invalid/export_1.js:2,4",
" export var V = 1;", " export var V = 1;",
" ^", " ^",
"ERROR: Export statement may only appear at top level" "ERROR: Export statement may only appear at top level"
@@ -563,6 +563,36 @@ describe("bin/uglifyjs", function () {
done(); done();
}); });
}); });
it("Should throw syntax error (anonymous class)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/export_2.js';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
"Parse error at test/input/invalid/export_2.js:1,12",
"export class{};",
" ^",
"ERROR: Unexpected token: punc ({)"
].join("\n"));
done();
});
});
it("Should throw syntax error (anonymous function)", function(done) {
var command = uglifyjscmd + ' test/input/invalid/export_3.js';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stdout, "");
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
"Parse error at test/input/invalid/export_3.js:1,15",
"export function(){};",
" ^",
"ERROR: Unexpected token: punc (()"
].join("\n"));
done();
});
});
it("Should handle literal string as source map input", function(done) { it("Should handle literal string as source map input", function(done) {
var command = [ var command = [
uglifyjscmd, uglifyjscmd,