simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

HarmonyExportImportedSpecifierDependency.js (34884B)


      1 /*
      2 	MIT License http://www.opensource.org/licenses/mit-license.php
      3 	Author Tobias Koppers @sokra
      4 */
      5 
      6 "use strict";
      7 
      8 const Dependency = require("../Dependency");
      9 const { UsageState } = require("../ExportsInfo");
     10 const HarmonyLinkingError = require("../HarmonyLinkingError");
     11 const InitFragment = require("../InitFragment");
     12 const RuntimeGlobals = require("../RuntimeGlobals");
     13 const Template = require("../Template");
     14 const { countIterable } = require("../util/IterableHelpers");
     15 const { first, combine } = require("../util/SetHelpers");
     16 const makeSerializable = require("../util/makeSerializable");
     17 const propertyAccess = require("../util/propertyAccess");
     18 const { getRuntimeKey, keyToRuntime } = require("../util/runtime");
     19 const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
     20 const HarmonyImportDependency = require("./HarmonyImportDependency");
     21 const processExportInfo = require("./processExportInfo");
     22 
     23 /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
     24 /** @typedef {import("../ChunkGraph")} ChunkGraph */
     25 /** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
     26 /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
     27 /** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
     28 /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
     29 /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */
     30 /** @typedef {import("../ExportsInfo")} ExportsInfo */
     31 /** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
     32 /** @typedef {import("../Module")} Module */
     33 /** @typedef {import("../ModuleGraph")} ModuleGraph */
     34 /** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
     35 /** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */
     36 /** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
     37 /** @typedef {import("../WebpackError")} WebpackError */
     38 /** @typedef {import("../util/Hash")} Hash */
     39 /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
     40 
     41 /** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */
     42 
     43 const { ExportPresenceModes } = HarmonyImportDependency;
     44 
     45 const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
     46 
     47 class NormalReexportItem {
     48 	/**
     49 	 * @param {string} name export name
     50 	 * @param {string[]} ids reexported ids from other module
     51 	 * @param {ExportInfo} exportInfo export info from other module
     52 	 * @param {boolean} checked true, if it should be checked at runtime if this export exists
     53 	 * @param {boolean} hidden true, if it is hidden behind another active export in the same module
     54 	 */
     55 	constructor(name, ids, exportInfo, checked, hidden) {
     56 		this.name = name;
     57 		this.ids = ids;
     58 		this.exportInfo = exportInfo;
     59 		this.checked = checked;
     60 		this.hidden = hidden;
     61 	}
     62 }
     63 
     64 class ExportMode {
     65 	/**
     66 	 * @param {ExportModeType} type type of the mode
     67 	 */
     68 	constructor(type) {
     69 		/** @type {ExportModeType} */
     70 		this.type = type;
     71 
     72 		// for "normal-reexport":
     73 		/** @type {NormalReexportItem[] | null} */
     74 		this.items = null;
     75 
     76 		// for "reexport-named-default" | "reexport-fake-namespace-object" | "reexport-namespace-object"
     77 		/** @type {string|null} */
     78 		this.name = null;
     79 		/** @type {ExportInfo | null} */
     80 		this.partialNamespaceExportInfo = null;
     81 
     82 		// for "dynamic-reexport":
     83 		/** @type {Set<string> | null} */
     84 		this.ignored = null;
     85 
     86 		// for "dynamic-reexport" | "empty-star":
     87 		/** @type {Set<string> | null} */
     88 		this.hidden = null;
     89 
     90 		// for "missing":
     91 		/** @type {string | null} */
     92 		this.userRequest = null;
     93 
     94 		// for "reexport-fake-namespace-object":
     95 		/** @type {number} */
     96 		this.fakeType = 0;
     97 	}
     98 }
     99 
    100 const determineExportAssignments = (
    101 	moduleGraph,
    102 	dependencies,
    103 	additionalDependency
    104 ) => {
    105 	const names = new Set();
    106 	const dependencyIndices = [];
    107 
    108 	if (additionalDependency) {
    109 		dependencies = dependencies.concat(additionalDependency);
    110 	}
    111 
    112 	for (const dep of dependencies) {
    113 		const i = dependencyIndices.length;
    114 		dependencyIndices[i] = names.size;
    115 		const otherImportedModule = moduleGraph.getModule(dep);
    116 		if (otherImportedModule) {
    117 			const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule);
    118 			for (const exportInfo of exportsInfo.exports) {
    119 				if (
    120 					exportInfo.provided === true &&
    121 					exportInfo.name !== "default" &&
    122 					!names.has(exportInfo.name)
    123 				) {
    124 					names.add(exportInfo.name);
    125 					dependencyIndices[i] = names.size;
    126 				}
    127 			}
    128 		}
    129 	}
    130 	dependencyIndices.push(names.size);
    131 
    132 	return { names: Array.from(names), dependencyIndices };
    133 };
    134 
    135 const findDependencyForName = (
    136 	{ names, dependencyIndices },
    137 	name,
    138 	dependencies
    139 ) => {
    140 	const dependenciesIt = dependencies[Symbol.iterator]();
    141 	const dependencyIndicesIt = dependencyIndices[Symbol.iterator]();
    142 	let dependenciesItResult = dependenciesIt.next();
    143 	let dependencyIndicesItResult = dependencyIndicesIt.next();
    144 	if (dependencyIndicesItResult.done) return;
    145 	for (let i = 0; i < names.length; i++) {
    146 		while (i >= dependencyIndicesItResult.value) {
    147 			dependenciesItResult = dependenciesIt.next();
    148 			dependencyIndicesItResult = dependencyIndicesIt.next();
    149 			if (dependencyIndicesItResult.done) return;
    150 		}
    151 		if (names[i] === name) return dependenciesItResult.value;
    152 	}
    153 	return undefined;
    154 };
    155 
    156 /**
    157  * @param {ModuleGraph} moduleGraph the module graph
    158  * @param {HarmonyExportImportedSpecifierDependency} dep the dependency
    159  * @param {string} runtimeKey the runtime key
    160  * @returns {ExportMode} the export mode
    161  */
    162 const getMode = (moduleGraph, dep, runtimeKey) => {
    163 	const importedModule = moduleGraph.getModule(dep);
    164 
    165 	if (!importedModule) {
    166 		const mode = new ExportMode("missing");
    167 
    168 		mode.userRequest = dep.userRequest;
    169 
    170 		return mode;
    171 	}
    172 
    173 	const name = dep.name;
    174 	const runtime = keyToRuntime(runtimeKey);
    175 	const parentModule = moduleGraph.getParentModule(dep);
    176 	const exportsInfo = moduleGraph.getExportsInfo(parentModule);
    177 
    178 	if (
    179 		name
    180 			? exportsInfo.getUsed(name, runtime) === UsageState.Unused
    181 			: exportsInfo.isUsed(runtime) === false
    182 	) {
    183 		const mode = new ExportMode("unused");
    184 
    185 		mode.name = name || "*";
    186 
    187 		return mode;
    188 	}
    189 
    190 	const importedExportsType = importedModule.getExportsType(
    191 		moduleGraph,
    192 		parentModule.buildMeta.strictHarmonyModule
    193 	);
    194 
    195 	const ids = dep.getIds(moduleGraph);
    196 
    197 	// Special handling for reexporting the default export
    198 	// from non-namespace modules
    199 	if (name && ids.length > 0 && ids[0] === "default") {
    200 		switch (importedExportsType) {
    201 			case "dynamic": {
    202 				const mode = new ExportMode("reexport-dynamic-default");
    203 
    204 				mode.name = name;
    205 
    206 				return mode;
    207 			}
    208 			case "default-only":
    209 			case "default-with-named": {
    210 				const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
    211 				const mode = new ExportMode("reexport-named-default");
    212 
    213 				mode.name = name;
    214 				mode.partialNamespaceExportInfo = exportInfo;
    215 
    216 				return mode;
    217 			}
    218 		}
    219 	}
    220 
    221 	// reexporting with a fixed name
    222 	if (name) {
    223 		let mode;
    224 		const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
    225 
    226 		if (ids.length > 0) {
    227 			// export { name as name }
    228 			switch (importedExportsType) {
    229 				case "default-only":
    230 					mode = new ExportMode("reexport-undefined");
    231 					mode.name = name;
    232 					break;
    233 				default:
    234 					mode = new ExportMode("normal-reexport");
    235 					mode.items = [
    236 						new NormalReexportItem(name, ids, exportInfo, false, false)
    237 					];
    238 					break;
    239 			}
    240 		} else {
    241 			// export * as name
    242 			switch (importedExportsType) {
    243 				case "default-only":
    244 					mode = new ExportMode("reexport-fake-namespace-object");
    245 					mode.name = name;
    246 					mode.partialNamespaceExportInfo = exportInfo;
    247 					mode.fakeType = 0;
    248 					break;
    249 				case "default-with-named":
    250 					mode = new ExportMode("reexport-fake-namespace-object");
    251 					mode.name = name;
    252 					mode.partialNamespaceExportInfo = exportInfo;
    253 					mode.fakeType = 2;
    254 					break;
    255 				case "dynamic":
    256 				default:
    257 					mode = new ExportMode("reexport-namespace-object");
    258 					mode.name = name;
    259 					mode.partialNamespaceExportInfo = exportInfo;
    260 			}
    261 		}
    262 
    263 		return mode;
    264 	}
    265 
    266 	// Star reexporting
    267 
    268 	const { ignoredExports, exports, checked, hidden } = dep.getStarReexports(
    269 		moduleGraph,
    270 		runtime,
    271 		exportsInfo,
    272 		importedModule
    273 	);
    274 	if (!exports) {
    275 		// We have too few info about the modules
    276 		// Delegate the logic to the runtime code
    277 
    278 		const mode = new ExportMode("dynamic-reexport");
    279 		mode.ignored = ignoredExports;
    280 		mode.hidden = hidden;
    281 
    282 		return mode;
    283 	}
    284 
    285 	if (exports.size === 0) {
    286 		const mode = new ExportMode("empty-star");
    287 		mode.hidden = hidden;
    288 
    289 		return mode;
    290 	}
    291 
    292 	const mode = new ExportMode("normal-reexport");
    293 
    294 	mode.items = Array.from(
    295 		exports,
    296 		exportName =>
    297 			new NormalReexportItem(
    298 				exportName,
    299 				[exportName],
    300 				exportsInfo.getReadOnlyExportInfo(exportName),
    301 				checked.has(exportName),
    302 				false
    303 			)
    304 	);
    305 	if (hidden !== undefined) {
    306 		for (const exportName of hidden) {
    307 			mode.items.push(
    308 				new NormalReexportItem(
    309 					exportName,
    310 					[exportName],
    311 					exportsInfo.getReadOnlyExportInfo(exportName),
    312 					false,
    313 					true
    314 				)
    315 			);
    316 		}
    317 	}
    318 
    319 	return mode;
    320 };
    321 
    322 class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
    323 	/**
    324 	 * @param {string} request the request string
    325 	 * @param {number} sourceOrder the order in the original source file
    326 	 * @param {string[]} ids the requested export name of the imported module
    327 	 * @param {string | null} name the export name of for this module
    328 	 * @param {Set<string>} activeExports other named exports in the module
    329 	 * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | Iterable<HarmonyExportImportedSpecifierDependency>} otherStarExports other star exports in the module before this import
    330 	 * @param {number} exportPresenceMode mode of checking export names
    331 	 * @param {HarmonyStarExportsList} allStarExports all star exports in the module
    332 	 * @param {Record<string, any>=} assertions import assertions
    333 	 */
    334 	constructor(
    335 		request,
    336 		sourceOrder,
    337 		ids,
    338 		name,
    339 		activeExports,
    340 		otherStarExports,
    341 		exportPresenceMode,
    342 		allStarExports,
    343 		assertions
    344 	) {
    345 		super(request, sourceOrder, assertions);
    346 
    347 		this.ids = ids;
    348 		this.name = name;
    349 		this.activeExports = activeExports;
    350 		this.otherStarExports = otherStarExports;
    351 		this.exportPresenceMode = exportPresenceMode;
    352 		this.allStarExports = allStarExports;
    353 	}
    354 
    355 	/**
    356 	 * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
    357 	 */
    358 	couldAffectReferencingModule() {
    359 		return Dependency.TRANSITIVE;
    360 	}
    361 
    362 	// TODO webpack 6 remove
    363 	get id() {
    364 		throw new Error("id was renamed to ids and type changed to string[]");
    365 	}
    366 
    367 	// TODO webpack 6 remove
    368 	getId() {
    369 		throw new Error("id was renamed to ids and type changed to string[]");
    370 	}
    371 
    372 	// TODO webpack 6 remove
    373 	setId() {
    374 		throw new Error("id was renamed to ids and type changed to string[]");
    375 	}
    376 
    377 	get type() {
    378 		return "harmony export imported specifier";
    379 	}
    380 
    381 	/**
    382 	 * @param {ModuleGraph} moduleGraph the module graph
    383 	 * @returns {string[]} the imported id
    384 	 */
    385 	getIds(moduleGraph) {
    386 		return moduleGraph.getMeta(this)[idsSymbol] || this.ids;
    387 	}
    388 
    389 	/**
    390 	 * @param {ModuleGraph} moduleGraph the module graph
    391 	 * @param {string[]} ids the imported ids
    392 	 * @returns {void}
    393 	 */
    394 	setIds(moduleGraph, ids) {
    395 		moduleGraph.getMeta(this)[idsSymbol] = ids;
    396 	}
    397 
    398 	/**
    399 	 * @param {ModuleGraph} moduleGraph the module graph
    400 	 * @param {RuntimeSpec} runtime the runtime
    401 	 * @returns {ExportMode} the export mode
    402 	 */
    403 	getMode(moduleGraph, runtime) {
    404 		return moduleGraph.dependencyCacheProvide(
    405 			this,
    406 			getRuntimeKey(runtime),
    407 			getMode
    408 		);
    409 	}
    410 
    411 	/**
    412 	 * @param {ModuleGraph} moduleGraph the module graph
    413 	 * @param {RuntimeSpec} runtime the runtime
    414 	 * @param {ExportsInfo} exportsInfo exports info about the current module (optional)
    415 	 * @param {Module} importedModule the imported module (optional)
    416 	 * @returns {{exports?: Set<string>, checked?: Set<string>, ignoredExports: Set<string>, hidden?: Set<string>}} information
    417 	 */
    418 	getStarReexports(
    419 		moduleGraph,
    420 		runtime,
    421 		exportsInfo = moduleGraph.getExportsInfo(moduleGraph.getParentModule(this)),
    422 		importedModule = moduleGraph.getModule(this)
    423 	) {
    424 		const importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
    425 
    426 		const noExtraExports =
    427 			importedExportsInfo.otherExportsInfo.provided === false;
    428 		const noExtraImports =
    429 			exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused;
    430 
    431 		const ignoredExports = new Set(["default", ...this.activeExports]);
    432 
    433 		let hiddenExports = undefined;
    434 		const otherStarExports =
    435 			this._discoverActiveExportsFromOtherStarExports(moduleGraph);
    436 		if (otherStarExports !== undefined) {
    437 			hiddenExports = new Set();
    438 			for (let i = 0; i < otherStarExports.namesSlice; i++) {
    439 				hiddenExports.add(otherStarExports.names[i]);
    440 			}
    441 			for (const e of ignoredExports) hiddenExports.delete(e);
    442 		}
    443 
    444 		if (!noExtraExports && !noExtraImports) {
    445 			return {
    446 				ignoredExports,
    447 				hidden: hiddenExports
    448 			};
    449 		}
    450 
    451 		/** @type {Set<string>} */
    452 		const exports = new Set();
    453 		/** @type {Set<string>} */
    454 		const checked = new Set();
    455 		/** @type {Set<string>} */
    456 		const hidden = hiddenExports !== undefined ? new Set() : undefined;
    457 
    458 		if (noExtraImports) {
    459 			for (const exportInfo of exportsInfo.orderedExports) {
    460 				const name = exportInfo.name;
    461 				if (ignoredExports.has(name)) continue;
    462 				if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
    463 				const importedExportInfo =
    464 					importedExportsInfo.getReadOnlyExportInfo(name);
    465 				if (importedExportInfo.provided === false) continue;
    466 				if (hiddenExports !== undefined && hiddenExports.has(name)) {
    467 					hidden.add(name);
    468 					continue;
    469 				}
    470 				exports.add(name);
    471 				if (importedExportInfo.provided === true) continue;
    472 				checked.add(name);
    473 			}
    474 		} else if (noExtraExports) {
    475 			for (const importedExportInfo of importedExportsInfo.orderedExports) {
    476 				const name = importedExportInfo.name;
    477 				if (ignoredExports.has(name)) continue;
    478 				if (importedExportInfo.provided === false) continue;
    479 				const exportInfo = exportsInfo.getReadOnlyExportInfo(name);
    480 				if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
    481 				if (hiddenExports !== undefined && hiddenExports.has(name)) {
    482 					hidden.add(name);
    483 					continue;
    484 				}
    485 				exports.add(name);
    486 				if (importedExportInfo.provided === true) continue;
    487 				checked.add(name);
    488 			}
    489 		}
    490 
    491 		return { ignoredExports, exports, checked, hidden };
    492 	}
    493 
    494 	/**
    495 	 * @param {ModuleGraph} moduleGraph module graph
    496 	 * @returns {null | false | function(ModuleGraphConnection, RuntimeSpec): ConnectionState} function to determine if the connection is active
    497 	 */
    498 	getCondition(moduleGraph) {
    499 		return (connection, runtime) => {
    500 			const mode = this.getMode(moduleGraph, runtime);
    501 			return mode.type !== "unused" && mode.type !== "empty-star";
    502 		};
    503 	}
    504 
    505 	/**
    506 	 * @param {ModuleGraph} moduleGraph the module graph
    507 	 * @returns {ConnectionState} how this dependency connects the module to referencing modules
    508 	 */
    509 	getModuleEvaluationSideEffectsState(moduleGraph) {
    510 		return false;
    511 	}
    512 
    513 	/**
    514 	 * Returns list of exports referenced by this dependency
    515 	 * @param {ModuleGraph} moduleGraph module graph
    516 	 * @param {RuntimeSpec} runtime the runtime for which the module is analysed
    517 	 * @returns {(string[] | ReferencedExport)[]} referenced exports
    518 	 */
    519 	getReferencedExports(moduleGraph, runtime) {
    520 		const mode = this.getMode(moduleGraph, runtime);
    521 
    522 		switch (mode.type) {
    523 			case "missing":
    524 			case "unused":
    525 			case "empty-star":
    526 			case "reexport-undefined":
    527 				return Dependency.NO_EXPORTS_REFERENCED;
    528 
    529 			case "reexport-dynamic-default":
    530 				return Dependency.EXPORTS_OBJECT_REFERENCED;
    531 
    532 			case "reexport-named-default": {
    533 				if (!mode.partialNamespaceExportInfo)
    534 					return Dependency.EXPORTS_OBJECT_REFERENCED;
    535 				/** @type {string[][]} */
    536 				const referencedExports = [];
    537 				processExportInfo(
    538 					runtime,
    539 					referencedExports,
    540 					[],
    541 					/** @type {ExportInfo} */ (mode.partialNamespaceExportInfo)
    542 				);
    543 				return referencedExports;
    544 			}
    545 
    546 			case "reexport-namespace-object":
    547 			case "reexport-fake-namespace-object": {
    548 				if (!mode.partialNamespaceExportInfo)
    549 					return Dependency.EXPORTS_OBJECT_REFERENCED;
    550 				/** @type {string[][]} */
    551 				const referencedExports = [];
    552 				processExportInfo(
    553 					runtime,
    554 					referencedExports,
    555 					[],
    556 					/** @type {ExportInfo} */ (mode.partialNamespaceExportInfo),
    557 					mode.type === "reexport-fake-namespace-object"
    558 				);
    559 				return referencedExports;
    560 			}
    561 
    562 			case "dynamic-reexport":
    563 				return Dependency.EXPORTS_OBJECT_REFERENCED;
    564 
    565 			case "normal-reexport": {
    566 				const referencedExports = [];
    567 				for (const { ids, exportInfo, hidden } of mode.items) {
    568 					if (hidden) continue;
    569 					processExportInfo(runtime, referencedExports, ids, exportInfo, false);
    570 				}
    571 				return referencedExports;
    572 			}
    573 
    574 			default:
    575 				throw new Error(`Unknown mode ${mode.type}`);
    576 		}
    577 	}
    578 
    579 	/**
    580 	 * @param {ModuleGraph} moduleGraph the module graph
    581 	 * @returns {{ names: string[], namesSlice: number, dependencyIndices: number[], dependencyIndex: number } | undefined} exported names and their origin dependency
    582 	 */
    583 	_discoverActiveExportsFromOtherStarExports(moduleGraph) {
    584 		if (!this.otherStarExports) return undefined;
    585 
    586 		const i =
    587 			"length" in this.otherStarExports
    588 				? this.otherStarExports.length
    589 				: countIterable(this.otherStarExports);
    590 		if (i === 0) return undefined;
    591 
    592 		if (this.allStarExports) {
    593 			const { names, dependencyIndices } = moduleGraph.cached(
    594 				determineExportAssignments,
    595 				this.allStarExports.dependencies
    596 			);
    597 
    598 			return {
    599 				names,
    600 				namesSlice: dependencyIndices[i - 1],
    601 				dependencyIndices,
    602 				dependencyIndex: i
    603 			};
    604 		}
    605 
    606 		const { names, dependencyIndices } = moduleGraph.cached(
    607 			determineExportAssignments,
    608 			this.otherStarExports,
    609 			this
    610 		);
    611 
    612 		return {
    613 			names,
    614 			namesSlice: dependencyIndices[i - 1],
    615 			dependencyIndices,
    616 			dependencyIndex: i
    617 		};
    618 	}
    619 
    620 	/**
    621 	 * Returns the exported names
    622 	 * @param {ModuleGraph} moduleGraph module graph
    623 	 * @returns {ExportsSpec | undefined} export names
    624 	 */
    625 	getExports(moduleGraph) {
    626 		const mode = this.getMode(moduleGraph, undefined);
    627 
    628 		switch (mode.type) {
    629 			case "missing":
    630 				return undefined;
    631 			case "dynamic-reexport": {
    632 				const from = moduleGraph.getConnection(this);
    633 				return {
    634 					exports: true,
    635 					from,
    636 					canMangle: false,
    637 					excludeExports: mode.hidden
    638 						? combine(mode.ignored, mode.hidden)
    639 						: mode.ignored,
    640 					hideExports: mode.hidden,
    641 					dependencies: [from.module]
    642 				};
    643 			}
    644 			case "empty-star":
    645 				return {
    646 					exports: [],
    647 					hideExports: mode.hidden,
    648 					dependencies: [moduleGraph.getModule(this)]
    649 				};
    650 			// falls through
    651 			case "normal-reexport": {
    652 				const from = moduleGraph.getConnection(this);
    653 				return {
    654 					exports: Array.from(mode.items, item => ({
    655 						name: item.name,
    656 						from,
    657 						export: item.ids,
    658 						hidden: item.hidden
    659 					})),
    660 					priority: 1,
    661 					dependencies: [from.module]
    662 				};
    663 			}
    664 			case "reexport-dynamic-default": {
    665 				{
    666 					const from = moduleGraph.getConnection(this);
    667 					return {
    668 						exports: [
    669 							{
    670 								name: mode.name,
    671 								from,
    672 								export: ["default"]
    673 							}
    674 						],
    675 						priority: 1,
    676 						dependencies: [from.module]
    677 					};
    678 				}
    679 			}
    680 			case "reexport-undefined":
    681 				return {
    682 					exports: [mode.name],
    683 					dependencies: [moduleGraph.getModule(this)]
    684 				};
    685 			case "reexport-fake-namespace-object": {
    686 				const from = moduleGraph.getConnection(this);
    687 				return {
    688 					exports: [
    689 						{
    690 							name: mode.name,
    691 							from,
    692 							export: null,
    693 							exports: [
    694 								{
    695 									name: "default",
    696 									canMangle: false,
    697 									from,
    698 									export: null
    699 								}
    700 							]
    701 						}
    702 					],
    703 					priority: 1,
    704 					dependencies: [from.module]
    705 				};
    706 			}
    707 			case "reexport-namespace-object": {
    708 				const from = moduleGraph.getConnection(this);
    709 				return {
    710 					exports: [
    711 						{
    712 							name: mode.name,
    713 							from,
    714 							export: null
    715 						}
    716 					],
    717 					priority: 1,
    718 					dependencies: [from.module]
    719 				};
    720 			}
    721 			case "reexport-named-default": {
    722 				const from = moduleGraph.getConnection(this);
    723 				return {
    724 					exports: [
    725 						{
    726 							name: mode.name,
    727 							from,
    728 							export: ["default"]
    729 						}
    730 					],
    731 					priority: 1,
    732 					dependencies: [from.module]
    733 				};
    734 			}
    735 			default:
    736 				throw new Error(`Unknown mode ${mode.type}`);
    737 		}
    738 	}
    739 
    740 	/**
    741 	 * @param {ModuleGraph} moduleGraph module graph
    742 	 * @returns {number} effective mode
    743 	 */
    744 	_getEffectiveExportPresenceLevel(moduleGraph) {
    745 		if (this.exportPresenceMode !== ExportPresenceModes.AUTO)
    746 			return this.exportPresenceMode;
    747 		return moduleGraph.getParentModule(this).buildMeta.strictHarmonyModule
    748 			? ExportPresenceModes.ERROR
    749 			: ExportPresenceModes.WARN;
    750 	}
    751 
    752 	/**
    753 	 * Returns warnings
    754 	 * @param {ModuleGraph} moduleGraph module graph
    755 	 * @returns {WebpackError[]} warnings
    756 	 */
    757 	getWarnings(moduleGraph) {
    758 		const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
    759 		if (exportsPresence === ExportPresenceModes.WARN) {
    760 			return this._getErrors(moduleGraph);
    761 		}
    762 		return null;
    763 	}
    764 
    765 	/**
    766 	 * Returns errors
    767 	 * @param {ModuleGraph} moduleGraph module graph
    768 	 * @returns {WebpackError[]} errors
    769 	 */
    770 	getErrors(moduleGraph) {
    771 		const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph);
    772 		if (exportsPresence === ExportPresenceModes.ERROR) {
    773 			return this._getErrors(moduleGraph);
    774 		}
    775 		return null;
    776 	}
    777 
    778 	/**
    779 	 * @param {ModuleGraph} moduleGraph module graph
    780 	 * @returns {WebpackError[] | undefined} errors
    781 	 */
    782 	_getErrors(moduleGraph) {
    783 		const ids = this.getIds(moduleGraph);
    784 		let errors = this.getLinkingErrors(
    785 			moduleGraph,
    786 			ids,
    787 			`(reexported as '${this.name}')`
    788 		);
    789 		if (ids.length === 0 && this.name === null) {
    790 			const potentialConflicts =
    791 				this._discoverActiveExportsFromOtherStarExports(moduleGraph);
    792 			if (potentialConflicts && potentialConflicts.namesSlice > 0) {
    793 				const ownNames = new Set(
    794 					potentialConflicts.names.slice(
    795 						potentialConflicts.namesSlice,
    796 						potentialConflicts.dependencyIndices[
    797 							potentialConflicts.dependencyIndex
    798 						]
    799 					)
    800 				);
    801 				const importedModule = moduleGraph.getModule(this);
    802 				if (importedModule) {
    803 					const exportsInfo = moduleGraph.getExportsInfo(importedModule);
    804 					const conflicts = new Map();
    805 					for (const exportInfo of exportsInfo.orderedExports) {
    806 						if (exportInfo.provided !== true) continue;
    807 						if (exportInfo.name === "default") continue;
    808 						if (this.activeExports.has(exportInfo.name)) continue;
    809 						if (ownNames.has(exportInfo.name)) continue;
    810 						const conflictingDependency = findDependencyForName(
    811 							potentialConflicts,
    812 							exportInfo.name,
    813 							this.allStarExports
    814 								? this.allStarExports.dependencies
    815 								: [...this.otherStarExports, this]
    816 						);
    817 						if (!conflictingDependency) continue;
    818 						const target = exportInfo.getTerminalBinding(moduleGraph);
    819 						if (!target) continue;
    820 						const conflictingModule = moduleGraph.getModule(
    821 							conflictingDependency
    822 						);
    823 						if (conflictingModule === importedModule) continue;
    824 						const conflictingExportInfo = moduleGraph.getExportInfo(
    825 							conflictingModule,
    826 							exportInfo.name
    827 						);
    828 						const conflictingTarget =
    829 							conflictingExportInfo.getTerminalBinding(moduleGraph);
    830 						if (!conflictingTarget) continue;
    831 						if (target === conflictingTarget) continue;
    832 						const list = conflicts.get(conflictingDependency.request);
    833 						if (list === undefined) {
    834 							conflicts.set(conflictingDependency.request, [exportInfo.name]);
    835 						} else {
    836 							list.push(exportInfo.name);
    837 						}
    838 					}
    839 					for (const [request, exports] of conflicts) {
    840 						if (!errors) errors = [];
    841 						errors.push(
    842 							new HarmonyLinkingError(
    843 								`The requested module '${
    844 									this.request
    845 								}' contains conflicting star exports for the ${
    846 									exports.length > 1 ? "names" : "name"
    847 								} ${exports
    848 									.map(e => `'${e}'`)
    849 									.join(", ")} with the previous requested module '${request}'`
    850 							)
    851 						);
    852 					}
    853 				}
    854 			}
    855 		}
    856 		return errors;
    857 	}
    858 
    859 	serialize(context) {
    860 		const { write, setCircularReference } = context;
    861 
    862 		setCircularReference(this);
    863 		write(this.ids);
    864 		write(this.name);
    865 		write(this.activeExports);
    866 		write(this.otherStarExports);
    867 		write(this.exportPresenceMode);
    868 		write(this.allStarExports);
    869 
    870 		super.serialize(context);
    871 	}
    872 
    873 	deserialize(context) {
    874 		const { read, setCircularReference } = context;
    875 
    876 		setCircularReference(this);
    877 		this.ids = read();
    878 		this.name = read();
    879 		this.activeExports = read();
    880 		this.otherStarExports = read();
    881 		this.exportPresenceMode = read();
    882 		this.allStarExports = read();
    883 
    884 		super.deserialize(context);
    885 	}
    886 }
    887 
    888 makeSerializable(
    889 	HarmonyExportImportedSpecifierDependency,
    890 	"webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency"
    891 );
    892 
    893 module.exports = HarmonyExportImportedSpecifierDependency;
    894 
    895 HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate extends (
    896 	HarmonyImportDependency.Template
    897 ) {
    898 	/**
    899 	 * @param {Dependency} dependency the dependency for which the template should be applied
    900 	 * @param {ReplaceSource} source the current replace source which can be modified
    901 	 * @param {DependencyTemplateContext} templateContext the context object
    902 	 * @returns {void}
    903 	 */
    904 	apply(dependency, source, templateContext) {
    905 		const { moduleGraph, runtime, concatenationScope } = templateContext;
    906 
    907 		const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ (
    908 			dependency
    909 		);
    910 
    911 		const mode = dep.getMode(moduleGraph, runtime);
    912 
    913 		if (concatenationScope) {
    914 			switch (mode.type) {
    915 				case "reexport-undefined":
    916 					concatenationScope.registerRawExport(
    917 						mode.name,
    918 						"/* reexport non-default export from non-harmony */ undefined"
    919 					);
    920 			}
    921 			return;
    922 		}
    923 
    924 		if (mode.type !== "unused" && mode.type !== "empty-star") {
    925 			super.apply(dependency, source, templateContext);
    926 
    927 			this._addExportFragments(
    928 				templateContext.initFragments,
    929 				dep,
    930 				mode,
    931 				templateContext.module,
    932 				moduleGraph,
    933 				runtime,
    934 				templateContext.runtimeTemplate,
    935 				templateContext.runtimeRequirements
    936 			);
    937 		}
    938 	}
    939 
    940 	/**
    941 	 * @param {InitFragment[]} initFragments target array for init fragments
    942 	 * @param {HarmonyExportImportedSpecifierDependency} dep dependency
    943 	 * @param {ExportMode} mode the export mode
    944 	 * @param {Module} module the current module
    945 	 * @param {ModuleGraph} moduleGraph the module graph
    946 	 * @param {RuntimeSpec} runtime the runtime
    947 	 * @param {RuntimeTemplate} runtimeTemplate the runtime template
    948 	 * @param {Set<string>} runtimeRequirements runtime requirements
    949 	 * @returns {void}
    950 	 */
    951 	_addExportFragments(
    952 		initFragments,
    953 		dep,
    954 		mode,
    955 		module,
    956 		moduleGraph,
    957 		runtime,
    958 		runtimeTemplate,
    959 		runtimeRequirements
    960 	) {
    961 		const importedModule = moduleGraph.getModule(dep);
    962 		const importVar = dep.getImportVar(moduleGraph);
    963 
    964 		switch (mode.type) {
    965 			case "missing":
    966 			case "empty-star":
    967 				initFragments.push(
    968 					new InitFragment(
    969 						"/* empty/unused harmony star reexport */\n",
    970 						InitFragment.STAGE_HARMONY_EXPORTS,
    971 						1
    972 					)
    973 				);
    974 				break;
    975 
    976 			case "unused":
    977 				initFragments.push(
    978 					new InitFragment(
    979 						`${Template.toNormalComment(
    980 							`unused harmony reexport ${mode.name}`
    981 						)}\n`,
    982 						InitFragment.STAGE_HARMONY_EXPORTS,
    983 						1
    984 					)
    985 				);
    986 				break;
    987 
    988 			case "reexport-dynamic-default":
    989 				initFragments.push(
    990 					this.getReexportFragment(
    991 						module,
    992 						"reexport default from dynamic",
    993 						moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime),
    994 						importVar,
    995 						null,
    996 						runtimeRequirements
    997 					)
    998 				);
    999 				break;
   1000 
   1001 			case "reexport-fake-namespace-object":
   1002 				initFragments.push(
   1003 					...this.getReexportFakeNamespaceObjectFragments(
   1004 						module,
   1005 						moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime),
   1006 						importVar,
   1007 						mode.fakeType,
   1008 						runtimeRequirements
   1009 					)
   1010 				);
   1011 				break;
   1012 
   1013 			case "reexport-undefined":
   1014 				initFragments.push(
   1015 					this.getReexportFragment(
   1016 						module,
   1017 						"reexport non-default export from non-harmony",
   1018 						moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime),
   1019 						"undefined",
   1020 						"",
   1021 						runtimeRequirements
   1022 					)
   1023 				);
   1024 				break;
   1025 
   1026 			case "reexport-named-default":
   1027 				initFragments.push(
   1028 					this.getReexportFragment(
   1029 						module,
   1030 						"reexport default export from named module",
   1031 						moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime),
   1032 						importVar,
   1033 						"",
   1034 						runtimeRequirements
   1035 					)
   1036 				);
   1037 				break;
   1038 
   1039 			case "reexport-namespace-object":
   1040 				initFragments.push(
   1041 					this.getReexportFragment(
   1042 						module,
   1043 						"reexport module object",
   1044 						moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime),
   1045 						importVar,
   1046 						"",
   1047 						runtimeRequirements
   1048 					)
   1049 				);
   1050 				break;
   1051 
   1052 			case "normal-reexport":
   1053 				for (const { name, ids, checked, hidden } of mode.items) {
   1054 					if (hidden) continue;
   1055 					if (checked) {
   1056 						initFragments.push(
   1057 							new InitFragment(
   1058 								"/* harmony reexport (checked) */ " +
   1059 									this.getConditionalReexportStatement(
   1060 										module,
   1061 										name,
   1062 										importVar,
   1063 										ids,
   1064 										runtimeRequirements
   1065 									),
   1066 								moduleGraph.isAsync(importedModule)
   1067 									? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
   1068 									: InitFragment.STAGE_HARMONY_IMPORTS,
   1069 								dep.sourceOrder
   1070 							)
   1071 						);
   1072 					} else {
   1073 						initFragments.push(
   1074 							this.getReexportFragment(
   1075 								module,
   1076 								"reexport safe",
   1077 								moduleGraph.getExportsInfo(module).getUsedName(name, runtime),
   1078 								importVar,
   1079 								moduleGraph
   1080 									.getExportsInfo(importedModule)
   1081 									.getUsedName(ids, runtime),
   1082 								runtimeRequirements
   1083 							)
   1084 						);
   1085 					}
   1086 				}
   1087 				break;
   1088 
   1089 			case "dynamic-reexport": {
   1090 				const ignored = mode.hidden
   1091 					? combine(mode.ignored, mode.hidden)
   1092 					: mode.ignored;
   1093 				const modern =
   1094 					runtimeTemplate.supportsConst() &&
   1095 					runtimeTemplate.supportsArrowFunction();
   1096 				let content =
   1097 					"/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n" +
   1098 					`/* harmony reexport (unknown) */ for(${
   1099 						modern ? "const" : "var"
   1100 					} __WEBPACK_IMPORT_KEY__ in ${importVar}) `;
   1101 
   1102 				// Filter out exports which are defined by other exports
   1103 				// and filter out default export because it cannot be reexported with *
   1104 				if (ignored.size > 1) {
   1105 					content +=
   1106 						"if(" +
   1107 						JSON.stringify(Array.from(ignored)) +
   1108 						".indexOf(__WEBPACK_IMPORT_KEY__) < 0) ";
   1109 				} else if (ignored.size === 1) {
   1110 					content += `if(__WEBPACK_IMPORT_KEY__ !== ${JSON.stringify(
   1111 						first(ignored)
   1112 					)}) `;
   1113 				}
   1114 
   1115 				content += `__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = `;
   1116 				if (modern) {
   1117 					content += `() => ${importVar}[__WEBPACK_IMPORT_KEY__]`;
   1118 				} else {
   1119 					content += `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`;
   1120 				}
   1121 
   1122 				runtimeRequirements.add(RuntimeGlobals.exports);
   1123 				runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
   1124 
   1125 				const exportsName = module.exportsArgument;
   1126 				initFragments.push(
   1127 					new InitFragment(
   1128 						`${content}\n/* harmony reexport (unknown) */ ${RuntimeGlobals.definePropertyGetters}(${exportsName}, __WEBPACK_REEXPORT_OBJECT__);\n`,
   1129 						moduleGraph.isAsync(importedModule)
   1130 							? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS
   1131 							: InitFragment.STAGE_HARMONY_IMPORTS,
   1132 						dep.sourceOrder
   1133 					)
   1134 				);
   1135 				break;
   1136 			}
   1137 
   1138 			default:
   1139 				throw new Error(`Unknown mode ${mode.type}`);
   1140 		}
   1141 	}
   1142 
   1143 	getReexportFragment(
   1144 		module,
   1145 		comment,
   1146 		key,
   1147 		name,
   1148 		valueKey,
   1149 		runtimeRequirements
   1150 	) {
   1151 		const returnValue = this.getReturnValue(name, valueKey);
   1152 
   1153 		runtimeRequirements.add(RuntimeGlobals.exports);
   1154 		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
   1155 
   1156 		const map = new Map();
   1157 		map.set(key, `/* ${comment} */ ${returnValue}`);
   1158 
   1159 		return new HarmonyExportInitFragment(module.exportsArgument, map);
   1160 	}
   1161 
   1162 	getReexportFakeNamespaceObjectFragments(
   1163 		module,
   1164 		key,
   1165 		name,
   1166 		fakeType,
   1167 		runtimeRequirements
   1168 	) {
   1169 		runtimeRequirements.add(RuntimeGlobals.exports);
   1170 		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
   1171 		runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
   1172 
   1173 		const map = new Map();
   1174 		map.set(
   1175 			key,
   1176 			`/* reexport fake namespace object from non-harmony */ ${name}_namespace_cache || (${name}_namespace_cache = ${
   1177 				RuntimeGlobals.createFakeNamespaceObject
   1178 			}(${name}${fakeType ? `, ${fakeType}` : ""}))`
   1179 		);
   1180 
   1181 		return [
   1182 			new InitFragment(
   1183 				`var ${name}_namespace_cache;\n`,
   1184 				InitFragment.STAGE_CONSTANTS,
   1185 				-1,
   1186 				`${name}_namespace_cache`
   1187 			),
   1188 			new HarmonyExportInitFragment(module.exportsArgument, map)
   1189 		];
   1190 	}
   1191 
   1192 	getConditionalReexportStatement(
   1193 		module,
   1194 		key,
   1195 		name,
   1196 		valueKey,
   1197 		runtimeRequirements
   1198 	) {
   1199 		if (valueKey === false) {
   1200 			return "/* unused export */\n";
   1201 		}
   1202 
   1203 		const exportsName = module.exportsArgument;
   1204 		const returnValue = this.getReturnValue(name, valueKey);
   1205 
   1206 		runtimeRequirements.add(RuntimeGlobals.exports);
   1207 		runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
   1208 		runtimeRequirements.add(RuntimeGlobals.hasOwnProperty);
   1209 
   1210 		return `if(${RuntimeGlobals.hasOwnProperty}(${name}, ${JSON.stringify(
   1211 			valueKey[0]
   1212 		)})) ${
   1213 			RuntimeGlobals.definePropertyGetters
   1214 		}(${exportsName}, { ${JSON.stringify(
   1215 			key
   1216 		)}: function() { return ${returnValue}; } });\n`;
   1217 	}
   1218 
   1219 	getReturnValue(name, valueKey) {
   1220 		if (valueKey === null) {
   1221 			return `${name}_default.a`;
   1222 		}
   1223 
   1224 		if (valueKey === "") {
   1225 			return name;
   1226 		}
   1227 
   1228 		if (valueKey === false) {
   1229 			return "/* unused export */ undefined";
   1230 		}
   1231 
   1232 		return `${name}${propertyAccess(valueKey)}`;
   1233 	}
   1234 };
   1235 
   1236 class HarmonyStarExportsList {
   1237 	constructor() {
   1238 		/** @type {HarmonyExportImportedSpecifierDependency[]} */
   1239 		this.dependencies = [];
   1240 	}
   1241 
   1242 	/**
   1243 	 * @param {HarmonyExportImportedSpecifierDependency} dep dependency
   1244 	 * @returns {void}
   1245 	 */
   1246 	push(dep) {
   1247 		this.dependencies.push(dep);
   1248 	}
   1249 
   1250 	slice() {
   1251 		return this.dependencies.slice();
   1252 	}
   1253 
   1254 	serialize({ write, setCircularReference }) {
   1255 		setCircularReference(this);
   1256 		write(this.dependencies);
   1257 	}
   1258 
   1259 	deserialize({ read, setCircularReference }) {
   1260 		setCircularReference(this);
   1261 		this.dependencies = read();
   1262 	}
   1263 }
   1264 
   1265 makeSerializable(
   1266 	HarmonyStarExportsList,
   1267 	"webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency",
   1268 	"HarmonyStarExportsList"
   1269 );
   1270 
   1271 module.exports.HarmonyStarExportsList = HarmonyStarExportsList;