@dacely/toildefender 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,490 +1,490 @@
1
- "use strict";
2
-
3
- var assert = require("assert");
4
-
5
- var _ = require("lodash");
6
-
7
- var utils = require("../utils");
8
- var traverser = require("../traverser");
9
- var estest = require("../estest");
10
-
11
- /**
12
- * Chain an array of expressions with an operator.
13
- * @param {Expression[]} expressions
14
- * @param {BinaryOperator} operator
15
- * @returns {Expression}
16
- */
17
- function chain (expressions, operator) {
18
- assert.ok(Array.isArray(expressions));
19
- assert.equal(typeof operator, "string");
20
-
21
- if (expressions.length == 0) {
22
- return { type: "Literal", value: true };
23
- } else if (expressions.length == 1) {
24
- return expressions[0];
25
- } else {
26
- var result = expressions[0];
27
- for (var i = 1; i < expressions.length; ++i) {
28
- result = {
29
- type: "BinaryExpression",
30
- operator: operator,
31
- left: result,
32
- right: expressions[1]
33
- };
34
- }
35
- return result;
36
- }
37
- }
38
-
39
- /**
40
- * Return node body as an array.
41
- * @param {Node} node
42
- * @returns {Node[]}
43
- */
44
- function blockToArray (node) {
45
- assert.ok(estest.isNode(node));
46
-
47
- if (Array.isArray(node.body)) {
48
- return node.body;
49
- } else {
50
- return [ node.body ];
51
- }
52
- }
53
-
54
- module.exports = class Normalizer {
55
-
56
- constructor (logger) {
57
- this.logger = logger;
58
- this.rngAlpha = new utils.UniqueRandomAlpha(3);
59
- }
60
-
61
- /**
62
- * Simplify AST.
63
- * @param {Node} ast Root node
64
- * @returns {Node}
65
- */
66
- simplify (ast) {
67
- assert.ok(estest.isNode(ast));
68
-
69
- return traverser.traverse(ast, [], (node, stack) => {
70
- switch (node.type) {
71
- case "Program":
72
- case "BlockStatement":
73
- return this.simplifyBlockStatement(node);
74
- /*case "WhileStatement":
75
- return this.simplifyWhileStatement(node);*/
76
- /*case "DoWhileStatement":
77
- return this.simplifyDoWhileStatement(node);*/
78
- case "ForStatement":
79
- return this.simplifyForStatement(node);
80
- case "ForInStatement":
81
- return this.simplifyForStatement(this.simplifyForInStatement(node));
82
- /*case "SwitchStatement":
83
- return this.simplifySwitchStatement(node);*/
84
- case "TryStatement":
85
- return this.simplifyTryStatement(node);
86
- default:
87
- return node;
88
- }
89
- });
90
-
91
- }
92
-
93
- /**
94
- * Simplify BlockStatement.
95
- * @param {BlockStatement} node
96
- * @return {Node}
97
- */
98
- simplifyBlockStatement (node) {
99
- assert.ok(estest.isNode(node));
100
-
101
- function getBlockBodys(node) {
102
- if (node.type == "Program" || node.type == "BlockStatement") {
103
- var stmts = [];
104
- node.body.forEach(stmt => utils.push(stmts, getBlockBodys(stmt)));
105
- return stmts;
106
- } else {
107
- return [ node ];
108
- }
109
- }
110
-
111
- return {
112
- type: node.type,
113
- body: getBlockBodys(node)
114
- };
115
- }
116
-
117
- /**
118
- * Simplify WhileStatement.
119
- * @param {WhileStatement} node
120
- * @return {Node}
121
- */
122
- simplifyWhileStatement (node) {
123
- assert.ok(estest.isNode(node));
124
-
125
- return {
126
- type: "WhileStatement",
127
- test: { type: "Literal", value: true },
128
- body: {
129
- type: "IfStatement",
130
- test: node.test,
131
- consequent: node.body,
132
- alternate: { type: "BreakStatement" }
133
- }
134
- };
135
- }
136
-
137
- /**
138
- * Simplify DoWhileStatement.
139
- * @param {DoWhileStatement} node
140
- * @return {Node}
141
- */
142
- simplifyDoWhileStatement (node) {
143
- assert.ok(estest.isNode(node));
144
-
145
- return {
146
- type: "WhileStatement",
147
- test: { type: "Literal", value: true },
148
- body: {
149
- type: "BlockStatement",
150
- body: [
151
- node.body,
152
- {
153
- type: "IfStatement",
154
- test: node.test,
155
- consequent: { type: "EmptyStatement" },
156
- alternate: { type: "BreakStatement" }
157
- }
158
- ]
159
- }
160
- };
161
- }
162
-
163
- /**
164
- * Simplify ForStatement.
165
- * @param {ForStatement} node
166
- * @return {Node}
167
- */
168
- simplifyForStatement (node) {
169
- assert.ok(estest.isNode(node));
170
-
171
- var body = [];
172
- if (node.init) {
173
- if (estest.isStatement(node.init)) {
174
- body.push(node.init);
175
- } else if (estest.isExpression(node.init)) {
176
- body.push({
177
- type: "ExpressionStatement",
178
- expression: node.init
179
- });
180
- } else {
181
- throw new Error("Invalid node.init type " + node.init.type);
182
- }
183
- }
184
- body.push({
185
- type: "WhileStatement",
186
- test: node.test,
187
- body: {
188
- type: "BlockStatement",
189
- body: blockToArray(node.body).concat(node.update ? [
190
- {
191
- type: "ExpressionStatement",
192
- expression: node.update
193
- }
194
- ] : [])
195
- }
196
- });
197
- return {
198
- type: "BlockStatement",
199
- body: body
200
- };
201
- }
202
-
203
- /**
204
- * Simplify ForInStatement.
205
- * @param {ForInStatement} node
206
- * @return {Node}
207
- */
208
- simplifyForInStatement (node) {
209
- assert.ok(estest.isNode(node));
210
-
211
- var propsName = `$$forin$props$${this.rngAlpha.get()}`, iterName = `$$forin$iter$${this.rngAlpha.get()}`;
212
-
213
- var forStmt = {
214
- type: "ForStatement",
215
- init: {
216
- type: "VariableDeclaration",
217
- kind: "var",
218
- declarations: [
219
- {
220
- type: "VariableDeclarator",
221
- id: { type: "Identifier", name: propsName },
222
- init: {
223
- type: "CallExpression",
224
- callee: {
225
- type: "MemberExpression",
226
- object: { type: "Identifier", name: "Object" },
227
- property: { type: "Identifier", name: "keys" },
228
- computed: false
229
- },
230
- arguments: [
231
- node.right
232
- ]
233
- }
234
- },
235
- {
236
- type: "VariableDeclarator",
237
- id: { type: "Identifier", name: iterName },
238
- init: { type: "Literal", value: 0 }
239
- }
240
- ]
241
- },
242
- test: {
243
- type: "BinaryExpression",
244
- operator: "<",
245
- left: { type: "Identifier", name: iterName },
246
- right: {
247
- type: "MemberExpression",
248
- object: { type: "Identifier", name: propsName },
249
- property: { type: "Identifier", name: "length" },
250
- computed: false
251
- }
252
- },
253
- update: {
254
- type: "UpdateExpression",
255
- operator: "++",
256
- argument: { type: "Identifier", name: iterName },
257
- prefix: true
258
- },
259
- body: {
260
- type: "BlockStatement",
261
- body: [
262
- node.left.type == "VariableDeclaration"
263
- ?
264
- {
265
- type: "VariableDeclaration",
266
- kind: "var",
267
- declarations: [
268
- {
269
- type: "VariableDeclarator",
270
- id: node.left.declarations[0].id,
271
- init: {
272
- type: "MemberExpression",
273
- object: { type: "Identifier", name: propsName },
274
- property: { type: "Identifier", name: iterName },
275
- computed: true
276
- }
277
- }
278
- ]
279
- }
280
- :
281
- {
282
- type: "ExpressionStatement",
283
- expression: {
284
- type: "AssignmentExpression",
285
- operator: "=",
286
- left: node.left,
287
- right: {
288
- type: "MemberExpression",
289
- object: { type: "Identifier", name: propsName },
290
- property: { type: "Identifier", name: iterName },
291
- computed: true
292
- }
293
- }
294
- },
295
- node.body
296
- ]
297
- }
298
- };
299
- return forStmt;
300
- }
301
-
302
- /**
303
- * Simplify SwitchStatement.
304
- * @param {SwitchStatement} node
305
- * @return {Node}
306
- */
307
- simplifySwitchStatement (node) {
308
- assert.ok(estest.isNode(node));
309
-
310
- var cases = node.cases.map(c => {
311
- var breakIndex = _.findIndex(c.consequent, x => x.type == "BreakStatement");
312
- var statements, breaks;
313
- if (breakIndex != -1) {
314
- statements = c.consequent.slice(0, breakIndex);
315
- breaks = true;
316
- } else {
317
- statements = c.consequent;
318
- breaks = false;
319
- }
320
- return {
321
- test: c.test,
322
- statements: statements,
323
- breaks: breaks
324
- };
325
- });
326
-
327
- var stack = [], ifStmts = [];
328
- for (let i = 0; i < cases.length; ++i) {
329
- stack.push(cases[i]);
330
- if (cases[i].breaks) {
331
- var testName = `$$switchtest$${this.rngAlpha.get()}`;
332
- var ifStmt;
333
-
334
- for (var j = 0; j < stack.length; ++j) {
335
- var sliced = stack.slice(0, j + 1);
336
- if (sliced.every(x => x.test)) {
337
-
338
- ifStmt = {
339
- type: "BlockStatement",
340
- body: [
341
- {
342
- type: "VariableDeclaration",
343
- kind: "var",
344
- declarations: [
345
- {
346
- type: "VariableDeclarator",
347
- id: { type: "Identifier", name: testName }
348
- }
349
- ]
350
- }
351
- ]
352
- };
353
- ifStmt = {
354
- type: "IfStatement",
355
- test: chain(sliced.map(x => {
356
- return { type: "BinaryExpression", operator: "==", left: x.test, right: node.discriminant };
357
- }), "||"),
358
- consequent: {
359
- type: "BlockStatement",
360
- body: (ifStmt ? [ ifStmt ] : []).concat(stack[j].statements)
361
- }
362
- };
363
- } else {
364
- ifStmt = {
365
- type: "BlockStatement",
366
- body: (ifStmt ? [ ifStmt ] : []).concat(stack[j].statements)
367
- };
368
- }
369
- }
370
- ifStmts.push(ifStmt);
371
-
372
- ifStmt = null;
373
- stack = [];
374
- }
375
- }
376
- this.logger.log(ifStmts);
377
- var combinedIfStmt = ifStmts[ifStmts.length - 1];
378
- for (let i = ifStmts.length - 2; i >= 0; --i) {
379
- combinedIfStmt = {
380
- type: "IfStatement",
381
- test: ifStmts[i].test,
382
- consequent: ifStmts[i].consequent,
383
- alternate: combinedIfStmt
384
- };
385
- }
386
- return combinedIfStmt;
387
- }
388
-
389
- /**
390
- * Simplify TryStatement.
391
- * @param {TryStatement} node
392
- * @return {Node}
393
- */
394
- simplifyTryStatement (node) {
395
- assert.ok(estest.isNode(node));
396
-
397
- if (node.finalizer) {
398
- if (node.handler) {
399
- return this.simplifyTryStatement({
400
- type: "TryStatement",
401
- block: {
402
- type: "BlockStatement",
403
- body: [
404
- {
405
- type: "TryStatement",
406
- block: node.block,
407
- handler: node.handler
408
- }
409
- ]
410
- },
411
- finalizer: node.finalizer
412
- });
413
- } else {
414
- var finalizer = node.finalizer;
415
- traverser.traverseEx(node.block, [], function (node, stack) {
416
- if (stack.some(x => estest.isFunction(x.node))) {
417
- this.abort();
418
- return node;
419
- } else if (node.type == "ReturnStatement") {
420
- return {
421
- type: "BlockStatement",
422
- body: [
423
- {
424
- type: "VariableDeclaration",
425
- kind: "var",
426
- declarations: [
427
- {
428
- type: "VariableDeclarator",
429
- id: { type: "Identifier", name: "veilmark$return" },
430
- init: node.argument
431
- }
432
- ]
433
- },
434
- utils.cloneISwearIKnowWhatImDoing(finalizer),
435
- {
436
- type: "ReturnStatement",
437
- argument: { type: "Identifier", name: "veilmark$return" }
438
- }
439
- ]
440
- };
441
- } else {
442
- return node;
443
- }
444
- });
445
-
446
- return {
447
- type: "BlockStatement",
448
- body: [
449
- {
450
- type: "TryStatement",
451
- block: node.block,
452
- handler: {
453
- type: "CatchClause",
454
- param: { type: "Identifier", name: "veilmark$e" },
455
- body: {
456
- type: "BlockStatement",
457
- body: [
458
- {
459
- type: "VariableDeclaration",
460
- kind: "var",
461
- declarations: [
462
- {
463
- type: "VariableDeclarator",
464
- id: { type: "Identifier", name: "veilmark$_e" },
465
- init: { type: "Identifier", name: "veilmark$e" }
466
- }
467
- ]
468
- }
469
- ]
470
- }
471
- }
472
- },
473
- node.finalizer,
474
- {
475
- type: "IfStatement",
476
- test: { type: "Identifier", name: "veilmark$_e" },
477
- consequent: {
478
- type: "ThrowStatement",
479
- argument: { type: "Identifier", name: "veilmark$_e" }
480
- }
481
- }
482
- ]
483
- };
484
- }
485
- } else {
486
- return node;
487
- }
488
- }
489
-
490
- };
1
+ "use strict";
2
+
3
+ var assert = require("assert");
4
+
5
+ var _ = require("lodash");
6
+
7
+ var utils = require("../utils");
8
+ var traverser = require("../traverser");
9
+ var estest = require("../estest");
10
+
11
+ /**
12
+ * Chain an array of expressions with an operator.
13
+ * @param {Expression[]} expressions
14
+ * @param {BinaryOperator} operator
15
+ * @returns {Expression}
16
+ */
17
+ function chain (expressions, operator) {
18
+ assert.ok(Array.isArray(expressions));
19
+ assert.equal(typeof operator, "string");
20
+
21
+ if (expressions.length == 0) {
22
+ return { type: "Literal", value: true };
23
+ } else if (expressions.length == 1) {
24
+ return expressions[0];
25
+ } else {
26
+ var result = expressions[0];
27
+ for (var i = 1; i < expressions.length; ++i) {
28
+ result = {
29
+ type: "BinaryExpression",
30
+ operator: operator,
31
+ left: result,
32
+ right: expressions[1]
33
+ };
34
+ }
35
+ return result;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Return node body as an array.
41
+ * @param {Node} node
42
+ * @returns {Node[]}
43
+ */
44
+ function blockToArray (node) {
45
+ assert.ok(estest.isNode(node));
46
+
47
+ if (Array.isArray(node.body)) {
48
+ return node.body;
49
+ } else {
50
+ return [ node.body ];
51
+ }
52
+ }
53
+
54
+ module.exports = class Normalizer {
55
+
56
+ constructor (logger) {
57
+ this.logger = logger;
58
+ this.rngAlpha = new utils.UniqueRandomAlpha(3);
59
+ }
60
+
61
+ /**
62
+ * Simplify AST.
63
+ * @param {Node} ast Root node
64
+ * @returns {Node}
65
+ */
66
+ simplify (ast) {
67
+ assert.ok(estest.isNode(ast));
68
+
69
+ return traverser.traverse(ast, [], (node, stack) => {
70
+ switch (node.type) {
71
+ case "Program":
72
+ case "BlockStatement":
73
+ return this.simplifyBlockStatement(node);
74
+ /*case "WhileStatement":
75
+ return this.simplifyWhileStatement(node);*/
76
+ /*case "DoWhileStatement":
77
+ return this.simplifyDoWhileStatement(node);*/
78
+ case "ForStatement":
79
+ return this.simplifyForStatement(node);
80
+ case "ForInStatement":
81
+ return this.simplifyForStatement(this.simplifyForInStatement(node));
82
+ /*case "SwitchStatement":
83
+ return this.simplifySwitchStatement(node);*/
84
+ case "TryStatement":
85
+ return this.simplifyTryStatement(node);
86
+ default:
87
+ return node;
88
+ }
89
+ });
90
+
91
+ }
92
+
93
+ /**
94
+ * Simplify BlockStatement.
95
+ * @param {BlockStatement} node
96
+ * @return {Node}
97
+ */
98
+ simplifyBlockStatement (node) {
99
+ assert.ok(estest.isNode(node));
100
+
101
+ function getBlockBodys(node) {
102
+ if (node.type == "Program" || node.type == "BlockStatement") {
103
+ var stmts = [];
104
+ node.body.forEach(stmt => utils.push(stmts, getBlockBodys(stmt)));
105
+ return stmts;
106
+ } else {
107
+ return [ node ];
108
+ }
109
+ }
110
+
111
+ return {
112
+ type: node.type,
113
+ body: getBlockBodys(node)
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Simplify WhileStatement.
119
+ * @param {WhileStatement} node
120
+ * @return {Node}
121
+ */
122
+ simplifyWhileStatement (node) {
123
+ assert.ok(estest.isNode(node));
124
+
125
+ return {
126
+ type: "WhileStatement",
127
+ test: { type: "Literal", value: true },
128
+ body: {
129
+ type: "IfStatement",
130
+ test: node.test,
131
+ consequent: node.body,
132
+ alternate: { type: "BreakStatement" }
133
+ }
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Simplify DoWhileStatement.
139
+ * @param {DoWhileStatement} node
140
+ * @return {Node}
141
+ */
142
+ simplifyDoWhileStatement (node) {
143
+ assert.ok(estest.isNode(node));
144
+
145
+ return {
146
+ type: "WhileStatement",
147
+ test: { type: "Literal", value: true },
148
+ body: {
149
+ type: "BlockStatement",
150
+ body: [
151
+ node.body,
152
+ {
153
+ type: "IfStatement",
154
+ test: node.test,
155
+ consequent: { type: "EmptyStatement" },
156
+ alternate: { type: "BreakStatement" }
157
+ }
158
+ ]
159
+ }
160
+ };
161
+ }
162
+
163
+ /**
164
+ * Simplify ForStatement.
165
+ * @param {ForStatement} node
166
+ * @return {Node}
167
+ */
168
+ simplifyForStatement (node) {
169
+ assert.ok(estest.isNode(node));
170
+
171
+ var body = [];
172
+ if (node.init) {
173
+ if (estest.isStatement(node.init)) {
174
+ body.push(node.init);
175
+ } else if (estest.isExpression(node.init)) {
176
+ body.push({
177
+ type: "ExpressionStatement",
178
+ expression: node.init
179
+ });
180
+ } else {
181
+ throw new Error("Invalid node.init type " + node.init.type);
182
+ }
183
+ }
184
+ body.push({
185
+ type: "WhileStatement",
186
+ test: node.test,
187
+ body: {
188
+ type: "BlockStatement",
189
+ body: blockToArray(node.body).concat(node.update ? [
190
+ {
191
+ type: "ExpressionStatement",
192
+ expression: node.update
193
+ }
194
+ ] : [])
195
+ }
196
+ });
197
+ return {
198
+ type: "BlockStatement",
199
+ body: body
200
+ };
201
+ }
202
+
203
+ /**
204
+ * Simplify ForInStatement.
205
+ * @param {ForInStatement} node
206
+ * @return {Node}
207
+ */
208
+ simplifyForInStatement (node) {
209
+ assert.ok(estest.isNode(node));
210
+
211
+ var propsName = `$$forin$props$${this.rngAlpha.get()}`, iterName = `$$forin$iter$${this.rngAlpha.get()}`;
212
+
213
+ var forStmt = {
214
+ type: "ForStatement",
215
+ init: {
216
+ type: "VariableDeclaration",
217
+ kind: "var",
218
+ declarations: [
219
+ {
220
+ type: "VariableDeclarator",
221
+ id: { type: "Identifier", name: propsName },
222
+ init: {
223
+ type: "CallExpression",
224
+ callee: {
225
+ type: "MemberExpression",
226
+ object: { type: "Identifier", name: "Object" },
227
+ property: { type: "Identifier", name: "keys" },
228
+ computed: false
229
+ },
230
+ arguments: [
231
+ node.right
232
+ ]
233
+ }
234
+ },
235
+ {
236
+ type: "VariableDeclarator",
237
+ id: { type: "Identifier", name: iterName },
238
+ init: { type: "Literal", value: 0 }
239
+ }
240
+ ]
241
+ },
242
+ test: {
243
+ type: "BinaryExpression",
244
+ operator: "<",
245
+ left: { type: "Identifier", name: iterName },
246
+ right: {
247
+ type: "MemberExpression",
248
+ object: { type: "Identifier", name: propsName },
249
+ property: { type: "Identifier", name: "length" },
250
+ computed: false
251
+ }
252
+ },
253
+ update: {
254
+ type: "UpdateExpression",
255
+ operator: "++",
256
+ argument: { type: "Identifier", name: iterName },
257
+ prefix: true
258
+ },
259
+ body: {
260
+ type: "BlockStatement",
261
+ body: [
262
+ node.left.type == "VariableDeclaration"
263
+ ?
264
+ {
265
+ type: "VariableDeclaration",
266
+ kind: "var",
267
+ declarations: [
268
+ {
269
+ type: "VariableDeclarator",
270
+ id: node.left.declarations[0].id,
271
+ init: {
272
+ type: "MemberExpression",
273
+ object: { type: "Identifier", name: propsName },
274
+ property: { type: "Identifier", name: iterName },
275
+ computed: true
276
+ }
277
+ }
278
+ ]
279
+ }
280
+ :
281
+ {
282
+ type: "ExpressionStatement",
283
+ expression: {
284
+ type: "AssignmentExpression",
285
+ operator: "=",
286
+ left: node.left,
287
+ right: {
288
+ type: "MemberExpression",
289
+ object: { type: "Identifier", name: propsName },
290
+ property: { type: "Identifier", name: iterName },
291
+ computed: true
292
+ }
293
+ }
294
+ },
295
+ node.body
296
+ ]
297
+ }
298
+ };
299
+ return forStmt;
300
+ }
301
+
302
+ /**
303
+ * Simplify SwitchStatement.
304
+ * @param {SwitchStatement} node
305
+ * @return {Node}
306
+ */
307
+ simplifySwitchStatement (node) {
308
+ assert.ok(estest.isNode(node));
309
+
310
+ var cases = node.cases.map(c => {
311
+ var breakIndex = _.findIndex(c.consequent, x => x.type == "BreakStatement");
312
+ var statements, breaks;
313
+ if (breakIndex != -1) {
314
+ statements = c.consequent.slice(0, breakIndex);
315
+ breaks = true;
316
+ } else {
317
+ statements = c.consequent;
318
+ breaks = false;
319
+ }
320
+ return {
321
+ test: c.test,
322
+ statements: statements,
323
+ breaks: breaks
324
+ };
325
+ });
326
+
327
+ var stack = [], ifStmts = [];
328
+ for (let i = 0; i < cases.length; ++i) {
329
+ stack.push(cases[i]);
330
+ if (cases[i].breaks) {
331
+ var testName = `$$switchtest$${this.rngAlpha.get()}`;
332
+ var ifStmt;
333
+
334
+ for (var j = 0; j < stack.length; ++j) {
335
+ var sliced = stack.slice(0, j + 1);
336
+ if (sliced.every(x => x.test)) {
337
+
338
+ ifStmt = {
339
+ type: "BlockStatement",
340
+ body: [
341
+ {
342
+ type: "VariableDeclaration",
343
+ kind: "var",
344
+ declarations: [
345
+ {
346
+ type: "VariableDeclarator",
347
+ id: { type: "Identifier", name: testName }
348
+ }
349
+ ]
350
+ }
351
+ ]
352
+ };
353
+ ifStmt = {
354
+ type: "IfStatement",
355
+ test: chain(sliced.map(x => {
356
+ return { type: "BinaryExpression", operator: "==", left: x.test, right: node.discriminant };
357
+ }), "||"),
358
+ consequent: {
359
+ type: "BlockStatement",
360
+ body: (ifStmt ? [ ifStmt ] : []).concat(stack[j].statements)
361
+ }
362
+ };
363
+ } else {
364
+ ifStmt = {
365
+ type: "BlockStatement",
366
+ body: (ifStmt ? [ ifStmt ] : []).concat(stack[j].statements)
367
+ };
368
+ }
369
+ }
370
+ ifStmts.push(ifStmt);
371
+
372
+ ifStmt = null;
373
+ stack = [];
374
+ }
375
+ }
376
+ this.logger.log(ifStmts);
377
+ var combinedIfStmt = ifStmts[ifStmts.length - 1];
378
+ for (let i = ifStmts.length - 2; i >= 0; --i) {
379
+ combinedIfStmt = {
380
+ type: "IfStatement",
381
+ test: ifStmts[i].test,
382
+ consequent: ifStmts[i].consequent,
383
+ alternate: combinedIfStmt
384
+ };
385
+ }
386
+ return combinedIfStmt;
387
+ }
388
+
389
+ /**
390
+ * Simplify TryStatement.
391
+ * @param {TryStatement} node
392
+ * @return {Node}
393
+ */
394
+ simplifyTryStatement (node) {
395
+ assert.ok(estest.isNode(node));
396
+
397
+ if (node.finalizer) {
398
+ if (node.handler) {
399
+ return this.simplifyTryStatement({
400
+ type: "TryStatement",
401
+ block: {
402
+ type: "BlockStatement",
403
+ body: [
404
+ {
405
+ type: "TryStatement",
406
+ block: node.block,
407
+ handler: node.handler
408
+ }
409
+ ]
410
+ },
411
+ finalizer: node.finalizer
412
+ });
413
+ } else {
414
+ var finalizer = node.finalizer;
415
+ traverser.traverseEx(node.block, [], function (node, stack) {
416
+ if (stack.some(x => estest.isFunction(x.node))) {
417
+ this.abort();
418
+ return node;
419
+ } else if (node.type == "ReturnStatement") {
420
+ return {
421
+ type: "BlockStatement",
422
+ body: [
423
+ {
424
+ type: "VariableDeclaration",
425
+ kind: "var",
426
+ declarations: [
427
+ {
428
+ type: "VariableDeclarator",
429
+ id: { type: "Identifier", name: "veilmark$return" },
430
+ init: node.argument
431
+ }
432
+ ]
433
+ },
434
+ utils.cloneISwearIKnowWhatImDoing(finalizer),
435
+ {
436
+ type: "ReturnStatement",
437
+ argument: { type: "Identifier", name: "veilmark$return" }
438
+ }
439
+ ]
440
+ };
441
+ } else {
442
+ return node;
443
+ }
444
+ });
445
+
446
+ return {
447
+ type: "BlockStatement",
448
+ body: [
449
+ {
450
+ type: "TryStatement",
451
+ block: node.block,
452
+ handler: {
453
+ type: "CatchClause",
454
+ param: { type: "Identifier", name: "veilmark$e" },
455
+ body: {
456
+ type: "BlockStatement",
457
+ body: [
458
+ {
459
+ type: "VariableDeclaration",
460
+ kind: "var",
461
+ declarations: [
462
+ {
463
+ type: "VariableDeclarator",
464
+ id: { type: "Identifier", name: "veilmark$_e" },
465
+ init: { type: "Identifier", name: "veilmark$e" }
466
+ }
467
+ ]
468
+ }
469
+ ]
470
+ }
471
+ }
472
+ },
473
+ node.finalizer,
474
+ {
475
+ type: "IfStatement",
476
+ test: { type: "Identifier", name: "veilmark$_e" },
477
+ consequent: {
478
+ type: "ThrowStatement",
479
+ argument: { type: "Identifier", name: "veilmark$_e" }
480
+ }
481
+ }
482
+ ]
483
+ };
484
+ }
485
+ } else {
486
+ return node;
487
+ }
488
+ }
489
+
490
+ };