UI for Zipcoin Blue

HarmonyExportImportedSpecifierDependency.js 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const NullDependency = require("./NullDependency");
  7. class HarmonyExportImportedSpecifierDependency extends NullDependency {
  8. constructor(originModule, importDependency, importedVar, id, name, activeExports, otherStarExports) {
  9. super();
  10. this.originModule = originModule;
  11. this.importDependency = importDependency;
  12. this.importedVar = importedVar;
  13. this.id = id;
  14. this.name = name;
  15. this.activeExports = activeExports;
  16. this.otherStarExports = otherStarExports;
  17. }
  18. get type() {
  19. return "harmony export imported specifier";
  20. }
  21. getReference() {
  22. const name = this.name;
  23. const used = this.originModule.isUsed(name);
  24. const importedModule = this.importDependency.module;
  25. if(!importedModule || !used || !this.originModule.usedExports) return null;
  26. const hasUsedExports = Array.isArray(this.originModule.usedExports);
  27. if(name) {
  28. const nameIsNotInUsedExports = hasUsedExports && this.originModule.usedExports.indexOf(name) < 0;
  29. if(nameIsNotInUsedExports) return null;
  30. // export { name as name }
  31. if(this.id) {
  32. return {
  33. module: importedModule,
  34. importedNames: [this.id]
  35. };
  36. }
  37. // export { * as name }
  38. return {
  39. module: importedModule,
  40. importedNames: true
  41. };
  42. }
  43. const hasProvidedExports = Array.isArray(importedModule.providedExports);
  44. const activeFromOtherStarExports = this._discoverActiveExportsFromOtherStartExports();
  45. // export *
  46. if(hasUsedExports) {
  47. // reexport * with known used exports
  48. const importedNames = this.originModule.usedExports.filter(id => {
  49. if(id === "default") return false;
  50. if(this.activeExports.has(id)) return false;
  51. if(activeFromOtherStarExports.has(id)) return false;
  52. if(hasProvidedExports && importedModule.providedExports.indexOf(id) < 0) return false;
  53. return true;
  54. });
  55. return {
  56. module: importedModule,
  57. importedNames
  58. };
  59. }
  60. if(hasProvidedExports) {
  61. return {
  62. module: importedModule,
  63. importedNames: importedModule.providedExports.filter(id => {
  64. if(id === "default") return false;
  65. if(this.activeExports.has(id)) return false;
  66. if(activeFromOtherStarExports.has(id)) return false;
  67. return true;
  68. })
  69. };
  70. }
  71. return {
  72. module: importedModule,
  73. importedNames: true,
  74. };
  75. }
  76. _discoverActiveExportsFromOtherStartExports() {
  77. if(!this.otherStarExports)
  78. return new Set();
  79. const result = new Set();
  80. // try to learn impossible exports from other star exports with provided exports
  81. for(const otherStarExport of this.otherStarExports) {
  82. const otherImportedModule = otherStarExport.importDependency.module;
  83. if(otherImportedModule && Array.isArray(otherImportedModule.providedExports)) {
  84. for(const exportName of otherImportedModule.providedExports)
  85. result.add(exportName);
  86. }
  87. }
  88. return result;
  89. }
  90. getExports() {
  91. if(this.name) {
  92. return {
  93. exports: [this.name]
  94. };
  95. }
  96. const importedModule = this.importDependency.module;
  97. if(!importedModule) {
  98. // no imported module available
  99. return {
  100. exports: null
  101. };
  102. }
  103. if(Array.isArray(importedModule.providedExports)) {
  104. return {
  105. exports: importedModule.providedExports.filter(id => id !== "default"),
  106. dependencies: [importedModule]
  107. };
  108. }
  109. if(importedModule.providedExports) {
  110. return {
  111. exports: true
  112. };
  113. }
  114. return {
  115. exports: null,
  116. dependencies: [importedModule]
  117. };
  118. }
  119. updateHash(hash) {
  120. super.updateHash(hash);
  121. const hashValue = this.getHashValue(this.importDependency.module);
  122. hash.update(hashValue);
  123. }
  124. getHashValue(importedModule) {
  125. if(!importedModule) {
  126. return "";
  127. }
  128. const stringifiedUsedExport = JSON.stringify(importedModule.usedExports);
  129. const stringifiedProvidedExport = JSON.stringify(importedModule.providedExports);
  130. return importedModule.used + stringifiedUsedExport + stringifiedProvidedExport;
  131. }
  132. }
  133. module.exports = HarmonyExportImportedSpecifierDependency;
  134. HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate {
  135. apply(dep, source, outputOptions, requestShortener) {
  136. const content = this.getContent(dep);
  137. source.insert(-1, content);
  138. }
  139. getContent(dep) {
  140. const name = dep.importedVar;
  141. const used = dep.originModule.isUsed(dep.name);
  142. const importedModule = dep.importDependency.module;
  143. const importsExportsUnknown = !importedModule || !Array.isArray(importedModule.providedExports);
  144. const getReexportStatement = this.reexportStatementCreator(dep.originModule, importsExportsUnknown, name);
  145. // we want to rexport something, but the export isn't used
  146. if(!used) {
  147. return "/* unused harmony reexport " + dep.name + " */\n";
  148. }
  149. // we want to reexport the default export from a non-hamory module
  150. const isNotAHarmonyModule = !(importedModule && (!importedModule.meta || importedModule.meta.harmonyModule));
  151. if(dep.name && dep.id === "default" && isNotAHarmonyModule) {
  152. return "/* harmony reexport (default from non-hamory) */ " + getReexportStatement(JSON.stringify(used), null);
  153. }
  154. // we want to reexport a key as new key
  155. if(dep.name && dep.id) {
  156. var idUsed = importedModule && importedModule.isUsed(dep.id);
  157. return "/* harmony reexport (binding) */ " + getReexportStatement(JSON.stringify(used), JSON.stringify(idUsed));
  158. }
  159. // we want to reexport the module object as named export
  160. if(dep.name) {
  161. return "/* harmony reexport (module object) */ " + getReexportStatement(JSON.stringify(used), "");
  162. }
  163. const hasProvidedExports = importedModule && Array.isArray(importedModule.providedExports);
  164. const activeFromOtherStarExports = dep._discoverActiveExportsFromOtherStartExports();
  165. // we know which exports are used
  166. if(Array.isArray(dep.originModule.usedExports)) {
  167. const items = dep.originModule.usedExports.map(id => {
  168. if(id === "default") return;
  169. if(dep.activeExports.has(id)) return;
  170. if(importedModule.isProvided(id) === false) return;
  171. if(activeFromOtherStarExports.has(id)) return;
  172. var exportUsed = dep.originModule.isUsed(id);
  173. var idUsed = importedModule && importedModule.isUsed(id);
  174. return [exportUsed, idUsed];
  175. }).filter(Boolean);
  176. if(items.length === 0) {
  177. return "/* unused harmony namespace reexport */\n";
  178. }
  179. return items.map(function(item) {
  180. return "/* harmony namespace reexport (by used) */ " + getReexportStatement(JSON.stringify(item[0]), JSON.stringify(item[1]));
  181. }).join("");
  182. }
  183. // not sure which exports are used, but we know which are provided
  184. if(dep.originModule.usedExports && importedModule && hasProvidedExports) {
  185. const items = importedModule.providedExports.map(id => {
  186. if(id === "default") return;
  187. if(dep.activeExports.has(id)) return;
  188. if(activeFromOtherStarExports.has(id)) return;
  189. var exportUsed = dep.originModule.isUsed(id);
  190. var idUsed = importedModule && importedModule.isUsed(id);
  191. return [exportUsed, idUsed];
  192. }).filter(Boolean);
  193. if(items.length === 0) {
  194. return "/* empty harmony namespace reexport */\n";
  195. }
  196. return items.map(function(item) {
  197. return "/* harmony namespace reexport (by provided) */ " + getReexportStatement(JSON.stringify(item[0]), JSON.stringify(item[1]));
  198. }).join("");
  199. }
  200. // not sure which exports are used and provided
  201. if(dep.originModule.usedExports) {
  202. const activeExports = Array.from(dep.activeExports).concat(Array.from(activeFromOtherStarExports));
  203. let content = "/* harmony namespace reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in " + name + ") ";
  204. // Filter out exports which are defined by other exports
  205. // and filter out default export because it cannot be reexported with *
  206. if(activeExports.length > 0)
  207. content += "if(" + JSON.stringify(activeExports.concat("default")) + ".indexOf(__WEBPACK_IMPORT_KEY__) < 0) ";
  208. else
  209. content += "if(__WEBPACK_IMPORT_KEY__ !== 'default') ";
  210. const exportsName = dep.originModule.exportsArgument || "exports";
  211. return content + `(function(key) { __webpack_require__.d(${exportsName}, key, function() { return ${name}[key]; }) }(__WEBPACK_IMPORT_KEY__));\n`;
  212. }
  213. return "/* unused harmony reexport namespace */\n";
  214. }
  215. reexportStatementCreator(module, importsExportsUnknown, name) {
  216. const exportsName = module.exportsArgument || "exports";
  217. const getReexportStatement = (key, valueKey) => {
  218. const conditional = this.getConditional(importsExportsUnknown, valueKey, name);
  219. const returnValue = this.getReturnValue(valueKey);
  220. return `${conditional}__webpack_require__.d(${exportsName}, ${key}, function() { return ${name}${returnValue}; });\n`;
  221. };
  222. return getReexportStatement;
  223. }
  224. getConditional(importsExportsUnknown, valueKey, name) {
  225. if(!importsExportsUnknown || !valueKey) {
  226. return "";
  227. }
  228. return `if(__webpack_require__.o(${name}, ${valueKey})) `;
  229. }
  230. getReturnValue(valueKey) {
  231. if(valueKey === null) {
  232. return "_default.a";
  233. }
  234. return valueKey && "[" + valueKey + "]";
  235. }
  236. };