support string namespace in import & export (#5570)
This commit is contained in:
52
lib/ast.js
52
lib/ast.js
@@ -1366,34 +1366,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||
$documentation: "An `export ... from '...'` statement",
|
||||
$propdoc: {
|
||||
aliases: "[string*] array of aliases to export",
|
||||
keys: "[string*] array of keys to import",
|
||||
path: "[string] the path to import module",
|
||||
quote: "[string?] the original quote character",
|
||||
aliases: "[AST_String*] array of aliases to export",
|
||||
keys: "[AST_String*] array of keys to import",
|
||||
path: "[AST_String] the path to import module",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path == node.path
|
||||
&& list_equals(this.aliases, node.aliases)
|
||||
&& list_equals(this.keys, node.keys);
|
||||
return this.path.equals(node.path)
|
||||
&& all_equals(this.aliases, node.aliases)
|
||||
&& all_equals(this.keys, node.keys);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.aliases.length != this.keys.length) {
|
||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||
}
|
||||
this.aliases.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("aliases must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String");
|
||||
});
|
||||
this.keys.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("keys must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String");
|
||||
});
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1420,17 +1415,16 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
var AST_Import = DEFNODE("Import", "all default path properties", {
|
||||
$documentation: "An `import` statement",
|
||||
$propdoc: {
|
||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
||||
path: "[string] the path to import module",
|
||||
path: "[AST_String] the path to import module",
|
||||
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||
quote: "[string?] the original quote character",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path == node.path
|
||||
return this.path.equals(node.path)
|
||||
&& prop_equals(this.all, node.all)
|
||||
&& prop_equals(this.default, node.default)
|
||||
&& !this.properties == !node.properties
|
||||
@@ -1453,16 +1447,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
}
|
||||
if (this.default != null) {
|
||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
||||
if (this.default.key !== "") throw new Error("invalid default key: " + this.default.key);
|
||||
if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value);
|
||||
}
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
if (this.properties != null) this.properties.forEach(function(node) {
|
||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
||||
});
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -2005,14 +1995,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||
$documentation: "Symbol defined by an `import` statement",
|
||||
$propdoc: {
|
||||
key: "[string] the original `export` name",
|
||||
key: "[AST_String] the original `export` name",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.key == node.key;
|
||||
&& this.key.equals(node.key);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.key != "string") throw new Error("key must be string");
|
||||
if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String");
|
||||
},
|
||||
}, AST_SymbolConst);
|
||||
|
||||
@@ -2066,14 +2056,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
||||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||
$documentation: "Reference in an `export` statement",
|
||||
$propdoc: {
|
||||
alias: "[string] the `export` alias",
|
||||
alias: "[AST_String] the `export` alias",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.alias == node.alias;
|
||||
&& this.alias.equals(node.alias);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.alias != "string") throw new Error("alias must be string");
|
||||
if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String");
|
||||
},
|
||||
}, AST_SymbolRef);
|
||||
|
||||
|
||||
@@ -294,7 +294,7 @@ Compressor.prototype.compress = function(node) {
|
||||
function export_symbol(sym) {
|
||||
if (!(sym instanceof AST_SymbolDeclaration)) return;
|
||||
var node = make_node(AST_SymbolExport, sym, sym);
|
||||
node.alias = node.name;
|
||||
node.alias = make_node(AST_String, node, { value: node.name });
|
||||
props.push(node);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -316,13 +316,22 @@
|
||||
});
|
||||
},
|
||||
ExportAllDeclaration: function(M) {
|
||||
var alias = M.exported ? read_name(M.exported) : "*";
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: M.source.value,
|
||||
start: start,
|
||||
end: end,
|
||||
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
keys: [ new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ExportDefaultDeclaration: function(M) {
|
||||
@@ -359,15 +368,15 @@
|
||||
if (M.source) {
|
||||
var aliases = [], keys = [];
|
||||
M.specifiers.forEach(function(prop) {
|
||||
aliases.push(read_name(prop.exported));
|
||||
keys.push(read_name(prop.local));
|
||||
aliases.push(from_moz_alias(prop.exported));
|
||||
keys.push(from_moz_alias(prop.local));
|
||||
});
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: aliases,
|
||||
keys: keys,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
}
|
||||
return new AST_ExportReferences({
|
||||
@@ -375,38 +384,48 @@
|
||||
end: my_end_token(M),
|
||||
properties: M.specifiers.map(function(prop) {
|
||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||
sym.alias = read_name(prop.exported);
|
||||
sym.alias = from_moz_alias(prop.exported);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
},
|
||||
ImportDeclaration: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
var all = null, def = null, props = null;
|
||||
M.specifiers.forEach(function(prop) {
|
||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||
switch (prop.type) {
|
||||
case "ImportDefaultSpecifier":
|
||||
def = sym;
|
||||
def.key = "";
|
||||
def.key = new AST_String({
|
||||
start: start,
|
||||
value: "",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
case "ImportNamespaceSpecifier":
|
||||
all = sym;
|
||||
all.key = "*";
|
||||
all.key = new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
sym.key = prop.imported.name || syn.name;
|
||||
sym.key = from_moz_alias(prop.imported);
|
||||
if (!props) props = [];
|
||||
props.push(sym);
|
||||
break;
|
||||
}
|
||||
});
|
||||
return new AST_Import({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
start: start,
|
||||
end: end,
|
||||
all: all,
|
||||
default: def,
|
||||
properties: props,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ImportExpression: function(M) {
|
||||
@@ -797,38 +816,26 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||
if (M.keys[0] == "*") return {
|
||||
if (M.keys[0].value == "*") return {
|
||||
type: "ExportAllDeclaration",
|
||||
exported: M.aliases[0] == "*" ? null : {
|
||||
type: "Identifier",
|
||||
name: M.aliases[0],
|
||||
},
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
var specifiers = [];
|
||||
for (var i = 0; i < M.aliases.length; i++) {
|
||||
specifiers.push({
|
||||
specifiers.push(set_moz_loc({
|
||||
start: M.keys[i].start,
|
||||
end: M.aliases[i].end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: M.aliases[i],
|
||||
},
|
||||
local: {
|
||||
type: "Identifier",
|
||||
name: M.keys[i],
|
||||
},
|
||||
});
|
||||
local: to_moz_alias(M.keys[i]),
|
||||
exported: to_moz_alias(M.aliases[i]),
|
||||
}));
|
||||
}
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -836,44 +843,41 @@
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.start,
|
||||
end: prop.alias.end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
local: to_moz(prop),
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: prop.alias,
|
||||
},
|
||||
};
|
||||
exported: to_moz_alias(prop.alias),
|
||||
});
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.key.start,
|
||||
end: prop.end,
|
||||
}, {
|
||||
type: "ImportSpecifier",
|
||||
local: to_moz(prop),
|
||||
imported: {
|
||||
type: "Identifier",
|
||||
name: prop.key,
|
||||
},
|
||||
};
|
||||
imported: to_moz_alias(prop.key),
|
||||
});
|
||||
}) : [];
|
||||
if (M.all) specifiers.unshift({
|
||||
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||
type: "ImportNamespaceSpecifier",
|
||||
local: to_moz(M.all),
|
||||
});
|
||||
if (M.default) specifiers.unshift({
|
||||
}));
|
||||
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||
type: "ImportDefaultSpecifier",
|
||||
local: to_moz(M.default),
|
||||
});
|
||||
}));
|
||||
return {
|
||||
type: "ImportDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1220,6 +1224,14 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
function from_moz_alias(moz) {
|
||||
return new AST_String({
|
||||
start: my_start_token(moz),
|
||||
value: read_name(moz),
|
||||
end: my_end_token(moz),
|
||||
});
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
@@ -1271,6 +1283,13 @@
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
}
|
||||
|
||||
function to_moz_alias(alias) {
|
||||
return is_identifier_string(alias.value) ? set_moz_loc(alias, {
|
||||
type: "Identifier",
|
||||
name: alias.value,
|
||||
}) : to_moz(alias);
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
|
||||
@@ -1061,6 +1061,14 @@ function OutputStream(options) {
|
||||
}
|
||||
output.semicolon();
|
||||
});
|
||||
function print_alias(alias, output) {
|
||||
var value = alias.value;
|
||||
if (value == "*" || is_identifier_string(value)) {
|
||||
output.print_name(value);
|
||||
} else {
|
||||
output.print_string(value, alias.quote);
|
||||
}
|
||||
}
|
||||
DEFPRINT(AST_ExportForeign, function(output) {
|
||||
var self = this;
|
||||
output.print("export");
|
||||
@@ -1068,7 +1076,7 @@ function OutputStream(options) {
|
||||
var len = self.keys.length;
|
||||
if (len == 0) {
|
||||
print_braced_empty(self, output);
|
||||
} else if (self.keys[0] == "*") {
|
||||
} else if (self.keys[0].value == "*") {
|
||||
print_entry(0);
|
||||
} else output.with_block(function() {
|
||||
output.indent();
|
||||
@@ -1084,18 +1092,18 @@ function OutputStream(options) {
|
||||
output.space();
|
||||
output.print("from");
|
||||
output.space();
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
|
||||
function print_entry(index) {
|
||||
var alias = self.aliases[index];
|
||||
var key = self.keys[index];
|
||||
output.print_name(key);
|
||||
if (alias != key) {
|
||||
print_alias(key, output);
|
||||
if (alias.value != key.value) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1124,7 +1132,7 @@ function OutputStream(options) {
|
||||
output.print("from");
|
||||
output.space();
|
||||
}
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
|
||||
@@ -1734,19 +1742,19 @@ function OutputStream(options) {
|
||||
var name = get_symbol_name(self);
|
||||
output.print_name(name);
|
||||
var alias = self.alias;
|
||||
if (alias != name) {
|
||||
if (alias.value != name) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_SymbolImport, function(output) {
|
||||
var self = this;
|
||||
var name = get_symbol_name(self);
|
||||
var key = self.key;
|
||||
if (key && key != name) {
|
||||
output.print_name(key);
|
||||
if (key.value && key.value != name) {
|
||||
print_alias(key, output);
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
|
||||
83
lib/parse.js
83
lib/parse.js
@@ -1442,28 +1442,41 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
function is_alias() {
|
||||
return is("name") || is_identifier_string(S.token.value);
|
||||
return is("name") || is("string") || is_identifier_string(S.token.value);
|
||||
}
|
||||
|
||||
function make_string(token) {
|
||||
return new AST_String({
|
||||
start: token,
|
||||
quote: token.quote,
|
||||
value: token.value,
|
||||
end: token,
|
||||
});
|
||||
}
|
||||
|
||||
function as_path() {
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return make_string(path);
|
||||
}
|
||||
|
||||
function export_() {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
var alias = key;
|
||||
next();
|
||||
var alias = "*";
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
alias = S.token.value;
|
||||
alias = S.token;
|
||||
next();
|
||||
}
|
||||
expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: [ make_string(alias) ],
|
||||
keys: [ make_string(key) ],
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
if (is("punc", "{")) {
|
||||
@@ -1477,26 +1490,20 @@ function parse($TEXT, options) {
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
aliases.push(S.token.value);
|
||||
aliases.push(S.token);
|
||||
next();
|
||||
} else {
|
||||
aliases.push(key.value);
|
||||
aliases.push(key);
|
||||
}
|
||||
if (!is("punc", "}")) expect(",");
|
||||
}
|
||||
expect("}");
|
||||
if (is("name", "from")) {
|
||||
next();
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: aliases,
|
||||
keys: keys.map(function(token) {
|
||||
return token.value;
|
||||
}),
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: aliases.map(make_string),
|
||||
keys: keys.map(make_string),
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
semicolon();
|
||||
@@ -1504,7 +1511,7 @@ function parse($TEXT, options) {
|
||||
properties: keys.map(function(token, index) {
|
||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||
var sym = _make_symbol(AST_SymbolExport, token);
|
||||
sym.alias = aliases[index];
|
||||
sym.alias = make_string(aliases[index]);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
@@ -1594,26 +1601,42 @@ function parse($TEXT, options) {
|
||||
var all = null;
|
||||
var def = as_symbol(AST_SymbolImport, true);
|
||||
var props = null;
|
||||
if (def ? (def.key = "", is("punc", ",") && next()) : !is("string")) {
|
||||
var cont;
|
||||
if (def) {
|
||||
def.key = new AST_String({
|
||||
start: def.start,
|
||||
value: "",
|
||||
end: def.end,
|
||||
});
|
||||
if (cont = is("punc", ",")) next();
|
||||
} else {
|
||||
cont = !is("string");
|
||||
}
|
||||
if (cont) {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
next();
|
||||
expect_token("name", "as");
|
||||
all = as_symbol(AST_SymbolImport);
|
||||
all.key = "*";
|
||||
all.key = make_string(key);
|
||||
} else {
|
||||
expect("{");
|
||||
props = [];
|
||||
while (is_alias()) {
|
||||
var alias;
|
||||
if (is_token(peek(), "name", "as")) {
|
||||
var key = S.token.value;
|
||||
var key = S.token;
|
||||
next();
|
||||
next();
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = key;
|
||||
alias.key = make_string(key);
|
||||
} else {
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = alias.name;
|
||||
alias.key = new AST_String({
|
||||
start: alias.start,
|
||||
value: alias.name,
|
||||
end: alias.end,
|
||||
});
|
||||
}
|
||||
props.push(alias);
|
||||
if (!is("punc", "}")) expect(",");
|
||||
@@ -1622,15 +1645,11 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
if (all || def || props) expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_Import({
|
||||
all: all,
|
||||
default: def,
|
||||
path: path.value,
|
||||
path: as_path(),
|
||||
properties: props,
|
||||
quote: path.quote,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +109,17 @@ foreign: {
|
||||
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
export * as "42" from 'foo';
|
||||
export { '42', "delete" as 'foo' } from "bar";
|
||||
}
|
||||
expect_exact: "export*as\"42\"from'foo';export{'42',delete as foo}from\"bar\";"
|
||||
}
|
||||
|
||||
same_quotes: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
|
||||
@@ -40,6 +40,17 @@ default_keys: {
|
||||
expect_exact: 'import foo,{bar}from"baz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
import { '42' as foo } from "bar";
|
||||
import { "foo" as bar } from 'baz';
|
||||
}
|
||||
expect_exact: "import{'42'as foo}from\"bar\";import{foo as bar}from'baz';"
|
||||
}
|
||||
|
||||
dynamic: {
|
||||
input: {
|
||||
(async a => await import(a))("foo").then(bar);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -25,6 +26,7 @@ describe("export", function() {
|
||||
"export { * };",
|
||||
"export { * as A };",
|
||||
"export { 42 as A };",
|
||||
"export { 'A' as B };",
|
||||
"export { A as B-C };",
|
||||
"export { default as A };",
|
||||
].forEach(function(code) {
|
||||
@@ -51,8 +53,11 @@ describe("export", function() {
|
||||
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||
[
|
||||
"export from 'path';",
|
||||
"export A from 'path';",
|
||||
"export * from `path`;",
|
||||
"export 'A' from 'path';",
|
||||
"export A as B from 'path';",
|
||||
"export 'A' as B from 'path';",
|
||||
"export default from 'path';",
|
||||
"export { A }, B from 'path';",
|
||||
"export * as A, B from 'path';",
|
||||
@@ -128,4 +133,49 @@ describe("export", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"export var A = 42;",
|
||||
"export default (class A {});",
|
||||
"var A; export { A as '42' };",
|
||||
"export { '42' } from 'path';",
|
||||
"export * as '42' from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -12,14 +13,21 @@ describe("import", function() {
|
||||
"import from 'path';",
|
||||
"if (0) import 'path';",
|
||||
"import * from 'path';",
|
||||
"import 'A' from 'path';",
|
||||
"import A-B from 'path';",
|
||||
"import A as B from 'path';",
|
||||
"import { A }, B from 'path';",
|
||||
"import * as 'A' 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-B } from 'path';",
|
||||
"function f() { import 'path'; }",
|
||||
"import { 42 as A } from 'path';",
|
||||
"import { A-B as C } from 'path';",
|
||||
"import { 'A' as 'B' } from 'path';",
|
||||
].forEach(function(code) {
|
||||
assert.throws(function() {
|
||||
UglifyJS.parse(code);
|
||||
@@ -53,4 +61,49 @@ describe("import", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"import A from 'path';",
|
||||
"import * as A from 'path';",
|
||||
"import A, * as B from 'path';",
|
||||
"import { '42' as A, B } from 'path';",
|
||||
"import A, { '42' as B } from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user