source: imaps-frontend/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 12.1 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const RuntimeGlobals = require("../RuntimeGlobals");
9const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
10const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
11const AMDRequireContextDependency = require("./AMDRequireContextDependency");
12const AMDRequireDependenciesBlock = require("./AMDRequireDependenciesBlock");
13const AMDRequireDependency = require("./AMDRequireDependency");
14const AMDRequireItemDependency = require("./AMDRequireItemDependency");
15const ConstDependency = require("./ConstDependency");
16const ContextDependencyHelpers = require("./ContextDependencyHelpers");
17const LocalModuleDependency = require("./LocalModuleDependency");
18const { getLocalModule } = require("./LocalModulesHelpers");
19const UnsupportedDependency = require("./UnsupportedDependency");
20const getFunctionExpression = require("./getFunctionExpression");
21
22/** @typedef {import("estree").CallExpression} CallExpression */
23/** @typedef {import("estree").Expression} Expression */
24/** @typedef {import("estree").Identifier} Identifier */
25/** @typedef {import("estree").SourceLocation} SourceLocation */
26/** @typedef {import("estree").SpreadElement} SpreadElement */
27/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
28/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
29/** @typedef {import("../Module").BuildInfo} BuildInfo */
30/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
31/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
32/** @typedef {import("../javascript/JavascriptParser").Range} Range */
33
34class AMDRequireDependenciesBlockParserPlugin {
35 /**
36 * @param {JavascriptParserOptions} options parserOptions
37 */
38 constructor(options) {
39 this.options = options;
40 }
41
42 /**
43 * @param {JavascriptParser} parser the parser
44 * @param {Expression | SpreadElement} expression expression
45 * @returns {boolean} need bind this
46 */
47 processFunctionArgument(parser, expression) {
48 let bindThis = true;
49 const fnData = getFunctionExpression(expression);
50 if (fnData) {
51 parser.inScope(
52 fnData.fn.params.filter(
53 i =>
54 !["require", "module", "exports"].includes(
55 /** @type {Identifier} */ (i).name
56 )
57 ),
58 () => {
59 if (fnData.fn.body.type === "BlockStatement") {
60 parser.walkStatement(fnData.fn.body);
61 } else {
62 parser.walkExpression(fnData.fn.body);
63 }
64 }
65 );
66 parser.walkExpressions(fnData.expressions);
67 if (fnData.needThis === false) {
68 bindThis = false;
69 }
70 } else {
71 parser.walkExpression(expression);
72 }
73 return bindThis;
74 }
75
76 /**
77 * @param {JavascriptParser} parser the parser
78 * @returns {void}
79 */
80 apply(parser) {
81 parser.hooks.call
82 .for("require")
83 .tap(
84 "AMDRequireDependenciesBlockParserPlugin",
85 this.processCallRequire.bind(this, parser)
86 );
87 }
88
89 /**
90 * @param {JavascriptParser} parser the parser
91 * @param {CallExpression} expr call expression
92 * @param {BasicEvaluatedExpression} param param
93 * @returns {boolean | undefined} result
94 */
95 processArray(parser, expr, param) {
96 if (param.isArray()) {
97 for (const p of /** @type {BasicEvaluatedExpression[]} */ (param.items)) {
98 const result = this.processItem(parser, expr, p);
99 if (result === undefined) {
100 this.processContext(parser, expr, p);
101 }
102 }
103 return true;
104 } else if (param.isConstArray()) {
105 /** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */
106 const deps = [];
107 for (const request of /** @type {any[]} */ (param.array)) {
108 let dep;
109 let localModule;
110 if (request === "require") {
111 dep = RuntimeGlobals.require;
112 } else if (["exports", "module"].includes(request)) {
113 dep = request;
114 } else if ((localModule = getLocalModule(parser.state, request))) {
115 localModule.flagUsed();
116 dep = new LocalModuleDependency(localModule, undefined, false);
117 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
118 parser.state.module.addPresentationalDependency(dep);
119 } else {
120 dep = this.newRequireItemDependency(request);
121 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
122 dep.optional = Boolean(parser.scope.inTry);
123 parser.state.current.addDependency(dep);
124 }
125 deps.push(dep);
126 }
127 const dep = this.newRequireArrayDependency(
128 deps,
129 /** @type {Range} */ (param.range)
130 );
131 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
132 dep.optional = Boolean(parser.scope.inTry);
133 parser.state.module.addPresentationalDependency(dep);
134 return true;
135 }
136 }
137
138 /**
139 * @param {JavascriptParser} parser the parser
140 * @param {CallExpression} expr call expression
141 * @param {BasicEvaluatedExpression} param param
142 * @returns {boolean | undefined} result
143 */
144 processItem(parser, expr, param) {
145 if (param.isConditional()) {
146 for (const p of /** @type {BasicEvaluatedExpression[]} */ (
147 param.options
148 )) {
149 const result = this.processItem(parser, expr, p);
150 if (result === undefined) {
151 this.processContext(parser, expr, p);
152 }
153 }
154 return true;
155 } else if (param.isString()) {
156 let dep;
157 let localModule;
158 if (param.string === "require") {
159 dep = new ConstDependency(
160 RuntimeGlobals.require,
161 /** @type {TODO} */ (param.string),
162 [RuntimeGlobals.require]
163 );
164 } else if (param.string === "module") {
165 dep = new ConstDependency(
166 /** @type {BuildInfo} */
167 (parser.state.module.buildInfo).moduleArgument,
168 /** @type {Range} */ (param.range),
169 [RuntimeGlobals.module]
170 );
171 } else if (param.string === "exports") {
172 dep = new ConstDependency(
173 /** @type {BuildInfo} */
174 (parser.state.module.buildInfo).exportsArgument,
175 /** @type {Range} */ (param.range),
176 [RuntimeGlobals.exports]
177 );
178 } else if (
179 (localModule = getLocalModule(
180 parser.state,
181 /** @type {string} */ (param.string)
182 ))
183 ) {
184 localModule.flagUsed();
185 dep = new LocalModuleDependency(localModule, param.range, false);
186 } else {
187 dep = this.newRequireItemDependency(
188 /** @type {string} */ (param.string),
189 param.range
190 );
191 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
192 dep.optional = Boolean(parser.scope.inTry);
193 parser.state.current.addDependency(dep);
194 return true;
195 }
196 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
197 parser.state.module.addPresentationalDependency(dep);
198 return true;
199 }
200 }
201
202 /**
203 * @param {JavascriptParser} parser the parser
204 * @param {CallExpression} expr call expression
205 * @param {BasicEvaluatedExpression} param param
206 * @returns {boolean | undefined} result
207 */
208 processContext(parser, expr, param) {
209 const dep = ContextDependencyHelpers.create(
210 AMDRequireContextDependency,
211 /** @type {Range} */ (param.range),
212 param,
213 expr,
214 this.options,
215 {
216 category: "amd"
217 },
218 parser
219 );
220 if (!dep) return;
221 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
222 dep.optional = Boolean(parser.scope.inTry);
223 parser.state.current.addDependency(dep);
224 return true;
225 }
226
227 /**
228 * @param {BasicEvaluatedExpression} param param
229 * @returns {string | undefined} result
230 */
231 processArrayForRequestString(param) {
232 if (param.isArray()) {
233 const result =
234 /** @type {BasicEvaluatedExpression[]} */
235 (param.items).map(item => this.processItemForRequestString(item));
236 if (result.every(Boolean)) return result.join(" ");
237 } else if (param.isConstArray()) {
238 return /** @type {string[]} */ (param.array).join(" ");
239 }
240 }
241
242 /**
243 * @param {BasicEvaluatedExpression} param param
244 * @returns {string | undefined} result
245 */
246 processItemForRequestString(param) {
247 if (param.isConditional()) {
248 const result =
249 /** @type {BasicEvaluatedExpression[]} */
250 (param.options).map(item => this.processItemForRequestString(item));
251 if (result.every(Boolean)) return result.join("|");
252 } else if (param.isString()) {
253 return param.string;
254 }
255 }
256
257 /**
258 * @param {JavascriptParser} parser the parser
259 * @param {CallExpression} expr call expression
260 * @returns {boolean | undefined} result
261 */
262 processCallRequire(parser, expr) {
263 /** @type {BasicEvaluatedExpression | undefined} */
264 let param;
265 /** @type {AMDRequireDependenciesBlock | undefined | null} */
266 let depBlock;
267 /** @type {AMDRequireDependency | undefined} */
268 let dep;
269 /** @type {boolean | undefined} */
270 let result;
271
272 const old = parser.state.current;
273
274 if (expr.arguments.length >= 1) {
275 param = parser.evaluateExpression(
276 /** @type {Expression} */ (expr.arguments[0])
277 );
278 depBlock = this.newRequireDependenciesBlock(
279 /** @type {DependencyLocation} */ (expr.loc),
280 this.processArrayForRequestString(param)
281 );
282 dep = this.newRequireDependency(
283 /** @type {Range} */ (expr.range),
284 /** @type {Range} */ (param.range),
285 expr.arguments.length > 1
286 ? /** @type {Range} */ (expr.arguments[1].range)
287 : null,
288 expr.arguments.length > 2
289 ? /** @type {Range} */ (expr.arguments[2].range)
290 : null
291 );
292 dep.loc = /** @type {DependencyLocation} */ (expr.loc);
293 depBlock.addDependency(dep);
294
295 parser.state.current = /** @type {TODO} */ (depBlock);
296 }
297
298 if (expr.arguments.length === 1) {
299 parser.inScope([], () => {
300 result = this.processArray(
301 parser,
302 expr,
303 /** @type {BasicEvaluatedExpression} */ (param)
304 );
305 });
306 parser.state.current = old;
307 if (!result) return;
308 parser.state.current.addBlock(
309 /** @type {AMDRequireDependenciesBlock} */ (depBlock)
310 );
311 return true;
312 }
313
314 if (expr.arguments.length === 2 || expr.arguments.length === 3) {
315 try {
316 parser.inScope([], () => {
317 result = this.processArray(
318 parser,
319 expr,
320 /** @type {BasicEvaluatedExpression} */ (param)
321 );
322 });
323 if (!result) {
324 const dep = new UnsupportedDependency(
325 "unsupported",
326 /** @type {Range} */ (expr.range)
327 );
328 old.addPresentationalDependency(dep);
329 if (parser.state.module) {
330 parser.state.module.addError(
331 new UnsupportedFeatureWarning(
332 `Cannot statically analyse 'require(…, …)' in line ${
333 /** @type {SourceLocation} */ (expr.loc).start.line
334 }`,
335 /** @type {DependencyLocation} */ (expr.loc)
336 )
337 );
338 }
339 depBlock = null;
340 return true;
341 }
342 /** @type {AMDRequireDependency} */
343 (dep).functionBindThis = this.processFunctionArgument(
344 parser,
345 expr.arguments[1]
346 );
347 if (expr.arguments.length === 3) {
348 /** @type {AMDRequireDependency} */
349 (dep).errorCallbackBindThis = this.processFunctionArgument(
350 parser,
351 expr.arguments[2]
352 );
353 }
354 } finally {
355 parser.state.current = old;
356 if (depBlock) parser.state.current.addBlock(depBlock);
357 }
358 return true;
359 }
360 }
361
362 /**
363 * @param {DependencyLocation} loc location
364 * @param {string=} request request
365 * @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock
366 */
367 newRequireDependenciesBlock(loc, request) {
368 return new AMDRequireDependenciesBlock(loc, request);
369 }
370
371 /**
372 * @param {Range} outerRange outer range
373 * @param {Range} arrayRange array range
374 * @param {Range | null} functionRange function range
375 * @param {Range | null} errorCallbackRange error callback range
376 * @returns {AMDRequireDependency} dependency
377 */
378 newRequireDependency(
379 outerRange,
380 arrayRange,
381 functionRange,
382 errorCallbackRange
383 ) {
384 return new AMDRequireDependency(
385 outerRange,
386 arrayRange,
387 functionRange,
388 errorCallbackRange
389 );
390 }
391
392 /**
393 * @param {string} request request
394 * @param {Range=} range range
395 * @returns {AMDRequireItemDependency} AMDRequireItemDependency
396 */
397 newRequireItemDependency(request, range) {
398 return new AMDRequireItemDependency(request, range);
399 }
400
401 /**
402 * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array
403 * @param {Range} range range
404 * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency
405 */
406 newRequireArrayDependency(depsArray, range) {
407 return new AMDRequireArrayDependency(depsArray, range);
408 }
409}
410module.exports = AMDRequireDependenciesBlockParserPlugin;
Note: See TracBrowser for help on using the repository browser.