You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.1 KiB
79 lines
2.1 KiB
var parse = require('acorn').parse; |
|
var isArray = require('isarray'); |
|
var objectKeys = require('object-keys'); |
|
var forEach = require('foreach'); |
|
|
|
module.exports = function (src, opts, fn) { |
|
if (typeof opts === 'function') { |
|
fn = opts; |
|
opts = {}; |
|
} |
|
if (src && typeof src === 'object' && src.constructor.name === 'Buffer') { |
|
src = src.toString(); |
|
} |
|
else if (src && typeof src === 'object') { |
|
opts = src; |
|
src = opts.source; |
|
delete opts.source; |
|
} |
|
src = src === undefined ? opts.source : src; |
|
if (typeof src !== 'string') src = String(src); |
|
if (opts.parser) parse = opts.parser.parse; |
|
var ast = parse(src, opts); |
|
|
|
var result = { |
|
chunks : src.split(''), |
|
toString : function () { return result.chunks.join('') }, |
|
inspect : function () { return result.toString() } |
|
}; |
|
var index = 0; |
|
|
|
(function walk (node, parent) { |
|
insertHelpers(node, parent, result.chunks); |
|
|
|
forEach(objectKeys(node), function (key) { |
|
if (key === 'parent') return; |
|
|
|
var child = node[key]; |
|
if (isArray(child)) { |
|
forEach(child, function (c) { |
|
if (c && typeof c.type === 'string') { |
|
walk(c, node); |
|
} |
|
}); |
|
} |
|
else if (child && typeof child.type === 'string') { |
|
walk(child, node); |
|
} |
|
}); |
|
fn(node); |
|
})(ast, undefined); |
|
|
|
return result; |
|
}; |
|
|
|
function insertHelpers (node, parent, chunks) { |
|
node.parent = parent; |
|
|
|
node.source = function () { |
|
return chunks.slice(node.start, node.end).join(''); |
|
}; |
|
|
|
if (node.update && typeof node.update === 'object') { |
|
var prev = node.update; |
|
forEach(objectKeys(prev), function (key) { |
|
update[key] = prev[key]; |
|
}); |
|
node.update = update; |
|
} |
|
else { |
|
node.update = update; |
|
} |
|
|
|
function update (s) { |
|
chunks[node.start] = s; |
|
for (var i = node.start + 1; i < node.end; i++) { |
|
chunks[i] = ''; |
|
} |
|
} |
|
}
|
|
|