Skip to content

Commit

Permalink
Merge pull request #55 from substack/use-acorn-traverse
Browse files Browse the repository at this point in the history
Use acorn's own traverser
  • Loading branch information
zertosh committed Aug 20, 2015
2 parents 3f03dd4 + b543079 commit 419a8c1
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 44 deletions.
61 changes: 19 additions & 42 deletions index.js
@@ -1,12 +1,13 @@
var aparse = require('acorn').parse;
var acorn = require('acorn');
var walk = require('acorn/dist/walk');
var escodegen = require('escodegen');
var defined = require('defined');

var requireRe = /\brequire\b/;

function parse (src, opts) {
if (!opts) opts = {};
return aparse(src, {
return acorn.parse(src, {
ecmaVersion: defined(opts.ecmaVersion, 6),
sourceType: opts.sourceType,
ranges: defined(opts.ranges, opts.range),
Expand All @@ -19,31 +20,6 @@ function parse (src, opts) {
});
}

var traverse = function (node, cb) {
if (Array.isArray(node)) {
for (var i = 0; i < node.length; i++) {
if (node[i] != null) {
node[i].parent = node;
traverse(node[i], cb);
}
}
}
else if (node && typeof node === 'object') {
cb(node);
for (var key in node) {
if (!node.hasOwnProperty(key)) continue;
if (key === 'parent' || !node[key]) continue;
node[key].parent = node;
traverse(node[key], cb);
}
}
};

var walk = function (src, opts, cb) {
var ast = parse(src, opts);
traverse(ast, cb);
};

var exports = module.exports = function (src, opts) {
return exports.find(src, opts).strings;
};
Expand All @@ -55,31 +31,32 @@ exports.find = function (src, opts) {
if (typeof src !== 'string') src = String(src);

var isRequire = opts.isRequire || function (node) {
var c = node.callee;
return c
&& node.type === 'CallExpression'
&& c.type === 'Identifier'
&& c.name === word
return node.callee.type === 'Identifier'
&& node.callee.name === word
;
}
};

var modules = { strings : [], expressions : [] };
if (opts.nodes) modules.nodes = [];

var wordRe = word === 'require' ? requireRe : RegExp('\\b' + word + '\\b');
if (!wordRe.test(src)) return modules;

walk(src, opts.parse, function (node) {
if (!isRequire(node)) return;
if (node.arguments.length) {
if (node.arguments[0].type === 'Literal') {
modules.strings.push(node.arguments[0].value);
}
else {
modules.expressions.push(escodegen.generate(node.arguments[0]));
var ast = parse(src, opts.parse);

walk.simple(ast, {
CallExpression: function (node) {
if (!isRequire(node)) return;
if (node.arguments.length) {
if (node.arguments[0].type === 'Literal') {
modules.strings.push(node.arguments[0].value);
}
else {
modules.expressions.push(escodegen.generate(node.arguments[0]));
}
}
if (opts.nodes) modules.nodes.push(node);
}
if (opts.nodes) modules.nodes.push(node);
});

return modules;
Expand Down
4 changes: 2 additions & 2 deletions readme.markdown
Expand Up @@ -61,8 +61,8 @@ Optionally:

* `opts.word` - specify a different function name instead of `"require"`
* `opts.nodes` - when `true`, populate `found.nodes`
* `opts.isRequire(node)` - a function returning whether an AST node is a require
call
* `opts.isRequire(node)` - a function returning whether an AST `CallExpression`
node is a require call
* `opts.parse` - supply options directly to
[acorn](https://npmjs.org/package/acorn) with some support for esprima-style
options `range` and `loc`
Expand Down

0 comments on commit 419a8c1

Please sign in to comment.