TransformGeneratorPlugin.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. const relateContext = require('./util/relate-context');
  2. const pluginCompat = require('./util/plugin-compat');
  3. const GeneratorSchemas4 = [
  4. ['ByTypeGenerator', 'map'],
  5. ['JavascriptGenerator'],
  6. ['JsonGenerator'],
  7. ['WebAssemblyGenerator'],
  8. ['WebAssemblyJavascriptGenerator'],
  9. ];
  10. try {
  11. try {
  12. GeneratorSchemas4[0].Generator = require('webpack/lib/Generator').byType(
  13. {},
  14. ).constructor;
  15. } catch (_) {}
  16. GeneratorSchemas4[1].Generator = require('webpack/lib/JavascriptGenerator');
  17. GeneratorSchemas4[2].Generator = require('webpack/lib/JsonGenerator');
  18. try {
  19. GeneratorSchemas4[3].Generator = require('webpack/lib/WebAssemblyGenerator');
  20. } catch (_) {
  21. GeneratorSchemas4[3].Generator = require('webpack/lib/wasm/WebAssemblyGenerator');
  22. }
  23. try {
  24. GeneratorSchemas4[4].Generator = require('webpack/lib/wasm/WebAssemblyJavascriptGenerator');
  25. } catch (_) {}
  26. } catch (_) {}
  27. const freezeArgument = {
  28. map(arg, generator, extra, methods) {
  29. const map = {};
  30. for (const key in arg) {
  31. map[key] = methods.freeze('Generator', null, arg[key], extra);
  32. }
  33. return map;
  34. },
  35. };
  36. const thawArgument = {
  37. map(arg, generator, extra, methods) {
  38. const map = {};
  39. for (const key in arg) {
  40. map[key] = methods.thaw('Generator', null, arg[key], extra);
  41. }
  42. return map;
  43. },
  44. };
  45. function freezeGenerator(generator, extra, methods) {
  46. const schemas = extra.schemas;
  47. for (let i = 0; i < schemas.length; i++) {
  48. if (generator.constructor === schemas[i].Generator) {
  49. const frozen = {
  50. type: schemas[i][0],
  51. };
  52. for (let j = 1; j < schemas[i].length; j++) {
  53. let arg = generator[schemas[i][j]];
  54. if (freezeArgument[schemas[i][j]]) {
  55. arg = freezeArgument[schemas[i][j]](arg, generator, extra, methods);
  56. }
  57. frozen[schemas[i][j]] = arg;
  58. }
  59. return frozen;
  60. }
  61. }
  62. }
  63. function thawGenerator(frozen, extra, methods) {
  64. const schemas = extra.schemas;
  65. for (let i = 0; i < schemas.length; i++) {
  66. if (frozen.type === schemas[i][0]) {
  67. const Generator = schemas[i].Generator;
  68. const args = [];
  69. for (let j = 1; j < schemas[i].length; j++) {
  70. let arg = frozen[schemas[i][j]];
  71. if (thawArgument[schemas[i][j]]) {
  72. arg = thawArgument[schemas[i][j]](arg, frozen, extra, methods);
  73. }
  74. args.push(arg);
  75. }
  76. try {
  77. return new Generator(...args);
  78. } catch (_) {
  79. return new (Function.prototype.bind.apply(
  80. Generator,
  81. [null].concat(args),
  82. ))();
  83. }
  84. }
  85. }
  86. }
  87. class TransformGeneratorPlugin {
  88. apply(compiler) {
  89. pluginCompat.register(
  90. compiler,
  91. '_hardSourceBeforeFreezeGenerator',
  92. 'syncWaterfall',
  93. ['frozen', 'item', 'extra'],
  94. );
  95. pluginCompat.register(
  96. compiler,
  97. '_hardSourceFreezeGenerator',
  98. 'syncWaterfall',
  99. ['frozen', 'item', 'extra'],
  100. );
  101. pluginCompat.register(
  102. compiler,
  103. '_hardSourceAfterFreezeGenerator',
  104. 'syncWaterfall',
  105. ['frozen', 'item', 'extra'],
  106. );
  107. pluginCompat.register(
  108. compiler,
  109. '_hardSourceBeforeThawGenerator',
  110. 'syncWaterfall',
  111. ['item', 'frozen', 'extra'],
  112. );
  113. pluginCompat.register(
  114. compiler,
  115. '_hardSourceThawGenerator',
  116. 'syncWaterfall',
  117. ['item', 'frozen', 'extra'],
  118. );
  119. pluginCompat.register(
  120. compiler,
  121. '_hardSourceAfterThawGenerator',
  122. 'syncWaterfall',
  123. ['item', 'frozen', 'extra'],
  124. );
  125. let methods;
  126. pluginCompat.tap(
  127. compiler,
  128. '_hardSourceMethods',
  129. 'TransformGeneratorPlugin',
  130. _methods => {
  131. methods = _methods;
  132. },
  133. );
  134. pluginCompat.tap(
  135. compiler,
  136. '_hardSourceFreezeGenerator',
  137. 'TransformGeneratorPlugin freeze',
  138. (frozen, generator, extra) => {
  139. extra.schemas = GeneratorSchemas4;
  140. frozen = freezeGenerator(generator, extra, methods);
  141. frozen.moduleType = extra.module.type;
  142. frozen.options = {};
  143. return frozen;
  144. },
  145. );
  146. pluginCompat.tap(
  147. compiler,
  148. '_hardSourceThawGenerator',
  149. 'TransformGeneratorPlugin thaw',
  150. (generator, { moduleType, options }, { normalModuleFactory }) => {
  151. return normalModuleFactory.getGenerator(moduleType, options);
  152. },
  153. );
  154. }
  155. }
  156. module.exports = TransformGeneratorPlugin;