no-unreadable-array-destructuring.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. 'use strict';
  2. const {isParenthesized} = require('@eslint-community/eslint-utils');
  3. const shouldAddParenthesesToMemberExpressionObject = require('./utils/should-add-parentheses-to-member-expression-object.js');
  4. const {fixSpaceAroundKeyword} = require('./fix/index.js');
  5. const MESSAGE_ID = 'no-unreadable-array-destructuring';
  6. const messages = {
  7. [MESSAGE_ID]: 'Array destructuring may not contain consecutive ignored values.',
  8. };
  9. const isCommaFollowedWithComma = (element, index, array) =>
  10. element === null && array[index + 1] === null;
  11. /** @param {import('eslint').Rule.RuleContext} context */
  12. const create = context => {
  13. const sourceCode = context.getSourceCode();
  14. return {
  15. 'ArrayPattern[elements.length>=3]'(node) {
  16. const {elements, parent} = node;
  17. if (!elements.some((element, index, elements) => isCommaFollowedWithComma(element, index, elements))) {
  18. return;
  19. }
  20. const problem = {
  21. node,
  22. messageId: MESSAGE_ID,
  23. };
  24. const nonNullElements = elements.filter(node => node !== null);
  25. if (
  26. parent.type === 'VariableDeclarator'
  27. && parent.id === node
  28. && parent.init !== null
  29. && nonNullElements.length === 1
  30. ) {
  31. const [element] = nonNullElements;
  32. if (element.type !== 'AssignmentPattern') {
  33. problem.fix = function * (fixer) {
  34. const index = elements.indexOf(element);
  35. const isSlice = element.type === 'RestElement';
  36. const variable = isSlice ? element.argument : element;
  37. yield fixer.replaceText(node, sourceCode.getText(variable));
  38. const code = isSlice ? `.slice(${index})` : `[${index}]`;
  39. const array = parent.init;
  40. if (
  41. !isParenthesized(array, sourceCode)
  42. && shouldAddParenthesesToMemberExpressionObject(array, sourceCode)
  43. ) {
  44. yield fixer.insertTextBefore(array, '(');
  45. yield fixer.insertTextAfter(parent, `)${code}`);
  46. } else {
  47. yield fixer.insertTextAfter(parent, code);
  48. }
  49. yield * fixSpaceAroundKeyword(fixer, node, sourceCode);
  50. };
  51. }
  52. }
  53. return problem;
  54. },
  55. };
  56. };
  57. /** @type {import('eslint').Rule.RuleModule} */
  58. module.exports = {
  59. create,
  60. meta: {
  61. type: 'suggestion',
  62. docs: {
  63. description: 'Disallow unreadable array destructuring.',
  64. },
  65. fixable: 'code',
  66. messages,
  67. },
  68. };