| | |
| | | const InitFragment = require("../InitFragment"); |
| | | const RuntimeGlobals = require("../RuntimeGlobals"); |
| | | const { first } = require("../util/SetHelpers"); |
| | | const { propertyName } = require("../util/propertyName"); |
| | | const { propertyName } = require("../util/property"); |
| | | |
| | | /** @typedef {import("webpack-sources").Source} Source */ |
| | | /** @typedef {import("../Generator").GenerateContext} GenerateContext */ |
| | | /** @typedef {import("../ExportsInfo").UsedName} UsedName */ |
| | | |
| | | /** |
| | | * Join iterable with comma. |
| | | * @param {Iterable<string>} iterable iterable strings |
| | | * @returns {string} result |
| | | */ |
| | |
| | | return str; |
| | | }; |
| | | |
| | | /** @typedef {Map<UsedName, string>} ExportMap */ |
| | | /** @typedef {Set<string>} UnusedExports */ |
| | | |
| | | /** @type {ExportMap} */ |
| | | const EMPTY_MAP = new Map(); |
| | | /** @type {UnusedExports} */ |
| | | const EMPTY_SET = new Set(); |
| | | |
| | | /** |
| | | * Represents HarmonyExportInitFragment. |
| | | * @extends {InitFragment<GenerateContext>} Context |
| | | */ |
| | | class HarmonyExportInitFragment extends InitFragment { |
| | | /** |
| | | * Creates an instance of HarmonyExportInitFragment. |
| | | * @param {string} exportsArgument the exports identifier |
| | | * @param {Map<string, string>} exportMap mapping from used name to exposed variable name |
| | | * @param {Set<string>} unusedExports list of unused export names |
| | | * @param {ExportMap} exportMap mapping from used name to exposed variable name |
| | | * @param {UnusedExports} unusedExports list of unused export names |
| | | */ |
| | | constructor( |
| | | exportsArgument, |
| | |
| | | unusedExports = EMPTY_SET |
| | | ) { |
| | | super(undefined, InitFragment.STAGE_HARMONY_EXPORTS, 1, "harmony-exports"); |
| | | /** @type {string} */ |
| | | this.exportsArgument = exportsArgument; |
| | | /** @type {ExportMap} */ |
| | | this.exportMap = exportMap; |
| | | /** @type {UnusedExports} */ |
| | | this.unusedExports = unusedExports; |
| | | } |
| | | |
| | | /** |
| | | * Merges the provided values into a single result. |
| | | * @param {HarmonyExportInitFragment[]} fragments all fragments to merge |
| | | * @returns {HarmonyExportInitFragment} merged fragment |
| | | */ |
| | | mergeAll(fragments) { |
| | | /** @type {undefined | ExportMap} */ |
| | | let exportMap; |
| | | let exportMapOwned = false; |
| | | /** @type {undefined | UnusedExports} */ |
| | | let unusedExports; |
| | | let unusedExportsOwned = false; |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns merged result. |
| | | * @param {HarmonyExportInitFragment} other other |
| | | * @returns {HarmonyExportInitFragment} merged result |
| | | */ |
| | | merge(other) { |
| | | /** @type {ExportMap} */ |
| | | let exportMap; |
| | | if (this.exportMap.size === 0) { |
| | | exportMap = other.exportMap; |
| | |
| | | if (!exportMap.has(key)) exportMap.set(key, value); |
| | | } |
| | | } |
| | | /** @type {UnusedExports} */ |
| | | let unusedExports; |
| | | if (this.unusedExports.size === 0) { |
| | | unusedExports = other.unusedExports; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the source code that will be included as initialization code. |
| | | * @param {GenerateContext} context context |
| | | * @returns {string | Source | undefined} the source code that will be included as initialization code |
| | | */ |
| | |
| | | : this.unusedExports.size > 0 |
| | | ? `/* unused harmony export ${first(this.unusedExports)} */\n` |
| | | : ""; |
| | | /** @type {string[]} */ |
| | | const definitions = []; |
| | | const orderedExportMap = [...this.exportMap].sort(([a], [b]) => |
| | | a < b ? -1 : 1 |
| | |
| | | for (const [key, value] of orderedExportMap) { |
| | | definitions.push( |
| | | `\n/* harmony export */ ${propertyName( |
| | | key |
| | | /** @type {string} */ (key) |
| | | )}: ${runtimeTemplate.returningFunction(value)}` |
| | | ); |
| | | } |