no-console-spaces.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. 'use strict';
  2. const {methodCallSelector} = require('./selectors/index.js');
  3. const toLocation = require('./utils/to-location.js');
  4. const MESSAGE_ID = 'no-console-spaces';
  5. const messages = {
  6. [MESSAGE_ID]: 'Do not use {{position}} space between `console.{{method}}` parameters.',
  7. };
  8. const methods = [
  9. 'log',
  10. 'debug',
  11. 'info',
  12. 'warn',
  13. 'error',
  14. ];
  15. const selector = methodCallSelector({
  16. methods,
  17. minimumArguments: 1,
  18. object: 'console',
  19. });
  20. // Find exactly one leading space, allow exactly one space
  21. const hasLeadingSpace = value => value.length > 1 && value.charAt(0) === ' ' && value.charAt(1) !== ' ';
  22. // Find exactly one trailing space, allow exactly one space
  23. const hasTrailingSpace = value => value.length > 1 && value.charAt(value.length - 1) === ' ' && value.charAt(value.length - 2) !== ' ';
  24. /** @param {import('eslint').Rule.RuleContext} context */
  25. const create = context => {
  26. const sourceCode = context.getSourceCode();
  27. const getProblem = (node, method, position) => {
  28. const index = position === 'leading'
  29. ? node.range[0] + 1
  30. : node.range[1] - 2;
  31. const range = [index, index + 1];
  32. return {
  33. loc: toLocation(range, sourceCode),
  34. messageId: MESSAGE_ID,
  35. data: {method, position},
  36. fix: fixer => fixer.removeRange(range),
  37. };
  38. };
  39. return {
  40. * [selector](node) {
  41. const method = node.callee.property.name;
  42. const {arguments: messages} = node;
  43. const {length} = messages;
  44. for (const [index, node] of messages.entries()) {
  45. const {type, value} = node;
  46. if (
  47. !(type === 'Literal' && typeof value === 'string')
  48. && type !== 'TemplateLiteral'
  49. ) {
  50. continue;
  51. }
  52. const raw = sourceCode.getText(node).slice(1, -1);
  53. if (index !== 0 && hasLeadingSpace(raw)) {
  54. yield getProblem(node, method, 'leading');
  55. }
  56. if (index !== length - 1 && hasTrailingSpace(raw)) {
  57. yield getProblem(node, method, 'trailing');
  58. }
  59. }
  60. },
  61. };
  62. };
  63. /** @type {import('eslint').Rule.RuleModule} */
  64. module.exports = {
  65. create,
  66. meta: {
  67. type: 'suggestion',
  68. docs: {
  69. description: 'Do not use leading/trailing space between `console.log` parameters.',
  70. },
  71. fixable: 'code',
  72. messages,
  73. },
  74. };