no-console-spaces.js 2.1 KB

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