const t = require('@babel/types') const { VAR_MP, VAR_ROOT, VAR_ORIGINAL, VAR_INDEX, INTERNAL_GET_ORIG, IDENTIFIER_METHOD, IDENTIFIER_FILTER } = require('../../constants') /** * e0=e=>count++ */ function getEventExpressionStatement (left, right) { return t.expressionStatement( t.assignmentExpression( '=', left, right ) ) } /** * if(!_isMounted){} */ function getInItIfStatement (expressionStatementArray) { return t.ifStatement( t.unaryExpression( '!', t.identifier('_isMounted') ), t.blockStatement(expressionStatementArray) ) } function getRenderSlotStatement (state, renderSlotStatementArray, forItem) { function cloneNode (node) { if (Array.isArray(node)) { return node.map(function (item) { return cloneNode(item) }) } else if (typeof node === 'object') { if (!node) { return node } if (t.isMemberExpression(node)) { // 纠正被处理过的对象 const name = node.object.name // identifier 使用原值以被后续修改 if ((name === VAR_ROOT || name === forItem) && t.isIdentifier(node.property) && [IDENTIFIER_METHOD, IDENTIFIER_FILTER].includes(node.property.name)) { return node.property } } else if (t.isIdentifier(node, { name: forItem })) { // 预处理 forItem return t.identifier(VAR_ORIGINAL) } const target = Object.create(node) Object.keys(node).forEach(function (key) { target[key] = cloneNode(node[key]) }) return target } else { return node } } renderSlotStatementArray.forEach(renderSlotStatement => { const argument = renderSlotStatement.expression.arguments[1] if (t.isObjectExpression(argument)) { // 克隆以避免影响模板 argument.properties = cloneNode(argument.properties) } }) const blockStatement = t.blockStatement(renderSlotStatementArray) if (state.options.scopedSlotsCompiler === 'auto') { return t.ifStatement( t.binaryExpression('===', t.memberExpression(t.memberExpression(t.identifier('$scope'), t.identifier(state.options.platform.name === 'mp-alipay' ? 'props' : 'data')), t.identifier('scopedSlotsCompiler')), t.stringLiteral('augmented') ), blockStatement ) } return blockStatement } /** * items.map(function(item,index){return {}}) */ function getMapCallExpression ( object, objectPropertyArray, declarationArray, renderSlotStatementArray, eventPropertyArray, forItem, forKey, forIndex, state ) { const blockStatement = [] // var $orgi = __get_orig(forItem) blockStatement.push(t.variableDeclaration('var', [ t.variableDeclarator(t.identifier(VAR_ORIGINAL), t.callExpression(t.identifier(INTERNAL_GET_ORIG), [ t.identifier(forItem) ])) ])) if (declarationArray.length) { declarationArray.forEach(declaration => { blockStatement.push(declaration) }) } if (renderSlotStatementArray.length) { blockStatement.push(getRenderSlotStatement(state, renderSlotStatementArray, forItem)) } blockStatement.push(t.returnStatement( // return {$orgi:$orgi} t.objectExpression( [ t.objectProperty( t.identifier(VAR_ORIGINAL), t.identifier(VAR_ORIGINAL) ) ].concat(objectPropertyArray) .concat(forKey && forIndex ? [t.objectProperty( t.identifier(VAR_INDEX), t.identifier(forIndex) )] : []) ) )) const params = [t.identifier(forItem)] if (forKey) { params.push(t.identifier(forKey)) } if (forIndex) { params.push(t.identifier(forIndex)) } return t.callExpression(t.identifier('__map'), [ object, t.functionExpression( null, params, t.blockStatement(blockStatement) ) ]) } /** * $mp.data = Object.assign({},{$root:{}}) */ function getDataExpressionStatement (objectPropertyArray) { return t.expressionStatement( t.assignmentExpression( '=', t.memberExpression( // left t.identifier(VAR_MP), t.identifier('data') ), t.callExpression( // right t.memberExpression( // Object.assign t.identifier('Object'), t.identifier('assign') ), [ t.objectExpression([]), // {} t.objectExpression([ // {$root:{}} t.objectProperty( t.identifier(VAR_ROOT), t.objectExpression(objectPropertyArray) ) ]) ] ) ) ) } module.exports = { getInItIfStatement, getMapCallExpression, getDataExpressionStatement, getEventExpressionStatement, getRenderSlotStatement }