buildBody() { this.constructorMeMaybe(); this.pushBody(); this.verifyConstructor(); if (this.userConstructor) { let constructorBody = this.constructorBody; constructorBody.body = constructorBody.body.concat(this.userConstructor.body.body); t.inherits(this.constructor, this.userConstructor); t.inherits(constructorBody, this.userConstructor.body); } this.pushDescriptors(); }
pushConstructor(replaceSupers, method: { type: "ClassMethod" }, path: NodePath) { this.bareSupers = replaceSupers.bareSupers; this.superReturns = replaceSupers.returns; // https://github.com/babel/babel/issues/1077 if (path.scope.hasOwnBinding(this.classRef.name)) { path.scope.rename(this.classRef.name); } let construct = this.constructor; this.userConstructorPath = path; this.userConstructor = method; this.hasConstructor = true; t.inheritsComments(construct, method); construct._ignoreUserWhitespace = true; construct.params = method.params; t.inherits(construct.body, method.body); construct.body.directives = method.body.directives; // push constructor to body this._pushConstructor(); }
function convertAttribute(node) { let value = convertAttributeValue(node.value || t.booleanLiteral(true)); if (t.isStringLiteral(value)) { value.value = value.value.replace(/\n\s+/g, " "); } if (t.isValidIdentifier(node.name.name)) { node.name.type = "Identifier"; } else { node.name = t.stringLiteral(node.name.name); } return t.inherits(t.objectProperty(node.name, value), node); }
pushDeclar(node: { type: "VariableDeclaration" }): Array<Object> { let declars = []; let names = t.getBindingIdentifiers(node); for (let name in names) { declars.push(t.variableDeclarator(names[name])); } this.body.push(t.variableDeclaration(node.kind, declars)); let replace = []; for (let i = 0; i < node.declarations.length; i++) { let declar = node.declarations[i]; if (!declar.init) continue; let expr = t.assignmentExpression("=", declar.id, declar.init); replace.push(t.inherits(expr, declar)); } return replace; }
export default function (opts) { let visitor = {}; visitor.JSXNamespacedName = function (path) { throw path.buildCodeFrameError("Namespace tags are not supported. ReactJSX is not XML."); }; visitor.JSXElement = { exit(path, file) { let callExpr = buildElementCall(path.get("openingElement"), file); callExpr.arguments = callExpr.arguments.concat(path.node.children); if (callExpr.arguments.length >= 3) { callExpr._prettyCall = true; } path.replaceWith(t.inherits(callExpr, path.node)); } }; return visitor; function convertJSXIdentifier(node, parent) { if (t.isJSXIdentifier(node)) { if (node.name === "this" && t.isReferenced(node, parent)) { return t.thisExpression(); } else if (esutils.keyword.isIdentifierNameES6(node.name)) { node.type = "Identifier"; } else { return t.stringLiteral(node.name); } } else if (t.isJSXMemberExpression(node)) { return t.memberExpression( convertJSXIdentifier(node.object, node), convertJSXIdentifier(node.property, node) ); } return node; } function convertAttributeValue(node) { if (t.isJSXExpressionContainer(node)) { return node.expression; } else { return node; } } function convertAttribute(node) { let value = convertAttributeValue(node.value || t.booleanLiteral(true)); if (t.isStringLiteral(value)) { value.value = value.value.replace(/\n\s+/g, " "); } if (t.isValidIdentifier(node.name.name)) { node.name.type = "Identifier"; } else { node.name = t.stringLiteral(node.name.name); } return t.inherits(t.objectProperty(node.name, value), node); } function buildElementCall(path, file) { path.parent.children = t.react.buildChildren(path.parent); let tagExpr = convertJSXIdentifier(path.node.name, path.node); let args = []; let tagName; if (t.isIdentifier(tagExpr)) { tagName = tagExpr.name; } else if (t.isLiteral(tagExpr)) { tagName = tagExpr.value; } let state: ElementState = { tagExpr: tagExpr, tagName: tagName, args: args }; if (opts.pre) { opts.pre(state, file); } let attribs = path.node.attributes; if (attribs.length) { attribs = buildOpeningElementAttributes(attribs, file); } else { attribs = t.nullLiteral(); } args.push(attribs); if (opts.post) { opts.post(state, file); } return state.call || t.callExpression(state.callee, args); } /** * The logic for this is quite terse. It's because we need to * support spread elements. We loop over all attributes, * breaking on spreads, we then push a new object containg * all prior attributes to an array for later processing. */ function buildOpeningElementAttributes(attribs, file) { let _props = []; let objs = []; function pushProps() { if (!_props.length) return; objs.push(t.objectExpression(_props)); _props = []; } while (attribs.length) { let prop = attribs.shift(); if (t.isJSXSpreadAttribute(prop)) { pushProps(); objs.push(prop.argument); } else { _props.push(convertAttribute(prop)); } } pushProps(); if (objs.length === 1) { // only one object attribs = objs[0]; } else { // looks like we have multiple objects if (!t.isObjectExpression(objs[0])) { objs.unshift(t.objectExpression([])); } // spread it attribs = t.callExpression( file.addHelper("extends"), objs ); } return attribs; } }
state.map[loopText] = node; replace = t.stringLiteral(loopText); } if (path.isReturnStatement()) { state.hasReturn = true; replace = t.objectExpression([ t.objectProperty(t.identifier("v"), node.argument || scope.buildUndefinedNode()) ]); } if (replace) { replace = t.returnStatement(replace); replace[this.LOOP_IGNORE] = true; path.skip(); path.replaceWith(t.inherits(replace, node)); } } }; class BlockScoping { constructor(loopPath?: NodePath, blockPath: NodePath, parent: Object, scope: Scope, file: File) { this.parent = parent; this.scope = scope; this.file = file; this.blockPath = blockPath; this.block = blockPath.node; this.outsideLetReferences = Object.create(null); this.hasLetReferences = false;
buildConstructor() { let func = t.functionDeclaration(this.classRef, [], this.constructorBody); t.inherits(func, this.node); return func; }