prefer-array-flat-map.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. 'use strict';
  2. const {isNodeMatches} = require('./utils/is-node-matches.js');
  3. const {methodCallSelector, matches} = require('./selectors/index.js');
  4. const {removeMethodCall} = require('./fix/index.js');
  5. const MESSAGE_ID = 'prefer-array-flat-map';
  6. const messages = {
  7. [MESSAGE_ID]: 'Prefer `.flatMap(…)` over `.map(…).flat()`.',
  8. };
  9. const selector = [
  10. methodCallSelector('flat'),
  11. matches([
  12. '[arguments.length=0]',
  13. '[arguments.length=1][arguments.0.type="Literal"][arguments.0.raw="1"]',
  14. ]),
  15. methodCallSelector({path: 'callee.object', method: 'map'}),
  16. ].join('');
  17. const ignored = ['React.Children', 'Children'];
  18. /** @param {import('eslint').Rule.RuleContext} context */
  19. const create = context => ({
  20. [selector](flatCallExpression) {
  21. const mapCallExpression = flatCallExpression.callee.object;
  22. if (isNodeMatches(mapCallExpression.callee.object, ignored)) {
  23. return;
  24. }
  25. const sourceCode = context.getSourceCode();
  26. const mapProperty = mapCallExpression.callee.property;
  27. return {
  28. node: flatCallExpression,
  29. loc: {start: mapProperty.loc.start, end: flatCallExpression.loc.end},
  30. messageId: MESSAGE_ID,
  31. * fix(fixer) {
  32. // Removes:
  33. // map(…).flat();
  34. // ^^^^^^^
  35. // (map(…)).flat();
  36. // ^^^^^^^
  37. yield * removeMethodCall(fixer, flatCallExpression, sourceCode);
  38. // Renames:
  39. // map(…).flat();
  40. // ^^^
  41. // (map(…)).flat();
  42. // ^^^
  43. yield fixer.replaceText(mapProperty, 'flatMap');
  44. },
  45. };
  46. },
  47. });
  48. /** @type {import('eslint').Rule.RuleModule} */
  49. module.exports = {
  50. create,
  51. meta: {
  52. type: 'suggestion',
  53. docs: {
  54. description: 'Prefer `.flatMap(…)` over `.map(…).flat()`.',
  55. },
  56. fixable: 'code',
  57. messages,
  58. },
  59. };