support export statements (#4650)

This commit is contained in:
Alex Lam S.L
2021-02-14 20:13:54 +00:00
committed by GitHub
parent b7219ac489
commit c21f096ab8
9 changed files with 526 additions and 16 deletions

View File

@@ -207,6 +207,7 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
_validate: function() {
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 (typeof this.value != "string") throw new Error("value must be string");
},
@@ -238,7 +239,7 @@ function must_be_expression(node, prop) {
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
$documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
$propdoc: {
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
},
walk: function(visitor) {
var node = this;
@@ -1038,6 +1039,86 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
/* -----[ OTHER ]----- */
var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
$documentation: "An `export` statement",
$propdoc: {
body: "[AST_Definitions|AST_LambdaDefinition] the statement to export",
},
walk: function(visitor) {
var node = this;
visitor.visit(node, function() {
node.body.walk(visitor);
});
},
_validate: function() {
if (!(this.body instanceof AST_Definitions || this.body instanceof AST_LambdaDefinition)) {
throw new Error("body must be AST_Definitions or AST_LambdaDefinition");
}
},
}, AST_Statement);
var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
$documentation: "An `export default` statement",
$propdoc: {
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
},
walk: function(visitor) {
var node = this;
visitor.visit(node, function() {
node.body.walk(visitor);
});
},
_validate: function() {
must_be_expression(this, "body");
},
}, AST_Statement);
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
$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",
},
_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");
});
this.keys.forEach(function(name) {
if (typeof name != "string") throw new Error("keys must contain 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);
}
},
}, AST_Statement);
var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
$documentation: "An `export { ... }` statement",
$propdoc: {
properties: "[AST_SymbolExport*] array of aliases to export",
},
walk: function(visitor) {
var node = this;
visitor.visit(node, function() {
node.properties.forEach(function(prop) {
prop.walk(visitor);
});
});
},
_validate: function() {
this.properties.forEach(function(prop) {
if (!(prop instanceof AST_SymbolExport)) throw new Error("properties must contain AST_SymbolExport");
});
},
}, AST_Statement);
var AST_Import = DEFNODE("Import", "all default path properties quote", {
$documentation: "An `import` statement",
$propdoc: {
@@ -1072,6 +1153,7 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
});
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);
@@ -1572,6 +1654,16 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
$documentation: "Reference to some symbol (not definition/declaration)",
}, AST_Symbol);
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
$documentation: "Reference in an `export` statement",
$propdoc: {
alias: "[string] the `export` alias",
},
_validate: function() {
if (typeof this.alias != "string") throw new Error("alias must be string");
},
}, AST_SymbolRef);
var AST_LabelRef = DEFNODE("LabelRef", null, {
$documentation: "Reference to a label symbol",
}, AST_Symbol);
@@ -1627,6 +1719,7 @@ var AST_String = DEFNODE("String", "quote value", {
_validate: function() {
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 (typeof this.value != "string") throw new Error("value must be string");
},