source: frontend/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const InitFragment = require("../InitFragment");
9const RuntimeGlobals = require("../RuntimeGlobals");
10const { first } = require("../util/SetHelpers");
11const { propertyName } = require("../util/property");
12
13/** @typedef {import("webpack-sources").Source} Source */
14/** @typedef {import("../Generator").GenerateContext} GenerateContext */
15/** @typedef {import("../ExportsInfo").UsedName} UsedName */
16
17/**
18 * Join iterable with comma.
19 * @param {Iterable<string>} iterable iterable strings
20 * @returns {string} result
21 */
22const joinIterableWithComma = (iterable) => {
23 // This is more performant than Array.from().join(", ")
24 // as it doesn't create an array
25 let str = "";
26 let first = true;
27 for (const item of iterable) {
28 if (first) {
29 first = false;
30 } else {
31 str += ", ";
32 }
33 str += item;
34 }
35 return str;
36};
37
38/** @typedef {Map<UsedName, string>} ExportMap */
39/** @typedef {Set<string>} UnusedExports */
40
41/** @type {ExportMap} */
42const EMPTY_MAP = new Map();
43/** @type {UnusedExports} */
44const EMPTY_SET = new Set();
45
46/**
47 * Represents HarmonyExportInitFragment.
48 * @extends {InitFragment<GenerateContext>} Context
49 */
50class HarmonyExportInitFragment extends InitFragment {
51 /**
52 * Creates an instance of HarmonyExportInitFragment.
53 * @param {string} exportsArgument the exports identifier
54 * @param {ExportMap} exportMap mapping from used name to exposed variable name
55 * @param {UnusedExports} unusedExports list of unused export names
56 */
57 constructor(
58 exportsArgument,
59 exportMap = EMPTY_MAP,
60 unusedExports = EMPTY_SET
61 ) {
62 super(undefined, InitFragment.STAGE_HARMONY_EXPORTS, 1, "harmony-exports");
63 /** @type {string} */
64 this.exportsArgument = exportsArgument;
65 /** @type {ExportMap} */
66 this.exportMap = exportMap;
67 /** @type {UnusedExports} */
68 this.unusedExports = unusedExports;
69 }
70
71 /**
72 * Merges the provided values into a single result.
73 * @param {HarmonyExportInitFragment[]} fragments all fragments to merge
74 * @returns {HarmonyExportInitFragment} merged fragment
75 */
76 mergeAll(fragments) {
77 /** @type {undefined | ExportMap} */
78 let exportMap;
79 let exportMapOwned = false;
80 /** @type {undefined | UnusedExports} */
81 let unusedExports;
82 let unusedExportsOwned = false;
83
84 for (const fragment of fragments) {
85 if (fragment.exportMap.size !== 0) {
86 if (exportMap === undefined) {
87 exportMap = fragment.exportMap;
88 exportMapOwned = false;
89 } else {
90 if (!exportMapOwned) {
91 exportMap = new Map(exportMap);
92 exportMapOwned = true;
93 }
94 for (const [key, value] of fragment.exportMap) {
95 if (!exportMap.has(key)) exportMap.set(key, value);
96 }
97 }
98 }
99 if (fragment.unusedExports.size !== 0) {
100 if (unusedExports === undefined) {
101 unusedExports = fragment.unusedExports;
102 unusedExportsOwned = false;
103 } else {
104 if (!unusedExportsOwned) {
105 unusedExports = new Set(unusedExports);
106 unusedExportsOwned = true;
107 }
108 for (const value of fragment.unusedExports) {
109 unusedExports.add(value);
110 }
111 }
112 }
113 }
114 return new HarmonyExportInitFragment(
115 this.exportsArgument,
116 exportMap,
117 unusedExports
118 );
119 }
120
121 /**
122 * Returns merged result.
123 * @param {HarmonyExportInitFragment} other other
124 * @returns {HarmonyExportInitFragment} merged result
125 */
126 merge(other) {
127 /** @type {ExportMap} */
128 let exportMap;
129 if (this.exportMap.size === 0) {
130 exportMap = other.exportMap;
131 } else if (other.exportMap.size === 0) {
132 exportMap = this.exportMap;
133 } else {
134 exportMap = new Map(other.exportMap);
135 for (const [key, value] of this.exportMap) {
136 if (!exportMap.has(key)) exportMap.set(key, value);
137 }
138 }
139 /** @type {UnusedExports} */
140 let unusedExports;
141 if (this.unusedExports.size === 0) {
142 unusedExports = other.unusedExports;
143 } else if (other.unusedExports.size === 0) {
144 unusedExports = this.unusedExports;
145 } else {
146 unusedExports = new Set(other.unusedExports);
147 for (const value of this.unusedExports) {
148 unusedExports.add(value);
149 }
150 }
151 return new HarmonyExportInitFragment(
152 this.exportsArgument,
153 exportMap,
154 unusedExports
155 );
156 }
157
158 /**
159 * Returns the source code that will be included as initialization code.
160 * @param {GenerateContext} context context
161 * @returns {string | Source | undefined} the source code that will be included as initialization code
162 */
163 getContent({ runtimeTemplate, runtimeRequirements }) {
164 runtimeRequirements.add(RuntimeGlobals.exports);
165 runtimeRequirements.add(RuntimeGlobals.definePropertyGetters);
166
167 const unusedPart =
168 this.unusedExports.size > 1
169 ? `/* unused harmony exports ${joinIterableWithComma(
170 this.unusedExports
171 )} */\n`
172 : this.unusedExports.size > 0
173 ? `/* unused harmony export ${first(this.unusedExports)} */\n`
174 : "";
175 /** @type {string[]} */
176 const definitions = [];
177 const orderedExportMap = [...this.exportMap].sort(([a], [b]) =>
178 a < b ? -1 : 1
179 );
180 for (const [key, value] of orderedExportMap) {
181 definitions.push(
182 `\n/* harmony export */ ${propertyName(
183 /** @type {string} */ (key)
184 )}: ${runtimeTemplate.returningFunction(value)}`
185 );
186 }
187 const definePart =
188 this.exportMap.size > 0
189 ? `/* harmony export */ ${RuntimeGlobals.definePropertyGetters}(${
190 this.exportsArgument
191 }, {${definitions.join(",")}\n/* harmony export */ });\n`
192 : "";
193 return `${definePart}${unusedPart}`;
194 }
195}
196
197module.exports = HarmonyExportInitFragment;
Note: See TracBrowser for help on using the repository browser.