| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const RuntimeGlobals = require("../RuntimeGlobals"); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | const formatLocation = require("../formatLocation"); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | const { evaluateToString } = require("../javascript/JavascriptParserHelpers"); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | const propertyAccess = require("../util/propertyAccess"); | 
					
						
							|  |  |  | const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency"); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | const CommonJsExportsDependency = require("./CommonJsExportsDependency"); | 
					
						
							|  |  |  | const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency"); | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | const DynamicExports = require("./DynamicExports"); | 
					
						
							|  |  |  | const HarmonyExports = require("./HarmonyExports"); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | const ModuleDecoratorDependency = require("./ModuleDecoratorDependency"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 06:44:45 +08:00
										 |  |  | /** @typedef {import("estree").AssignmentExpression} AssignmentExpression */ | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | /** @typedef {import("estree").CallExpression} CallExpression */ | 
					
						
							|  |  |  | /** @typedef {import("estree").Expression} Expression */ | 
					
						
							| 
									
										
										
										
											2023-04-24 06:44:45 +08:00
										 |  |  | /** @typedef {import("estree").Super} Super */ | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | /** @typedef {import("../ModuleGraph")} ModuleGraph */ | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | /** @typedef {import("../NormalModule")} NormalModule */ | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | /** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | /** @typedef {import("../javascript/JavascriptParser").Range} Range */ | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | /** @typedef {import("../javascript/JavascriptParser").StatementPath} StatementPath */ | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | /** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2023-04-24 06:44:45 +08:00
										 |  |  |  * This function takes a generic expression and detects whether it is an ObjectExpression. | 
					
						
							|  |  |  |  * This is used in the context of parsing CommonJS exports to get the value of the property descriptor | 
					
						
							|  |  |  |  * when the `exports` object is assigned to `Object.defineProperty`. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * In CommonJS modules, the `exports` object can be assigned to `Object.defineProperty` and therefore | 
					
						
							|  |  |  |  * webpack has to detect this case and get the value key of the property descriptor. See the following example | 
					
						
							|  |  |  |  * for more information: https://astexplorer.net/#/gist/83ce51a4e96e59d777df315a6d111da6/8058ead48a1bb53c097738225db0967ef7f70e57
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This would be an example of a CommonJS module that exports an object with a property descriptor: | 
					
						
							|  |  |  |  * ```js
 | 
					
						
							|  |  |  |  * Object.defineProperty(exports, "__esModule", { value: true }); | 
					
						
							|  |  |  |  * exports.foo = void 0; | 
					
						
							|  |  |  |  * exports.foo = "bar"; | 
					
						
							|  |  |  |  * ```
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  |  * @param {TODO} expr expression | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  |  * @returns {Expression | undefined} returns the value of property descriptor | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | const getValueOfPropertyDescription = expr => { | 
					
						
							|  |  |  | 	if (expr.type !== "ObjectExpression") return; | 
					
						
							|  |  |  | 	for (const property of expr.properties) { | 
					
						
							|  |  |  | 		if (property.computed) continue; | 
					
						
							|  |  |  | 		const key = property.key; | 
					
						
							|  |  |  | 		if (key.type !== "Identifier" || key.name !== "value") continue; | 
					
						
							|  |  |  | 		return property.value; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * The purpose of this function is to check whether an expression is a truthy literal or not. This is | 
					
						
							|  |  |  |  * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy | 
					
						
							|  |  |  |  * values like `null` and `false`. However, exports should only be created if the exported value is truthy. | 
					
						
							|  |  |  |  * @param {Expression} expr expression being checked | 
					
						
							|  |  |  |  * @returns {boolean} true, when the expression is a truthy literal | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | const isTruthyLiteral = expr => { | 
					
						
							|  |  |  | 	switch (expr.type) { | 
					
						
							|  |  |  | 		case "Literal": | 
					
						
							| 
									
										
										
										
											2024-07-31 11:11:11 +08:00
										 |  |  | 			return Boolean(expr.value); | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 		case "UnaryExpression": | 
					
						
							|  |  |  | 			if (expr.operator === "!") return isFalsyLiteral(expr.argument); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * The purpose of this function is to check whether an expression is a falsy literal or not. This is | 
					
						
							|  |  |  |  * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy | 
					
						
							|  |  |  |  * values like `null` and `false`. However, exports should only be created if the exported value is truthy. | 
					
						
							|  |  |  |  * @param {Expression} expr expression being checked | 
					
						
							|  |  |  |  * @returns {boolean} true, when the expression is a falsy literal | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | const isFalsyLiteral = expr => { | 
					
						
							|  |  |  | 	switch (expr.type) { | 
					
						
							|  |  |  | 		case "Literal": | 
					
						
							|  |  |  | 			return !expr.value; | 
					
						
							|  |  |  | 		case "UnaryExpression": | 
					
						
							|  |  |  | 			if (expr.operator === "!") return isTruthyLiteral(expr.argument); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {JavascriptParser} parser the parser | 
					
						
							| 
									
										
										
										
											2023-05-22 04:31:30 +08:00
										 |  |  |  * @param {Expression} expr expression | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  |  * @returns {{ argument: BasicEvaluatedExpression, ids: string[] } | undefined} parsed call | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const parseRequireCall = (parser, expr) => { | 
					
						
							|  |  |  | 	const ids = []; | 
					
						
							|  |  |  | 	while (expr.type === "MemberExpression") { | 
					
						
							|  |  |  | 		if (expr.object.type === "Super") return; | 
					
						
							|  |  |  | 		if (!expr.property) return; | 
					
						
							|  |  |  | 		const prop = expr.property; | 
					
						
							|  |  |  | 		if (expr.computed) { | 
					
						
							|  |  |  | 			if (prop.type !== "Literal") return; | 
					
						
							|  |  |  | 			ids.push(`${prop.value}`); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (prop.type !== "Identifier") return; | 
					
						
							|  |  |  | 			ids.push(prop.name); | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		expr = expr.object; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (expr.type !== "CallExpression" || expr.arguments.length !== 1) return; | 
					
						
							|  |  |  | 	const callee = expr.callee; | 
					
						
							|  |  |  | 	if ( | 
					
						
							|  |  |  | 		callee.type !== "Identifier" || | 
					
						
							|  |  |  | 		parser.getVariableInfo(callee.name) !== "require" | 
					
						
							|  |  |  | 	) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	const arg = expr.arguments[0]; | 
					
						
							|  |  |  | 	if (arg.type === "SpreadElement") return; | 
					
						
							|  |  |  | 	const argValue = parser.evaluateExpression(arg); | 
					
						
							|  |  |  | 	return { argument: argValue, ids: ids.reverse() }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CommonJsExportsParserPlugin { | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {ModuleGraph} moduleGraph module graph | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 	constructor(moduleGraph) { | 
					
						
							|  |  |  | 		this.moduleGraph = moduleGraph; | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {JavascriptParser} parser the parser | 
					
						
							| 
									
										
										
										
											2023-05-22 05:47:28 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 	 */ | 
					
						
							|  |  |  | 	apply(parser) { | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 		const enableStructuredExports = () => { | 
					
						
							| 
									
										
										
										
											2019-12-07 08:04:38 +08:00
										 |  |  | 			DynamicExports.enable(parser.state); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {boolean} topLevel true, when the export is on top level | 
					
						
							|  |  |  | 		 * @param {string[]} members members of the export | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 		 * @param {Expression | undefined} valueExpr expression for the value | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 		 * @returns {void} | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		const checkNamespace = (topLevel, members, valueExpr) => { | 
					
						
							| 
									
										
										
										
											2019-12-07 08:04:38 +08:00
										 |  |  | 			if (!DynamicExports.isEnabled(parser.state)) return; | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			if (members.length > 0 && members[0] === "__esModule") { | 
					
						
							| 
									
										
										
										
											2020-11-18 18:09:45 +08:00
										 |  |  | 				if (valueExpr && isTruthyLiteral(valueExpr) && topLevel) { | 
					
						
							| 
									
										
										
										
											2019-12-07 08:04:38 +08:00
										 |  |  | 					DynamicExports.setFlagged(parser.state); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 					DynamicExports.setDynamic(parser.state); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string=} reason reason | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		const bailout = reason => { | 
					
						
							| 
									
										
										
										
											2019-12-07 08:04:38 +08:00
										 |  |  | 			DynamicExports.bailout(parser.state); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			if (reason) bailoutHint(reason); | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {string} reason reason | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		const bailoutHint = reason => { | 
					
						
							|  |  |  | 			this.moduleGraph | 
					
						
							|  |  |  | 				.getOptimizationBailout(parser.state.module) | 
					
						
							|  |  |  | 				.push(`CommonJS bailout: ${reason}`); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// metadata //
 | 
					
						
							|  |  |  | 		parser.hooks.evaluateTypeof | 
					
						
							|  |  |  | 			.for("module") | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", evaluateToString("object")); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 		parser.hooks.evaluateTypeof | 
					
						
							|  |  |  | 			.for("exports") | 
					
						
							|  |  |  | 			.tap("CommonJsPlugin", evaluateToString("object")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// exporting //
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							|  |  |  | 		 * @param {AssignmentExpression} expr expression | 
					
						
							|  |  |  | 		 * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords | 
					
						
							|  |  |  | 		 * @param {string[]} members members of the export | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 		 * @returns {boolean | undefined} true, when the expression was handled | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		const handleAssignExport = (expr, base, members) => { | 
					
						
							|  |  |  | 			if (HarmonyExports.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 			// Handle reexporting
 | 
					
						
							|  |  |  | 			const requireCall = parseRequireCall(parser, expr.right); | 
					
						
							|  |  |  | 			if ( | 
					
						
							|  |  |  | 				requireCall && | 
					
						
							|  |  |  | 				requireCall.argument.isString() && | 
					
						
							|  |  |  | 				(members.length === 0 || members[0] !== "__esModule") | 
					
						
							|  |  |  | 			) { | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 				enableStructuredExports(); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				// It's possible to reexport __esModule, so we must convert to a dynamic module
 | 
					
						
							|  |  |  | 				if (members.length === 0) DynamicExports.setDynamic(parser.state); | 
					
						
							|  |  |  | 				const dep = new CommonJsExportRequireDependency( | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 					/** @type {Range} */ (expr.range), | 
					
						
							| 
									
										
										
										
											2019-12-22 03:26:41 +08:00
										 |  |  | 					null, | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 					base, | 
					
						
							|  |  |  | 					members, | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 					/** @type {string} */ (requireCall.argument.string), | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 					requireCall.ids, | 
					
						
							|  |  |  | 					!parser.isStatementLevelExpression(expr) | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 				dep.loc = /** @type {DependencyLocation} */ (expr.loc); | 
					
						
							| 
									
										
										
										
											2024-07-31 11:11:11 +08:00
										 |  |  | 				dep.optional = Boolean(parser.scope.inTry); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (members.length === 0) return; | 
					
						
							|  |  |  | 			enableStructuredExports(); | 
					
						
							|  |  |  | 			const remainingMembers = members; | 
					
						
							|  |  |  | 			checkNamespace( | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 				/** @type {StatementPath} */ | 
					
						
							|  |  |  | 				(parser.statementPath).length === 1 && | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 					parser.isStatementLevelExpression(expr), | 
					
						
							|  |  |  | 				remainingMembers, | 
					
						
							|  |  |  | 				expr.right | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 			const dep = new CommonJsExportsDependency( | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 				/** @type {Range} */ (expr.left.range), | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				null, | 
					
						
							|  |  |  | 				base, | 
					
						
							|  |  |  | 				remainingMembers | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 			dep.loc = /** @type {DependencyLocation} */ (expr.loc); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 			parser.walkExpression(expr.right); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		parser.hooks.assignMemberChain | 
					
						
							|  |  |  | 			.for("exports") | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => | 
					
						
							|  |  |  | 				handleAssignExport(expr, "exports", members) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 		parser.hooks.assignMemberChain | 
					
						
							|  |  |  | 			.for("this") | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => { | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				if (!parser.scope.topLevelScope) return; | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				return handleAssignExport(expr, "this", members); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		parser.hooks.assignMemberChain | 
					
						
							|  |  |  | 			.for("module") | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => { | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				if (members[0] !== "exports") return; | 
					
						
							|  |  |  | 				return handleAssignExport(expr, "module.exports", members.slice(1)); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 		parser.hooks.call | 
					
						
							|  |  |  | 			.for("Object.defineProperty") | 
					
						
							|  |  |  | 			.tap("CommonJsExportsParserPlugin", expression => { | 
					
						
							| 
									
										
										
										
											2023-04-24 06:44:45 +08:00
										 |  |  | 				const expr = /** @type {CallExpression} */ (expression); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				if (!parser.isStatementLevelExpression(expr)) return; | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 				if (expr.arguments.length !== 3) return; | 
					
						
							|  |  |  | 				if (expr.arguments[0].type === "SpreadElement") return; | 
					
						
							|  |  |  | 				if (expr.arguments[1].type === "SpreadElement") return; | 
					
						
							|  |  |  | 				if (expr.arguments[2].type === "SpreadElement") return; | 
					
						
							|  |  |  | 				const exportsArg = parser.evaluateExpression(expr.arguments[0]); | 
					
						
							| 
									
										
										
										
											2022-03-15 20:37:17 +08:00
										 |  |  | 				if (!exportsArg.isIdentifier()) return; | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 				if ( | 
					
						
							|  |  |  | 					exportsArg.identifier !== "exports" && | 
					
						
							|  |  |  | 					exportsArg.identifier !== "module.exports" && | 
					
						
							| 
									
										
										
										
											2019-12-22 03:26:41 +08:00
										 |  |  | 					(exportsArg.identifier !== "this" || !parser.scope.topLevelScope) | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 				) { | 
					
						
							|  |  |  | 					return; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				const propertyArg = parser.evaluateExpression(expr.arguments[1]); | 
					
						
							|  |  |  | 				const property = propertyArg.asString(); | 
					
						
							|  |  |  | 				if (typeof property !== "string") return; | 
					
						
							|  |  |  | 				enableStructuredExports(); | 
					
						
							|  |  |  | 				const descArg = expr.arguments[2]; | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				checkNamespace( | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 					/** @type {StatementPath} */ | 
					
						
							|  |  |  | 					(parser.statementPath).length === 1, | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 					[property], | 
					
						
							|  |  |  | 					getValueOfPropertyDescription(descArg) | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 				const dep = new CommonJsExportsDependency( | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 					/** @type {Range} */ (expr.range), | 
					
						
							|  |  |  | 					/** @type {Range} */ (expr.arguments[2].range), | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 					`Object.defineProperty(${exportsArg.identifier})`, | 
					
						
							|  |  |  | 					[property] | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 				dep.loc = /** @type {DependencyLocation} */ (expr.loc); | 
					
						
							| 
									
										
										
										
											2019-12-06 18:06:46 +08:00
										 |  |  | 				parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				parser.walkExpression(expr.arguments[2]); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Self reference //
 | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/** | 
					
						
							| 
									
										
										
										
											2023-04-24 06:44:45 +08:00
										 |  |  | 		 * @param {Expression | Super} expr expression | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 		 * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords | 
					
						
							|  |  |  | 		 * @param {string[]} members members of the export | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 		 * @param {CallExpression=} call call expression | 
					
						
							|  |  |  | 		 * @returns {boolean | void} true, when the expression was handled | 
					
						
							| 
									
										
										
										
											2023-04-23 13:35:52 +08:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 		const handleAccessExport = (expr, base, members, call) => { | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			if (HarmonyExports.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 			if (members.length === 0) { | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 				bailout( | 
					
						
							|  |  |  | 					`${base} is used directly at ${formatLocation( | 
					
						
							|  |  |  | 						/** @type {DependencyLocation} */ (expr.loc) | 
					
						
							|  |  |  | 					)}`
 | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (call && members.length === 1) { | 
					
						
							|  |  |  | 				bailoutHint( | 
					
						
							|  |  |  | 					`${base}${propertyAccess( | 
					
						
							|  |  |  | 						members | 
					
						
							| 
									
										
										
										
											2020-09-22 22:47:09 +08:00
										 |  |  | 					)}(...) prevents optimization as ${base} is passed as call context at ${formatLocation( | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 						/** @type {DependencyLocation} */ (expr.loc) | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 					)}`
 | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			const dep = new CommonJsSelfReferenceDependency( | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 				/** @type {Range} */ (expr.range), | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				base, | 
					
						
							|  |  |  | 				members, | 
					
						
							| 
									
										
										
										
											2024-07-31 11:11:11 +08:00
										 |  |  | 				Boolean(call) | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 			dep.loc = /** @type {DependencyLocation} */ (expr.loc); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 			if (call) { | 
					
						
							|  |  |  | 				parser.walkExpressions(call.arguments); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		parser.hooks.callMemberChain | 
					
						
							|  |  |  | 			.for("exports") | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => | 
					
						
							|  |  |  | 				handleAccessExport(expr.callee, "exports", members, expr) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		parser.hooks.expressionMemberChain | 
					
						
							|  |  |  | 			.for("exports") | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => | 
					
						
							|  |  |  | 				handleAccessExport(expr, "exports", members) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 		parser.hooks.expression | 
					
						
							|  |  |  | 			.for("exports") | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", expr => | 
					
						
							|  |  |  | 				handleAccessExport(expr, "exports", []) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		parser.hooks.callMemberChain | 
					
						
							|  |  |  | 			.for("module") | 
					
						
							|  |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => { | 
					
						
							|  |  |  | 				if (members[0] !== "exports") return; | 
					
						
							|  |  |  | 				return handleAccessExport( | 
					
						
							|  |  |  | 					expr.callee, | 
					
						
							|  |  |  | 					"module.exports", | 
					
						
							|  |  |  | 					members.slice(1), | 
					
						
							|  |  |  | 					expr | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		parser.hooks.expressionMemberChain | 
					
						
							|  |  |  | 			.for("module") | 
					
						
							|  |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => { | 
					
						
							|  |  |  | 				if (members[0] !== "exports") return; | 
					
						
							|  |  |  | 				return handleAccessExport(expr, "module.exports", members.slice(1)); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		parser.hooks.expression | 
					
						
							|  |  |  | 			.for("module.exports") | 
					
						
							| 
									
										
										
										
											2024-07-31 11:31:11 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", expr => | 
					
						
							|  |  |  | 				handleAccessExport(expr, "module.exports", []) | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 		parser.hooks.callMemberChain | 
					
						
							|  |  |  | 			.for("this") | 
					
						
							|  |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => { | 
					
						
							|  |  |  | 				if (!parser.scope.topLevelScope) return; | 
					
						
							|  |  |  | 				return handleAccessExport(expr.callee, "this", members, expr); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		parser.hooks.expressionMemberChain | 
					
						
							|  |  |  | 			.for("this") | 
					
						
							|  |  |  | 			.tap("CommonJsExportsParserPlugin", (expr, members) => { | 
					
						
							|  |  |  | 				if (!parser.scope.topLevelScope) return; | 
					
						
							|  |  |  | 				return handleAccessExport(expr, "this", members); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 		parser.hooks.expression | 
					
						
							|  |  |  | 			.for("this") | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 			.tap("CommonJsExportsParserPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 				if (!parser.scope.topLevelScope) return; | 
					
						
							| 
									
										
										
										
											2020-08-18 03:32:47 +08:00
										 |  |  | 				return handleAccessExport(expr, "this", []); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Bailouts //
 | 
					
						
							|  |  |  | 		parser.hooks.expression.for("module").tap("CommonJsPlugin", expr => { | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | 			bailout(); | 
					
						
							| 
									
										
										
										
											2019-12-07 08:04:38 +08:00
										 |  |  | 			const isHarmony = HarmonyExports.isEnabled(parser.state); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			const dep = new ModuleDecoratorDependency( | 
					
						
							|  |  |  | 				isHarmony | 
					
						
							|  |  |  | 					? RuntimeGlobals.harmonyModuleDecorator | 
					
						
							| 
									
										
										
										
											2020-05-18 23:10:08 +08:00
										 |  |  | 					: RuntimeGlobals.nodeModuleDecorator, | 
					
						
							|  |  |  | 				!isHarmony | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 			dep.loc = /** @type {DependencyLocation} */ (expr.loc); | 
					
						
							| 
									
										
										
										
											2019-12-05 05:54:26 +08:00
										 |  |  | 			parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-12-06 17:19:41 +08:00
										 |  |  | module.exports = CommonJsExportsParserPlugin; |