index.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. require('./monkeys');
  2. var Promise = require('bluebird');
  3. var jsparser = require('jsparser');
  4. // "jsparser": "git+http://git@github.com/cjihrig/jsparser.git", // old one, fuck json for not having comments
  5. var fs = Promise.promisifyAll(require('fs'));
  6. var _ = require('lodash');
  7. var Path = require('path');
  8. var util = require('util');
  9. var colors = require('colors');
  10. var tree = require('./lib/tree');
  11. var print = require('./print')(console.log);
  12. var treeStructure = require('./structure');
  13. var path = process.argv[2];
  14. var argv = require('minimist')(process.argv.slice(2));
  15. function loadPasses(folder) {
  16. return fs.readdirAsync(folder)
  17. .filter(function(x) { return x[0] != '.'; })
  18. .map(function(file) {
  19. return {name: file.replace(/\..*$/, ''), fn: require('./'+Path.join(folder, file))};
  20. });
  21. }
  22. function loadAxioms(folder) {
  23. return fs.readdirAsync(folder)
  24. .filter(function(x) { return x[0] != '.'; })
  25. .reduce(acc, function(file) {
  26. return _.extend(acc, require('./'+Path.join(folder, file)));
  27. });
  28. }
  29. function parseFile(path) {
  30. return fs.readFileAsync(path)
  31. .then(function(source) {
  32. return parseScope(jsparser.parse(source+''), null);
  33. });
  34. }
  35. function scanDir(root) {
  36. return fs.statAsync(root)
  37. .then(function(stats) {
  38. if(!stats.isDirectory()) return [root];
  39. return fs.readdirAsync(root)
  40. .filter(function(x) { return x[0] != '.'; })
  41. .map(function(file) {
  42. return scanDir(Path.join(root, file));
  43. });
  44. })
  45. .then(_.flatten);
  46. }
  47. /* old junk
  48. function parseFn(ast, parent) {
  49. var scope = {
  50. symDeclared: {},
  51. fnDeclared: [],
  52. varDeclared: {},
  53. symReferenced: {},
  54. fnCalled: {},
  55. varReferenced: {},
  56. // flatExp: walkTree(ast, expRules),
  57. };
  58. var handlers = {
  59. Identifier: function(node) {
  60. },
  61. FunctionDeclaration: function(node) {
  62. var fn = parseFn(node.body, scope, node);
  63. scope.fnDeclared.push(fn);
  64. },
  65. };
  66. function parseNode(node) {
  67. if(node instanceof Array) {
  68. return node.map(parseNode);
  69. }
  70. var fn = handlers[node.type];
  71. if(!fn) return;
  72. fn(node)
  73. }
  74. parseNode(ast);
  75. return scope;
  76. }
  77. */
  78. var fnCrawl = tree.dfSearch(treeStructure.scopes);
  79. function parseScope(ast, name) {
  80. var scope = {
  81. name: name || 'unknown fn',
  82. params: [],
  83. fnDec: [],
  84. ast: ast,
  85. };
  86. scope.fnDec = fnCrawl(ast.body, function(node, acc) {
  87. if(node.type == 'FunctionExpression' || node.type == 'FunctionDeclaration') {
  88. acc.push(node);
  89. }
  90. return acc;
  91. }, []).map(parseScope).setProperty('parent', scope);
  92. scope.flatExp = fnCrawl(scope.ast.body, function(node, acc) {
  93. acc.push(node);
  94. return acc;
  95. }, []);
  96. return scope;
  97. }
  98. function flatten(scope) {
  99. return [scope].concat(scope.fnDec.reduce(function(acc, s) {
  100. return acc.concat(flatten(s));
  101. }, []));
  102. }
  103. scanDir(argv._[0])
  104. .map(parseFile)
  105. .then(function(scopes) {
  106. var flat = Array.prototype.concat.apply([], scopes.map(flatten));
  107. loadPasses('./passes').then(function(mods) {
  108. var m = _.indexBy(mods, 'name');
  109. // meh, prolly need some other sort of tree mapping function
  110. flat.map(m.simpleAST.fn);
  111. if(argv['print-scopes']) scopes.map(print.scopes);
  112. if(argv['print-ast']) {
  113. var line = argv['near'] || null;
  114. var ep = argv['epsilon']|0||0;
  115. if(line == null) {
  116. scopes.map(function(s) {
  117. console.log(util.inspect(s.ast, true, null));
  118. });
  119. return;
  120. }
  121. tree.dfSearch(treeStructure.all)(scopes[0].ast, function(node, acc) {;
  122. if(!node.loc) return;
  123. if(Math.abs(node.loc.start.line - line) <= ep ||
  124. Math.abs(node.loc.end.line - line) <= ep) {
  125. console.log(node);
  126. }
  127. });
  128. }
  129. //console.log(util.inspect(scopes, true, null));
  130. });
  131. })
  132. .catch(SyntaxError, function(e) {
  133. console.log(e);
  134. });