processExportInfo.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { UsageState } = require("../ExportsInfo");
  7. /** @import { RawReferencedExports } from "../Dependency" */
  8. /** @import { ExportInfo } from "../ExportsInfo" */
  9. /** @import { RuntimeSpec } from "../util/runtime" */
  10. /**
  11. * Process export info.
  12. * @param {RuntimeSpec} runtime the runtime
  13. * @param {RawReferencedExports} referencedExports list of referenced exports, will be added to
  14. * @param {string[]} prefix export prefix
  15. * @param {InstanceType<ExportInfo>=} exportInfo the export info
  16. * @param {boolean} defaultPointsToSelf when true, using default will reference itself
  17. * @param {Set<InstanceType<ExportInfo>>=} alreadyVisited already visited export info (to handle circular reexports)
  18. */
  19. const processExportInfo = (
  20. runtime,
  21. referencedExports,
  22. prefix,
  23. exportInfo,
  24. defaultPointsToSelf = false,
  25. alreadyVisited = undefined
  26. ) => {
  27. if (!exportInfo) {
  28. referencedExports.push(prefix);
  29. return;
  30. }
  31. const used = exportInfo.getUsed(runtime);
  32. if (used === UsageState.Unused) return;
  33. if (alreadyVisited !== undefined && alreadyVisited.has(exportInfo)) {
  34. referencedExports.push(prefix);
  35. return;
  36. }
  37. // Terminal case: not recursing, so no need to track visited here
  38. if (
  39. used !== UsageState.OnlyPropertiesUsed ||
  40. !exportInfo.exportsInfo ||
  41. exportInfo.exportsInfo.otherExportsInfo.getUsed(runtime) !==
  42. UsageState.Unused
  43. ) {
  44. referencedExports.push(prefix);
  45. return;
  46. }
  47. // Only the recursive path needs the visited set; allocate it lazily
  48. const visited = alreadyVisited !== undefined ? alreadyVisited : new Set();
  49. visited.add(exportInfo);
  50. const exportsInfo = exportInfo.exportsInfo;
  51. for (const childExportInfo of exportsInfo.orderedExports) {
  52. processExportInfo(
  53. runtime,
  54. referencedExports,
  55. defaultPointsToSelf && childExportInfo.name === "default"
  56. ? prefix
  57. : [...prefix, childExportInfo.name],
  58. childExportInfo,
  59. false,
  60. visited
  61. );
  62. }
  63. visited.delete(exportInfo);
  64. };
  65. module.exports = processExportInfo;