UNPKG

2.53 kBJavaScriptView Raw
1'use strict';
2
3var estraverse = require('estraverse');
4var parser = require('acorn');
5require('acorn-es7-plugin')(parser);
6var EventEmitter = require('events').EventEmitter;
7var inherits = require('util').inherits;
8var EsNode = require('./esnode');
9var forEach = require('array-foreach');
10var reduce = require('array-reduce');
11
12function ContextTraversal (context) {
13 this.context = context;
14 EventEmitter.call(this);
15}
16inherits(ContextTraversal, EventEmitter);
17
18ContextTraversal.prototype.traverse = function () {
19 var _this = this;
20 forEach(this.context.args, function (arg) {
21 onEachEsNode(arg, _this.context.source, function (esNode) {
22 _this.emit('esnode', esNode);
23 });
24 });
25};
26
27function onEachEsNode(arg, source, callback) {
28 var parseResult = parse(source);
29 var tokens = parseResult.tokens;
30 var espathToValue = reduce(arg.events, function (accum, ev) {
31 accum[ev.espath] = ev.value;
32 return accum;
33 }, {});
34 var nodeStack = [];
35 estraverse.traverse(parseResult.expression, {
36 enter: function (currentNode, parentNode) {
37 var esNode = new EsNode(this.path(), currentNode, parentNode, espathToValue, source.content, tokens);
38 if (1 < nodeStack.length) {
39 esNode.setParent(nodeStack[nodeStack.length - 1]);
40 }
41 nodeStack.push(esNode);
42 callback(esNode);
43 },
44 leave: function (currentNode, parentNode) {
45 nodeStack.pop();
46 }
47 });
48}
49
50function parserOptions(tokens) {
51 return {
52 sourceType: 'module',
53 ecmaVersion: 7,
54 locations: true,
55 ranges: true,
56 onToken: tokens,
57 plugins: {asyncawait: true}
58 };
59}
60
61function wrappedInGenerator(jsCode) {
62 return 'function *wrapper() {\n' + jsCode + '\n}';
63}
64
65function wrappedInAsync(jsCode) {
66 return 'async function wrapper() {\n' + jsCode + '\n}';
67}
68
69function parse(source) {
70 var ast;
71 var tokens = [];
72
73 function doParse(wrapper) {
74 var content = wrapper ? wrapper(source.content) : source.content;
75 ast = parser.parse(content, parserOptions(tokens));
76 if (wrapper) {
77 ast = ast.body[0].body;
78 }
79 }
80
81 if (source.async) {
82 doParse(wrappedInAsync);
83 } else if (source.generator) {
84 doParse(wrappedInGenerator);
85 } else {
86 doParse();
87 }
88
89 return {
90 tokens: tokens,
91 expression: ast.body[0].expression
92 };
93}
94
95module.exports = ContextTraversal;