-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjswrap.js
85 lines (71 loc) · 2.39 KB
/
jswrap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'use strict';
var esprima, escodegen, _;
module.exports = function (code, catchbody, module) {
esprima = esprima || require('esprima');
escodegen = escodegen || require('escodegen');
_ = _ || require('lodash');
_.templateSettings = {
evaluate: /\{\{#([\s\S]+?)\}\}/g, // {{# console.log("blah") }}
interpolate: /\{\{[^#\{]([\s\S]+?)[^\}]\}\}/g, // {{ title }}
escape: /\{\{\{([\s\S]+?)\}\}\}/g, // {{{ title }}}
}
if (catchbody) {
var astbody = JSON.stringify(esprima.parseScript(catchbody).body);
var catcher = function (fn_id) {
return JSON.parse(astbody.replace('{{fn_id}}', fn_id));
}
} else {
var catcher = function () {
return [];
}
}
var root = module ? esprima.parseModule(code) : esprima.parseScript(code)
var fns = []
function isFn(el) {
return el instanceof Object && !(el instanceof Array) &&
(el.type === 'FunctionDeclaration' || el.type === 'FunctionExpression');
}
function parse(root) {
_.each(root, function (el) {
if (isFn(el)) fns.push(el)
if (el instanceof Object) parse(el);
})
}
parse(root)
_.each(fns, function (fn, index) {
// move nested functions outside the body
var nestedFns = [];
_.each(fn.body.body, function (el) {
if (isFn(el)) {
nestedFns.push(el);
fn.body.body = _.without(fn.body.body, el);
};
})
fn.body.body = nestedFns.concat([
{
"type": "TryStatement",
"block": {
"type": "BlockStatement",
"body": fn.body.body
},
"guardedHandlers": [],
"handlers": [
{
"type": "CatchClause",
"param": {
"type": "Identifier",
"name": "jswrap_exception"
},
"body": {
"type": "BlockStatement",
"body": catcher(index)
}
}
],
"finalizer": null
}
]);
});
var result = escodegen.generate(root);
return result;
};