Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

157 строки
4.5 KiB

  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { getOrInsert } = require("./util/MapHelpers");
  7. const { first } = require("./util/SetHelpers");
  8. const createHash = require("./util/createHash");
  9. const { runtimeToString, RuntimeSpecMap } = require("./util/runtime");
  10. /** @typedef {import("webpack-sources").Source} Source */
  11. /** @typedef {import("./Module")} Module */
  12. /** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
  13. /** @typedef {typeof import("./util/Hash")} Hash */
  14. /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
  15. class CodeGenerationResults {
  16. /**
  17. * @param {string | Hash} hashFunction the hash function to use
  18. */
  19. constructor(hashFunction = "md4") {
  20. /** @type {Map<Module, RuntimeSpecMap<CodeGenerationResult>>} */
  21. this.map = new Map();
  22. this._hashFunction = hashFunction;
  23. }
  24. /**
  25. * @param {Module} module the module
  26. * @param {RuntimeSpec} runtime runtime(s)
  27. * @returns {CodeGenerationResult} the CodeGenerationResult
  28. */
  29. get(module, runtime) {
  30. const entry = this.map.get(module);
  31. if (entry === undefined) {
  32. throw new Error(
  33. `No code generation entry for ${module.identifier()} (existing entries: ${Array.from(
  34. this.map.keys(),
  35. m => m.identifier()
  36. ).join(", ")})`
  37. );
  38. }
  39. if (runtime === undefined) {
  40. if (
  41. /** @type {RuntimeSpecMap<CodeGenerationResult>} */ (entry).size > 1
  42. ) {
  43. const results = new Set(entry.values());
  44. if (results.size !== 1) {
  45. throw new Error(
  46. `No unique code generation entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from(
  47. entry.keys(),
  48. r => runtimeToString(r)
  49. ).join(", ")}).
  50. Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
  51. );
  52. }
  53. return /** @type {CodeGenerationResult} */ (first(results));
  54. }
  55. return /** @type {CodeGenerationResult} */ (entry.values().next().value);
  56. }
  57. const result = entry.get(runtime);
  58. if (result === undefined) {
  59. throw new Error(
  60. `No code generation entry for runtime ${runtimeToString(
  61. runtime
  62. )} for ${module.identifier()} (existing runtimes: ${Array.from(
  63. entry.keys(),
  64. r => runtimeToString(r)
  65. ).join(", ")})`
  66. );
  67. }
  68. return result;
  69. }
  70. /**
  71. * @param {Module} module the module
  72. * @param {RuntimeSpec} runtime runtime(s)
  73. * @returns {boolean} true, when we have data for this
  74. */
  75. has(module, runtime) {
  76. const entry = this.map.get(module);
  77. if (entry === undefined) {
  78. return false;
  79. }
  80. if (runtime !== undefined) {
  81. return entry.has(runtime);
  82. } else if (entry.size > 1) {
  83. const results = new Set(entry.values());
  84. return results.size === 1;
  85. }
  86. return entry.size === 1;
  87. }
  88. /**
  89. * @param {Module} module the module
  90. * @param {RuntimeSpec} runtime runtime(s)
  91. * @param {string} sourceType the source type
  92. * @returns {Source} a source
  93. */
  94. getSource(module, runtime, sourceType) {
  95. return this.get(module, runtime).sources.get(sourceType);
  96. }
  97. /**
  98. * @param {Module} module the module
  99. * @param {RuntimeSpec} runtime runtime(s)
  100. * @returns {ReadonlySet<string>} runtime requirements
  101. */
  102. getRuntimeRequirements(module, runtime) {
  103. return this.get(module, runtime).runtimeRequirements;
  104. }
  105. /**
  106. * @param {Module} module the module
  107. * @param {RuntimeSpec} runtime runtime(s)
  108. * @param {string} key data key
  109. * @returns {any} data generated by code generation
  110. */
  111. getData(module, runtime, key) {
  112. const data = this.get(module, runtime).data;
  113. return data === undefined ? undefined : data.get(key);
  114. }
  115. /**
  116. * @param {Module} module the module
  117. * @param {RuntimeSpec} runtime runtime(s)
  118. * @returns {any} hash of the code generation
  119. */
  120. getHash(module, runtime) {
  121. const info = this.get(module, runtime);
  122. if (info.hash !== undefined) return info.hash;
  123. const hash = createHash(this._hashFunction);
  124. for (const [type, source] of info.sources) {
  125. hash.update(type);
  126. source.updateHash(hash);
  127. }
  128. if (info.runtimeRequirements) {
  129. for (const rr of info.runtimeRequirements) hash.update(rr);
  130. }
  131. return (info.hash = /** @type {string} */ (hash.digest("hex")));
  132. }
  133. /**
  134. * @param {Module} module the module
  135. * @param {RuntimeSpec} runtime runtime(s)
  136. * @param {CodeGenerationResult} result result from module
  137. * @returns {void}
  138. */
  139. add(module, runtime, result) {
  140. const map = getOrInsert(this.map, module, () => new RuntimeSpecMap());
  141. map.set(runtime, result);
  142. }
  143. }
  144. module.exports = CodeGenerationResults;