You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							127 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
	
	
							127 lines
						
					
					
						
							3.8 KiB
						
					
					
				| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Tobias Koppers @sokra
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const RequireEnsureDependenciesBlock = require("./RequireEnsureDependenciesBlock");
 | |
| const RequireEnsureDependency = require("./RequireEnsureDependency");
 | |
| const RequireEnsureItemDependency = require("./RequireEnsureItemDependency");
 | |
| const getFunctionExpression = require("./getFunctionExpression");
 | |
| 
 | |
| /** @typedef {import("../ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */
 | |
| /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
 | |
| 
 | |
| module.exports = class RequireEnsureDependenciesBlockParserPlugin {
 | |
| 	apply(parser) {
 | |
| 		parser.hooks.call
 | |
| 			.for("require.ensure")
 | |
| 			.tap("RequireEnsureDependenciesBlockParserPlugin", expr => {
 | |
| 				let chunkName = null;
 | |
| 				let errorExpressionArg = null;
 | |
| 				let errorExpression = null;
 | |
| 				switch (expr.arguments.length) {
 | |
| 					case 4: {
 | |
| 						const chunkNameExpr = parser.evaluateExpression(expr.arguments[3]);
 | |
| 						if (!chunkNameExpr.isString()) return;
 | |
| 						chunkName = chunkNameExpr.string;
 | |
| 					}
 | |
| 					// falls through
 | |
| 					case 3: {
 | |
| 						errorExpressionArg = expr.arguments[2];
 | |
| 						errorExpression = getFunctionExpression(errorExpressionArg);
 | |
| 
 | |
| 						if (!errorExpression && !chunkName) {
 | |
| 							const chunkNameExpr = parser.evaluateExpression(
 | |
| 								expr.arguments[2]
 | |
| 							);
 | |
| 							if (!chunkNameExpr.isString()) return;
 | |
| 							chunkName = chunkNameExpr.string;
 | |
| 						}
 | |
| 					}
 | |
| 					// falls through
 | |
| 					case 2: {
 | |
| 						const dependenciesExpr = parser.evaluateExpression(
 | |
| 							expr.arguments[0]
 | |
| 						);
 | |
| 						const dependenciesItems = dependenciesExpr.isArray()
 | |
| 							? dependenciesExpr.items
 | |
| 							: [dependenciesExpr];
 | |
| 						const successExpressionArg = expr.arguments[1];
 | |
| 						const successExpression =
 | |
| 							getFunctionExpression(successExpressionArg);
 | |
| 
 | |
| 						if (successExpression) {
 | |
| 							parser.walkExpressions(successExpression.expressions);
 | |
| 						}
 | |
| 						if (errorExpression) {
 | |
| 							parser.walkExpressions(errorExpression.expressions);
 | |
| 						}
 | |
| 
 | |
| 						const depBlock = new RequireEnsureDependenciesBlock(
 | |
| 							/** @type {ChunkGroupOptions & { entryOptions?: TODO }} */ (
 | |
| 								chunkName
 | |
| 							),
 | |
| 							expr.loc
 | |
| 						);
 | |
| 						const errorCallbackExists =
 | |
| 							expr.arguments.length === 4 ||
 | |
| 							(!chunkName && expr.arguments.length === 3);
 | |
| 						const dep = new RequireEnsureDependency(
 | |
| 							expr.range,
 | |
| 							expr.arguments[1].range,
 | |
| 							errorCallbackExists && expr.arguments[2].range
 | |
| 						);
 | |
| 						dep.loc = expr.loc;
 | |
| 						depBlock.addDependency(dep);
 | |
| 						const old = parser.state.current;
 | |
| 						parser.state.current = depBlock;
 | |
| 						try {
 | |
| 							let failed = false;
 | |
| 							parser.inScope([], () => {
 | |
| 								for (const ee of dependenciesItems) {
 | |
| 									if (ee.isString()) {
 | |
| 										const ensureDependency = new RequireEnsureItemDependency(
 | |
| 											ee.string
 | |
| 										);
 | |
| 										ensureDependency.loc = ee.loc || expr.loc;
 | |
| 										depBlock.addDependency(ensureDependency);
 | |
| 									} else {
 | |
| 										failed = true;
 | |
| 									}
 | |
| 								}
 | |
| 							});
 | |
| 							if (failed) {
 | |
| 								return;
 | |
| 							}
 | |
| 							if (successExpression) {
 | |
| 								if (successExpression.fn.body.type === "BlockStatement") {
 | |
| 									parser.walkStatement(successExpression.fn.body);
 | |
| 								} else {
 | |
| 									parser.walkExpression(successExpression.fn.body);
 | |
| 								}
 | |
| 							}
 | |
| 							old.addBlock(depBlock);
 | |
| 						} finally {
 | |
| 							parser.state.current = old;
 | |
| 						}
 | |
| 						if (!successExpression) {
 | |
| 							parser.walkExpression(successExpressionArg);
 | |
| 						}
 | |
| 						if (errorExpression) {
 | |
| 							if (errorExpression.fn.body.type === "BlockStatement") {
 | |
| 								parser.walkStatement(errorExpression.fn.body);
 | |
| 							} else {
 | |
| 								parser.walkExpression(errorExpression.fn.body);
 | |
| 							}
 | |
| 						} else if (errorExpressionArg) {
 | |
| 							parser.walkExpression(errorExpressionArg);
 | |
| 						}
 | |
| 						return true;
 | |
| 					}
 | |
| 				}
 | |
| 			});
 | |
| 	}
 | |
| };
 |