source: frontend/node_modules/webpack/lib/ConcatenationScope.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: 6.7 KB
RevLine 
[9af201e]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const {
9 DEFAULT_EXPORT,
10 NAMESPACE_OBJECT_EXPORT
11} = require("./util/concatenate");
12
13/** @typedef {import("./Chunk")} Chunk */
14/** @typedef {import("./Module")} Module */
15/** @typedef {import("./optimize/ConcatenatedModule").ConcatenatedModuleInfo} ConcatenatedModuleInfo */
16/** @typedef {import("./optimize/ConcatenatedModule").ModuleInfo} ModuleInfo */
17/** @typedef {import("./optimize/ConcatenatedModule").ExportName} Ids */
18
19const MODULE_REFERENCE_REGEXP =
20 /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_directImport)?(_deferredImport)?(?:_asiSafe(\d))?__$/;
21
22/**
23 * Encodes how a concatenated module reference should be interpreted when it is
24 * later reconstructed from its placeholder identifier.
25 * @typedef {object} ModuleReferenceOptions
26 * @property {Ids} ids the properties or exports selected from the referenced module
27 * @property {boolean} call true, when this referenced export is called
28 * @property {boolean} directImport true, when this referenced export is directly imported (not via property access)
29 * @property {boolean} deferredImport true, when this referenced export is deferred
30 * @property {boolean | undefined} asiSafe if the position is ASI safe or unknown
31 */
32
33/**
34 * Tracks the symbols and cross-module references needed while rendering a
35 * concatenated module.
36 */
37class ConcatenationScope {
38 /**
39 * Creates the mutable scope object used while rendering a concatenated
40 * module and its cross-module references.
41 * @param {ModuleInfo[] | Map<Module, ModuleInfo>} modulesMap all module info by module
42 * @param {ConcatenatedModuleInfo} currentModule the current module info
43 * @param {Set<string>} usedNames all used names
44 */
45 constructor(modulesMap, currentModule, usedNames) {
46 this._currentModule = currentModule;
47 if (Array.isArray(modulesMap)) {
48 /** @type {Map<Module, ConcatenatedModuleInfo>} */
49 const map = new Map();
50 for (const info of modulesMap) {
51 map.set(info.module, /** @type {ConcatenatedModuleInfo} */ (info));
52 }
53 modulesMap = map;
54 }
55 this.usedNames = usedNames;
56 this._modulesMap = modulesMap;
57 }
58
59 /**
60 * Checks whether a module participates in the current concatenation scope.
61 * @param {Module} module the referenced module
62 * @returns {boolean} true, when it's in the scope
63 */
64 isModuleInScope(module) {
65 return this._modulesMap.has(module);
66 }
67
68 /**
69 * Records the symbol that should be used when the current module exports a
70 * named binding.
71 * @param {string} exportName name of the export
72 * @param {string} symbol identifier of the export in source code
73 */
74 registerExport(exportName, symbol) {
75 if (!this._currentModule.exportMap) {
76 this._currentModule.exportMap = new Map();
77 }
78 if (!this._currentModule.exportMap.has(exportName)) {
79 this._currentModule.exportMap.set(exportName, symbol);
80 }
81 }
82
83 /**
84 * Records a raw expression that can be used to reference an export without
85 * going through the normal symbol map.
86 * @param {string} exportName name of the export
87 * @param {string} expression expression to be used
88 */
89 registerRawExport(exportName, expression) {
90 if (!this._currentModule.rawExportMap) {
91 this._currentModule.rawExportMap = new Map();
92 }
93 if (!this._currentModule.rawExportMap.has(exportName)) {
94 this._currentModule.rawExportMap.set(exportName, expression);
95 }
96 }
97
98 /**
99 * Returns the raw expression registered for an export, if one exists.
100 * @param {string} exportName name of the export
101 * @returns {string | undefined} the expression of the export
102 */
103 getRawExport(exportName) {
104 if (!this._currentModule.rawExportMap) {
105 return undefined;
106 }
107 return this._currentModule.rawExportMap.get(exportName);
108 }
109
110 /**
111 * Replaces the raw expression for an export only when that export already
112 * has an entry in the raw export map.
113 * @param {string} exportName name of the export
114 * @param {string} expression expression to be used
115 */
116 setRawExportMap(exportName, expression) {
117 if (!this._currentModule.rawExportMap) {
118 this._currentModule.rawExportMap = new Map();
119 }
120 if (this._currentModule.rawExportMap.has(exportName)) {
121 this._currentModule.rawExportMap.set(exportName, expression);
122 }
123 }
124
125 /**
126 * Records the symbol that should be used for the synthetic namespace export.
127 * @param {string} symbol identifier of the export in source code
128 */
129 registerNamespaceExport(symbol) {
130 this._currentModule.namespaceExportSymbol = symbol;
131 }
132
133 /**
134 * Encodes a reference to another concatenated module as a placeholder
135 * identifier that can be parsed later during code generation.
136 * @param {Module} module the referenced module
137 * @param {Partial<ModuleReferenceOptions>} options options
138 * @returns {string} the reference as identifier
139 */
140 createModuleReference(
141 module,
142 {
143 ids = undefined,
144 call = false,
145 directImport = false,
146 deferredImport = false,
147 asiSafe = false
148 }
149 ) {
150 const info = /** @type {ModuleInfo} */ (this._modulesMap.get(module));
151 const callFlag = call ? "_call" : "";
152 const directImportFlag = directImport ? "_directImport" : "";
153 const deferredImportFlag = deferredImport ? "_deferredImport" : "";
154 const asiSafeFlag = asiSafe
155 ? "_asiSafe1"
156 : asiSafe === false
157 ? "_asiSafe0"
158 : "";
159 const exportData = ids
160 ? Buffer.from(JSON.stringify(ids), "utf8").toString("hex")
161 : "ns";
162 // a "._" is appended to allow "delete ...", which would cause a SyntaxError in strict mode
163 return `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportData}${callFlag}${directImportFlag}${deferredImportFlag}${asiSafeFlag}__._`;
164 }
165
166 /**
167 * Checks whether an identifier is one of webpack's encoded concatenation
168 * module references.
169 * @param {string} name the identifier
170 * @returns {boolean} true, when it's an module reference
171 */
172 static isModuleReference(name) {
173 return MODULE_REFERENCE_REGEXP.test(name);
174 }
175
176 /**
177 * Parses an encoded module reference back into its module index and
178 * reference flags.
179 * @param {string} name the identifier
180 * @returns {ModuleReferenceOptions & { index: number } | null} parsed options and index
181 */
182 static matchModuleReference(name) {
183 const match = MODULE_REFERENCE_REGEXP.exec(name);
184 if (!match) return null;
185 const index = Number(match[1]);
186 const asiSafe = match[6];
187 return {
188 index,
189 ids:
190 match[2] === "ns"
191 ? []
192 : JSON.parse(Buffer.from(match[2], "hex").toString("utf8")),
193 call: Boolean(match[3]),
194 directImport: Boolean(match[4]),
195 deferredImport: Boolean(match[5]),
196 asiSafe: asiSafe ? asiSafe === "1" : undefined
197 };
198 }
199}
200
201ConcatenationScope.DEFAULT_EXPORT = DEFAULT_EXPORT;
202ConcatenationScope.NAMESPACE_OBJECT_EXPORT = NAMESPACE_OBJECT_EXPORT;
203
204module.exports = ConcatenationScope;
Note: See TracBrowser for help on using the repository browser.