| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 07:48:37 +08:00
										 |  |  | const { provide } = require("./util/MapHelpers"); | 
					
						
							|  |  |  | const createHash = require("./util/createHash"); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | const { runtimeToString, RuntimeSpecMap } = require("./util/runtime"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** @typedef {import("webpack-sources").Source} Source */ | 
					
						
							|  |  |  | /** @typedef {import("./Module")} Module */ | 
					
						
							|  |  |  | /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */ | 
					
						
							|  |  |  | /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CodeGenerationResults { | 
					
						
							|  |  |  | 	constructor() { | 
					
						
							|  |  |  | 		/** @type {Map<Module, RuntimeSpecMap<CodeGenerationResult>>} */ | 
					
						
							|  |  |  | 		this.map = new Map(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @returns {CodeGenerationResult} the CodeGenerationResult | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2020-07-28 01:36:06 +08:00
										 |  |  | 	get(module, runtime) { | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 		const entry = this.map.get(module); | 
					
						
							|  |  |  | 		if (entry === undefined) { | 
					
						
							|  |  |  | 			throw new Error( | 
					
						
							|  |  |  | 				`No code generation entry for ${module.identifier()} (existing entries: ${Array.from( | 
					
						
							|  |  |  | 					this.map.keys(), | 
					
						
							|  |  |  | 					m => m.identifier() | 
					
						
							|  |  |  | 				).join(", ")})`
 | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (runtime === undefined) { | 
					
						
							| 
									
										
										
										
											2021-01-27 21:48:28 +08:00
										 |  |  | 			if (entry.size > 1) { | 
					
						
							|  |  |  | 				const results = new Set(entry.values()); | 
					
						
							|  |  |  | 				if (results.size !== 1) { | 
					
						
							|  |  |  | 					throw new Error( | 
					
						
							|  |  |  | 						`No unique code generation entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from( | 
					
						
							|  |  |  | 							entry.keys(), | 
					
						
							|  |  |  | 							r => runtimeToString(r) | 
					
						
							|  |  |  | 						).join(", ")}). | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
 | 
					
						
							| 
									
										
										
										
											2021-01-27 21:48:28 +08:00
										 |  |  | 					); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return results.values().next().value; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-01-27 21:48:28 +08:00
										 |  |  | 			return entry.values().next().value; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		const result = entry.get(runtime); | 
					
						
							|  |  |  | 		if (result === undefined) { | 
					
						
							|  |  |  | 			throw new Error( | 
					
						
							|  |  |  | 				`No code generation entry for runtime ${runtimeToString( | 
					
						
							|  |  |  | 					runtime | 
					
						
							|  |  |  | 				)} for ${module.identifier()} (existing runtimes: ${Array.from( | 
					
						
							|  |  |  | 					entry.keys(), | 
					
						
							|  |  |  | 					r => runtimeToString(r) | 
					
						
							|  |  |  | 				).join(", ")})`
 | 
					
						
							|  |  |  | 			); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-01-27 21:48:28 +08:00
										 |  |  | 		return result; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 07:48:37 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @returns {boolean} true, when we have data for this | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	has(module, runtime) { | 
					
						
							|  |  |  | 		const entry = this.map.get(module); | 
					
						
							|  |  |  | 		if (entry === undefined) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-01-27 21:48:28 +08:00
										 |  |  | 		if (runtime !== undefined) { | 
					
						
							|  |  |  | 			return entry.has(runtime); | 
					
						
							|  |  |  | 		} else if (entry.size > 1) { | 
					
						
							| 
									
										
										
										
											2021-01-26 07:48:37 +08:00
										 |  |  | 			const results = new Set(entry.values()); | 
					
						
							|  |  |  | 			return results.size === 1; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2021-01-27 21:48:28 +08:00
										 |  |  | 			return entry.size === 1; | 
					
						
							| 
									
										
										
										
											2021-01-26 07:48:37 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @param {string} sourceType the source type | 
					
						
							|  |  |  | 	 * @returns {Source} a source | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getSource(module, runtime, sourceType) { | 
					
						
							| 
									
										
										
										
											2020-07-28 01:36:06 +08:00
										 |  |  | 		return this.get(module, runtime).sources.get(sourceType); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @returns {ReadonlySet<string>} runtime requirements | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getRuntimeRequirements(module, runtime) { | 
					
						
							| 
									
										
										
										
											2020-07-28 01:36:06 +08:00
										 |  |  | 		return this.get(module, runtime).runtimeRequirements; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @param {string} key data key | 
					
						
							|  |  |  | 	 * @returns {any} data generated by code generation | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getData(module, runtime, key) { | 
					
						
							| 
									
										
										
										
											2020-07-28 01:36:06 +08:00
										 |  |  | 		const data = this.get(module, runtime).data; | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 		return data === undefined ? undefined : data.get(key); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-26 07:48:37 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @returns {any} hash of the code generation | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	getHash(module, runtime) { | 
					
						
							|  |  |  | 		const info = this.get(module, runtime); | 
					
						
							|  |  |  | 		if (info.hash !== undefined) return info.hash; | 
					
						
							|  |  |  | 		const hash = createHash("md4"); | 
					
						
							|  |  |  | 		for (const [type, source] of info.sources) { | 
					
						
							|  |  |  | 			hash.update(type); | 
					
						
							|  |  |  | 			source.updateHash(hash); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (info.runtimeRequirements) { | 
					
						
							|  |  |  | 			for (const rr of info.runtimeRequirements) hash.update(rr); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return (info.hash = /** @type {string} */ (hash.digest("hex"))); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	/** | 
					
						
							|  |  |  | 	 * @param {Module} module the module | 
					
						
							|  |  |  | 	 * @param {RuntimeSpec} runtime runtime(s) | 
					
						
							|  |  |  | 	 * @param {CodeGenerationResult} result result from module | 
					
						
							|  |  |  | 	 * @returns {void} | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	add(module, runtime, result) { | 
					
						
							| 
									
										
										
										
											2021-01-26 07:48:37 +08:00
										 |  |  | 		const map = provide(this.map, module, () => new RuntimeSpecMap()); | 
					
						
							|  |  |  | 		map.set(runtime, result); | 
					
						
							| 
									
										
										
										
											2020-07-28 00:09:48 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = CodeGenerationResults; |