vars.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. var _ = require('lodash');
  2. var tree = require('../lib/tree');
  3. var treeStructure = require('../structure').scopes;
  4. module.exports = function(scope) {
  5. if(!scope.ast.params) return;
  6. scope.params = scope.ast.params.map(function(p) {
  7. return {
  8. name: p.name,
  9. };
  10. });
  11. scope.varsDeclared = _.where(scope.flatExp, {type: 'VariableDeclarator'}).map(function(e) {
  12. return {
  13. name: e.name,
  14. ast: e,
  15. };
  16. });
  17. scope.symsDeclared = _.extend([], scope.varsDeclared, scope.params);
  18. var vars = Object.create(null);
  19. scope.varsRefd = [];
  20. (function harvest(ast) {
  21. // BUG: this doesn't get vars nested inside member expressions
  22. extractFirstLayer(ast, ['MemberExpression']).map(function(n) {
  23. var o = baseObject(n);
  24. if(o.type == 'Identifier' && !vars[o.name]) {
  25. vars[o.name] = true;
  26. scope.varsRefd.push({
  27. name: o.name,
  28. });
  29. return;
  30. }
  31. //console.log(o);
  32. console.log('-------------------------------------------'.blue.bold);
  33. console.log('harvesting');
  34. var y = tree.nextLayer(o);
  35. console.log(y);
  36. harvest(y);
  37. console.log('==========================================='.magenta);
  38. });
  39. })(scope.ast);
  40. return scope;
  41. /*
  42. { type: 'MemberExpression',
  43. object:
  44. { type: 'Identifier',
  45. name: 't',
  46. loc: { source: null, start: [Object], end: [Object] } },
  47. property:
  48. { type: 'Identifier',
  49. name: 'u',
  50. loc: { source: null, start: [Object], end: [Object] } },
  51. computed: false,
  52. loc:
  53. { source: null,
  54. start: { line: 17, column: 1 },
  55. end: { line: 17, column: 4 } } }
  56. { type: 'MemberExpression',
  57. object:
  58. { type: 'MemberExpression',
  59. object: { type: 'Identifier', name: 't', loc: [Object] },
  60. property: { type: 'Identifier', name: 'u', loc: [Object] },
  61. computed: false,
  62. loc: { source: null, start: [Object], end: [Object] } },
  63. property:
  64. { type: 'Identifier',
  65. name: 'k',
  66. loc: { source: null, start: [Object], end: [Object] } },
  67. computed: false,
  68. loc:
  69. { source: null,
  70. start: { line: 17, column: 1 },
  71. end: { line: 17, column: 6 } } }
  72. */
  73. };
  74. function baseObject(exp) {
  75. if(!exp.object) {
  76. console.log('!! Missing object '.red, exp);
  77. return;
  78. }
  79. // recurse, object is nested
  80. if(exp.object.type == 'MemberExpression') {
  81. return baseObject(exp.object);
  82. }
  83. //if(exp.object.type == 'Identifier' || exp.object.type == 'ThisExpression') {
  84. return exp.object;
  85. //}
  86. console.log('!! unexpected path in baseObject. '.red, exp);
  87. }
  88. // we need to pull out the 'object' of the deepest nested member expression
  89. // however, recurse into calculated expressions as other variables may be referenced
  90. // object references have deeply nested identifier names.
  91. function collectIdName(id) {
  92. if(id.type == 'Identifier');
  93. console.log(id);
  94. }
  95. function extractFirstLayer(ast, types) {
  96. if(ast instanceof Array) {
  97. var t = ast.reduce(function(acc, a) {
  98. acc.concat(extractFirstLayer(a, types));
  99. return acc;
  100. }, []);
  101. console.log('t:', t);
  102. return t;
  103. }
  104. var ts = _.extend({}, treeStructure);
  105. // don't recurse into the node types we are looking for
  106. types.map(function(t) {
  107. ts[t] = [];
  108. });
  109. var crawl = tree.dfSearch(ts);
  110. return crawl(ast.body, function(node, acc) {
  111. if(types.indexOf(node.type) > -1) {
  112. acc.push(node);
  113. }
  114. return acc;
  115. }, []);
  116. };