1 | var acorn = require('acorn')
|
2 | var isBuffer = require('is-buffer')
|
3 | var MagicString = require('magic-string')
|
4 |
|
5 | module.exports = function astTransform (source, options, cb) {
|
6 | if (typeof options === 'function') {
|
7 | cb = options
|
8 | options = {}
|
9 | }
|
10 | if (typeof source === 'object' && !isBuffer(source)) {
|
11 | options = source
|
12 | }
|
13 | if (!options) options = {}
|
14 | if (options.source) {
|
15 | source = options.source
|
16 | delete options.source
|
17 | }
|
18 | if (isBuffer(source)) {
|
19 | source = source.toString('utf8')
|
20 | }
|
21 |
|
22 | var parse = (options.parser || acorn).parse
|
23 |
|
24 | var string = new MagicString(source, options)
|
25 | var ast = parse(source + '', options)
|
26 |
|
27 | walk(ast, null, cb || function () {})
|
28 |
|
29 | string.inspect = string.toString
|
30 | string.walk = function (cb) {
|
31 | walk(ast, null, cb)
|
32 | }
|
33 | return string
|
34 |
|
35 | function walk (node, parent, cb) {
|
36 | node.parent = parent
|
37 | if (!node.edit) {
|
38 | addHelpers(node)
|
39 | }
|
40 |
|
41 | Object.keys(node).forEach(function (key) {
|
42 | if (key === 'parent') return null
|
43 | if (Array.isArray(node[key])) {
|
44 | node[key].forEach(function (child) {
|
45 | if (child && typeof child.type === 'string') {
|
46 | walk(child, node, cb)
|
47 | }
|
48 | })
|
49 | }
|
50 | if (node[key] && typeof node[key].type === 'string') {
|
51 | walk(node[key], node, cb)
|
52 | }
|
53 | })
|
54 |
|
55 | cb(node)
|
56 | }
|
57 | function addHelpers (node) {
|
58 | var edit = {
|
59 | source: function () {
|
60 | return string.slice(node.start, node.end)
|
61 | },
|
62 | update: function (replacement) {
|
63 | string.overwrite(node.start, node.end, replacement)
|
64 | return edit
|
65 | },
|
66 | append: function (append) {
|
67 | string.appendLeft(node.end, append)
|
68 | return node
|
69 | },
|
70 | prepend: function (prepend) {
|
71 | string.prependRight(node.start, prepend)
|
72 | return node
|
73 | }
|
74 | }
|
75 | node.edit = edit
|
76 | node.getSource = edit.source
|
77 | Object.keys(edit).forEach(function (k) {
|
78 | if (!(k in node)) node[k] = edit[k]
|
79 | })
|
80 | }
|
81 | }
|