1 | var esprima = require('esprima-next'),
|
2 | traverse = require('./traverse'),
|
3 | comparify = require('comparify'),
|
4 | getAst = require("./get_ast"),
|
5 | estraverse = require("estraverse");
|
6 |
|
7 | function toVariableName(moduleName){
|
8 | return "__"+moduleName.replace(/[^\w]/g,"_")
|
9 | }
|
10 |
|
11 | function isRequire(obj){
|
12 | return comparify(obj, {
|
13 | "type": "CallExpression",
|
14 | "callee": {
|
15 | "type": "Identifier",
|
16 | "name": "require"
|
17 | }
|
18 | });
|
19 | }
|
20 |
|
21 | module.exports = function(load){
|
22 |
|
23 | var moduleNameToVariables = {};
|
24 |
|
25 | var ast = getAst(load);
|
26 |
|
27 | traverse(ast, function(obj){
|
28 | var moduleName;
|
29 | var variableName;
|
30 |
|
31 | if( isRequire(obj) &&
|
32 | obj.arguments.length && obj.arguments[0].type === "Literal" ) {
|
33 | moduleName = obj.arguments[0].value;
|
34 | variableName = toVariableName(moduleName);
|
35 | moduleNameToVariables[moduleName] = variableName;
|
36 | obj.type = "Identifier";
|
37 | obj.name = variableName;
|
38 | delete obj.arguments;
|
39 | delete obj.callee;
|
40 | }
|
41 | else if(
|
42 | comparify(obj,
|
43 | {
|
44 | type: "MemberExpression",
|
45 | object: {
|
46 | type: "CallExpression",
|
47 | callee: {
|
48 | type: "Identifier",
|
49 | name: "require"
|
50 | }
|
51 | }
|
52 | }) &&
|
53 | obj.object.arguments[0].type === "Literal"
|
54 | ) {
|
55 | moduleName = obj.object.arguments[0].value;
|
56 | variableName = toVariableName(moduleName);
|
57 | moduleNameToVariables[moduleName] = variableName;
|
58 | obj.object = {name: variableName, type: "Identifier"};
|
59 | } else if(
|
60 | comparify(obj,
|
61 | {
|
62 | type: "ExpressionStatement",
|
63 | "expression": {
|
64 | "type": "AssignmentExpression",
|
65 | "operator": "=",
|
66 | "left": {
|
67 | "type": "MemberExpression",
|
68 | "computed": false,
|
69 | "object": {
|
70 | "type": "Identifier",
|
71 | "name": "module"
|
72 | },
|
73 | "property": {
|
74 | "type": "Identifier",
|
75 | "name": "exports"
|
76 | }
|
77 | },
|
78 | "right": {
|
79 | "type": "ObjectExpression"
|
80 | }
|
81 | }
|
82 | })
|
83 | ) {
|
84 | var objExpression = obj.expression.right;
|
85 | delete obj.expression;
|
86 | obj.type = "ReturnStatement";
|
87 | obj.argument = objExpression;
|
88 | }
|
89 | });
|
90 | var moduleNames = [],
|
91 | variableNames = [];
|
92 |
|
93 | for(var moduleName in moduleNameToVariables) {
|
94 | moduleNames.push(moduleName);
|
95 | variableNames.push(moduleNameToVariables[moduleName]);
|
96 | }
|
97 |
|
98 | var newAst = stealInsert(moduleNames, variableNames, ast.body);
|
99 |
|
100 | return newAst;
|
101 | };
|
102 |
|
103 | function stealInsert(deps, vars, body) {
|
104 | var depString = deps.join("','");
|
105 | var varString = vars.join(",");
|
106 | var code = "steal('" + depString + "', function(" +
|
107 | varString + "){\n" + "\n});";
|
108 |
|
109 | var ast = esprima.parse(code);
|
110 | var astBody = body || [];
|
111 |
|
112 | var isFunction;
|
113 | estraverse.traverse(ast, {
|
114 | enter: function(node) {
|
115 | if(node.type === "FunctionExpression") {
|
116 | isFunction = true;
|
117 | }
|
118 | if(isFunction && node.type === "BlockStatement") {
|
119 | astBody.forEach(function(part){
|
120 | node.body.push(part);
|
121 | });
|
122 | this.break();
|
123 | }
|
124 | }
|
125 | });
|
126 |
|
127 | return ast;
|
128 | }
|