| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | const { | 
					
						
							|  |  |  | 	JAVASCRIPT_MODULE_TYPE_AUTO, | 
					
						
							|  |  |  | 	JAVASCRIPT_MODULE_TYPE_ESM | 
					
						
							|  |  |  | } = require("../ModuleTypeConstants"); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | const PureExpressionDependency = require("../dependencies/PureExpressionDependency"); | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | const InnerGraph = require("./InnerGraph"); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | /** @typedef {import("estree").ClassDeclaration} ClassDeclaration */ | 
					
						
							|  |  |  | /** @typedef {import("estree").ClassExpression} ClassExpression */ | 
					
						
							|  |  |  | /** @typedef {import("estree").Expression} Expression */ | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | /** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */ | 
					
						
							|  |  |  | /** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */ | 
					
						
							| 
									
										
										
										
											2020-04-09 03:40:13 +08:00
										 |  |  | /** @typedef {import("estree").Node} Node */ | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | /** @typedef {import("estree").VariableDeclarator} VariableDeclarator */ | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | /** @typedef {import("../Compiler")} Compiler */ | 
					
						
							| 
									
										
										
										
											2019-09-04 15:27:19 +08:00
										 |  |  | /** @typedef {import("../Dependency")} Dependency */ | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | /** @typedef {import("../dependencies/HarmonyImportSpecifierDependency")} HarmonyImportSpecifierDependency */ | 
					
						
							| 
									
										
										
										
											2019-10-11 21:46:57 +08:00
										 |  |  | /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | /** @typedef {import("../javascript/JavascriptParser").Range} Range */ | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | /** @typedef {import("./InnerGraph").InnerGraph} InnerGraph */ | 
					
						
							|  |  |  | /** @typedef {import("./InnerGraph").TopLevelSymbol} TopLevelSymbol */ | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | const { topLevelSymbolTag } = InnerGraph; | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | const PLUGIN_NAME = "InnerGraphPlugin"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | class InnerGraphPlugin { | 
					
						
							|  |  |  | 	/** | 
					
						
							| 
									
										
										
										
											2020-04-23 16:48:36 +08:00
										 |  |  | 	 * Apply the plugin | 
					
						
							|  |  |  | 	 * @param {Compiler} compiler the compiler instance | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	apply(compiler) { | 
					
						
							|  |  |  | 		compiler.hooks.compilation.tap( | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 			PLUGIN_NAME, | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 			(compilation, { normalModuleFactory }) => { | 
					
						
							| 
									
										
										
										
											2020-01-30 18:34:33 +08:00
										 |  |  | 				const logger = compilation.getLogger("webpack.InnerGraphPlugin"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 				compilation.dependencyTemplates.set( | 
					
						
							|  |  |  | 					PureExpressionDependency, | 
					
						
							|  |  |  | 					new PureExpressionDependency.Template() | 
					
						
							|  |  |  | 				); | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 				/** | 
					
						
							|  |  |  | 				 * @param {JavascriptParser} parser the parser | 
					
						
							| 
									
										
										
										
											2023-06-17 01:13:03 +08:00
										 |  |  | 				 * @param {JavascriptParserOptions} parserOptions options | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 				 * @returns {void} | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 				const handler = (parser, parserOptions) => { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 					/** | 
					
						
							|  |  |  | 					 * @param {Expression} sup sup | 
					
						
							|  |  |  | 					 */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					const onUsageSuper = (sup) => { | 
					
						
							|  |  |  | 						InnerGraph.onUsage(parser.state, (usedByExports) => { | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 							switch (usedByExports) { | 
					
						
							|  |  |  | 								case undefined: | 
					
						
							|  |  |  | 								case true: | 
					
						
							|  |  |  | 									return; | 
					
						
							|  |  |  | 								default: { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 									const dep = new PureExpressionDependency( | 
					
						
							|  |  |  | 										/** @type {Range} */ | 
					
						
							|  |  |  | 										(sup.range) | 
					
						
							|  |  |  | 									); | 
					
						
							|  |  |  | 									dep.loc = /** @type {DependencyLocation} */ (sup.loc); | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 									dep.usedByExports = usedByExports; | 
					
						
							|  |  |  | 									parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 									break; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 					parser.hooks.program.tap(PLUGIN_NAME, () => { | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | 						InnerGraph.enable(parser.state); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 					}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 					parser.hooks.finish.tap(PLUGIN_NAME, () => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 						if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-30 18:34:33 +08:00
										 |  |  | 						logger.time("infer dependency usage"); | 
					
						
							| 
									
										
										
										
											2020-01-30 09:34:30 +08:00
										 |  |  | 						InnerGraph.inferDependencyUsage(parser.state); | 
					
						
							| 
									
										
										
										
											2020-01-30 18:34:33 +08:00
										 |  |  | 						logger.timeAggregate("infer dependency usage"); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// During prewalking the following datastructures are filled with
 | 
					
						
							|  |  |  | 					// nodes that have a TopLevelSymbol assigned and
 | 
					
						
							|  |  |  | 					// variables are tagged with the assigned TopLevelSymbol
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// We differ 3 types of nodes:
 | 
					
						
							|  |  |  | 					// 1. full statements (export default, function declaration)
 | 
					
						
							|  |  |  | 					// 2. classes (class declaration, class expression)
 | 
					
						
							|  |  |  | 					// 3. variable declarators (const x = ...)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | 					/** @type {WeakMap<Node | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, TopLevelSymbol>} */ | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 					const statementWithTopLevelSymbol = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | 					/** @type {WeakMap<Node | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration, Node>} */ | 
					
						
							| 
									
										
										
										
											2020-04-09 03:40:13 +08:00
										 |  |  | 					const statementPurePart = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | 					/** @type {WeakMap<ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration, TopLevelSymbol>} */ | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 					const classWithTopLevelSymbol = new WeakMap(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | 					/** @type {WeakMap<VariableDeclarator, TopLevelSymbol>} */ | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 					const declWithTopLevelSymbol = new WeakMap(); | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | 					/** @type {WeakSet<VariableDeclarator>} */ | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 					const pureDeclarators = new WeakSet(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// The following hooks are used during prewalking:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 						if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 						if ( | 
					
						
							|  |  |  | 							parser.scope.topLevelScope === true && | 
					
						
							|  |  |  | 							statement.type === "FunctionDeclaration" | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							const name = statement.id ? statement.id.name : "*default*"; | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 							const fn = | 
					
						
							|  |  |  | 								/** @type {TopLevelSymbol} */ | 
					
						
							|  |  |  | 								(InnerGraph.tagTopLevelSymbol(parser, name)); | 
					
						
							| 
									
										
										
										
											2024-08-02 02:36:27 +08:00
										 |  |  | 							statementWithTopLevelSymbol.set(statement, fn); | 
					
						
							|  |  |  | 							return true; | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					parser.hooks.blockPreStatement.tap(PLUGIN_NAME, (statement) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 						if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						if (parser.scope.topLevelScope === true) { | 
					
						
							| 
									
										
										
										
											2023-05-21 23:06:37 +08:00
										 |  |  | 							if ( | 
					
						
							|  |  |  | 								statement.type === "ClassDeclaration" && | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 								parser.isPure( | 
					
						
							|  |  |  | 									statement, | 
					
						
							|  |  |  | 									/** @type {Range} */ (statement.range)[0] | 
					
						
							|  |  |  | 								) | 
					
						
							| 
									
										
										
										
											2023-05-21 23:06:37 +08:00
										 |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 								const name = statement.id ? statement.id.name : "*default*"; | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 								const fn = /** @type {TopLevelSymbol} */ ( | 
					
						
							|  |  |  | 									InnerGraph.tagTopLevelSymbol(parser, name) | 
					
						
							|  |  |  | 								); | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 								classWithTopLevelSymbol.set(statement, fn); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 								return true; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (statement.type === "ExportDefaultDeclaration") { | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 								const name = "*default*"; | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 								const fn = | 
					
						
							|  |  |  | 									/** @type {TopLevelSymbol} */ | 
					
						
							|  |  |  | 									(InnerGraph.tagTopLevelSymbol(parser, name)); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 								const decl = statement.declaration; | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 								if ( | 
					
						
							| 
									
										
										
										
											2023-05-22 00:08:54 +08:00
										 |  |  | 									(decl.type === "ClassExpression" || | 
					
						
							|  |  |  | 										decl.type === "ClassDeclaration") && | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 									parser.isPure( | 
					
						
							|  |  |  | 										/** @type {ClassExpression | ClassDeclaration} */ | 
					
						
							|  |  |  | 										(decl), | 
					
						
							|  |  |  | 										/** @type {Range} */ | 
					
						
							|  |  |  | 										(decl.range)[0] | 
					
						
							|  |  |  | 									) | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 								) { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 									classWithTopLevelSymbol.set( | 
					
						
							|  |  |  | 										/** @type {ClassExpression | ClassDeclaration} */ | 
					
						
							|  |  |  | 										(decl), | 
					
						
							|  |  |  | 										fn | 
					
						
							|  |  |  | 									); | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 								} else if ( | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 									parser.isPure( | 
					
						
							|  |  |  | 										/** @type {Expression} */ | 
					
						
							|  |  |  | 										(decl), | 
					
						
							|  |  |  | 										/** @type {Range} */ | 
					
						
							|  |  |  | 										(statement.range)[0] | 
					
						
							|  |  |  | 									) | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 								) { | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 									statementWithTopLevelSymbol.set(statement, fn); | 
					
						
							| 
									
										
										
										
											2020-04-09 03:40:13 +08:00
										 |  |  | 									if ( | 
					
						
							|  |  |  | 										!decl.type.endsWith("FunctionExpression") && | 
					
						
							|  |  |  | 										!decl.type.endsWith("Declaration") && | 
					
						
							|  |  |  | 										decl.type !== "Literal" | 
					
						
							|  |  |  | 									) { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 										statementPurePart.set( | 
					
						
							|  |  |  | 											statement, | 
					
						
							|  |  |  | 											/** @type {Expression} */ | 
					
						
							|  |  |  | 											(decl) | 
					
						
							|  |  |  | 										); | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-08 22:46:17 +08:00
										 |  |  | 					parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, _statement) => { | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 						if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 						if ( | 
					
						
							|  |  |  | 							parser.scope.topLevelScope === true && | 
					
						
							|  |  |  | 							decl.init && | 
					
						
							|  |  |  | 							decl.id.type === "Identifier" | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							const name = decl.id.name; | 
					
						
							| 
									
										
										
										
											2023-05-21 23:06:37 +08:00
										 |  |  | 							if ( | 
					
						
							|  |  |  | 								decl.init.type === "ClassExpression" && | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 								parser.isPure( | 
					
						
							|  |  |  | 									decl.init, | 
					
						
							|  |  |  | 									/** @type {Range} */ (decl.id.range)[1] | 
					
						
							|  |  |  | 								) | 
					
						
							| 
									
										
										
										
											2023-05-21 23:06:37 +08:00
										 |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 								const fn = | 
					
						
							|  |  |  | 									/** @type {TopLevelSymbol} */ | 
					
						
							|  |  |  | 									(InnerGraph.tagTopLevelSymbol(parser, name)); | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 								classWithTopLevelSymbol.set(decl.init, fn); | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 							} else if ( | 
					
						
							|  |  |  | 								parser.isPure( | 
					
						
							|  |  |  | 									decl.init, | 
					
						
							|  |  |  | 									/** @type {Range} */ (decl.id.range)[1] | 
					
						
							|  |  |  | 								) | 
					
						
							|  |  |  | 							) { | 
					
						
							| 
									
										
										
										
											2024-10-02 05:18:10 +08:00
										 |  |  | 								const fn = | 
					
						
							|  |  |  | 									/** @type {TopLevelSymbol} */ | 
					
						
							|  |  |  | 									(InnerGraph.tagTopLevelSymbol(parser, name)); | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 								declWithTopLevelSymbol.set(decl, fn); | 
					
						
							|  |  |  | 								if ( | 
					
						
							|  |  |  | 									!decl.init.type.endsWith("FunctionExpression") && | 
					
						
							|  |  |  | 									decl.init.type !== "Literal" | 
					
						
							|  |  |  | 								) { | 
					
						
							|  |  |  | 									pureDeclarators.add(decl); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// During real walking we set the TopLevelSymbol state to the assigned
 | 
					
						
							|  |  |  | 					// TopLevelSymbol by using the fill datastructures.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// In addition to tracking TopLevelSymbols, we sometimes need to
 | 
					
						
							|  |  |  | 					// add a PureExpressionDependency. This is needed to skip execution
 | 
					
						
							|  |  |  | 					// of pure expressions, even when they are not dropped due to
 | 
					
						
							|  |  |  | 					// minimizing. Otherwise symbols used there might not exist anymore
 | 
					
						
							|  |  |  | 					// as they are removed as unused by this optimization
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// When we find a reference to a TopLevelSymbol, we register a
 | 
					
						
							|  |  |  | 					// TopLevelSymbol dependency from TopLevelSymbol in state to the
 | 
					
						
							|  |  |  | 					// referenced TopLevelSymbol. This way we get a graph of all
 | 
					
						
							|  |  |  | 					// TopLevelSymbols.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// The following hooks are called during walking:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					parser.hooks.statement.tap(PLUGIN_NAME, (statement) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 						if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						if (parser.scope.topLevelScope === true) { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 							InnerGraph.setTopLevelSymbol(parser.state, undefined); | 
					
						
							| 
									
										
										
										
											2020-04-09 00:22:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 							const fn = statementWithTopLevelSymbol.get(statement); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 							if (fn) { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 								InnerGraph.setTopLevelSymbol(parser.state, fn); | 
					
						
							| 
									
										
										
										
											2020-04-09 03:40:13 +08:00
										 |  |  | 								const purePart = statementPurePart.get(statement); | 
					
						
							|  |  |  | 								if (purePart) { | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 									InnerGraph.onUsage(parser.state, (usedByExports) => { | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 										switch (usedByExports) { | 
					
						
							|  |  |  | 											case undefined: | 
					
						
							|  |  |  | 											case true: | 
					
						
							|  |  |  | 												return; | 
					
						
							|  |  |  | 											default: { | 
					
						
							| 
									
										
										
										
											2020-04-09 03:40:13 +08:00
										 |  |  | 												const dep = new PureExpressionDependency( | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 													/** @type {Range} */ (purePart.range) | 
					
						
							| 
									
										
										
										
											2020-04-09 03:40:13 +08:00
										 |  |  | 												); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 												dep.loc = | 
					
						
							|  |  |  | 													/** @type {DependencyLocation} */ | 
					
						
							|  |  |  | 													(statement.loc); | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 												dep.usedByExports = usedByExports; | 
					
						
							| 
									
										
										
										
											2020-04-06 05:59:01 +08:00
										 |  |  | 												parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 												break; | 
					
						
							|  |  |  | 											} | 
					
						
							|  |  |  | 										} | 
					
						
							|  |  |  | 									}); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					parser.hooks.classExtendsExpression.tap( | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 						PLUGIN_NAME, | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 						(expr, statement) => { | 
					
						
							|  |  |  | 							if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 							if (parser.scope.topLevelScope === true) { | 
					
						
							|  |  |  | 								const fn = classWithTopLevelSymbol.get(statement); | 
					
						
							| 
									
										
										
										
											2020-04-06 05:59:01 +08:00
										 |  |  | 								if ( | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 									fn && | 
					
						
							| 
									
										
										
										
											2020-10-05 22:57:31 +08:00
										 |  |  | 									parser.isPure( | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 										expr, | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 										statement.id | 
					
						
							|  |  |  | 											? /** @type {Range} */ (statement.id.range)[1] | 
					
						
							|  |  |  | 											: /** @type {Range} */ (statement.range)[0] | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 									) | 
					
						
							| 
									
										
										
										
											2020-04-06 05:59:01 +08:00
										 |  |  | 								) { | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 									InnerGraph.setTopLevelSymbol(parser.state, fn); | 
					
						
							|  |  |  | 									onUsageSuper(expr); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 					parser.hooks.classBodyElement.tap( | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 						PLUGIN_NAME, | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 						(element, classDefinition) => { | 
					
						
							|  |  |  | 							if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 							if (parser.scope.topLevelScope === true) { | 
					
						
							|  |  |  | 								const fn = classWithTopLevelSymbol.get(classDefinition); | 
					
						
							|  |  |  | 								if (fn) { | 
					
						
							|  |  |  | 									InnerGraph.setTopLevelSymbol(parser.state, undefined); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 05:33:27 +08:00
										 |  |  | 					parser.hooks.classBodyValue.tap( | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 						PLUGIN_NAME, | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 						(expression, element, classDefinition) => { | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 							if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 							if (parser.scope.topLevelScope === true) { | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 								const fn = classWithTopLevelSymbol.get(classDefinition); | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 								if (fn) { | 
					
						
							| 
									
										
										
										
											2021-04-27 05:33:27 +08:00
										 |  |  | 									if ( | 
					
						
							|  |  |  | 										!element.static || | 
					
						
							|  |  |  | 										parser.isPure( | 
					
						
							|  |  |  | 											expression, | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 											element.key | 
					
						
							|  |  |  | 												? /** @type {Range} */ (element.key.range)[1] | 
					
						
							|  |  |  | 												: /** @type {Range} */ (element.range)[0] | 
					
						
							| 
									
										
										
										
											2021-04-27 05:33:27 +08:00
										 |  |  | 										) | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 									) { | 
					
						
							| 
									
										
										
										
											2024-01-24 18:05:09 +08:00
										 |  |  | 										InnerGraph.setTopLevelSymbol(parser.state, fn); | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 										if (element.type !== "MethodDefinition" && element.static) { | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 											InnerGraph.onUsage(parser.state, (usedByExports) => { | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 												switch (usedByExports) { | 
					
						
							|  |  |  | 													case undefined: | 
					
						
							|  |  |  | 													case true: | 
					
						
							|  |  |  | 														return; | 
					
						
							|  |  |  | 													default: { | 
					
						
							|  |  |  | 														const dep = new PureExpressionDependency( | 
					
						
							| 
									
										
										
										
											2024-02-22 22:20:17 +08:00
										 |  |  | 															/** @type {Range} */ (expression.range) | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 														); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 														dep.loc = | 
					
						
							|  |  |  | 															/** @type {DependencyLocation} */ | 
					
						
							|  |  |  | 															(expression.loc); | 
					
						
							| 
									
										
										
										
											2021-06-21 15:28:25 +08:00
										 |  |  | 														dep.usedByExports = usedByExports; | 
					
						
							|  |  |  | 														parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 														break; | 
					
						
							|  |  |  | 													} | 
					
						
							|  |  |  | 												} | 
					
						
							|  |  |  | 											}); | 
					
						
							|  |  |  | 										} | 
					
						
							| 
									
										
										
										
											2020-04-09 00:22:40 +08:00
										 |  |  | 									} else { | 
					
						
							|  |  |  | 										InnerGraph.setTopLevelSymbol(parser.state, undefined); | 
					
						
							|  |  |  | 									} | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-08 22:46:17 +08:00
										 |  |  | 					parser.hooks.declarator.tap(PLUGIN_NAME, (decl, _statement) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 						if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						const fn = declWithTopLevelSymbol.get(decl); | 
					
						
							| 
									
										
										
										
											2020-04-04 04:52:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						if (fn) { | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 							InnerGraph.setTopLevelSymbol(parser.state, fn); | 
					
						
							| 
									
										
										
										
											2019-09-08 21:21:00 +08:00
										 |  |  | 							if (pureDeclarators.has(decl)) { | 
					
						
							| 
									
										
										
										
											2024-10-24 04:30:31 +08:00
										 |  |  | 								if ( | 
					
						
							|  |  |  | 									/** @type {ClassExpression} */ | 
					
						
							|  |  |  | 									(decl.init).type === "ClassExpression" | 
					
						
							|  |  |  | 								) { | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 									if (decl.init.superClass) { | 
					
						
							|  |  |  | 										onUsageSuper(decl.init.superClass); | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 									} | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 								} else { | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 									InnerGraph.onUsage(parser.state, (usedByExports) => { | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 										switch (usedByExports) { | 
					
						
							|  |  |  | 											case undefined: | 
					
						
							|  |  |  | 											case true: | 
					
						
							|  |  |  | 												return; | 
					
						
							|  |  |  | 											default: { | 
					
						
							|  |  |  | 												const dep = new PureExpressionDependency( | 
					
						
							| 
									
										
										
										
											2024-10-24 04:30:31 +08:00
										 |  |  | 													/** @type {Range} */ ( | 
					
						
							|  |  |  | 														/** @type {ClassExpression} */ | 
					
						
							|  |  |  | 														(decl.init).range | 
					
						
							|  |  |  | 													) | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 												); | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | 												dep.loc = /** @type {DependencyLocation} */ (decl.loc); | 
					
						
							| 
									
										
										
										
											2020-04-09 15:28:46 +08:00
										 |  |  | 												dep.usedByExports = usedByExports; | 
					
						
							|  |  |  | 												parser.state.module.addDependency(dep); | 
					
						
							|  |  |  | 												break; | 
					
						
							|  |  |  | 											} | 
					
						
							|  |  |  | 										} | 
					
						
							|  |  |  | 									}); | 
					
						
							|  |  |  | 								} | 
					
						
							| 
									
										
										
										
											2019-09-08 21:21:00 +08:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2025-04-07 21:09:05 +08:00
										 |  |  | 							parser.walkExpression( | 
					
						
							|  |  |  | 								/** @type {NonNullable<VariableDeclarator["init"]>} */ ( | 
					
						
							|  |  |  | 									decl.init | 
					
						
							|  |  |  | 								) | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 							InnerGraph.setTopLevelSymbol(parser.state, undefined); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 							return true; | 
					
						
							| 
									
										
										
										
											2024-01-24 19:04:06 +08:00
										 |  |  | 						} else if ( | 
					
						
							|  |  |  | 							decl.id.type === "Identifier" && | 
					
						
							|  |  |  | 							decl.init && | 
					
						
							|  |  |  | 							decl.init.type === "ClassExpression" && | 
					
						
							|  |  |  | 							classWithTopLevelSymbol.has(decl.init) | 
					
						
							|  |  |  | 						) { | 
					
						
							|  |  |  | 							parser.walkExpression(decl.init); | 
					
						
							|  |  |  | 							InnerGraph.setTopLevelSymbol(parser.state, undefined); | 
					
						
							|  |  |  | 							return true; | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						} | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2020-04-09 21:53:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 					parser.hooks.expression | 
					
						
							|  |  |  | 						.for(topLevelSymbolTag) | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 						.tap(PLUGIN_NAME, () => { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 							const topLevelSymbol = /** @type {TopLevelSymbol} */ ( | 
					
						
							|  |  |  | 								parser.currentTagData | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 							const currentTopLevelSymbol = InnerGraph.getTopLevelSymbol( | 
					
						
							|  |  |  | 								parser.state | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  | 							InnerGraph.addUsage( | 
					
						
							|  |  |  | 								parser.state, | 
					
						
							|  |  |  | 								topLevelSymbol, | 
					
						
							|  |  |  | 								currentTopLevelSymbol || true | 
					
						
							|  |  |  | 							); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					parser.hooks.assign | 
					
						
							|  |  |  | 						.for(topLevelSymbolTag) | 
					
						
							|  |  |  | 						.tap(PLUGIN_NAME, (expr) => { | 
					
						
							|  |  |  | 							if (!InnerGraph.isEnabled(parser.state)) return; | 
					
						
							|  |  |  | 							if (expr.operator === "=") return true; | 
					
						
							|  |  |  | 						}); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 				}; | 
					
						
							|  |  |  | 				normalModuleFactory.hooks.parser | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 					.for(JAVASCRIPT_MODULE_TYPE_AUTO) | 
					
						
							|  |  |  | 					.tap(PLUGIN_NAME, handler); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 				normalModuleFactory.hooks.parser | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 					.for(JAVASCRIPT_MODULE_TYPE_ESM) | 
					
						
							|  |  |  | 					.tap(PLUGIN_NAME, handler); | 
					
						
							| 
									
										
										
										
											2020-01-30 18:34:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-01 01:56:32 +08:00
										 |  |  | 				compilation.hooks.finishModules.tap(PLUGIN_NAME, () => { | 
					
						
							| 
									
										
										
										
											2020-01-30 18:34:33 +08:00
										 |  |  | 					logger.timeAggregateEnd("infer dependency usage"); | 
					
						
							|  |  |  | 				}); | 
					
						
							| 
									
										
										
										
											2019-09-03 20:11:50 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = InnerGraphPlugin; |