require("./es7"); var types = require("../lib/types"); var def = types.Type.def; var or = types.Type.or; var defaults = require("../lib/shared").defaults; def("JSXAttribute") .bases("Node") .build("name", "value") .field("name", or(def("JSXIdentifier"), def("JSXNamespacedName"))) .field("value", or( def("Literal"), // attr="value" def("JSXExpressionContainer"), // attr={value} null // attr= or just attr ), defaults["null"]); def("JSXIdentifier") .bases("Identifier") .build("name") .field("name", String); def("JSXNamespacedName") .bases("Node") .build("namespace", "name") .field("namespace", def("JSXIdentifier")) .field("name", def("JSXIdentifier")); def("JSXMemberExpression") .bases("MemberExpression") .build("object", "property") .field("object", or(def("JSXIdentifier"), def("JSXMemberExpression"))) .field("property", def("JSXIdentifier")) .field("computed", Boolean, defaults.false); var JSXElementName = or( def("JSXIdentifier"), def("JSXNamespacedName"), def("JSXMemberExpression") ); def("JSXSpreadAttribute") .bases("Node") .build("argument") .field("argument", def("Expression")); var JSXAttributes = [or( def("JSXAttribute"), def("JSXSpreadAttribute") )]; def("JSXExpressionContainer") .bases("Expression") .build("expression") .field("expression", def("Expression")); def("JSXElement") .bases("Expression") .build("openingElement", "closingElement", "children") .field("openingElement", def("JSXOpeningElement")) .field("closingElement", or(def("JSXClosingElement"), null), defaults["null"]) .field("children", [or( def("JSXElement"), def("JSXExpressionContainer"), def("JSXText"), def("Literal") // TODO Esprima should return JSXText instead. )], defaults.emptyArray) .field("name", JSXElementName, 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; }, true) // hidden from traversal .field("selfClosing", Boolean, function() { return this.openingElement.selfClosing; }, true) // hidden from traversal .field("attributes", JSXAttributes, function() { return this.openingElement.attributes; }, true); // hidden from traversal def("JSXOpeningElement") .bases("Node") // TODO Does this make sense? Can't really be an JSXElement. .build("name", "attributes", "selfClosing") .field("name", JSXElementName) .field("attributes", JSXAttributes, defaults.emptyArray) .field("selfClosing", Boolean, defaults["false"]); def("JSXClosingElement") .bases("Node") // TODO Same concern. .build("name") .field("name", JSXElementName); def("JSXText") .bases("Literal") .build("value") .field("value", String); def("JSXEmptyExpression").bases("Expression").build();