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.

80 lines
2.6 KiB

2 years ago
  1. var acorn = require('acorn-node');
  2. var walk = require('acorn-node/walk');
  3. var defined = require('defined');
  4. var requireRe = /\brequire\b/;
  5. function parse (src, opts) {
  6. if (!opts) opts = {};
  7. var acornOpts = {
  8. ranges: defined(opts.ranges, opts.range),
  9. locations: defined(opts.locations, opts.loc),
  10. allowReserved: defined(opts.allowReserved, true),
  11. allowImportExportEverywhere: defined(opts.allowImportExportEverywhere, false)
  12. };
  13. // Use acorn-node's defaults for the rest.
  14. if (opts.ecmaVersion != null) acornOpts.ecmaVersion = opts.ecmaVersion;
  15. if (opts.sourceType != null) acornOpts.sourceType = opts.sourceType;
  16. if (opts.allowHashBang != null) acornOpts.allowHashBang = opts.allowHashBang;
  17. if (opts.allowReturnOutsideFunction != null) acornOpts.allowReturnOutsideFunction = opts.allowReturnOutsideFunction;
  18. return acorn.parse(src, acornOpts);
  19. }
  20. var exports = module.exports = function (src, opts) {
  21. return exports.find(src, opts).strings;
  22. };
  23. exports.find = function (src, opts) {
  24. if (!opts) opts = {};
  25. var word = opts.word === undefined ? 'require' : opts.word;
  26. if (typeof src !== 'string') src = String(src);
  27. var isRequire = opts.isRequire || function (node) {
  28. return node.callee.type === 'Identifier'
  29. && node.callee.name === word
  30. ;
  31. };
  32. var modules = { strings : [], expressions : [] };
  33. if (opts.nodes) modules.nodes = [];
  34. var wordRe = word === 'require' ? requireRe : RegExp('\\b' + word + '\\b');
  35. if (!wordRe.test(src)) return modules;
  36. var ast = parse(src, opts.parse);
  37. function visit(node, st, c) {
  38. var hasRequire = wordRe.test(src.slice(node.start, node.end));
  39. if (!hasRequire) return;
  40. walk.base[node.type](node, st, c);
  41. if (node.type !== 'CallExpression') return;
  42. if (isRequire(node)) {
  43. if (node.arguments.length) {
  44. var arg = node.arguments[0];
  45. if (arg.type === 'Literal') {
  46. modules.strings.push(arg.value);
  47. }
  48. else if (arg.type === 'TemplateLiteral'
  49. && arg.quasis.length === 1
  50. && arg.expressions.length === 0) {
  51. modules.strings.push(arg.quasis[0].value.raw);
  52. }
  53. else {
  54. modules.expressions.push(src.slice(arg.start, arg.end));
  55. }
  56. }
  57. if (opts.nodes) modules.nodes.push(node);
  58. }
  59. }
  60. walk.recursive(ast, null, {
  61. Statement: visit,
  62. Expression: visit
  63. });
  64. return modules;
  65. };