require(“./core”); var types = require(“../lib/types”); var def = types.Type.def; var or = types.Type.or; var builtin = types.builtInTypes; var isString = builtin.string; var isBoolean = builtin.boolean; var defaults = require(“../lib/shared”).defaults;
def(“XJSAttribute”)
.bases("Node") .build("name", "value") .field("name", or(def("XJSIdentifier"), def("XJSNamespacedName"))) .field("value", or( def("Literal"), // attr="value" def("XJSExpressionContainer"), // attr={value} null // attr= or just attr ), defaults["null"]);
def(“XJSIdentifier”)
.bases("Node") .build("name") .field("name", isString);
def(“XJSNamespacedName”)
.bases("Node") .build("namespace", "name") .field("namespace", def("XJSIdentifier")) .field("name", def("XJSIdentifier"));
def(“XJSMemberExpression”)
.bases("MemberExpression") .build("object", "property") .field("object", or(def("XJSIdentifier"), def("XJSMemberExpression"))) .field("property", def("XJSIdentifier")) .field("computed", isBoolean, defaults.false);
var XJSElementName = or(
def("XJSIdentifier"), def("XJSNamespacedName"), def("XJSMemberExpression")
);
def(“XJSSpreadAttribute”)
.bases("Node") .build("argument") .field("argument", def("Expression"));
var XJSAttributes = [or(
def("XJSAttribute"), def("XJSSpreadAttribute")
)];
def(“XJSExpressionContainer”)
.bases("Expression") .build("expression") .field("expression", def("Expression"));
def(“XJSElement”)
.bases("Expression") .build("openingElement", "closingElement", "children") .field("openingElement", def("XJSOpeningElement")) .field("closingElement", or(def("XJSClosingElement"), null), defaults["null"]) .field("children", [or( def("XJSElement"), def("XJSExpressionContainer"), def("XJSText"), def("Literal") // TODO Esprima should return XJSText instead. )], defaults.emptyArray) .field("name", XJSElementName, function() { // Little-known fact: the `this` object inside a default function // is none other than the partially-built object itself, and any // fields initialized directly from builder function arguments // (like openingElement, closingElement, and children) are // guaranteed to be available. return this.openingElement.name; }) .field("selfClosing", isBoolean, function() { return this.openingElement.selfClosing; }) .field("attributes", XJSAttributes, function() { return this.openingElement.attributes; });
def(“XJSOpeningElement”)
.bases("Node") // TODO Does this make sense? Can't really be an XJSElement. .build("name", "attributes", "selfClosing") .field("name", XJSElementName) .field("attributes", XJSAttributes, defaults.emptyArray) .field("selfClosing", isBoolean, defaults["false"]);
def(“XJSClosingElement”)
.bases("Node") // TODO Same concern. .build("name") .field("name", XJSElementName);
def(“XJSText”)
.bases("Literal") .build("value") .field("value", isString);
def(“XJSEmptyExpression”).bases(“Expression”).build();
def(“TypeAnnotatedIdentifier”)
.bases("Pattern") .build("annotation", "identifier") .field("annotation", def("TypeAnnotation")) .field("identifier", def("Identifier"));
def(“TypeAnnotation”)
.bases("Pattern") .build("annotatedType", "templateTypes", "paramTypes", "returnType", "unionType", "nullable") .field("annotatedType", def("Identifier")) .field("templateTypes", or([def("TypeAnnotation")], null)) .field("paramTypes", or([def("TypeAnnotation")], null)) .field("returnType", or(def("TypeAnnotation"), null)) .field("unionType", or(def("TypeAnnotation"), null)) .field("nullable", isBoolean);
def(“Identifier”)
.field("annotation", or(def("TypeAnnotation"), null), defaults['null']);
def(“Function”)
.field("returnType", or(def("TypeAnnotation"), null), defaults['null']);
def(“ClassProperty”)
.field("id", or(def("Identifier"), def("TypeAnnotatedIdentifier")));