import { types as t } from "@babel/core"; // tries to optimize sequence expressions in the format // (a = b, ((c) => d + e)(a)) // to // (a = b, a + e) const buildOptimizedSequenceExpression = ({ assign, call, path }) => { const { left: placeholderNode, right: pipelineLeft } = assign; const { callee: calledExpression } = call; let optimizeArrow = t.isArrowFunctionExpression(calledExpression) && t.isExpression(calledExpression.body) && !calledExpression.async && !calledExpression.generator; let param; if (optimizeArrow) { const { params } = calledExpression; if (params.length === 1 && t.isIdentifier(params[0])) { param = params[0]; } else if (params.length > 0) { optimizeArrow = false; } } else if (t.isIdentifier(calledExpression, { name: "eval" })) { const evalSequence = t.sequenceExpression([ t.numericLiteral(0), calledExpression, ]); call.callee = evalSequence; path.scope.push({ id: placeholderNode }); return t.sequenceExpression([assign, call]); } if (optimizeArrow && !param) { // Arrow function with 0 arguments return t.sequenceExpression([pipelineLeft, calledExpression.body]); } path.scope.push({ id: placeholderNode }); if (param) { path.get("right").scope.rename(param.name, placeholderNode.name); return t.sequenceExpression([assign, calledExpression.body]); } return t.sequenceExpression([assign, call]); }; export default buildOptimizedSequenceExpression;