mark-exported-symbols-as-used.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /**
  2. * @fileoverview Simply marks exported symbols as used. Designed for use in
  3. * .jsm files only.
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. */
  9. "use strict";
  10. function markArrayElementsAsUsed(context, node, expression) {
  11. if (expression.type != "ArrayExpression") {
  12. context.report({
  13. node,
  14. message: "Unexpected assignment of non-Array to EXPORTED_SYMBOLS",
  15. });
  16. return;
  17. }
  18. for (let element of expression.elements) {
  19. context.markVariableAsUsed(element.value);
  20. }
  21. // Also mark EXPORTED_SYMBOLS as used.
  22. context.markVariableAsUsed("EXPORTED_SYMBOLS");
  23. }
  24. // Ignore assignments not in the global scope, e.g. where special module
  25. // definitions are required due to having different ways of importing files,
  26. // e.g. osfile.
  27. function isGlobalScope(context) {
  28. return !context.getScope().upper;
  29. }
  30. module.exports = {
  31. meta: {
  32. docs: {
  33. url:
  34. "https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/mark-exported-symbols-as-used.html",
  35. },
  36. type: "problem",
  37. },
  38. create(context) {
  39. return {
  40. AssignmentExpression(node, parents) {
  41. if (
  42. node.operator === "=" &&
  43. node.left.type === "MemberExpression" &&
  44. node.left.object.type === "ThisExpression" &&
  45. node.left.property.name === "EXPORTED_SYMBOLS" &&
  46. isGlobalScope(context)
  47. ) {
  48. markArrayElementsAsUsed(context, node, node.right);
  49. }
  50. },
  51. VariableDeclaration(node, parents) {
  52. if (!isGlobalScope(context)) {
  53. return;
  54. }
  55. for (let item of node.declarations) {
  56. if (
  57. item.id &&
  58. item.id.type == "Identifier" &&
  59. item.id.name === "EXPORTED_SYMBOLS"
  60. ) {
  61. if (node.kind === "let") {
  62. // The use of 'let' isn't allowed as the lexical scope may die after
  63. // the script executes.
  64. context.report({
  65. node,
  66. message:
  67. "EXPORTED_SYMBOLS cannot be declared via `let`. Use `var` or `this.EXPORTED_SYMBOLS =`",
  68. });
  69. }
  70. markArrayElementsAsUsed(context, node, item.init);
  71. }
  72. }
  73. },
  74. };
  75. },
  76. };