require(“./core”); var types = require(“../lib/types”); var def = types.Type.def; var or = types.Type.or; var builtin = types.builtInTypes; var isBoolean = builtin.boolean; var isObject = builtin.object; var isString = builtin.string; var defaults = require(“../lib/shared”).defaults;
def(“Function”)
.field("generator", isBoolean, defaults["false"]) .field("expression", isBoolean, defaults["false"]) .field("defaults", [or(def("Expression"), null)], defaults.emptyArray) // TODO This could be represented as a SpreadElementPattern in .params. .field("rest", or(def("Identifier"), null), defaults["null"]);
def(“FunctionDeclaration”)
.build("id", "params", "body", "generator", "expression");
def(“FunctionExpression”)
.build("id", "params", "body", "generator", "expression");
// TODO The Parser API calls this ArrowExpression, but Esprima uses // ArrowFunctionExpression. def(“ArrowFunctionExpression”)
.bases("Function", "Expression") .build("params", "body", "expression") // The forced null value here is compatible with the overridden // definition of the "id" field in the Function interface. .field("id", null, defaults["null"]) // The current spec forbids arrow generators, so I have taken the // liberty of enforcing that. TODO Report this. .field("generator", false);
def(“YieldExpression”)
.bases("Expression") .build("argument", "delegate") .field("argument", or(def("Expression"), null)) .field("delegate", isBoolean, defaults["false"]);
def(“GeneratorExpression”)
.bases("Expression") .build("body", "blocks", "filter") .field("body", def("Expression")) .field("blocks", [def("ComprehensionBlock")]) .field("filter", or(def("Expression"), null));
def(“ComprehensionExpression”)
.bases("Expression") .build("body", "blocks", "filter") .field("body", def("Expression")) .field("blocks", [def("ComprehensionBlock")]) .field("filter", or(def("Expression"), null));
def(“ComprehensionBlock”)
.bases("Node") .build("left", "right", "each") .field("left", def("Pattern")) .field("right", def("Expression")) .field("each", isBoolean);
def(“ModuleSpecifier”)
.bases("Literal") .build("value") .field("value", isString);
def(“Property”)
// Esprima extensions not mentioned in the Mozilla Parser API: .field("method", isBoolean, defaults["false"]) .field("shorthand", isBoolean, defaults["false"]) .field("computed", isBoolean, defaults["false"]);
def(“MethodDefinition”)
.bases("Declaration") .build("kind", "key", "value") .field("kind", or("init", "get", "set", "")) .field("key", or(def("Literal"), def("Identifier"))) .field("value", def("Function"));
def(“SpreadElement”)
.bases("Node") .build("argument") .field("argument", def("Expression"));
def(“ArrayExpression”)
.field("elements", [or(def("Expression"), def("SpreadElement"), null)]);
def(“NewExpression”)
.field("arguments", [or(def("Expression"), def("SpreadElement"))]);
def(“CallExpression”)
.field("arguments", [or(def("Expression"), def("SpreadElement"))]);
def(“SpreadElementPattern”)
.bases("Pattern") .build("argument") .field("argument", def("Pattern"));
var ClassBodyElement = or(
def("MethodDefinition"), def("VariableDeclarator"), def("ClassPropertyDefinition"), def("ClassProperty")
);
def(“ClassProperty”)
.bases("Declaration") .build("id") .field("id", def("Identifier"));
def(“ClassPropertyDefinition”) // static property
.bases("Declaration") .build("definition") // Yes, Virginia, circular definitions are permitted. .field("definition", ClassBodyElement);
def(“ClassBody”)
.bases("Declaration") .build("body") .field("body", [ClassBodyElement]);
def(“ClassDeclaration”)
.bases("Declaration") .build("id", "body", "superClass") .field("id", def("Identifier")) .field("body", def("ClassBody")) .field("superClass", or(def("Expression"), null), defaults["null"]);
def(“ClassExpression”)
.bases("Expression") .build("id", "body", "superClass") .field("id", or(def("Identifier"), null), defaults["null"]) .field("body", def("ClassBody")) .field("superClass", or(def("Expression"), null), defaults["null"]);
// Specifier and NamedSpecifier are abstract non-standard types that I // introduced for definitional convenience. def(“Specifier”).bases(“Node”); def(“NamedSpecifier”)
.bases("Specifier") // Note: this abstract type is intentionally not buildable. .field("id", def("Identifier")) .field("name", or(def("Identifier"), null), defaults["null"]);
// Like NamedSpecifier, except type:“ExportSpecifier” and buildable. // export {<id [as name]>} [from …]; def(“ExportSpecifier”)
.bases("NamedSpecifier") .build("id", "name");
// export <*> from …; def(“ExportBatchSpecifier”)
.bases("Specifier") .build();
// Like NamedSpecifier, except type:“ImportSpecifier” and buildable. // import {<id [as name]>} from …; def(“ImportSpecifier”)
.bases("NamedSpecifier") .build("id", "name");
// import <* as id> from …; def(“ImportNamespaceSpecifier”)
.bases("Specifier") .build("id") .field("id", def("Identifier"));
// import <id> from …; def(“ImportDefaultSpecifier”)
.bases("Specifier") .build("id") .field("id", def("Identifier"));
def(“ExportDeclaration”)
.bases("Declaration") .build("default", "declaration", "specifiers", "source") .field("default", isBoolean) .field("declaration", or( def("Declaration"), def("Expression"), // Implies default. null )) .field("specifiers", [or( def("ExportSpecifier"), def("ExportBatchSpecifier") )], defaults.emptyArray) .field("source", or(def("ModuleSpecifier"), null), defaults["null"]);
def(“ImportDeclaration”)
.bases("Declaration") .build("specifiers", "source") .field("specifiers", [or( def("ImportSpecifier"), def("ImportNamespaceSpecifier"), def("ImportDefaultSpecifier") )], defaults.emptyArray) .field("source", def("ModuleSpecifier"));
def(“TaggedTemplateExpression”)
.bases("Expression") .field("tag", def("Expression")) .field("quasi", def("TemplateLiteral"));
def(“TemplateLiteral”)
.bases("Expression") .build("quasis", "expressions") .field("quasis", [def("TemplateElement")]) .field("expressions", [def("Expression")]);
def(“TemplateElement”)
.bases("Node") .build("value", "tail") .field("value", {"cooked": isString, "raw": isString}) .field("tail", isBoolean);