Implemented parse for export Name from Module variants.

This commit is contained in:
Ondřej Španěl 2017-03-27 12:30:38 +02:00
parent 6a54de79b5
commit 1eabf5b20c
3 changed files with 116 additions and 1 deletions

View File

@ -789,11 +789,13 @@ var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
}
});
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default", {
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name", {
$documentation: "An `export` statement",
$propdoc: {
exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
exported_value: "[AST_Node?] An exported value",
exported_names: "[string*] List of exported names",
module_name: "[string?] Name of the file to load exports from",
is_default: "[Boolean] Whether this is the default exported value of this module"
},
_walk: function (visitor) {
@ -1179,6 +1181,9 @@ var AST_SymbolImport = DEFNODE("SymbolImport", null, {
var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, {
$documentation: "A symbol imported from a module, but it is defined in the other module, and its real name is irrelevant for this module's purposes",
}, AST_Symbol);
var AST_SymbolImportAsterisk = DEFNODE("SymbolImportAsterisk", null, {
$documentation: "All symbols imported / exported from a module",
}, AST_Symbol);
var AST_Label = DEFNODE("Label", "references", {
$documentation: "Symbol naming a label (declaration)",

View File

@ -2236,17 +2236,86 @@ function parse($TEXT, options) {
})
}
function import_nameAsterisk() {
var start = S.token;
var foreign_name;
var name;
next();
var end = prev();
name = new AST_Symbol({
name: '*',
start: start,
end: end,
});
foreign_name = new AST_SymbolImportForeign({
name: '*',
start: start,
end: end,
});
return new AST_NameImport({
start: start,
foreign_name: foreign_name,
name: name,
end: end,
})
}
function export_() {
var start = S.token;
var is_default;
var exported_value;
var exported_definition;
var exported_names;
if (is("keyword", "default")) {
is_default = true;
next();
}
if (is("punc", "{")) {
next();
exported_names = [];
while (!is("punc", "}")) {
exported_names.push(import_name());
if (is("punc", ",")) {
next();
}
}
next();
} else if (is("operator", "*")) {
var st = prev();
exported_names = [import_nameAsterisk()];
}
if (exported_names) {
expect_token("name", "from");
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(),
});
}
var is_definition =
is("keyword", "var") || is("keyword", "let") || is("keyword", "const") ||
is("keyword", "class") || is("keyword", "function");

41
test/mocha/export.js Normal file
View File

@ -0,0 +1,41 @@
var assert = require("assert");
var uglify = require("../../");
describe("Export", function() {
it ("Should parse export directives", function() {
var inputs = [
['export * from "a.js"', ['*'], "a.js"],
['export {A} from "a.js"', ['A'], "a.js"],
['export {A, B} from "a.js"', ['A', 'B'], "a.js"],
];
var test = function(code) {
return uglify.parse(code, {fromString: true});
};
var extractNames = function(symbols) {
var ret = [];
for (var i = 0; i < symbols.length; i++) {
ret.push(symbols[i].name.name)
}
return ret;
};
for (var i = 0; i < inputs.length; i++) {
//console.log(inputs[i][0]);
var ast = test(inputs[i][0]);
var names = inputs[i][1];
var filename = inputs[i][2];
assert(ast instanceof uglify.AST_Toplevel);
assert.equal(ast.body.length, 1);
var st = ast.body[0];
assert(st instanceof uglify.AST_Export);
var actualNames = extractNames(st.exported_names);
assert.deepEqual(actualNames, names);
assert.equal(st.module_name.value, filename)
}
})
});