@@ -815,7 +815,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var statement = embed_tokens(function() {
|
var statement = embed_tokens(function(toplevel) {
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
switch (S.token.type) {
|
switch (S.token.type) {
|
||||||
case "string":
|
case "string":
|
||||||
@@ -854,9 +854,11 @@ function parse($TEXT, options) {
|
|||||||
if (S.in_async) return simple_statement();
|
if (S.in_async) return simple_statement();
|
||||||
break;
|
break;
|
||||||
case "export":
|
case "export":
|
||||||
|
if (!toplevel && options.module !== "") unexpected();
|
||||||
next();
|
next();
|
||||||
return export_();
|
return export_();
|
||||||
case "import":
|
case "import":
|
||||||
|
if (!toplevel && options.module !== "") unexpected();
|
||||||
var token = peek();
|
var token = peek();
|
||||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
||||||
next();
|
next();
|
||||||
@@ -2563,7 +2565,7 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
while (!is("eof"))
|
while (!is("eof"))
|
||||||
body.push(statement());
|
body.push(statement(true));
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
var end = prev() || start;
|
var end = prev() || start;
|
||||||
var toplevel = options.toplevel;
|
var toplevel = options.toplevel;
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ function make_code(ast, options) {
|
|||||||
function parse_test(file) {
|
function parse_test(file) {
|
||||||
var script = fs.readFileSync(file, "utf8");
|
var script = fs.readFileSync(file, "utf8");
|
||||||
try {
|
try {
|
||||||
var ast = U.parse(script, { filename: file });
|
var ast = U.parse(script, { filename: file, module: "" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Caught error while parsing tests in " + file);
|
console.error("Caught error while parsing tests in " + file);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|||||||
@@ -193,22 +193,6 @@ forbid_merge: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merge_tail: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
if (console)
|
|
||||||
import "foo";
|
|
||||||
else
|
|
||||||
import "foo";
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console;
|
|
||||||
import "foo";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_4708_1: {
|
issue_4708_1: {
|
||||||
options = {
|
options = {
|
||||||
imports: true,
|
imports: true,
|
||||||
|
|||||||
@@ -68,4 +68,64 @@ describe("export", function() {
|
|||||||
}, code);
|
}, code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should reject `export` statement not under top-level scope", function() {
|
||||||
|
[
|
||||||
|
"{ export {}; }",
|
||||||
|
"if (0) export var A;",
|
||||||
|
"function f() { export default 42; }",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should compare `export` statements correctly", function() {
|
||||||
|
var stats = {
|
||||||
|
Declaration: [
|
||||||
|
"export let A;",
|
||||||
|
"export const A = 42;",
|
||||||
|
"export var { A, B: [] } = C;",
|
||||||
|
"export function A() { return B(A); }",
|
||||||
|
"export async function* A({}, ...[]) { return B(A); }",
|
||||||
|
],
|
||||||
|
Default: [
|
||||||
|
"export default 42;",
|
||||||
|
"export default A => A(B);",
|
||||||
|
"export default class A extends B {}",
|
||||||
|
"export default (class A extends B {});",
|
||||||
|
"export default class A { static C = 42; }",
|
||||||
|
"export default class A extends B { static C = 42; }",
|
||||||
|
],
|
||||||
|
Foreign: [
|
||||||
|
"export * from 'path';",
|
||||||
|
"export {} from 'path';",
|
||||||
|
"export * as A from 'path';",
|
||||||
|
"export { default } from 'path';",
|
||||||
|
"export { A, B as C } from 'path';",
|
||||||
|
"export { A, default as C } from 'path';",
|
||||||
|
],
|
||||||
|
References: [
|
||||||
|
"export {};",
|
||||||
|
"export { A };",
|
||||||
|
"export { A as B };",
|
||||||
|
"export { A, B as C };",
|
||||||
|
"export { A as default };",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
for (var k in stats) stats[k].forEach(function(c, i) {
|
||||||
|
var s = UglifyJS.parse(c);
|
||||||
|
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||||
|
assert.strictEqual(s.body.length, 1, c);
|
||||||
|
assert.strictEqual(s.body[0].TYPE, "Export" + k, c);
|
||||||
|
for (var l in stats) stats[l].forEach(function(d, j) {
|
||||||
|
var t = UglifyJS.parse(d);
|
||||||
|
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||||
|
assert.strictEqual(t.body.length, 1, d);
|
||||||
|
assert.strictEqual(t.body[0].TYPE, "Export" + l, d);
|
||||||
|
assert.strictEqual(s.equals(t), k === l && i === j, c + "\n" + d);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ describe("import", function() {
|
|||||||
"import A;",
|
"import A;",
|
||||||
"import {};",
|
"import {};",
|
||||||
"import `path`;",
|
"import `path`;",
|
||||||
|
"{ import 'path'; }",
|
||||||
"import from 'path';",
|
"import from 'path';",
|
||||||
|
"if (0) import 'path';",
|
||||||
"import * from 'path';",
|
"import * from 'path';",
|
||||||
"import A as B from 'path';",
|
"import A as B from 'path';",
|
||||||
"import { A }, B from 'path';",
|
"import { A }, B from 'path';",
|
||||||
"import * as A, B from 'path';",
|
"import * as A, B from 'path';",
|
||||||
"import * as A, {} from 'path';",
|
"import * as A, {} from 'path';",
|
||||||
"import { * as A } from 'path';",
|
"import { * as A } from 'path';",
|
||||||
|
"function f() { import 'path'; }",
|
||||||
"import { 42 as A } from 'path';",
|
"import { 42 as A } from 'path';",
|
||||||
"import { A-B as C } from 'path';",
|
"import { A-B as C } from 'path';",
|
||||||
].forEach(function(code) {
|
].forEach(function(code) {
|
||||||
@@ -25,4 +28,29 @@ describe("import", function() {
|
|||||||
}, code);
|
}, code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should compare `import` statements correctly", function() {
|
||||||
|
[
|
||||||
|
"import 'foo';",
|
||||||
|
"import 'path';",
|
||||||
|
"import A from 'path';",
|
||||||
|
"import { A } from 'path';",
|
||||||
|
"import * as A from 'path';",
|
||||||
|
"import A, { B } from 'path';",
|
||||||
|
"import A, * as B from 'path';",
|
||||||
|
"import { A as B } from 'path';",
|
||||||
|
"import A, { B, C as D } from 'path';",
|
||||||
|
].forEach(function(c, i, stats) {
|
||||||
|
var s = UglifyJS.parse(c);
|
||||||
|
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||||
|
assert.strictEqual(s.body.length, 1, c);
|
||||||
|
assert.ok(s.body[0] instanceof UglifyJS.AST_Import, c);
|
||||||
|
stats.forEach(function(d, j) {
|
||||||
|
var t = UglifyJS.parse(d);
|
||||||
|
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||||
|
assert.strictEqual(t.body.length, 1, d);
|
||||||
|
assert.ok(t.body[0] instanceof UglifyJS.AST_Import, d);
|
||||||
|
assert.strictEqual(s.equals(t), i === j, c + "\n" + d);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user