var build = function () { var self = node.blocks.shift(); if (!self) return; var child = build(); if (!child) { // last item child = util.template("array-push", { STATEMENT: node.body, KEY: uid }, true); // add a filter as this is our final stop if (node.filter) { child = b.ifStatement(node.filter, b.blockStatement([child])); } } var container2 = util.template("array-comprehension-for-each", { ARRAY: self.right, KEY: self.left }, true); // set function body container2.expression.arguments[0].body.body = [child]; return container2; };
var buildVariableAssign = function (kind, id, init) { if (kind === false) { return b.expressionStatement(b.assignmentExpression("=", id, init)); } else { return b.variableDeclaration(kind, [ b.variableDeclarator(id, init) ]); } };
var pushPattern = function (kind, nodes, pattern, parentId, file) { if (parentId.type !== "MemberExpression" && parentId.type !== "Identifier") { var key = b.identifier(file.generateUid("ref")); nodes.push(b.variableDeclaration("var", [ b.variableDeclarator(key, parentId) ])); parentId = key; } push(kind, nodes, pattern, parentId); };
exports.XJSIdentifier = function (node) { if (esutils.keyword.isIdentifierName(node.name)) { node.type = "Identifier"; } else { return b.literal(node.name); } };
_.each(classBody, function (node) { var methodName = node.key.name; var method = node.value; replaceInstanceSuperReferences(superName, method, node, methodName); if (methodName === "constructor") { if (node.kind === "") { hasConstructor = true; addConstructor(construct, method); } else { throw util.errorWithNode(node, "unknown kind for constructor method"); } } else { var mutatorMap = instanceMutatorMap; if (node.static) mutatorMap = staticMutatorMap; var kind = node.kind; if (kind === "") { kind = "value"; util.pushMutatorMap(mutatorMap, methodName, "writable", b.identifier("true")); } util.pushMutatorMap(mutatorMap, methodName, kind, node); } });
exit: function (node, parent, file) { var tagExpr = node.name; if (_.contains(KNOWN_TAGS, tagExpr.name)) { tagExpr = b.memberExpression(file.jsx, tagExpr, false); } var props = node.attributes; if (props.length) { props = b.objectExpression(props); } else { props = b.literal(null); } return b.callExpression(tagExpr, [props]); }
exports.ExpressionStatement = function (node, parent, file) { var expr = node.expression; if (expr.type !== "AssignmentExpression") return; if (!traverse.isPattern(expr.left)) return; var nodes = []; var ref = b.identifier(file.generateUid("ref")); nodes.push(b.variableDeclaration("var", [ b.variableDeclarator(ref, expr.right) ])); push(false, nodes, expr.left, ref); return nodes; };
node.params = node.params.map(function (pattern) { if (!traverse.isPattern(pattern)) return pattern; hasDestructuring = true; var parentId = b.identifier(file.generateUid("ref")); pushPattern("var", nodes, pattern, parentId, file); return parentId; });
UMDFormatter.prototype.transform = function (ast) { var program = ast.program; var body = program.body; // build an array of module names var names = []; _.each(this.ids, function (id, name) { names.push(b.literal(name)); }); // factory var ids = _.values(this.ids); var args = [b.identifier("exports")].concat(ids); var factory = b.functionExpression(null, args, b.blockStatement(body)); // runner var runner = util.template("umd-runner-body", { AMD_ARGUMENTS: b.arrayExpression([b.literal("exports")].concat(names)), COMMON_ARGUMENTS: names.map(function (name) { return b.callExpression(b.identifier("require"), [name]); }) }); // var call = b.callExpression(runner, [factory]); program.body = [b.expressionStatement(call)]; };
_.each(pattern.properties, function (prop) { var pattern2 = prop.value; var patternId2 = b.memberExpression(parentId, prop.key, false); if (traverse.isPattern(pattern2)) { push(kind, nodes, pattern2, patternId2); } else { nodes.push(buildVariableAssign(kind, pattern2, patternId2)); } });
var buildClass = function (node, file) { var superName = node.superClass; var className = node.id || b.identifier(file.generateUid("class")); var superClassArgument = node.superClass; var superClassCallee = node.superClass; if (superName) { if (superName.type === "MemberExpression") { superClassArgument = superClassCallee = getMemberExpressionObject(superName); } else if (superName.type !== "Identifier") { superClassArgument = superName; superClassCallee = superName = b.identifier(file.generateUid("ref")); } } var container = util.template("class", { CLASS_NAME: className }); var block = container.callee.body; var body = block.body; if (node.id) { body[0].declarations[0].init.id = className; } var returnStatement = body.pop(); if (superName) { body.push(b.expressionStatement(b.callExpression(file.addDeclaration("extends"), [className, superName]))); container.arguments.push(superClassArgument); container.callee.params.push(superClassCallee); } buildClassBody(file, body, className, superName, node); body.push(returnStatement); return container; };
exports.Literal = function (node) { var regex = node.regex; if (!regex) return; var flags = regex.flags.split(""); if (!_.contains(regex.flags, "u")) return; _.pull(flags, "u"); var pattern = rewritePattern(regex.pattern, regex.flags); return b.literal(new RegExp(pattern, flags.join(""))); };
exports.ForOfStatement = function (node, parent, file) { var declar = node.left; if (declar.type !== "VariableDeclaration") return; var pattern = declar.declarations[0].id; if (!traverse.isPattern(pattern)) return; var key = b.identifier(file.generateUid("ref")); node.left = b.variableDeclaration(declar.kind, [ b.variableDeclarator(key, null) ]); var nodes = []; push(declar.kind, nodes, pattern, key); util.ensureBlock(node); var block = node.body; block.body = nodes.concat(block.body); };
traverse(method, function (node, parent) { if (node.type === "Identifier" && node.name === "super") { return superIdentifier(superName, methodNode, methodName, node, parent); } else if (node.type === "CallExpression") { var callee = node.callee; if (callee.type !== "MemberExpression") return; if (callee.object.name !== "super") return; // super.test(); -> ClassName.prototype.MethodName.call(this); callee.property.name = callee.property.name + ".call"; node.arguments.unshift(b.thisExpression()); } });
CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) { var variableName = util.getSpecifierName(specifier); // import foo from "foo"; if (specifier.default) { specifier.id = b.identifier("default"); } var templateName = "require-assign"; // import * as bar from "foo"; if (specifier.type !== "ImportBatchSpecifier") templateName += "-key"; nodes.push(util.template(templateName, { VARIABLE_NAME: variableName, MODULE_NAME: node.source.raw, KEY: specifier.id })); };
COMMON_ARGUMENTS: names.map(function (name) { return b.callExpression(b.identifier("require"), [name]); })
var getArgumentsId = function () { return argumentsId = argumentsId || b.identifier(file.generateUid("arguments")); };
var superIdentifier = function (superName, methodNode, methodName, node, parent) { if (parent.property === node) { return; } else if (parent.type === "CallExpression" && parent.callee === node) { // super(); -> ClassName.prototype.MethodName.call(this); parent.arguments.unshift(b.thisExpression()); if (methodName === "constructor") { // constructor() { super(); } return b.memberExpression(superName, b.identifier("call"), false); } else { node = superName; // foo() { super(); } if (!methodNode.static) { node = b.memberExpression(node, b.identifier("prototype"), false); } node = b.memberExpression(node, b.identifier(methodName), false); return b.memberExpression(node, b.identifier("call"), false); } } else if (parent.type === "MemberExpression" && !methodNode.static) { // super.test -> ClassName.prototype.test return b.memberExpression(superName, b.identifier("prototype"), false); } else { return superName; } };
file.jsx = jsx.split(".").map(b.identifier).reduce(function (object, property) { return b.memberExpression(object, property, false); });
_.each(pattern.elements, function (elem, i) { if (!elem) return; var newPatternId = b.memberExpression(parentId, b.literal(i), true); push(kind, nodes, elem, newPatternId); });
var buildClassBody = function (file, body, className, superName, node) { var instanceMutatorMap = {}; var staticMutatorMap = {}; var hasConstructor = false; var construct = body[0].declarations[0].init; var classBody = node.body.body; _.each(classBody, function (node) { var methodName = node.key.name; var method = node.value; replaceInstanceSuperReferences(superName, method, node, methodName); if (methodName === "constructor") { if (node.kind === "") { hasConstructor = true; addConstructor(construct, method); } else { throw util.errorWithNode(node, "unknown kind for constructor method"); } } else { var mutatorMap = instanceMutatorMap; if (node.static) mutatorMap = staticMutatorMap; var kind = node.kind; if (kind === "") { kind = "value"; util.pushMutatorMap(mutatorMap, methodName, "writable", b.identifier("true")); } util.pushMutatorMap(mutatorMap, methodName, kind, node); } }); if (!hasConstructor && superName) { construct.body.body.push(util.template("class-super-constructor-call", { SUPER_NAME: superName }, true)); } var instanceProps; var staticProps; if (!_.isEmpty(instanceMutatorMap)) { var protoId = util.template("prototype-identifier", { CLASS_NAME: className }); instanceProps = util.buildDefineProperties(instanceMutatorMap, protoId); } if (!_.isEmpty(staticMutatorMap)) { staticProps = util.buildDefineProperties(staticMutatorMap, className); } if (instanceProps || staticProps) { instanceProps = instanceProps || b.literal(null); staticProps = staticProps || b.literal(null); body.push(b.expressionStatement( b.callExpression(file.addDeclaration("class-props"), [className, staticProps, instanceProps]) )); } };
_.each(this.ids, function (id, name) { names.push(b.literal(name)); });
exit: function (node) { var value = node.value || b.literal(true); var propNode = b.property("init", node.name, value); propNode.loc = node.loc; return propNode; }
exports.ClassDeclaration = function (node, parent, file) { return b.variableDeclaration("var", [ b.variableDeclarator(node.id, buildClass(node, file)) ]); };
return this._exportSpecifier(function () { return b.callExpression(b.identifier("require"), [node.source]); }, specifier, node, nodes);
var pushDeclaration = function (id, init) { body = body || getBody(); body.unshift(b.variableDeclaration("var", [ b.variableDeclarator(id, init) ])); };
var go = function (getBody, node, file) { var argumentsId; var thisId; var getArgumentsId = function () { return argumentsId = argumentsId || b.identifier(file.generateUid("arguments")); }; var getThisId = function () { return thisId = thisId || b.identifier(file.generateUid("this")); }; // traverse the function and find all alias functions so we can alias // arguments and this if necessary traverse(node, function (node) { var _aliasFunction = node._aliasFunction; if (!_aliasFunction) { if (traverse.isFunction(node)) { // stop traversal of this node as it'll be hit again by this transformer return false; } else { return; } } // traverse all child nodes of this function and find arguments and this traverse(node, function (node, parent) { if (_aliasFunction === "arrows") { if (traverse.isFunction(node) && node._aliasFunction !== "arrows") { return false; } } if (node._ignoreAliasFunctions) return; var getId; if (node.type === "Identifier" && node.name === "arguments") { getId = getArgumentsId; } else if (node.type === "ThisExpression") { getId = getThisId; } else { return; } if (util.isReferenced(node, parent)) return getId(); }); return false; }); var body; var pushDeclaration = function (id, init) { body = body || getBody(); body.unshift(b.variableDeclaration("var", [ b.variableDeclarator(id, init) ])); }; if (argumentsId) { pushDeclaration(argumentsId, b.identifier("arguments")); } if (thisId) { pushDeclaration(thisId, b.identifier("this")); } };
var getThisId = function () { return thisId = thisId || b.identifier(file.generateUid("this")); };