HarmonyImportSpecifierDependency.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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 !== "default"
  75. ) {
  76. // In strict harmony modules we only support the default export
  77. const exportName = this._id
  78. ? `the named export '${this._id}'`
  79. : "the namespace object";
  80. return [
  81. new HarmonyLinkingError(
  82. `Can't import ${exportName} from non EcmaScript module (only default export is available)`
  83. )
  84. ];
  85. }
  86. return;
  87. }
  88. if (!this._id) {
  89. return;
  90. }
  91. if (importedModule.isProvided(this._id) !== false) {
  92. // It's provided or we are not sure
  93. return;
  94. }
  95. // We are sure that it's not provided
  96. const idIsNotNameMessage =
  97. this._id !== this.name ? ` (imported as '${this.name}')` : "";
  98. const errorMessage = `"export '${
  99. this._id
  100. }'${idIsNotNameMessage} was not found in '${this.userRequest}'`;
  101. return [new HarmonyLinkingError(errorMessage)];
  102. }
  103. // implement this method to allow the occurrence order plugin to count correctly
  104. getNumberOfIdOccurrences() {
  105. return 0;
  106. }
  107. updateHash(hash) {
  108. super.updateHash(hash);
  109. const importedModule = this._module;
  110. hash.update((importedModule && this._id) + "");
  111. hash.update(
  112. (importedModule && this._id && importedModule.isUsed(this._id)) + ""
  113. );
  114. hash.update(
  115. (importedModule &&
  116. (!importedModule.buildMeta || importedModule.buildMeta.exportsType)) +
  117. ""
  118. );
  119. hash.update(
  120. (importedModule &&
  121. importedModule.used + JSON.stringify(importedModule.usedExports)) + ""
  122. );
  123. }
  124. disconnect() {
  125. super.disconnect();
  126. this.redirectedId = undefined;
  127. }
  128. }
  129. HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependencyTemplate extends HarmonyImportDependency.Template {
  130. apply(dep, source, runtime) {
  131. super.apply(dep, source, runtime);
  132. const content = this.getContent(dep, runtime);
  133. source.replace(dep.range[0], dep.range[1] - 1, content);
  134. }
  135. getContent(dep, runtime) {
  136. const exportExpr = runtime.exportFromImport({
  137. module: dep._module,
  138. request: dep.request,
  139. exportName: dep._id,
  140. originModule: dep.originModule,
  141. asiSafe: dep.shorthand,
  142. isCall: dep.call,
  143. callContext: !dep.directImport,
  144. importVar: dep.getImportVar()
  145. });
  146. return dep.shorthand ? `${dep.name}: ${exportExpr}` : exportExpr;
  147. }
  148. };
  149. module.exports = HarmonyImportSpecifierDependency;