no-native-reassign.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /**
  2. * @fileoverview Rule to disallow assignments to native objects or read-only global variables
  3. * @author Ilya Volodin
  4. * @deprecated in ESLint v3.3.0
  5. */
  6. "use strict";
  7. //------------------------------------------------------------------------------
  8. // Rule Definition
  9. //------------------------------------------------------------------------------
  10. /** @type {import('../types').Rule.RuleModule} */
  11. module.exports = {
  12. meta: {
  13. type: "suggestion",
  14. docs: {
  15. description:
  16. "Disallow assignments to native objects or read-only global variables",
  17. recommended: false,
  18. url: "https://eslint.org/docs/latest/rules/no-native-reassign",
  19. },
  20. deprecated: {
  21. message: "Renamed rule.",
  22. url: "https://eslint.org/blog/2016/08/eslint-v3.3.0-released/#deprecated-rules",
  23. deprecatedSince: "3.3.0",
  24. availableUntil: "11.0.0",
  25. replacedBy: [
  26. {
  27. rule: {
  28. name: "no-global-assign",
  29. url: "https://eslint.org/docs/rules/no-global-assign",
  30. },
  31. },
  32. ],
  33. },
  34. schema: [
  35. {
  36. type: "object",
  37. properties: {
  38. exceptions: {
  39. type: "array",
  40. items: { type: "string" },
  41. uniqueItems: true,
  42. },
  43. },
  44. additionalProperties: false,
  45. },
  46. ],
  47. messages: {
  48. nativeReassign:
  49. "Read-only global '{{name}}' should not be modified.",
  50. },
  51. },
  52. create(context) {
  53. const config = context.options[0];
  54. const exceptions = (config && config.exceptions) || [];
  55. const sourceCode = context.sourceCode;
  56. /**
  57. * Reports write references.
  58. * @param {Reference} reference A reference to check.
  59. * @param {number} index The index of the reference in the references.
  60. * @param {Reference[]} references The array that the reference belongs to.
  61. * @returns {void}
  62. */
  63. function checkReference(reference, index, references) {
  64. const identifier = reference.identifier;
  65. if (
  66. reference.init === false &&
  67. reference.isWrite() &&
  68. /*
  69. * Destructuring assignments can have multiple default value,
  70. * so possibly there are multiple writeable references for the same identifier.
  71. */
  72. (index === 0 || references[index - 1].identifier !== identifier)
  73. ) {
  74. context.report({
  75. node: identifier,
  76. messageId: "nativeReassign",
  77. data: identifier,
  78. });
  79. }
  80. }
  81. /**
  82. * Reports write references if a given variable is read-only builtin.
  83. * @param {Variable} variable A variable to check.
  84. * @returns {void}
  85. */
  86. function checkVariable(variable) {
  87. if (
  88. variable.writeable === false &&
  89. !exceptions.includes(variable.name)
  90. ) {
  91. variable.references.forEach(checkReference);
  92. }
  93. }
  94. return {
  95. Program(node) {
  96. const globalScope = sourceCode.getScope(node);
  97. globalScope.variables.forEach(checkVariable);
  98. },
  99. };
  100. },
  101. };