1var esprima = require('esprima') 2var escodegen = require('escodegen') 3 4// code sample of hacking old script 5;({ 6 "type": "Program", 7 "body": [ 8 { 9 "type": "ExpressionStatement", 10 "expression": { 11 "type": "AssignmentExpression", 12 "operator": "=", 13 "left": { 14 "type": "MemberExpression", 15 "computed": false, 16 "object": { 17 "type": "Identifier", 18 "name": "module" 19 }, 20 "property": { 21 "type": "Identifier", 22 "name": "exports" 23 } 24 }, 25 "right": { 26 "type": "ObjectExpression", 27 "properties": [ 28 { 29 "type": "Property", 30 "key": { 31 "type": "Identifier", 32 "name": "data" 33 }, 34 "computed": false, 35 "value": { 36 // "type": "FunctionExpression", 37 // "id": null, 38 // "params": [], 39 // "defaults": [], 40 // "body": { 41 // "type": "BlockStatement", 42 // "body": [ 43 // { 44 // "type": "ReturnStatement", 45 // "argument": { 46 "type": "ObjectExpression", 47 "properties": [] 48 // } 49 // } 50 // ] 51 // }, 52 // "generator": false, 53 // "expression": false 54 }, 55 "kind": "init", 56 "method": false, 57 "shorthand": false 58 } 59 ] 60 } 61 } 62 } 63 ], 64 "sourceType": "script" 65}) 66 67var LEFT_MODULE_EXPORTS_AST = { 68 "type": "MemberExpression", 69 "computed": false, 70 "object": { 71 "type": "Identifier", 72 "name": "module" 73 }, 74 "property": { 75 "type": "Identifier", 76 "name": "exports" 77 } 78} 79 80function removeAllLoc(ast) { 81 ast = JSON.parse(JSON.stringify(ast)) 82 function remove(o) { 83 if (Array.isArray(o)) { 84 o.forEach(remove) 85 } 86 else if (typeof o === 'object') { 87 for (var i in o) { 88 if (i === 'loc') { 89 delete o[i] 90 } 91 if (i === 'range') { 92 delete o[i] 93 } 94 else { 95 if (typeof o[i] === 'object') { 96 remove(o[i]) 97 } 98 } 99 } 100 } 101 } 102 remove(ast) 103 return ast 104} 105 106function findDataValue(ast) { 107 var exp, left, right, dataValue 108 if (ast && ast.body && ast.body.length) { 109 ast.body.forEach(function (bodyItem) { 110 if (bodyItem.type === 'ExpressionStatement') { 111 exp = bodyItem.expression 112 if (exp.type === 'AssignmentExpression' && exp.operator === '=') { 113 left = removeAllLoc(exp.left || {}) 114 if (JSON.stringify(left) === JSON.stringify(LEFT_MODULE_EXPORTS_AST)) { 115 right = exp.right 116 if (right.type === 'ObjectExpression') { 117 right.properties.some(function (prop) { 118 if (prop.type === 'Property' && prop.key && prop.key.name === 'data') { 119 if (prop.value && prop.value.type === 'ObjectExpression') { 120 dataValue = prop 121 return true 122 } 123 } 124 }) 125 } 126 } 127 } 128 } 129 }) 130 } 131 return dataValue 132} 133 134function convertValueAst(value) { 135 var data = { 136 type: "FunctionExpression", 137 id: null, 138 params: [], 139 defaults: [], 140 body: { 141 type: "BlockStatement", 142 body: [ 143 { 144 type: "ReturnStatement", 145 argument: value 146 } 147 ] 148 }, 149 generator: false, 150 expression: false 151 } 152 return data 153} 154 155function format(code, needCodegen) { 156 var ast = esprima.parse(code) 157 var prop = findDataValue(ast) 158 159 if (prop) { 160 prop.value = convertValueAst(prop.value) 161 needCodegen = true 162 } 163 164 return needCodegen ? escodegen.generate(ast) : code 165} 166 167function formatBetter(code) { 168 esprima.parse(code, {range: true}) 169 170 return code 171} 172 173exports.fix = formatBetter 174exports.formatWhenFix = format 175