use-static-import.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * @fileoverview Require use of static imports where possible.
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. */
  8. "use strict";
  9. const helpers = require("../helpers");
  10. function isIdentifier(node, id) {
  11. return node && node.type === "Identifier" && node.name === id;
  12. }
  13. module.exports = {
  14. meta: {
  15. docs: {
  16. url:
  17. "https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/use-static-import.html",
  18. },
  19. fixable: "code",
  20. messages: {
  21. useStaticImport:
  22. "Please use static import instead of ChromeUtils.importESModule",
  23. },
  24. type: "suggestion",
  25. },
  26. create(context) {
  27. return {
  28. VariableDeclarator(node) {
  29. if (
  30. node.init?.type != "CallExpression" ||
  31. node.init?.callee?.type != "MemberExpression" ||
  32. !context.getFilename().endsWith(".sys.mjs") ||
  33. !helpers.isTopLevel(context.getAncestors())
  34. ) {
  35. return;
  36. }
  37. let callee = node.init.callee;
  38. if (
  39. isIdentifier(callee.object, "ChromeUtils") &&
  40. isIdentifier(callee.property, "importESModule") &&
  41. callee.parent.arguments.length == 1
  42. ) {
  43. let sourceCode = context.getSourceCode();
  44. let importItemSource;
  45. if (node.id.type != "ObjectPattern") {
  46. importItemSource = sourceCode.getText(node.id);
  47. } else {
  48. importItemSource = "{ ";
  49. let initial = true;
  50. for (let property of node.id.properties) {
  51. if (!initial) {
  52. importItemSource += ", ";
  53. }
  54. initial = false;
  55. if (property.key.name == property.value.name) {
  56. importItemSource += property.key.name;
  57. } else {
  58. importItemSource += `${property.key.name} as ${property.value.name}`;
  59. }
  60. }
  61. importItemSource += " }";
  62. }
  63. context.report({
  64. node: node.parent,
  65. messageId: "useStaticImport",
  66. fix(fixer) {
  67. return fixer.replaceText(
  68. node.parent,
  69. `import ${importItemSource} from ${sourceCode.getText(
  70. callee.parent.arguments[0]
  71. )}`
  72. );
  73. },
  74. });
  75. }
  76. },
  77. };
  78. },
  79. };