UNPKG

4.85 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.6.3
2(function() {
3 var escodegen, esprima, estools, noopDef, noopExpression, tools, wrapLogic, wrapPred, _;
4
5 _ = require('underscore');
6
7 estools = require('./estools');
8
9 tools = require('./tools');
10
11 esprima = require('esprima');
12
13 escodegen = require('escodegen');
14
15 noopDef = function(name) {
16 return {
17 kind: 'var',
18 type: 'VariableDeclaration',
19 declarations: [
20 {
21 type: 'VariableDeclarator',
22 id: {
23 type: 'Identifier',
24 name: name
25 },
26 init: {
27 type: 'FunctionExpression',
28 id: null,
29 params: [],
30 defaults: [],
31 body: {
32 type: 'BlockStatement',
33 body: [
34 {
35 type: 'ReturnStatement',
36 argument: {
37 type: 'Literal',
38 value: null
39 }
40 }
41 ]
42 }
43 },
44 rest: null,
45 generator: false,
46 expression: false
47 }
48 ]
49 };
50 };
51
52 noopExpression = function(name) {
53 return {
54 type: 'ExpressionStatement',
55 expression: {
56 "arguments": [],
57 type: 'CallExpression',
58 callee: {
59 type: 'Identifier',
60 name: name
61 }
62 }
63 };
64 };
65
66 wrapPred = function(test, left, right) {
67 return {
68 type: 'CallExpression',
69 "arguments": [
70 {
71 type: 'ThisExpression'
72 }, {
73 type: 'Identifier',
74 name: 'arguments'
75 }
76 ],
77 callee: {
78 type: 'MemberExpression',
79 computed: false,
80 property: {
81 type: 'Identifier',
82 name: 'call'
83 },
84 object: {
85 type: 'FunctionExpression',
86 id: null,
87 rest: null,
88 generator: false,
89 expression: false,
90 params: [
91 {
92 type: 'Identifier',
93 name: 'arguments'
94 }
95 ],
96 defaults: [],
97 body: {
98 type: 'BlockStatement',
99 body: [
100 {
101 type: 'IfStatement',
102 test: test,
103 consequent: {
104 type: 'ReturnStatement',
105 argument: left
106 },
107 alternate: {
108 type: 'ReturnStatement',
109 argument: right
110 }
111 }
112 ]
113 }
114 }
115 }
116 };
117 };
118
119 wrapLogic = function(isAnd, left, right, tmpvar) {
120 var l, r, res;
121 l = isAnd ? right : {
122 type: 'Identifier',
123 name: tmpvar
124 };
125 r = !isAnd ? right : {
126 type: 'Identifier',
127 name: tmpvar
128 };
129 res = wrapPred({
130 type: 'Identifier',
131 name: tmpvar
132 }, l, r);
133 res.callee.object.body.body = [
134 {
135 kind: 'var',
136 type: 'VariableDeclaration',
137 declarations: [
138 {
139 type: 'VariableDeclarator',
140 id: {
141 type: 'Identifier',
142 name: tmpvar
143 },
144 init: left
145 }
146 ]
147 }
148 ].concat(res.callee.object.body.body);
149 return res;
150 };
151
152 exports.expand = function(ast) {
153 var addNoop;
154 if (typeof ast === 'string') {
155 return escodegen.generate(exports.expand(esprima.parse(ast, {
156 loc: false
157 })), {
158 indent: " "
159 });
160 }
161 addNoop = false;
162 estools.traverse(ast, ['IfStatement'], function(node) {
163 if (node.alternate == null) {
164 addNoop = true;
165 return node.alternate = noopExpression('__noop__');
166 }
167 });
168 estools.traverse(ast, ['LogicalExpression'], function(node) {
169 if (node.operator === '&&' || node.operator === '||') {
170 if (node.left.type === 'Literal' || node.left.type === 'Identifier') {
171 if (node.operator === '&&') {
172 tools.replaceProperties(node, wrapPred(node.left, node.right, node.left));
173 } else {
174 tools.replaceProperties(node, wrapPred(node.left, node.left, node.right));
175 }
176 } else {
177 tools.replaceProperties(node, wrapLogic(node.operator === '&&', node.left, node.right, '__lhs__'));
178 }
179 delete node.operator;
180 delete node.left;
181 return delete node.right;
182 }
183 });
184 estools.traverse(ast, ['ConditionalExpression'], function(node) {
185 tools.replaceProperties(node, wrapPred(node.test, node.consequent, node.alternate));
186 delete node.test;
187 delete node.consequent;
188 return delete node.alternate;
189 });
190 if (addNoop) {
191 estools.traverse(ast, ['Program'], function(node) {
192 return node.body = [noopDef('__noop__')].concat(node.body);
193 });
194 }
195 return ast;
196 };
197
198}).call(this);