1 | 'use strict';
|
2 |
|
3 | var estraverse = require('estraverse'),
|
4 | esprima = require('esprima'),
|
5 | EventEmitter = require('events').EventEmitter,
|
6 | util = require('util'),
|
7 | EsNode = require('./esnode');
|
8 |
|
9 | function ContextTraversal (context) {
|
10 | this.context = context;
|
11 | EventEmitter.call(this);
|
12 | }
|
13 | util.inherits(ContextTraversal, EventEmitter);
|
14 |
|
15 | ContextTraversal.prototype.traverse = function () {
|
16 | var _this = this;
|
17 | this.context.args.forEach(function (arg) {
|
18 | onEachEsNode(arg, _this.context.source.content, function (esNode) {
|
19 | _this.emit('esnode', esNode);
|
20 | });
|
21 | });
|
22 | };
|
23 |
|
24 | function onEachEsNode(arg, jsCode, callback) {
|
25 | var jsAST = esprima.parse(jsCode, {tolerant: true, loc: true, tokens: true, raw: true}),
|
26 | espathToValue = arg.events.reduce(function (accum, ev) {
|
27 | accum[ev.espath] = ev.value;
|
28 | return accum;
|
29 | }, {}),
|
30 | nodeStack = [];
|
31 | estraverse.traverse(extractExpressionFrom(jsAST), {
|
32 | enter: function (currentNode, parentNode) {
|
33 | var esNode = new EsNode(this.path(), currentNode, parentNode, espathToValue, jsCode, jsAST);
|
34 | if (1 < nodeStack.length) {
|
35 | esNode.setParent(nodeStack[nodeStack.length - 1]);
|
36 | }
|
37 | nodeStack.push(esNode);
|
38 | callback(esNode);
|
39 | },
|
40 | leave: function (currentNode, parentNode) {
|
41 | nodeStack.pop();
|
42 | }
|
43 | });
|
44 | }
|
45 |
|
46 | function extractExpressionFrom (tree) {
|
47 | var expressionStatement = tree.body[0],
|
48 | expression = expressionStatement.expression;
|
49 | return expression;
|
50 | }
|
51 |
|
52 | module.exports = ContextTraversal;
|