| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Sergey Melyukov @smelukov | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 20:31:55 +08:00
										 |  |  | const { UsageState } = require("../ExportsInfo"); | 
					
						
							| 
									
										
										
										
											2025-08-14 02:36:56 +08:00
										 |  |  | const JavascriptParser = require("../javascript/JavascriptParser"); | 
					
						
							| 
									
										
										
										
											2021-01-19 20:31:55 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** @typedef {import("../Dependency")} Dependency */ | 
					
						
							| 
									
										
										
										
											2025-03-12 09:56:14 +08:00
										 |  |  | /** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ | 
					
						
							| 
									
										
										
										
											2024-03-18 23:28:40 +08:00
										 |  |  | /** @typedef {import("../Module")} Module */ | 
					
						
							| 
									
										
										
										
											2021-01-19 20:31:55 +08:00
										 |  |  | /** @typedef {import("../ModuleGraph")} ModuleGraph */ | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | /** @typedef {import("../Parser").ParserState} ParserState */ | 
					
						
							| 
									
										
										
										
											2021-01-19 20:31:55 +08:00
										 |  |  | /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ | 
					
						
							| 
									
										
										
										
											2020-02-05 17:17:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  | /** @typedef {Set<string | TopLevelSymbol>} InnerGraphValueSet */ | 
					
						
							|  |  |  | /** @typedef {InnerGraphValueSet | true} InnerGraphValue */ | 
					
						
							|  |  |  | /** @typedef {TopLevelSymbol | null} InnerGraphKey */ | 
					
						
							|  |  |  | /** @typedef {Map<InnerGraphKey, InnerGraphValue | undefined>} InnerGraph */ | 
					
						
							| 
									
										
										
										
											2025-03-12 09:56:14 +08:00
										 |  |  | /** @typedef {(value: boolean | Set<string> | undefined) => void} UsageCallback */ | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 17:17:05 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2024-06-11 21:09:50 +08:00
										 |  |  |  * @typedef {object} StateObject | 
					
						
							| 
									
										
										
										
											2020-02-05 17:17:05 +08:00
										 |  |  |  * @property {InnerGraph} innerGraph | 
					
						
							|  |  |  |  * @property {TopLevelSymbol=} currentTopLevelSymbol | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  |  * @property {Map<TopLevelSymbol, Set<UsageCallback>>} usageCallbackMap | 
					
						
							| 
									
										
										
										
											2020-02-05 17:17:05 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-09-09 23:41:52 +08:00
										 |  |  | /** @typedef {false | StateObject} State */ | 
					
						
							| 
									
										
										
										
											2020-02-05 17:17:05 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | class TopLevelSymbol { | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {string} name name of the variable | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	constructor(name) { | 
					
						
							|  |  |  | 		this.name = name; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.TopLevelSymbol = TopLevelSymbol; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | /** @type {WeakMap<ParserState, State>} */ | 
					
						
							|  |  |  | const parserStateMap = new WeakMap(); | 
					
						
							|  |  |  | const topLevelSymbolTag = Symbol("top level symbol"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} parserState parser state | 
					
						
							| 
									
										
										
										
											2023-06-04 01:52:25 +08:00
										 |  |  |  * @returns {State | undefined} state | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | function getState(parserState) { | 
					
						
							|  |  |  | 	return parserStateMap.get(parserState); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  |  * @param {ParserState} state parser state | 
					
						
							| 
									
										
										
										
											2021-09-20 18:26:18 +08:00
										 |  |  |  * @param {TopLevelSymbol | null} symbol the symbol, or null for all symbols | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  |  * @param {Usage} usage usage data | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  |  * @returns {void} | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | module.exports.addUsage = (state, symbol, usage) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 	const innerGraphState = getState(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (innerGraphState) { | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  | 		const { innerGraph } = innerGraphState; | 
					
						
							|  |  |  | 		const info = innerGraph.get(symbol); | 
					
						
							|  |  |  | 		if (usage === true) { | 
					
						
							|  |  |  | 			innerGraph.set(symbol, true); | 
					
						
							|  |  |  | 		} else if (info === undefined) { | 
					
						
							|  |  |  | 			innerGraph.set(symbol, new Set([usage])); | 
					
						
							|  |  |  | 		} else if (info !== true) { | 
					
						
							|  |  |  | 			info.add(usage); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  | /** @typedef {string | TopLevelSymbol | true} Usage */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  |  * @param {JavascriptParser} parser the parser | 
					
						
							|  |  |  |  * @param {string} name name of variable | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  |  * @param {Usage} usage usage data | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  |  * @returns {void} | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | module.exports.addVariableUsage = (parser, name, usage) => { | 
					
						
							| 
									
										
										
										
											2021-02-15 02:43:39 +08:00
										 |  |  | 	const symbol = | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 		/** @type {TopLevelSymbol} */ ( | 
					
						
							|  |  |  | 			parser.getTagData(name, topLevelSymbolTag) | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 		) || module.exports.tagTopLevelSymbol(parser, name); | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  | 	if (symbol) { | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | 		module.exports.addUsage(parser.state, symbol, usage); | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} parserState parser state | 
					
						
							|  |  |  |  * @returns {void} | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | module.exports.bailout = (parserState) => { | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | 	parserStateMap.set(parserState, false); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} parserState parser state | 
					
						
							|  |  |  |  * @returns {void} | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | module.exports.enable = (parserState) => { | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | 	const state = parserStateMap.get(parserState); | 
					
						
							|  |  |  | 	if (state === false) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	parserStateMap.set(parserState, { | 
					
						
							|  |  |  | 		innerGraph: new Map(), | 
					
						
							|  |  |  | 		currentTopLevelSymbol: undefined, | 
					
						
							|  |  |  | 		usageCallbackMap: new Map() | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  | /** @typedef {Set<string> | boolean} UsedByExports */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {Dependency} dependency the dependency | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  |  * @param {UsedByExports | undefined} usedByExports usedByExports info | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  |  * @param {ModuleGraph} moduleGraph moduleGraph | 
					
						
							|  |  |  |  * @returns {null | false | GetConditionFn} function to determine if the connection is active | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | module.exports.getDependencyUsedByExportsCondition = ( | 
					
						
							|  |  |  | 	dependency, | 
					
						
							|  |  |  | 	usedByExports, | 
					
						
							|  |  |  | 	moduleGraph | 
					
						
							|  |  |  | ) => { | 
					
						
							|  |  |  | 	if (usedByExports === false) return false; | 
					
						
							|  |  |  | 	if (usedByExports !== true && usedByExports !== undefined) { | 
					
						
							|  |  |  | 		const selfModule = | 
					
						
							|  |  |  | 			/** @type {Module} */ | 
					
						
							|  |  |  | 			(moduleGraph.getParentModule(dependency)); | 
					
						
							|  |  |  | 		const exportsInfo = moduleGraph.getExportsInfo(selfModule); | 
					
						
							|  |  |  | 		return (connections, runtime) => { | 
					
						
							|  |  |  | 			for (const exportName of usedByExports) { | 
					
						
							|  |  |  | 				if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) { | 
					
						
							|  |  |  | 					return true; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return null; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} state parser state | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  |  * @returns {TopLevelSymbol | void} usage data | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | module.exports.getTopLevelSymbol = (state) => { | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | 	const innerGraphState = getState(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (innerGraphState) { | 
					
						
							|  |  |  | 		return innerGraphState.currentTopLevelSymbol; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} state parser state | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  |  * @returns {void} | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | module.exports.inferDependencyUsage = (state) => { | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 	const innerGraphState = getState(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!innerGraphState) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 	const { innerGraph, usageCallbackMap } = innerGraphState; | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  | 	/** @type {Map<InnerGraphKey, InnerGraphValueSet | undefined>} */ | 
					
						
							| 
									
										
										
										
											2020-10-15 19:24:40 +08:00
										 |  |  | 	const processed = new Map(); | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 	// flatten graph to terminal nodes (string, undefined or true)
 | 
					
						
							|  |  |  | 	const nonTerminal = new Set(innerGraph.keys()); | 
					
						
							|  |  |  | 	while (nonTerminal.size > 0) { | 
					
						
							|  |  |  | 		for (const key of nonTerminal) { | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  | 			/** @type {InnerGraphValue} */ | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 			let newSet = new Set(); | 
					
						
							|  |  |  | 			let isTerminal = true; | 
					
						
							|  |  |  | 			const value = innerGraph.get(key); | 
					
						
							| 
									
										
										
										
											2020-10-15 19:24:40 +08:00
										 |  |  | 			let alreadyProcessed = processed.get(key); | 
					
						
							|  |  |  | 			if (alreadyProcessed === undefined) { | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  | 				/** @type {InnerGraphValueSet} */ | 
					
						
							| 
									
										
										
										
											2020-10-15 19:24:40 +08:00
										 |  |  | 				alreadyProcessed = new Set(); | 
					
						
							|  |  |  | 				processed.set(key, alreadyProcessed); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 			if (value !== true && value !== undefined) { | 
					
						
							| 
									
										
										
										
											2020-10-15 19:24:40 +08:00
										 |  |  | 				for (const item of value) { | 
					
						
							|  |  |  | 					alreadyProcessed.add(item); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 				for (const item of value) { | 
					
						
							|  |  |  | 					if (typeof item === "string") { | 
					
						
							|  |  |  | 						newSet.add(item); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						const itemValue = innerGraph.get(item); | 
					
						
							|  |  |  | 						if (itemValue === true) { | 
					
						
							|  |  |  | 							newSet = true; | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (itemValue !== undefined) { | 
					
						
							|  |  |  | 							for (const i of itemValue) { | 
					
						
							|  |  |  | 								if (i === key) continue; | 
					
						
							| 
									
										
										
										
											2020-10-15 19:24:40 +08:00
										 |  |  | 								if (alreadyProcessed.has(i)) continue; | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 								newSet.add(i); | 
					
						
							|  |  |  | 								if (typeof i !== "string") { | 
					
						
							|  |  |  | 									isTerminal = false; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (newSet === true) { | 
					
						
							|  |  |  | 					innerGraph.set(key, true); | 
					
						
							|  |  |  | 				} else if (newSet.size === 0) { | 
					
						
							|  |  |  | 					innerGraph.set(key, undefined); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					innerGraph.set(key, newSet); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (isTerminal) { | 
					
						
							|  |  |  | 				nonTerminal.delete(key); | 
					
						
							| 
									
										
										
										
											2021-09-20 18:26:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// For the global key, merge with all other keys
 | 
					
						
							|  |  |  | 				if (key === null) { | 
					
						
							|  |  |  | 					const globalValue = innerGraph.get(null); | 
					
						
							|  |  |  | 					if (globalValue) { | 
					
						
							|  |  |  | 						for (const [key, value] of innerGraph) { | 
					
						
							|  |  |  | 							if (key !== null && value !== true) { | 
					
						
							|  |  |  | 								if (globalValue === true) { | 
					
						
							|  |  |  | 									innerGraph.set(key, true); | 
					
						
							|  |  |  | 								} else { | 
					
						
							|  |  |  | 									const newSet = new Set(value); | 
					
						
							|  |  |  | 									for (const item of globalValue) { | 
					
						
							|  |  |  | 										newSet.add(item); | 
					
						
							|  |  |  | 									} | 
					
						
							|  |  |  | 									innerGraph.set(key, newSet); | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  | 	/** @type {Map<Dependency, true | Set<string>>} */ | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 	for (const [symbol, callbacks] of usageCallbackMap) { | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 		const usage = /** @type {true | Set<string> | undefined} */ ( | 
					
						
							|  |  |  | 			innerGraph.get(symbol) | 
					
						
							|  |  |  | 		); | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 		for (const callback of callbacks) { | 
					
						
							|  |  |  | 			callback(usage === undefined ? false : usage); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {Dependency} dependency the dependency | 
					
						
							| 
									
										
										
										
											2025-08-28 18:34:30 +08:00
										 |  |  |  * @param {UsedByExports | undefined} usedByExports usedByExports info | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  |  * @param {ModuleGraph} moduleGraph moduleGraph | 
					
						
							|  |  |  |  * @param {RuntimeSpec} runtime runtime | 
					
						
							|  |  |  |  * @returns {boolean} false, when unused. Otherwise true | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | module.exports.isDependencyUsedByExports = ( | 
					
						
							|  |  |  | 	dependency, | 
					
						
							|  |  |  | 	usedByExports, | 
					
						
							|  |  |  | 	moduleGraph, | 
					
						
							|  |  |  | 	runtime | 
					
						
							|  |  |  | ) => { | 
					
						
							|  |  |  | 	if (usedByExports === false) return false; | 
					
						
							|  |  |  | 	if (usedByExports !== true && usedByExports !== undefined) { | 
					
						
							|  |  |  | 		const selfModule = | 
					
						
							|  |  |  | 			/** @type {Module} */ | 
					
						
							|  |  |  | 			(moduleGraph.getParentModule(dependency)); | 
					
						
							|  |  |  | 		const exportsInfo = moduleGraph.getExportsInfo(selfModule); | 
					
						
							|  |  |  | 		let used = false; | 
					
						
							|  |  |  | 		for (const exportName of usedByExports) { | 
					
						
							|  |  |  | 			if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) { | 
					
						
							|  |  |  | 				used = true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!used) return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} parserState parser state | 
					
						
							|  |  |  |  * @returns {boolean} true, when enabled | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | module.exports.isEnabled = (parserState) => { | 
					
						
							| 
									
										
										
										
											2025-07-03 17:06:45 +08:00
										 |  |  | 	const state = parserStateMap.get(parserState); | 
					
						
							|  |  |  | 	return Boolean(state); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} state parser state | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  |  * @param {UsageCallback} onUsageCallback on usage callback | 
					
						
							| 
									
										
										
										
											2020-01-27 23:33:40 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | module.exports.onUsage = (state, onUsageCallback) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 	const innerGraphState = getState(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (innerGraphState) { | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 		const { usageCallbackMap, currentTopLevelSymbol } = innerGraphState; | 
					
						
							|  |  |  | 		if (currentTopLevelSymbol) { | 
					
						
							|  |  |  | 			let callbacks = usageCallbackMap.get(currentTopLevelSymbol); | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 18:06:27 +08:00
										 |  |  | 			if (callbacks === undefined) { | 
					
						
							|  |  |  | 				callbacks = new Set(); | 
					
						
							|  |  |  | 				usageCallbackMap.set(currentTopLevelSymbol, callbacks); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			callbacks.add(onUsageCallback); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			onUsageCallback(true); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		onUsageCallback(undefined); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-30 09:34:30 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {ParserState} state parser state | 
					
						
							| 
									
										
										
										
											2023-06-04 01:52:25 +08:00
										 |  |  |  * @param {TopLevelSymbol | undefined} symbol the symbol | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | module.exports.setTopLevelSymbol = (state, symbol) => { | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 	const innerGraphState = getState(state); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (innerGraphState) { | 
					
						
							|  |  |  | 		innerGraphState.currentTopLevelSymbol = symbol; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  |  * @param {JavascriptParser} parser parser | 
					
						
							|  |  |  |  * @param {string} name name of variable | 
					
						
							| 
									
										
										
										
											2023-06-04 01:52:25 +08:00
										 |  |  |  * @returns {TopLevelSymbol | undefined} symbol | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | module.exports.tagTopLevelSymbol = (parser, name) => { | 
					
						
							| 
									
										
										
										
											2020-01-27 23:46:23 +08:00
										 |  |  | 	const innerGraphState = getState(parser.state); | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  | 	if (!innerGraphState) return; | 
					
						
							| 
									
										
										
										
											2020-01-23 20:59:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-27 23:46:23 +08:00
										 |  |  | 	parser.defineVariable(name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 15:31:46 +08:00
										 |  |  | 	const existingTag = /** @type {TopLevelSymbol} */ ( | 
					
						
							|  |  |  | 		parser.getTagData(name, topLevelSymbolTag) | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2020-01-27 23:46:23 +08:00
										 |  |  | 	if (existingTag) { | 
					
						
							|  |  |  | 		return existingTag; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-29 21:24:55 +08:00
										 |  |  | 	const fn = new TopLevelSymbol(name); | 
					
						
							| 
									
										
										
										
											2025-08-14 02:36:56 +08:00
										 |  |  | 	parser.tagVariable( | 
					
						
							|  |  |  | 		name, | 
					
						
							|  |  |  | 		topLevelSymbolTag, | 
					
						
							|  |  |  | 		fn, | 
					
						
							|  |  |  | 		JavascriptParser.VariableInfoFlags.Normal | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2020-01-27 23:46:23 +08:00
										 |  |  | 	return fn; | 
					
						
							| 
									
										
										
										
											2020-01-21 22:25:40 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-31 04:54:55 +08:00
										 |  |  | module.exports.topLevelSymbolTag = topLevelSymbolTag; |