• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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