| 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 |
1
1
1
1
1
1
1
1
1
252
90
90
90
90
90
90
1
484
1
1
484
484
313
313
72
70
2
2
72
180
70
70
30
40
40
110
110
180
61
61
61
61
313
313
313
311
100
40
40
40
313
313
171
171
171
171
171
182
40
40
142
142
142
180
180
180
313
211
211
211
211
211
211
102
40
40
120
40
40
40
40
40
40
62
62
313
313
313
131
313
313
484
171
161
132
10
132
132
161
10
10
10
50
50
10
10
40
20
20
20
20
20
20
20
50
10
10
10
10
10
484
132
132
132
132
10
122
122
20
102
132
132
132
132
484
| /*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var AMDRequireItemDependency = require("./AMDRequireItemDependency");
var AMDRequireContextDependency = require("./AMDRequireContextDependency");
var ConstDependency = require("./ConstDependency");
var AMDDefineDependency = require("./AMDDefineDependency");
var AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
var LocalModuleDependency = require("./LocalModuleDependency");
var ContextDependencyHelpers = require("./ContextDependencyHelpers");
var LocalModulesHelpers = require("./LocalModulesHelpers");
function isBoundFunctionExpression(expr) {
if(expr.type !== "CallExpression") return false;
Iif(expr.callee.type !== "MemberExpression") return false;
Iif(expr.callee.computed) return false;
Iif(expr.callee.object.type !== "FunctionExpression") return false;
Iif(expr.callee.property.type !== "Identifier") return false;
Iif(expr.callee.property.name !== "bind") return false;
return true;
}
function AMDDefineDependencyParserPlugin(options) {
this.options = options;
}
module.exports = AMDDefineDependencyParserPlugin;
AMDDefineDependencyParserPlugin.prototype.apply = function(parser) {
var options = this.options;
parser.plugin("call define", function(expr) {
var array, fn, obj, namedModule;
switch(expr.arguments.length) {
case 1:
if(expr.arguments[0].type === "FunctionExpression" || isBoundFunctionExpression(expr.arguments[0])) {
// define(f() {...})
fn = expr.arguments[0];
} else Eif(expr.arguments[0].type === "ObjectExpression") {
// define({...})
obj = expr.arguments[0];
} else {
// define(expr)
// unclear if function or object
obj = fn = expr.arguments[0];
}
break;
case 2:
if(expr.arguments[0].type === "Literal") {
namedModule = expr.arguments[0].value;
// define("...", ...)
if(expr.arguments[1].type === "FunctionExpression" || isBoundFunctionExpression(expr.arguments[0])) {
// define("...", f() {...})
fn = expr.arguments[1];
} else Iif(expr.arguments[1].type === "ObjectExpression") {
// define("...", {...})
obj = expr.arguments[1];
} else {
// define("...", expr)
// unclear if function or object
obj = fn = expr.arguments[1];
}
} else {
// define([...], f() {})
array = expr.arguments[0];
fn = expr.arguments[1];
}
break;
case 3:
// define("...", [...], f() {...})
namedModule = expr.arguments[0].value;
array = expr.arguments[1];
fn = expr.arguments[2];
break;
default: return;
}
var fnParams = null;
var fnParamsOffset = 0;
if(fn) {
if(fn.type === "FunctionExpression") fnParams = fn.params;
else if(isBoundFunctionExpression(fn)) {
fnParams = fn.callee.object.params;
fnParamsOffset = fn.arguments.length - 1;
Iif(fnParamsOffset < 0) fnParamsOffset = 0;
}
}
var fnRenames = Object.create(this.scope.renames);
if(array) {
var identifiers = {};
var param = this.evaluateExpression(array);
var result = this.applyPluginsBailResult("call define:amd:array", expr, param, identifiers);
Iif(!result) return;
if(fnParams) fnParams = fnParams.slice(fnParamsOffset).filter(function(param, idx) {
if(identifiers[idx]) {
fnRenames["$"+param.name] = identifiers[idx];
return false;
}
return true;
});
} else {
var identifiers = ["require", "exports", "module"];
if(fnParams) fnParams = fnParams.slice(fnParamsOffset).filter(function(param, idx) {
Eif(identifiers[idx]) {
fnRenames["$"+param.name] = identifiers[idx];
return false;
}
return true;
});
}
if(fn && fn.type === "FunctionExpression") {
var inTry = this.scope.inTry;
this.inScope(fnParams, function() {
this.scope.renames = fnRenames;
this.scope.inTry = inTry;
Eif(fn.body.type === "BlockStatement")
this.walkStatement(fn.body);
else
this.walkExpression(fn.body);
}.bind(this));
} else if(fn && isBoundFunctionExpression(fn)) {
var inTry = this.scope.inTry;
this.inScope(fn.callee.object.params.filter(function(i) {
return ["require", "module", "exports"].indexOf(i.name) < 0;
}), function() {
this.scope.renames = fnRenames;
this.scope.inTry = inTry;
Eif(fn.callee.object.body.type === "BlockStatement")
this.walkStatement(fn.callee.object.body);
else
this.walkExpression(fn.callee.object.body);
}.bind(this));
Eif(fn.arguments)
this.walkExpressions(fn.arguments);
} else Eif(fn || obj) {
this.walkExpression(fn || obj);
}
var dep = new AMDDefineDependency(expr.range, array ? array.range : null, fn ? fn.range : null, obj ? obj.range : null);
dep.loc = expr.loc;
if(namedModule) {
dep.localModule = LocalModulesHelpers.addLocalModule(this.state, namedModule);
}
this.state.current.addDependency(dep);
return true;
});
parser.plugin("call define:amd:array", function(expr, param, identifiers) {
if(param.isArray()) {
param.items.forEach(function(param, idx) {
if(param.isString() && ["require", "module", "exports"].indexOf(param.string) >= 0)
identifiers[idx] = param.string;
var result = this.applyPluginsBailResult("call define:amd:item", expr, param);
Iif(result === undefined) {
this.applyPluginsBailResult("call define:amd:context", expr, param);
}
}, this);
return true;
} else Eif(param.isConstArray()) {
var deps = [];
param.array.forEach(function(request, idx) {
var dep, localModule;
if(request === "require") {
identifiers[idx] = request;
dep = "__webpack_require__";
} else if(["exports", "module"].indexOf(request) >= 0) {
identifiers[idx] = request;
dep = request;
} else Iif(localModule = LocalModulesHelpers.getLocalModule(this.state, request)) {
dep = new LocalModuleDependency(localModule);
dep.loc = expr.loc;
this.state.current.addDependency(dep);
} else {
dep = new AMDRequireItemDependency(request);
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
}
deps.push(dep);
}, this);
var dep = new AMDRequireArrayDependency(deps, param.range);
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
}
});
parser.plugin("call define:amd:item", function(expr, param) {
Iif(param.isConditional()) {
param.options.forEach(function(param) {
var result = this.applyPluginsBailResult("call define:amd:item", expr, param);
if(result === undefined) {
this.applyPluginsBailResult("call define:amd:context", expr, param);
}
}, this);
return true;
} else Eif(param.isString()) {
var dep, localModule;
if(param.string === "require") {
dep = new ConstDependency("__webpack_require__", param.range);
} else Iif(["require", "exports", "module"].indexOf(param.string) >= 0) {
dep = new ConstDependency(param.string, param.range);
} else if(localModule = LocalModulesHelpers.getLocalModule(this.state, param.string)) {
dep = new LocalModuleDependency(localModule, param.range);
} else {
dep = new AMDRequireItemDependency(param.string, param.range);
}
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
}
});
parser.plugin("call define:amd:context", function(expr, param) {
var dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
if(!dep) return;
dep.loc = expr.loc;
dep.optional = !!this.scope.inTry;
this.state.current.addDependency(dep);
return true;
});
};
|