[6a3a178] | 1 | /*
|
---|
| 2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
| 3 | Author Tobias Koppers @sokra
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | "use strict";
|
---|
| 7 |
|
---|
| 8 | /** @typedef {import("./Module")} Module */
|
---|
| 9 |
|
---|
| 10 | const MODULE_REFERENCE_REGEXP =
|
---|
| 11 | /^__WEBPACK_MODULE_REFERENCE__(\d+)_([\da-f]+|ns)(_call)?(_directImport)?(?:_asiSafe(\d))?__$/;
|
---|
| 12 |
|
---|
| 13 | const DEFAULT_EXPORT = "__WEBPACK_DEFAULT_EXPORT__";
|
---|
| 14 | const NAMESPACE_OBJECT_EXPORT = "__WEBPACK_NAMESPACE_OBJECT__";
|
---|
| 15 |
|
---|
| 16 | /**
|
---|
| 17 | * @typedef {Object} ExternalModuleInfo
|
---|
| 18 | * @property {number} index
|
---|
| 19 | * @property {Module} module
|
---|
| 20 | */
|
---|
| 21 |
|
---|
| 22 | /**
|
---|
| 23 | * @typedef {Object} ConcatenatedModuleInfo
|
---|
| 24 | * @property {number} index
|
---|
| 25 | * @property {Module} module
|
---|
| 26 | * @property {Map<string, string>} exportMap mapping from export name to symbol
|
---|
| 27 | * @property {Map<string, string>} rawExportMap mapping from export name to symbol
|
---|
| 28 | * @property {string=} namespaceExportSymbol
|
---|
| 29 | */
|
---|
| 30 |
|
---|
| 31 | /** @typedef {ConcatenatedModuleInfo | ExternalModuleInfo} ModuleInfo */
|
---|
| 32 |
|
---|
| 33 | /**
|
---|
| 34 | * @typedef {Object} ModuleReferenceOptions
|
---|
| 35 | * @property {string[]} ids the properties/exports of the module
|
---|
| 36 | * @property {boolean} call true, when this referenced export is called
|
---|
| 37 | * @property {boolean} directImport true, when this referenced export is directly imported (not via property access)
|
---|
| 38 | * @property {boolean | undefined} asiSafe if the position is ASI safe or unknown
|
---|
| 39 | */
|
---|
| 40 |
|
---|
| 41 | class ConcatenationScope {
|
---|
| 42 | /**
|
---|
| 43 | * @param {ModuleInfo[] | Map<Module, ModuleInfo>} modulesMap all module info by module
|
---|
| 44 | * @param {ConcatenatedModuleInfo} currentModule the current module info
|
---|
| 45 | */
|
---|
| 46 | constructor(modulesMap, currentModule) {
|
---|
| 47 | this._currentModule = currentModule;
|
---|
| 48 | if (Array.isArray(modulesMap)) {
|
---|
| 49 | const map = new Map();
|
---|
| 50 | for (const info of modulesMap) {
|
---|
| 51 | map.set(info.module, info);
|
---|
| 52 | }
|
---|
| 53 | modulesMap = map;
|
---|
| 54 | }
|
---|
| 55 | this._modulesMap = modulesMap;
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | /**
|
---|
| 59 | * @param {Module} module the referenced module
|
---|
| 60 | * @returns {boolean} true, when it's in the scope
|
---|
| 61 | */
|
---|
| 62 | isModuleInScope(module) {
|
---|
| 63 | return this._modulesMap.has(module);
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | /**
|
---|
| 67 | *
|
---|
| 68 | * @param {string} exportName name of the export
|
---|
| 69 | * @param {string} symbol identifier of the export in source code
|
---|
| 70 | */
|
---|
| 71 | registerExport(exportName, symbol) {
|
---|
| 72 | if (!this._currentModule.exportMap) {
|
---|
| 73 | this._currentModule.exportMap = new Map();
|
---|
| 74 | }
|
---|
| 75 | if (!this._currentModule.exportMap.has(exportName)) {
|
---|
| 76 | this._currentModule.exportMap.set(exportName, symbol);
|
---|
| 77 | }
|
---|
| 78 | }
|
---|
| 79 |
|
---|
| 80 | /**
|
---|
| 81 | *
|
---|
| 82 | * @param {string} exportName name of the export
|
---|
| 83 | * @param {string} expression expression to be used
|
---|
| 84 | */
|
---|
| 85 | registerRawExport(exportName, expression) {
|
---|
| 86 | if (!this._currentModule.rawExportMap) {
|
---|
| 87 | this._currentModule.rawExportMap = new Map();
|
---|
| 88 | }
|
---|
| 89 | if (!this._currentModule.rawExportMap.has(exportName)) {
|
---|
| 90 | this._currentModule.rawExportMap.set(exportName, expression);
|
---|
| 91 | }
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | /**
|
---|
| 95 | * @param {string} symbol identifier of the export in source code
|
---|
| 96 | */
|
---|
| 97 | registerNamespaceExport(symbol) {
|
---|
| 98 | this._currentModule.namespaceExportSymbol = symbol;
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | /**
|
---|
| 102 | *
|
---|
| 103 | * @param {Module} module the referenced module
|
---|
| 104 | * @param {Partial<ModuleReferenceOptions>} options options
|
---|
| 105 | * @returns {string} the reference as identifier
|
---|
| 106 | */
|
---|
| 107 | createModuleReference(
|
---|
| 108 | module,
|
---|
| 109 | { ids = undefined, call = false, directImport = false, asiSafe = false }
|
---|
| 110 | ) {
|
---|
| 111 | const info = this._modulesMap.get(module);
|
---|
| 112 | const callFlag = call ? "_call" : "";
|
---|
| 113 | const directImportFlag = directImport ? "_directImport" : "";
|
---|
| 114 | const asiSafeFlag = asiSafe
|
---|
| 115 | ? "_asiSafe1"
|
---|
| 116 | : asiSafe === false
|
---|
| 117 | ? "_asiSafe0"
|
---|
| 118 | : "";
|
---|
| 119 | const exportData = ids
|
---|
| 120 | ? Buffer.from(JSON.stringify(ids), "utf-8").toString("hex")
|
---|
| 121 | : "ns";
|
---|
| 122 | // a "._" is appended to allow "delete ...", which would cause a SyntaxError in strict mode
|
---|
| 123 | return `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportData}${callFlag}${directImportFlag}${asiSafeFlag}__._`;
|
---|
| 124 | }
|
---|
| 125 |
|
---|
| 126 | /**
|
---|
| 127 | * @param {string} name the identifier
|
---|
| 128 | * @returns {boolean} true, when it's an module reference
|
---|
| 129 | */
|
---|
| 130 | static isModuleReference(name) {
|
---|
| 131 | return MODULE_REFERENCE_REGEXP.test(name);
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | /**
|
---|
| 135 | * @param {string} name the identifier
|
---|
| 136 | * @returns {ModuleReferenceOptions & { index: number }} parsed options and index
|
---|
| 137 | */
|
---|
| 138 | static matchModuleReference(name) {
|
---|
| 139 | const match = MODULE_REFERENCE_REGEXP.exec(name);
|
---|
| 140 | if (!match) return null;
|
---|
| 141 | const index = +match[1];
|
---|
| 142 | const asiSafe = match[5];
|
---|
| 143 | return {
|
---|
| 144 | index,
|
---|
| 145 | ids:
|
---|
| 146 | match[2] === "ns"
|
---|
| 147 | ? []
|
---|
| 148 | : JSON.parse(Buffer.from(match[2], "hex").toString("utf-8")),
|
---|
| 149 | call: !!match[3],
|
---|
| 150 | directImport: !!match[4],
|
---|
| 151 | asiSafe: asiSafe ? asiSafe === "1" : undefined
|
---|
| 152 | };
|
---|
| 153 | }
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | ConcatenationScope.DEFAULT_EXPORT = DEFAULT_EXPORT;
|
---|
| 157 | ConcatenationScope.NAMESPACE_OBJECT_EXPORT = NAMESPACE_OBJECT_EXPORT;
|
---|
| 158 |
|
---|
| 159 | module.exports = ConcatenationScope;
|
---|