1 |
|
2 | (function() {
|
3 | var computedMember, escodegen, tools, _;
|
4 |
|
5 | escodegen = require('escodegen');
|
6 |
|
7 | tools = require('./tools');
|
8 |
|
9 | _ = require('underscore');
|
10 |
|
11 | exports.createLiteral = function(value) {
|
12 | if (typeof value === 'number' && value < 0) {
|
13 | return {
|
14 | type: 'UnaryExpression',
|
15 | operator: '-',
|
16 | argument: {
|
17 | type: 'Literal',
|
18 | value: -value
|
19 | }
|
20 | };
|
21 | } else {
|
22 | return {
|
23 | type: 'Literal',
|
24 | value: value
|
25 | };
|
26 | }
|
27 | };
|
28 |
|
29 | computedMember = function(_arg) {
|
30 | var object, property;
|
31 | property = _arg.property, object = _arg.object;
|
32 | return {
|
33 | type: 'MemberExpression',
|
34 | computed: true,
|
35 | property: property,
|
36 | object: object
|
37 | };
|
38 | };
|
39 |
|
40 | exports.coverageNode = function(node, filename, identifier) {
|
41 | return {
|
42 | type: 'ExpressionStatement',
|
43 | expression: {
|
44 | type: 'UpdateExpression',
|
45 | operator: '++',
|
46 | prefix: false,
|
47 | argument: computedMember({
|
48 | property: exports.createLiteral(node.loc.start.line),
|
49 | object: computedMember({
|
50 | property: exports.createLiteral(filename),
|
51 | object: {
|
52 | type: 'Identifier',
|
53 | name: identifier
|
54 | }
|
55 | })
|
56 | })
|
57 | }
|
58 | };
|
59 | };
|
60 |
|
61 | exports.traverse = function(ast, filter, callback) {
|
62 | if (callback == null) {
|
63 | callback = filter;
|
64 | filter = [];
|
65 | }
|
66 | return escodegen.traverse(ast, {
|
67 | enter: function(node) {
|
68 | if (filter.length === 0 || filter.indexOf(node.type) !== -1) {
|
69 | return callback(node);
|
70 | }
|
71 | }
|
72 | });
|
73 | };
|
74 |
|
75 | exports.addBeforeEveryStatement = function(ast, addback) {
|
76 | exports.traverse(ast, function(node) {
|
77 | if (node.type === 'IfStatement') {
|
78 | ['consequent', 'alternate'].forEach(function(path) {
|
79 | if ((node[path] != null) && node[path].type !== 'BlockStatement') {
|
80 | return node[path] = {
|
81 | type: 'BlockStatement',
|
82 | body: [node[path]]
|
83 | };
|
84 | }
|
85 | });
|
86 | }
|
87 | if (['ForInStatement', 'ForStatement', 'WhileStatement', 'WithStatement', 'DoWhileStatement'].indexOf(node.type) !== -1 && (node.body != null) && node.body.type !== 'BlockStatement') {
|
88 | return node.body = {
|
89 | type: 'BlockStatement',
|
90 | body: [node.body]
|
91 | };
|
92 | }
|
93 | });
|
94 | return exports.traverse(ast, function(node) {
|
95 | if (['BlockStatement', 'Program'].indexOf(node.type) !== -1) {
|
96 | node.body = _.flatten(node.body.map(function(statement) {
|
97 | var _ref, _ref1;
|
98 | if (((_ref = statement.expression) != null ? _ref.type : void 0) === 'FunctionExpression') {
|
99 | return [addback(statement.expression), statement];
|
100 | } else if (((_ref1 = statement.expression) != null ? _ref1.type : void 0) === 'CallExpression') {
|
101 | return [addback(statement.expression), statement];
|
102 | } else if (statement.type === 'FunctionDeclaration') {
|
103 | return [addback(statement.body), statement];
|
104 | } else {
|
105 | return [addback(statement), statement];
|
106 | }
|
107 | }));
|
108 | }
|
109 | if (node.type === 'SwitchCase') {
|
110 | return node.consequent = _.flatten(node.consequent.map(function(statement) {
|
111 | return [addback(statement), statement];
|
112 | }));
|
113 | }
|
114 | });
|
115 | };
|
116 |
|
117 | }).call(this);
|