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.

163 lines
3.9 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 DependencyReference = require("./DependencyReference");
  7. const HarmonyImportDependency = require("./HarmonyImportDependency");
  8. const HarmonyLinkingError = require("../HarmonyLinkingError");
  9. class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
  10. constructor(
  11. request,
  12. originModule,
  13. sourceOrder,
  14. parserScope,
  15. id,
  16. name,
  17. range,
  18. strictExportPresence
  19. ) {
  20. super(request, originModule, sourceOrder, parserScope);
  21. this.id = id === null ? null : `${id}`;
  22. this.redirectedId = undefined;
  23. this.name = name;
  24. this.range = range;
  25. this.strictExportPresence = strictExportPresence;
  26. this.namespaceObjectAsContext = false;
  27. this.callArgs = undefined;
  28. this.call = undefined;
  29. this.directImport = undefined;
  30. this.shorthand = undefined;
  31. }
  32. get type() {
  33. return "harmony import specifier";
  34. }
  35. get _id() {
  36. return this.redirectedId || this.id;
  37. }
  38. getReference() {
  39. if (!this._module) return null;
  40. return new DependencyReference(
  41. this._module,
  42. this._id && !this.namespaceObjectAsContext ? [this._id] : true,
  43. false,
  44. this.sourceOrder
  45. );
  46. }
  47. getWarnings() {
  48. if (
  49. this.strictExportPresence ||
  50. this.originModule.buildMeta.strictHarmonyModule
  51. ) {
  52. return [];
  53. }
  54. return this._getErrors();
  55. }
  56. getErrors() {
  57. if (
  58. this.strictExportPresence ||
  59. this.originModule.buildMeta.strictHarmonyModule
  60. ) {
  61. return this._getErrors();
  62. }
  63. return [];
  64. }
  65. _getErrors() {
  66. const importedModule = this._module;
  67. if (!importedModule) {
  68. return;
  69. }
  70. if (!importedModule.buildMeta || !importedModule.buildMeta.exportsType) {
  71. // It's not an harmony module
  72. if (
  73. this.originModule.buildMeta.strictHarmonyModule &&
  74. this._id &&
  75. this._id !== "default"
  76. ) {
  77. // In strict harmony modules we only support the default export
  78. return [
  79. new HarmonyLinkingError(
  80. `Can't import the named export '${this._id}' from non EcmaScript module (only default export is available)`
  81. )
  82. ];
  83. }
  84. return;
  85. }
  86. if (!this._id) {
  87. return;
  88. }
  89. if (importedModule.isProvided(this._id) !== false) {
  90. // It's provided or we are not sure
  91. return;
  92. }
  93. // We are sure that it's not provided
  94. const idIsNotNameMessage =
  95. this._id !== this.name ? ` (imported as '${this.name}')` : "";
  96. const errorMessage = `"export '${this._id}'${idIsNotNameMessage} was not found in '${this.userRequest}'`;
  97. return [new HarmonyLinkingError(errorMessage)];
  98. }
  99. // implement this method to allow the occurrence order plugin to count correctly
  100. getNumberOfIdOccurrences() {
  101. return 0;
  102. }
  103. updateHash(hash) {
  104. super.updateHash(hash);
  105. const importedModule = this._module;
  106. hash.update((importedModule && this._id) + "");
  107. hash.update(
  108. (importedModule && this._id && importedModule.isUsed(this._id)) + ""
  109. );
  110. hash.update(
  111. (importedModule &&
  112. (!importedModule.buildMeta || importedModule.buildMeta.exportsType)) +
  113. ""
  114. );
  115. hash.update(
  116. (importedModule &&
  117. importedModule.used + JSON.stringify(importedModule.usedExports)) + ""
  118. );
  119. }
  120. disconnect() {
  121. super.disconnect();
  122. this.redirectedId = undefined;
  123. }
  124. }
  125. HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependencyTemplate extends HarmonyImportDependency.Template {
  126. apply(dep, source, runtime) {
  127. super.apply(dep, source, runtime);
  128. const content = this.getContent(dep, runtime);
  129. source.replace(dep.range[0], dep.range[1] - 1, content);
  130. }
  131. getContent(dep, runtime) {
  132. const exportExpr = runtime.exportFromImport({
  133. module: dep._module,
  134. request: dep.request,
  135. exportName: dep._id,
  136. originModule: dep.originModule,
  137. asiSafe: dep.shorthand,
  138. isCall: dep.call,
  139. callContext: !dep.directImport,
  140. importVar: dep.getImportVar()
  141. });
  142. return dep.shorthand ? `${dep.name}: ${exportExpr}` : exportExpr;
  143. }
  144. };
  145. module.exports = HarmonyImportSpecifierDependency;