You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.6 KiB

4 years ago
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
  7. const HarmonyInitDependency = require("./HarmonyInitDependency");
  8. module.exports = class HarmonyDetectionParserPlugin {
  9. apply(parser) {
  10. parser.hooks.program.tap("HarmonyDetectionParserPlugin", ast => {
  11. const isStrictHarmony = parser.state.module.type === "javascript/esm";
  12. const isHarmony =
  13. isStrictHarmony ||
  14. ast.body.some(
  15. statement =>
  16. statement.type === "ImportDeclaration" ||
  17. statement.type === "ExportDefaultDeclaration" ||
  18. statement.type === "ExportNamedDeclaration" ||
  19. statement.type === "ExportAllDeclaration"
  20. );
  21. if (isHarmony) {
  22. const module = parser.state.module;
  23. const compatDep = new HarmonyCompatibilityDependency(module);
  24. compatDep.loc = {
  25. start: {
  26. line: -1,
  27. column: 0
  28. },
  29. end: {
  30. line: -1,
  31. column: 0
  32. },
  33. index: -3
  34. };
  35. module.addDependency(compatDep);
  36. const initDep = new HarmonyInitDependency(module);
  37. initDep.loc = {
  38. start: {
  39. line: -1,
  40. column: 0
  41. },
  42. end: {
  43. line: -1,
  44. column: 0
  45. },
  46. index: -2
  47. };
  48. module.addDependency(initDep);
  49. parser.state.harmonyParserScope = parser.state.harmonyParserScope || {};
  50. parser.scope.isStrict = true;
  51. module.buildMeta.exportsType = "namespace";
  52. module.buildInfo.strict = true;
  53. module.buildInfo.exportsArgument = "__webpack_exports__";
  54. if (isStrictHarmony) {
  55. module.buildMeta.strictHarmonyModule = true;
  56. module.buildInfo.moduleArgument = "__webpack_module__";
  57. }
  58. }
  59. });
  60. const skipInHarmony = () => {
  61. const module = parser.state.module;
  62. if (module && module.buildMeta && module.buildMeta.exportsType) {
  63. return true;
  64. }
  65. };
  66. const nullInHarmony = () => {
  67. const module = parser.state.module;
  68. if (module && module.buildMeta && module.buildMeta.exportsType) {
  69. return null;
  70. }
  71. };
  72. const nonHarmonyIdentifiers = ["define", "exports"];
  73. for (const identifer of nonHarmonyIdentifiers) {
  74. parser.hooks.evaluateTypeof
  75. .for(identifer)
  76. .tap("HarmonyDetectionParserPlugin", nullInHarmony);
  77. parser.hooks.typeof
  78. .for(identifer)
  79. .tap("HarmonyDetectionParserPlugin", skipInHarmony);
  80. parser.hooks.evaluate
  81. .for(identifer)
  82. .tap("HarmonyDetectionParserPlugin", nullInHarmony);
  83. parser.hooks.expression
  84. .for(identifer)
  85. .tap("HarmonyDetectionParserPlugin", skipInHarmony);
  86. parser.hooks.call
  87. .for(identifer)
  88. .tap("HarmonyDetectionParserPlugin", skipInHarmony);
  89. }
  90. }
  91. };